github.com/golangci/go-tools@v0.0.0-20190318060251-af6baa5dc196/ssa/builder.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 // This file implements the BUILD phase of SSA construction. 8 // 9 // SSA construction has two phases, CREATE and BUILD. In the CREATE phase 10 // (create.go), all packages are constructed and type-checked and 11 // definitions of all package members are created, method-sets are 12 // computed, and wrapper methods are synthesized. 13 // ssa.Packages are created in arbitrary order. 14 // 15 // In the BUILD phase (builder.go), the builder traverses the AST of 16 // each Go source function and generates SSA instructions for the 17 // function body. Initializer expressions for package-level variables 18 // are emitted to the package's init() function in the order specified 19 // by go/types.Info.InitOrder, then code for each function in the 20 // package is generated in lexical order. 21 // The BUILD phases for distinct packages are independent and are 22 // executed in parallel. 23 // 24 // TODO(adonovan): indeed, building functions is now embarrassingly parallel. 25 // Audit for concurrency then benchmark using more goroutines. 26 // 27 // The builder's and Program's indices (maps) are populated and 28 // mutated during the CREATE phase, but during the BUILD phase they 29 // remain constant. The sole exception is Prog.methodSets and its 30 // related maps, which are protected by a dedicated mutex. 31 32 import ( 33 "fmt" 34 "go/ast" 35 exact "go/constant" 36 "go/token" 37 "go/types" 38 "os" 39 "sync" 40 ) 41 42 type opaqueType struct { 43 types.Type 44 name string 45 } 46 47 func (t *opaqueType) String() string { return t.name } 48 49 var ( 50 varOk = newVar("ok", tBool) 51 varIndex = newVar("index", tInt) 52 53 // Type constants. 54 tBool = types.Typ[types.Bool] 55 tByte = types.Typ[types.Byte] 56 tInt = types.Typ[types.Int] 57 tInvalid = types.Typ[types.Invalid] 58 tString = types.Typ[types.String] 59 tUntypedNil = types.Typ[types.UntypedNil] 60 tRangeIter = &opaqueType{nil, "iter"} // the type of all "range" iterators 61 tEface = types.NewInterface(nil, nil).Complete() 62 63 // SSA Value constants. 64 vZero = intConst(0) 65 vOne = intConst(1) 66 vTrue = NewConst(exact.MakeBool(true), tBool) 67 ) 68 69 // builder holds state associated with the package currently being built. 70 // Its methods contain all the logic for AST-to-SSA conversion. 71 type builder struct{} 72 73 // cond emits to fn code to evaluate boolean condition e and jump 74 // to t or f depending on its value, performing various simplifications. 75 // 76 // Postcondition: fn.currentBlock is nil. 77 // 78 func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) { 79 switch e := e.(type) { 80 case *ast.ParenExpr: 81 b.cond(fn, e.X, t, f) 82 return 83 84 case *ast.BinaryExpr: 85 switch e.Op { 86 case token.LAND: 87 ltrue := fn.newBasicBlock("cond.true") 88 b.cond(fn, e.X, ltrue, f) 89 fn.currentBlock = ltrue 90 b.cond(fn, e.Y, t, f) 91 return 92 93 case token.LOR: 94 lfalse := fn.newBasicBlock("cond.false") 95 b.cond(fn, e.X, t, lfalse) 96 fn.currentBlock = lfalse 97 b.cond(fn, e.Y, t, f) 98 return 99 } 100 101 case *ast.UnaryExpr: 102 if e.Op == token.NOT { 103 b.cond(fn, e.X, f, t) 104 return 105 } 106 } 107 108 // A traditional compiler would simplify "if false" (etc) here 109 // but we do not, for better fidelity to the source code. 110 // 111 // The value of a constant condition may be platform-specific, 112 // and may cause blocks that are reachable in some configuration 113 // to be hidden from subsequent analyses such as bug-finding tools. 114 emitIf(fn, b.expr(fn, e), t, f) 115 } 116 117 // logicalBinop emits code to fn to evaluate e, a &&- or 118 // ||-expression whose reified boolean value is wanted. 119 // The value is returned. 120 // 121 func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value { 122 rhs := fn.newBasicBlock("binop.rhs") 123 done := fn.newBasicBlock("binop.done") 124 125 // T(e) = T(e.X) = T(e.Y) after untyped constants have been 126 // eliminated. 127 // TODO(adonovan): not true; MyBool==MyBool yields UntypedBool. 128 t := fn.Pkg.typeOf(e) 129 130 var short Value // value of the short-circuit path 131 switch e.Op { 132 case token.LAND: 133 b.cond(fn, e.X, rhs, done) 134 short = NewConst(exact.MakeBool(false), t) 135 136 case token.LOR: 137 b.cond(fn, e.X, done, rhs) 138 short = NewConst(exact.MakeBool(true), t) 139 } 140 141 // Is rhs unreachable? 142 if rhs.Preds == nil { 143 // Simplify false&&y to false, true||y to true. 144 fn.currentBlock = done 145 return short 146 } 147 148 // Is done unreachable? 149 if done.Preds == nil { 150 // Simplify true&&y (or false||y) to y. 151 fn.currentBlock = rhs 152 return b.expr(fn, e.Y) 153 } 154 155 // All edges from e.X to done carry the short-circuit value. 156 var edges []Value 157 for range done.Preds { 158 edges = append(edges, short) 159 } 160 161 // The edge from e.Y to done carries the value of e.Y. 162 fn.currentBlock = rhs 163 edges = append(edges, b.expr(fn, e.Y)) 164 emitJump(fn, done) 165 fn.currentBlock = done 166 167 phi := &Phi{Edges: edges, Comment: e.Op.String()} 168 phi.pos = e.OpPos 169 phi.typ = t 170 return done.emit(phi) 171 } 172 173 // exprN lowers a multi-result expression e to SSA form, emitting code 174 // to fn and returning a single Value whose type is a *types.Tuple. 175 // The caller must access the components via Extract. 176 // 177 // Multi-result expressions include CallExprs in a multi-value 178 // assignment or return statement, and "value,ok" uses of 179 // TypeAssertExpr, IndexExpr (when X is a map), and UnaryExpr (when Op 180 // is token.ARROW). 181 // 182 func (b *builder) exprN(fn *Function, e ast.Expr) Value { 183 typ := fn.Pkg.typeOf(e).(*types.Tuple) 184 switch e := e.(type) { 185 case *ast.ParenExpr: 186 return b.exprN(fn, e.X) 187 188 case *ast.CallExpr: 189 // Currently, no built-in function nor type conversion 190 // has multiple results, so we can avoid some of the 191 // cases for single-valued CallExpr. 192 var c Call 193 b.setCall(fn, e, &c.Call) 194 c.typ = typ 195 return fn.emit(&c) 196 197 case *ast.IndexExpr: 198 mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) 199 lookup := &Lookup{ 200 X: b.expr(fn, e.X), 201 Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()), 202 CommaOk: true, 203 } 204 lookup.setType(typ) 205 lookup.setPos(e.Lbrack) 206 return fn.emit(lookup) 207 208 case *ast.TypeAssertExpr: 209 return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e.Lparen) 210 211 case *ast.UnaryExpr: // must be receive <- 212 unop := &UnOp{ 213 Op: token.ARROW, 214 X: b.expr(fn, e.X), 215 CommaOk: true, 216 } 217 unop.setType(typ) 218 unop.setPos(e.OpPos) 219 return fn.emit(unop) 220 } 221 panic(fmt.Sprintf("exprN(%T) in %s", e, fn)) 222 } 223 224 // builtin emits to fn SSA instructions to implement a call to the 225 // built-in function obj with the specified arguments 226 // and return type. It returns the value defined by the result. 227 // 228 // The result is nil if no special handling was required; in this case 229 // the caller should treat this like an ordinary library function 230 // call. 231 // 232 func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, pos token.Pos) Value { 233 switch obj.Name() { 234 case "make": 235 switch typ.Underlying().(type) { 236 case *types.Slice: 237 n := b.expr(fn, args[1]) 238 m := n 239 if len(args) == 3 { 240 m = b.expr(fn, args[2]) 241 } 242 if m, ok := m.(*Const); ok { 243 // treat make([]T, n, m) as new([m]T)[:n] 244 cap := m.Int64() 245 at := types.NewArray(typ.Underlying().(*types.Slice).Elem(), cap) 246 alloc := emitNew(fn, at, pos) 247 alloc.Comment = "makeslice" 248 v := &Slice{ 249 X: alloc, 250 High: n, 251 } 252 v.setPos(pos) 253 v.setType(typ) 254 return fn.emit(v) 255 } 256 v := &MakeSlice{ 257 Len: n, 258 Cap: m, 259 } 260 v.setPos(pos) 261 v.setType(typ) 262 return fn.emit(v) 263 264 case *types.Map: 265 var res Value 266 if len(args) == 2 { 267 res = b.expr(fn, args[1]) 268 } 269 v := &MakeMap{Reserve: res} 270 v.setPos(pos) 271 v.setType(typ) 272 return fn.emit(v) 273 274 case *types.Chan: 275 var sz Value = vZero 276 if len(args) == 2 { 277 sz = b.expr(fn, args[1]) 278 } 279 v := &MakeChan{Size: sz} 280 v.setPos(pos) 281 v.setType(typ) 282 return fn.emit(v) 283 } 284 285 case "new": 286 alloc := emitNew(fn, deref(typ), pos) 287 alloc.Comment = "new" 288 return alloc 289 290 case "len", "cap": 291 // Special case: len or cap of an array or *array is 292 // based on the type, not the value which may be nil. 293 // We must still evaluate the value, though. (If it 294 // was side-effect free, the whole call would have 295 // been constant-folded.) 296 t := deref(fn.Pkg.typeOf(args[0])).Underlying() 297 if at, ok := t.(*types.Array); ok { 298 b.expr(fn, args[0]) // for effects only 299 return intConst(at.Len()) 300 } 301 // Otherwise treat as normal. 302 303 case "panic": 304 fn.emit(&Panic{ 305 X: emitConv(fn, b.expr(fn, args[0]), tEface), 306 pos: pos, 307 }) 308 fn.currentBlock = fn.newBasicBlock("unreachable") 309 return vTrue // any non-nil Value will do 310 } 311 return nil // treat all others as a regular function call 312 } 313 314 // addr lowers a single-result addressable expression e to SSA form, 315 // emitting code to fn and returning the location (an lvalue) defined 316 // by the expression. 317 // 318 // If escaping is true, addr marks the base variable of the 319 // addressable expression e as being a potentially escaping pointer 320 // value. For example, in this code: 321 // 322 // a := A{ 323 // b: [1]B{B{c: 1}} 324 // } 325 // return &a.b[0].c 326 // 327 // the application of & causes a.b[0].c to have its address taken, 328 // which means that ultimately the local variable a must be 329 // heap-allocated. This is a simple but very conservative escape 330 // analysis. 331 // 332 // Operations forming potentially escaping pointers include: 333 // - &x, including when implicit in method call or composite literals. 334 // - a[:] iff a is an array (not *array) 335 // - references to variables in lexically enclosing functions. 336 // 337 func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { 338 switch e := e.(type) { 339 case *ast.Ident: 340 if isBlankIdent(e) { 341 return blank{} 342 } 343 obj := fn.Pkg.objectOf(e) 344 v := fn.Prog.packageLevelValue(obj) // var (address) 345 if v == nil { 346 v = fn.lookup(obj, escaping) 347 } 348 return &address{addr: v, pos: e.Pos(), expr: e} 349 350 case *ast.CompositeLit: 351 t := deref(fn.Pkg.typeOf(e)) 352 var v *Alloc 353 if escaping { 354 v = emitNew(fn, t, e.Lbrace) 355 } else { 356 v = fn.addLocal(t, e.Lbrace) 357 } 358 v.Comment = "complit" 359 var sb storebuf 360 b.compLit(fn, v, e, true, &sb) 361 sb.emit(fn) 362 return &address{addr: v, pos: e.Lbrace, expr: e} 363 364 case *ast.ParenExpr: 365 return b.addr(fn, e.X, escaping) 366 367 case *ast.SelectorExpr: 368 sel, ok := fn.Pkg.info.Selections[e] 369 if !ok { 370 // qualified identifier 371 return b.addr(fn, e.Sel, escaping) 372 } 373 if sel.Kind() != types.FieldVal { 374 panic(sel) 375 } 376 wantAddr := true 377 v := b.receiver(fn, e.X, wantAddr, escaping, sel) 378 last := len(sel.Index()) - 1 379 return &address{ 380 addr: emitFieldSelection(fn, v, sel.Index()[last], true, e.Sel), 381 pos: e.Sel.Pos(), 382 expr: e.Sel, 383 } 384 385 case *ast.IndexExpr: 386 var x Value 387 var et types.Type 388 switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { 389 case *types.Array: 390 x = b.addr(fn, e.X, escaping).address(fn) 391 et = types.NewPointer(t.Elem()) 392 case *types.Pointer: // *array 393 x = b.expr(fn, e.X) 394 et = types.NewPointer(t.Elem().Underlying().(*types.Array).Elem()) 395 case *types.Slice: 396 x = b.expr(fn, e.X) 397 et = types.NewPointer(t.Elem()) 398 case *types.Map: 399 return &element{ 400 m: b.expr(fn, e.X), 401 k: emitConv(fn, b.expr(fn, e.Index), t.Key()), 402 t: t.Elem(), 403 pos: e.Lbrack, 404 } 405 default: 406 panic("unexpected container type in IndexExpr: " + t.String()) 407 } 408 v := &IndexAddr{ 409 X: x, 410 Index: emitConv(fn, b.expr(fn, e.Index), tInt), 411 } 412 v.setPos(e.Lbrack) 413 v.setType(et) 414 return &address{addr: fn.emit(v), pos: e.Lbrack, expr: e} 415 416 case *ast.StarExpr: 417 return &address{addr: b.expr(fn, e.X), pos: e.Star, expr: e} 418 } 419 420 panic(fmt.Sprintf("unexpected address expression: %T", e)) 421 } 422 423 type store struct { 424 lhs lvalue 425 rhs Value 426 } 427 428 type storebuf struct{ stores []store } 429 430 func (sb *storebuf) store(lhs lvalue, rhs Value) { 431 sb.stores = append(sb.stores, store{lhs, rhs}) 432 } 433 434 func (sb *storebuf) emit(fn *Function) { 435 for _, s := range sb.stores { 436 s.lhs.store(fn, s.rhs) 437 } 438 } 439 440 // assign emits to fn code to initialize the lvalue loc with the value 441 // of expression e. If isZero is true, assign assumes that loc holds 442 // the zero value for its type. 443 // 444 // This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate 445 // better code in some cases, e.g., for composite literals in an 446 // addressable location. 447 // 448 // If sb is not nil, assign generates code to evaluate expression e, but 449 // not to update loc. Instead, the necessary stores are appended to the 450 // storebuf sb so that they can be executed later. This allows correct 451 // in-place update of existing variables when the RHS is a composite 452 // literal that may reference parts of the LHS. 453 // 454 func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf) { 455 // Can we initialize it in place? 456 if e, ok := unparen(e).(*ast.CompositeLit); ok { 457 // A CompositeLit never evaluates to a pointer, 458 // so if the type of the location is a pointer, 459 // an &-operation is implied. 460 if _, ok := loc.(blank); !ok { // avoid calling blank.typ() 461 if isPointer(loc.typ()) { 462 ptr := b.addr(fn, e, true).address(fn) 463 // copy address 464 if sb != nil { 465 sb.store(loc, ptr) 466 } else { 467 loc.store(fn, ptr) 468 } 469 return 470 } 471 } 472 473 if _, ok := loc.(*address); ok { 474 if isInterface(loc.typ()) { 475 // e.g. var x interface{} = T{...} 476 // Can't in-place initialize an interface value. 477 // Fall back to copying. 478 } else { 479 // x = T{...} or x := T{...} 480 addr := loc.address(fn) 481 if sb != nil { 482 b.compLit(fn, addr, e, isZero, sb) 483 } else { 484 var sb storebuf 485 b.compLit(fn, addr, e, isZero, &sb) 486 sb.emit(fn) 487 } 488 489 // Subtle: emit debug ref for aggregate types only; 490 // slice and map are handled by store ops in compLit. 491 switch loc.typ().Underlying().(type) { 492 case *types.Struct, *types.Array: 493 emitDebugRef(fn, e, addr, true) 494 } 495 496 return 497 } 498 } 499 } 500 501 // simple case: just copy 502 rhs := b.expr(fn, e) 503 if sb != nil { 504 sb.store(loc, rhs) 505 } else { 506 loc.store(fn, rhs) 507 } 508 } 509 510 // expr lowers a single-result expression e to SSA form, emitting code 511 // to fn and returning the Value defined by the expression. 512 // 513 func (b *builder) expr(fn *Function, e ast.Expr) Value { 514 e = unparen(e) 515 516 tv := fn.Pkg.info.Types[e] 517 518 // Is expression a constant? 519 if tv.Value != nil { 520 return NewConst(tv.Value, tv.Type) 521 } 522 523 var v Value 524 if tv.Addressable() { 525 // Prefer pointer arithmetic ({Index,Field}Addr) followed 526 // by Load over subelement extraction (e.g. Index, Field), 527 // to avoid large copies. 528 v = b.addr(fn, e, false).load(fn) 529 } else { 530 v = b.expr0(fn, e, tv) 531 } 532 if fn.debugInfo() { 533 emitDebugRef(fn, e, v, false) 534 } 535 return v 536 } 537 538 func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { 539 switch e := e.(type) { 540 case *ast.BasicLit: 541 panic("non-constant BasicLit") // unreachable 542 543 case *ast.FuncLit: 544 fn2 := &Function{ 545 name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)), 546 Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature), 547 pos: e.Type.Func, 548 parent: fn, 549 Pkg: fn.Pkg, 550 Prog: fn.Prog, 551 syntax: e, 552 } 553 fn.AnonFuncs = append(fn.AnonFuncs, fn2) 554 b.buildFunction(fn2) 555 if fn2.FreeVars == nil { 556 return fn2 557 } 558 v := &MakeClosure{Fn: fn2} 559 v.setType(tv.Type) 560 for _, fv := range fn2.FreeVars { 561 v.Bindings = append(v.Bindings, fv.outer) 562 fv.outer = nil 563 } 564 return fn.emit(v) 565 566 case *ast.TypeAssertExpr: // single-result form only 567 return emitTypeAssert(fn, b.expr(fn, e.X), tv.Type, e.Lparen) 568 569 case *ast.CallExpr: 570 if fn.Pkg.info.Types[e.Fun].IsType() { 571 // Explicit type conversion, e.g. string(x) or big.Int(x) 572 x := b.expr(fn, e.Args[0]) 573 y := emitConv(fn, x, tv.Type) 574 if y != x { 575 switch y := y.(type) { 576 case *Convert: 577 y.pos = e.Lparen 578 case *ChangeType: 579 y.pos = e.Lparen 580 case *MakeInterface: 581 y.pos = e.Lparen 582 } 583 } 584 return y 585 } 586 // Call to "intrinsic" built-ins, e.g. new, make, panic. 587 if id, ok := unparen(e.Fun).(*ast.Ident); ok { 588 if obj, ok := fn.Pkg.info.Uses[id].(*types.Builtin); ok { 589 if v := b.builtin(fn, obj, e.Args, tv.Type, e.Lparen); v != nil { 590 return v 591 } 592 } 593 } 594 // Regular function call. 595 var v Call 596 b.setCall(fn, e, &v.Call) 597 v.setType(tv.Type) 598 return fn.emit(&v) 599 600 case *ast.UnaryExpr: 601 switch e.Op { 602 case token.AND: // &X --- potentially escaping. 603 addr := b.addr(fn, e.X, true) 604 if _, ok := unparen(e.X).(*ast.StarExpr); ok { 605 // &*p must panic if p is nil (http://golang.org/s/go12nil). 606 // For simplicity, we'll just (suboptimally) rely 607 // on the side effects of a load. 608 // TODO(adonovan): emit dedicated nilcheck. 609 addr.load(fn) 610 } 611 return addr.address(fn) 612 case token.ADD: 613 return b.expr(fn, e.X) 614 case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^ 615 v := &UnOp{ 616 Op: e.Op, 617 X: b.expr(fn, e.X), 618 } 619 v.setPos(e.OpPos) 620 v.setType(tv.Type) 621 return fn.emit(v) 622 default: 623 panic(e.Op) 624 } 625 626 case *ast.BinaryExpr: 627 switch e.Op { 628 case token.LAND, token.LOR: 629 return b.logicalBinop(fn, e) 630 case token.SHL, token.SHR: 631 fallthrough 632 case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: 633 return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), tv.Type, e.OpPos) 634 635 case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ: 636 cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e.OpPos) 637 // The type of x==y may be UntypedBool. 638 return emitConv(fn, cmp, DefaultType(tv.Type)) 639 default: 640 panic("illegal op in BinaryExpr: " + e.Op.String()) 641 } 642 643 case *ast.SliceExpr: 644 var low, high, max Value 645 var x Value 646 switch fn.Pkg.typeOf(e.X).Underlying().(type) { 647 case *types.Array: 648 // Potentially escaping. 649 x = b.addr(fn, e.X, true).address(fn) 650 case *types.Basic, *types.Slice, *types.Pointer: // *array 651 x = b.expr(fn, e.X) 652 default: 653 panic("unreachable") 654 } 655 if e.High != nil { 656 high = b.expr(fn, e.High) 657 } 658 if e.Low != nil { 659 low = b.expr(fn, e.Low) 660 } 661 if e.Slice3 { 662 max = b.expr(fn, e.Max) 663 } 664 v := &Slice{ 665 X: x, 666 Low: low, 667 High: high, 668 Max: max, 669 } 670 v.setPos(e.Lbrack) 671 v.setType(tv.Type) 672 return fn.emit(v) 673 674 case *ast.Ident: 675 obj := fn.Pkg.info.Uses[e] 676 // Universal built-in or nil? 677 switch obj := obj.(type) { 678 case *types.Builtin: 679 return &Builtin{name: obj.Name(), sig: tv.Type.(*types.Signature)} 680 case *types.Nil: 681 return nilConst(tv.Type) 682 } 683 // Package-level func or var? 684 if v := fn.Prog.packageLevelValue(obj); v != nil { 685 if _, ok := obj.(*types.Var); ok { 686 return emitLoad(fn, v) // var (address) 687 } 688 return v // (func) 689 } 690 // Local var. 691 return emitLoad(fn, fn.lookup(obj, false)) // var (address) 692 693 case *ast.SelectorExpr: 694 sel, ok := fn.Pkg.info.Selections[e] 695 if !ok { 696 // qualified identifier 697 return b.expr(fn, e.Sel) 698 } 699 switch sel.Kind() { 700 case types.MethodExpr: 701 // (*T).f or T.f, the method f from the method-set of type T. 702 // The result is a "thunk". 703 return emitConv(fn, makeThunk(fn.Prog, sel), tv.Type) 704 705 case types.MethodVal: 706 // e.f where e is an expression and f is a method. 707 // The result is a "bound". 708 obj := sel.Obj().(*types.Func) 709 rt := recvType(obj) 710 wantAddr := isPointer(rt) 711 escaping := true 712 v := b.receiver(fn, e.X, wantAddr, escaping, sel) 713 if isInterface(rt) { 714 // If v has interface type I, 715 // we must emit a check that v is non-nil. 716 // We use: typeassert v.(I). 717 emitTypeAssert(fn, v, rt, token.NoPos) 718 } 719 c := &MakeClosure{ 720 Fn: makeBound(fn.Prog, obj), 721 Bindings: []Value{v}, 722 } 723 c.setPos(e.Sel.Pos()) 724 c.setType(tv.Type) 725 return fn.emit(c) 726 727 case types.FieldVal: 728 indices := sel.Index() 729 last := len(indices) - 1 730 v := b.expr(fn, e.X) 731 v = emitImplicitSelections(fn, v, indices[:last]) 732 v = emitFieldSelection(fn, v, indices[last], false, e.Sel) 733 return v 734 } 735 736 panic("unexpected expression-relative selector") 737 738 case *ast.IndexExpr: 739 switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { 740 case *types.Array: 741 // Non-addressable array (in a register). 742 v := &Index{ 743 X: b.expr(fn, e.X), 744 Index: emitConv(fn, b.expr(fn, e.Index), tInt), 745 } 746 v.setPos(e.Lbrack) 747 v.setType(t.Elem()) 748 return fn.emit(v) 749 750 case *types.Map: 751 // Maps are not addressable. 752 mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) 753 v := &Lookup{ 754 X: b.expr(fn, e.X), 755 Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()), 756 } 757 v.setPos(e.Lbrack) 758 v.setType(mapt.Elem()) 759 return fn.emit(v) 760 761 case *types.Basic: // => string 762 // Strings are not addressable. 763 v := &Lookup{ 764 X: b.expr(fn, e.X), 765 Index: b.expr(fn, e.Index), 766 } 767 v.setPos(e.Lbrack) 768 v.setType(tByte) 769 return fn.emit(v) 770 771 case *types.Slice, *types.Pointer: // *array 772 // Addressable slice/array; use IndexAddr and Load. 773 return b.addr(fn, e, false).load(fn) 774 775 default: 776 panic("unexpected container type in IndexExpr: " + t.String()) 777 } 778 779 case *ast.CompositeLit, *ast.StarExpr: 780 // Addressable types (lvalues) 781 return b.addr(fn, e, false).load(fn) 782 } 783 784 panic(fmt.Sprintf("unexpected expr: %T", e)) 785 } 786 787 // stmtList emits to fn code for all statements in list. 788 func (b *builder) stmtList(fn *Function, list []ast.Stmt) { 789 for _, s := range list { 790 b.stmt(fn, s) 791 } 792 } 793 794 // receiver emits to fn code for expression e in the "receiver" 795 // position of selection e.f (where f may be a field or a method) and 796 // returns the effective receiver after applying the implicit field 797 // selections of sel. 798 // 799 // wantAddr requests that the result is an an address. If 800 // !sel.Indirect(), this may require that e be built in addr() mode; it 801 // must thus be addressable. 802 // 803 // escaping is defined as per builder.addr(). 804 // 805 func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *types.Selection) Value { 806 var v Value 807 if wantAddr && !sel.Indirect() && !isPointer(fn.Pkg.typeOf(e)) { 808 v = b.addr(fn, e, escaping).address(fn) 809 } else { 810 v = b.expr(fn, e) 811 } 812 813 last := len(sel.Index()) - 1 814 v = emitImplicitSelections(fn, v, sel.Index()[:last]) 815 if !wantAddr && isPointer(v.Type()) { 816 v = emitLoad(fn, v) 817 } 818 return v 819 } 820 821 // setCallFunc populates the function parts of a CallCommon structure 822 // (Func, Method, Recv, Args[0]) based on the kind of invocation 823 // occurring in e. 824 // 825 func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) { 826 c.pos = e.Lparen 827 828 // Is this a method call? 829 if selector, ok := unparen(e.Fun).(*ast.SelectorExpr); ok { 830 sel, ok := fn.Pkg.info.Selections[selector] 831 if ok && sel.Kind() == types.MethodVal { 832 obj := sel.Obj().(*types.Func) 833 recv := recvType(obj) 834 wantAddr := isPointer(recv) 835 escaping := true 836 v := b.receiver(fn, selector.X, wantAddr, escaping, sel) 837 if isInterface(recv) { 838 // Invoke-mode call. 839 c.Value = v 840 c.Method = obj 841 } else { 842 // "Call"-mode call. 843 c.Value = fn.Prog.declaredFunc(obj) 844 c.Args = append(c.Args, v) 845 } 846 return 847 } 848 849 // sel.Kind()==MethodExpr indicates T.f() or (*T).f(): 850 // a statically dispatched call to the method f in the 851 // method-set of T or *T. T may be an interface. 852 // 853 // e.Fun would evaluate to a concrete method, interface 854 // wrapper function, or promotion wrapper. 855 // 856 // For now, we evaluate it in the usual way. 857 // 858 // TODO(adonovan): opt: inline expr() here, to make the 859 // call static and to avoid generation of wrappers. 860 // It's somewhat tricky as it may consume the first 861 // actual parameter if the call is "invoke" mode. 862 // 863 // Examples: 864 // type T struct{}; func (T) f() {} // "call" mode 865 // type T interface { f() } // "invoke" mode 866 // 867 // type S struct{ T } 868 // 869 // var s S 870 // S.f(s) 871 // (*S).f(&s) 872 // 873 // Suggested approach: 874 // - consume the first actual parameter expression 875 // and build it with b.expr(). 876 // - apply implicit field selections. 877 // - use MethodVal logic to populate fields of c. 878 } 879 880 // Evaluate the function operand in the usual way. 881 c.Value = b.expr(fn, e.Fun) 882 } 883 884 // emitCallArgs emits to f code for the actual parameters of call e to 885 // a (possibly built-in) function of effective type sig. 886 // The argument values are appended to args, which is then returned. 887 // 888 func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value { 889 // f(x, y, z...): pass slice z straight through. 890 if e.Ellipsis != 0 { 891 for i, arg := range e.Args { 892 v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type()) 893 args = append(args, v) 894 } 895 return args 896 } 897 898 offset := len(args) // 1 if call has receiver, 0 otherwise 899 900 // Evaluate actual parameter expressions. 901 // 902 // If this is a chained call of the form f(g()) where g has 903 // multiple return values (MRV), they are flattened out into 904 // args; a suffix of them may end up in a varargs slice. 905 for _, arg := range e.Args { 906 v := b.expr(fn, arg) 907 if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain 908 for i, n := 0, ttuple.Len(); i < n; i++ { 909 args = append(args, emitExtract(fn, v, i)) 910 } 911 } else { 912 args = append(args, v) 913 } 914 } 915 916 // Actual->formal assignability conversions for normal parameters. 917 np := sig.Params().Len() // number of normal parameters 918 if sig.Variadic() { 919 np-- 920 } 921 for i := 0; i < np; i++ { 922 args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type()) 923 } 924 925 // Actual->formal assignability conversions for variadic parameter, 926 // and construction of slice. 927 if sig.Variadic() { 928 varargs := args[offset+np:] 929 st := sig.Params().At(np).Type().(*types.Slice) 930 vt := st.Elem() 931 if len(varargs) == 0 { 932 args = append(args, nilConst(st)) 933 } else { 934 // Replace a suffix of args with a slice containing it. 935 at := types.NewArray(vt, int64(len(varargs))) 936 a := emitNew(fn, at, token.NoPos) 937 a.setPos(e.Rparen) 938 a.Comment = "varargs" 939 for i, arg := range varargs { 940 iaddr := &IndexAddr{ 941 X: a, 942 Index: intConst(int64(i)), 943 } 944 iaddr.setType(types.NewPointer(vt)) 945 fn.emit(iaddr) 946 emitStore(fn, iaddr, arg, arg.Pos()) 947 } 948 s := &Slice{X: a} 949 s.setType(st) 950 args[offset+np] = fn.emit(s) 951 args = args[:offset+np+1] 952 } 953 } 954 return args 955 } 956 957 // setCall emits to fn code to evaluate all the parameters of a function 958 // call e, and populates *c with those values. 959 // 960 func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { 961 // First deal with the f(...) part and optional receiver. 962 b.setCallFunc(fn, e, c) 963 964 // Then append the other actual parameters. 965 sig, _ := fn.Pkg.typeOf(e.Fun).Underlying().(*types.Signature) 966 if sig == nil { 967 panic(fmt.Sprintf("no signature for call of %s", e.Fun)) 968 } 969 c.Args = b.emitCallArgs(fn, sig, e, c.Args) 970 } 971 972 // assignOp emits to fn code to perform loc += incr or loc -= incr. 973 func (b *builder) assignOp(fn *Function, loc lvalue, incr Value, op token.Token, pos token.Pos) { 974 oldv := loc.load(fn) 975 loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, incr, oldv.Type()), loc.typ(), pos)) 976 } 977 978 // localValueSpec emits to fn code to define all of the vars in the 979 // function-local ValueSpec, spec. 980 // 981 func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) { 982 switch { 983 case len(spec.Values) == len(spec.Names): 984 // e.g. var x, y = 0, 1 985 // 1:1 assignment 986 for i, id := range spec.Names { 987 if !isBlankIdent(id) { 988 fn.addLocalForIdent(id) 989 } 990 lval := b.addr(fn, id, false) // non-escaping 991 b.assign(fn, lval, spec.Values[i], true, nil) 992 } 993 994 case len(spec.Values) == 0: 995 // e.g. var x, y int 996 // Locals are implicitly zero-initialized. 997 for _, id := range spec.Names { 998 if !isBlankIdent(id) { 999 lhs := fn.addLocalForIdent(id) 1000 if fn.debugInfo() { 1001 emitDebugRef(fn, id, lhs, true) 1002 } 1003 } 1004 } 1005 1006 default: 1007 // e.g. var x, y = pos() 1008 tuple := b.exprN(fn, spec.Values[0]) 1009 for i, id := range spec.Names { 1010 if !isBlankIdent(id) { 1011 fn.addLocalForIdent(id) 1012 lhs := b.addr(fn, id, false) // non-escaping 1013 lhs.store(fn, emitExtract(fn, tuple, i)) 1014 } 1015 } 1016 } 1017 } 1018 1019 // assignStmt emits code to fn for a parallel assignment of rhss to lhss. 1020 // isDef is true if this is a short variable declaration (:=). 1021 // 1022 // Note the similarity with localValueSpec. 1023 // 1024 func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) { 1025 // Side effects of all LHSs and RHSs must occur in left-to-right order. 1026 lvals := make([]lvalue, len(lhss)) 1027 isZero := make([]bool, len(lhss)) 1028 for i, lhs := range lhss { 1029 var lval lvalue = blank{} 1030 if !isBlankIdent(lhs) { 1031 if isDef { 1032 if obj := fn.Pkg.info.Defs[lhs.(*ast.Ident)]; obj != nil { 1033 fn.addNamedLocal(obj) 1034 isZero[i] = true 1035 } 1036 } 1037 lval = b.addr(fn, lhs, false) // non-escaping 1038 } 1039 lvals[i] = lval 1040 } 1041 if len(lhss) == len(rhss) { 1042 // Simple assignment: x = f() (!isDef) 1043 // Parallel assignment: x, y = f(), g() (!isDef) 1044 // or short var decl: x, y := f(), g() (isDef) 1045 // 1046 // In all cases, the RHSs may refer to the LHSs, 1047 // so we need a storebuf. 1048 var sb storebuf 1049 for i := range rhss { 1050 b.assign(fn, lvals[i], rhss[i], isZero[i], &sb) 1051 } 1052 sb.emit(fn) 1053 } else { 1054 // e.g. x, y = pos() 1055 tuple := b.exprN(fn, rhss[0]) 1056 emitDebugRef(fn, rhss[0], tuple, false) 1057 for i, lval := range lvals { 1058 lval.store(fn, emitExtract(fn, tuple, i)) 1059 } 1060 } 1061 } 1062 1063 // arrayLen returns the length of the array whose composite literal elements are elts. 1064 func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 { 1065 var max int64 = -1 1066 var i int64 = -1 1067 for _, e := range elts { 1068 if kv, ok := e.(*ast.KeyValueExpr); ok { 1069 i = b.expr(fn, kv.Key).(*Const).Int64() 1070 } else { 1071 i++ 1072 } 1073 if i > max { 1074 max = i 1075 } 1076 } 1077 return max + 1 1078 } 1079 1080 // compLit emits to fn code to initialize a composite literal e at 1081 // address addr with type typ. 1082 // 1083 // Nested composite literals are recursively initialized in place 1084 // where possible. If isZero is true, compLit assumes that addr 1085 // holds the zero value for typ. 1086 // 1087 // Because the elements of a composite literal may refer to the 1088 // variables being updated, as in the second line below, 1089 // x := T{a: 1} 1090 // x = T{a: x.a} 1091 // all the reads must occur before all the writes. Thus all stores to 1092 // loc are emitted to the storebuf sb for later execution. 1093 // 1094 // A CompositeLit may have pointer type only in the recursive (nested) 1095 // case when the type name is implicit. e.g. in []*T{{}}, the inner 1096 // literal has type *T behaves like &T{}. 1097 // In that case, addr must hold a T, not a *T. 1098 // 1099 func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) { 1100 typ := deref(fn.Pkg.typeOf(e)) 1101 switch t := typ.Underlying().(type) { 1102 case *types.Struct: 1103 if !isZero && len(e.Elts) != t.NumFields() { 1104 // memclear 1105 sb.store(&address{addr, e.Lbrace, nil}, 1106 zeroValue(fn, deref(addr.Type()))) 1107 isZero = true 1108 } 1109 for i, e := range e.Elts { 1110 fieldIndex := i 1111 pos := e.Pos() 1112 if kv, ok := e.(*ast.KeyValueExpr); ok { 1113 fname := kv.Key.(*ast.Ident).Name 1114 for i, n := 0, t.NumFields(); i < n; i++ { 1115 sf := t.Field(i) 1116 if sf.Name() == fname { 1117 fieldIndex = i 1118 pos = kv.Colon 1119 e = kv.Value 1120 break 1121 } 1122 } 1123 } 1124 sf := t.Field(fieldIndex) 1125 faddr := &FieldAddr{ 1126 X: addr, 1127 Field: fieldIndex, 1128 } 1129 faddr.setType(types.NewPointer(sf.Type())) 1130 fn.emit(faddr) 1131 b.assign(fn, &address{addr: faddr, pos: pos, expr: e}, e, isZero, sb) 1132 } 1133 1134 case *types.Array, *types.Slice: 1135 var at *types.Array 1136 var array Value 1137 switch t := t.(type) { 1138 case *types.Slice: 1139 at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts)) 1140 alloc := emitNew(fn, at, e.Lbrace) 1141 alloc.Comment = "slicelit" 1142 array = alloc 1143 case *types.Array: 1144 at = t 1145 array = addr 1146 1147 if !isZero && int64(len(e.Elts)) != at.Len() { 1148 // memclear 1149 sb.store(&address{array, e.Lbrace, nil}, 1150 zeroValue(fn, deref(array.Type()))) 1151 } 1152 } 1153 1154 var idx *Const 1155 for _, e := range e.Elts { 1156 pos := e.Pos() 1157 if kv, ok := e.(*ast.KeyValueExpr); ok { 1158 idx = b.expr(fn, kv.Key).(*Const) 1159 pos = kv.Colon 1160 e = kv.Value 1161 } else { 1162 var idxval int64 1163 if idx != nil { 1164 idxval = idx.Int64() + 1 1165 } 1166 idx = intConst(idxval) 1167 } 1168 iaddr := &IndexAddr{ 1169 X: array, 1170 Index: idx, 1171 } 1172 iaddr.setType(types.NewPointer(at.Elem())) 1173 fn.emit(iaddr) 1174 if t != at { // slice 1175 // backing array is unaliased => storebuf not needed. 1176 b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, nil) 1177 } else { 1178 b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, sb) 1179 } 1180 } 1181 1182 if t != at { // slice 1183 s := &Slice{X: array} 1184 s.setPos(e.Lbrace) 1185 s.setType(typ) 1186 sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, fn.emit(s)) 1187 } 1188 1189 case *types.Map: 1190 m := &MakeMap{Reserve: intConst(int64(len(e.Elts)))} 1191 m.setPos(e.Lbrace) 1192 m.setType(typ) 1193 fn.emit(m) 1194 for _, e := range e.Elts { 1195 e := e.(*ast.KeyValueExpr) 1196 1197 // If a key expression in a map literal is itself a 1198 // composite literal, the type may be omitted. 1199 // For example: 1200 // map[*struct{}]bool{{}: true} 1201 // An &-operation may be implied: 1202 // map[*struct{}]bool{&struct{}{}: true} 1203 var key Value 1204 if _, ok := unparen(e.Key).(*ast.CompositeLit); ok && isPointer(t.Key()) { 1205 // A CompositeLit never evaluates to a pointer, 1206 // so if the type of the location is a pointer, 1207 // an &-operation is implied. 1208 key = b.addr(fn, e.Key, true).address(fn) 1209 } else { 1210 key = b.expr(fn, e.Key) 1211 } 1212 1213 loc := element{ 1214 m: m, 1215 k: emitConv(fn, key, t.Key()), 1216 t: t.Elem(), 1217 pos: e.Colon, 1218 } 1219 1220 // We call assign() only because it takes care 1221 // of any &-operation required in the recursive 1222 // case, e.g., 1223 // map[int]*struct{}{0: {}} implies &struct{}{}. 1224 // In-place update is of course impossible, 1225 // and no storebuf is needed. 1226 b.assign(fn, &loc, e.Value, true, nil) 1227 } 1228 sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, m) 1229 1230 default: 1231 panic("unexpected CompositeLit type: " + t.String()) 1232 } 1233 } 1234 1235 // switchStmt emits to fn code for the switch statement s, optionally 1236 // labelled by label. 1237 // 1238 func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) { 1239 // We treat SwitchStmt like a sequential if-else chain. 1240 // Multiway dispatch can be recovered later by ssautil.Switches() 1241 // to those cases that are free of side effects. 1242 if s.Init != nil { 1243 b.stmt(fn, s.Init) 1244 } 1245 var tag Value = vTrue 1246 if s.Tag != nil { 1247 tag = b.expr(fn, s.Tag) 1248 } 1249 done := fn.newBasicBlock("switch.done") 1250 if label != nil { 1251 label._break = done 1252 } 1253 // We pull the default case (if present) down to the end. 1254 // But each fallthrough label must point to the next 1255 // body block in source order, so we preallocate a 1256 // body block (fallthru) for the next case. 1257 // Unfortunately this makes for a confusing block order. 1258 var dfltBody *[]ast.Stmt 1259 var dfltFallthrough *BasicBlock 1260 var fallthru, dfltBlock *BasicBlock 1261 ncases := len(s.Body.List) 1262 for i, clause := range s.Body.List { 1263 body := fallthru 1264 if body == nil { 1265 body = fn.newBasicBlock("switch.body") // first case only 1266 } 1267 1268 // Preallocate body block for the next case. 1269 fallthru = done 1270 if i+1 < ncases { 1271 fallthru = fn.newBasicBlock("switch.body") 1272 } 1273 1274 cc := clause.(*ast.CaseClause) 1275 if cc.List == nil { 1276 // Default case. 1277 dfltBody = &cc.Body 1278 dfltFallthrough = fallthru 1279 dfltBlock = body 1280 continue 1281 } 1282 1283 var nextCond *BasicBlock 1284 for _, cond := range cc.List { 1285 nextCond = fn.newBasicBlock("switch.next") 1286 // TODO(adonovan): opt: when tag==vTrue, we'd 1287 // get better code if we use b.cond(cond) 1288 // instead of BinOp(EQL, tag, b.expr(cond)) 1289 // followed by If. Don't forget conversions 1290 // though. 1291 cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos()) 1292 emitIf(fn, cond, body, nextCond) 1293 fn.currentBlock = nextCond 1294 } 1295 fn.currentBlock = body 1296 fn.targets = &targets{ 1297 tail: fn.targets, 1298 _break: done, 1299 _fallthrough: fallthru, 1300 } 1301 b.stmtList(fn, cc.Body) 1302 fn.targets = fn.targets.tail 1303 emitJump(fn, done) 1304 fn.currentBlock = nextCond 1305 } 1306 if dfltBlock != nil { 1307 emitJump(fn, dfltBlock) 1308 fn.currentBlock = dfltBlock 1309 fn.targets = &targets{ 1310 tail: fn.targets, 1311 _break: done, 1312 _fallthrough: dfltFallthrough, 1313 } 1314 b.stmtList(fn, *dfltBody) 1315 fn.targets = fn.targets.tail 1316 } 1317 emitJump(fn, done) 1318 fn.currentBlock = done 1319 } 1320 1321 // typeSwitchStmt emits to fn code for the type switch statement s, optionally 1322 // labelled by label. 1323 // 1324 func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) { 1325 // We treat TypeSwitchStmt like a sequential if-else chain. 1326 // Multiway dispatch can be recovered later by ssautil.Switches(). 1327 1328 // Typeswitch lowering: 1329 // 1330 // var x X 1331 // switch y := x.(type) { 1332 // case T1, T2: S1 // >1 (y := x) 1333 // case nil: SN // nil (y := x) 1334 // default: SD // 0 types (y := x) 1335 // case T3: S3 // 1 type (y := x.(T3)) 1336 // } 1337 // 1338 // ...s.Init... 1339 // x := eval x 1340 // .caseT1: 1341 // t1, ok1 := typeswitch,ok x <T1> 1342 // if ok1 then goto S1 else goto .caseT2 1343 // .caseT2: 1344 // t2, ok2 := typeswitch,ok x <T2> 1345 // if ok2 then goto S1 else goto .caseNil 1346 // .S1: 1347 // y := x 1348 // ...S1... 1349 // goto done 1350 // .caseNil: 1351 // if t2, ok2 := typeswitch,ok x <T2> 1352 // if x == nil then goto SN else goto .caseT3 1353 // .SN: 1354 // y := x 1355 // ...SN... 1356 // goto done 1357 // .caseT3: 1358 // t3, ok3 := typeswitch,ok x <T3> 1359 // if ok3 then goto S3 else goto default 1360 // .S3: 1361 // y := t3 1362 // ...S3... 1363 // goto done 1364 // .default: 1365 // y := x 1366 // ...SD... 1367 // goto done 1368 // .done: 1369 1370 if s.Init != nil { 1371 b.stmt(fn, s.Init) 1372 } 1373 1374 var x Value 1375 switch ass := s.Assign.(type) { 1376 case *ast.ExprStmt: // x.(type) 1377 x = b.expr(fn, unparen(ass.X).(*ast.TypeAssertExpr).X) 1378 case *ast.AssignStmt: // y := x.(type) 1379 x = b.expr(fn, unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X) 1380 } 1381 1382 done := fn.newBasicBlock("typeswitch.done") 1383 if label != nil { 1384 label._break = done 1385 } 1386 var default_ *ast.CaseClause 1387 for _, clause := range s.Body.List { 1388 cc := clause.(*ast.CaseClause) 1389 if cc.List == nil { 1390 default_ = cc 1391 continue 1392 } 1393 body := fn.newBasicBlock("typeswitch.body") 1394 var next *BasicBlock 1395 var casetype types.Type 1396 var ti Value // ti, ok := typeassert,ok x <Ti> 1397 for _, cond := range cc.List { 1398 next = fn.newBasicBlock("typeswitch.next") 1399 casetype = fn.Pkg.typeOf(cond) 1400 var condv Value 1401 if casetype == tUntypedNil { 1402 condv = emitCompare(fn, token.EQL, x, nilConst(x.Type()), token.NoPos) 1403 ti = x 1404 } else { 1405 yok := emitTypeTest(fn, x, casetype, cc.Case) 1406 ti = emitExtract(fn, yok, 0) 1407 condv = emitExtract(fn, yok, 1) 1408 } 1409 emitIf(fn, condv, body, next) 1410 fn.currentBlock = next 1411 } 1412 if len(cc.List) != 1 { 1413 ti = x 1414 } 1415 fn.currentBlock = body 1416 b.typeCaseBody(fn, cc, ti, done) 1417 fn.currentBlock = next 1418 } 1419 if default_ != nil { 1420 b.typeCaseBody(fn, default_, x, done) 1421 } else { 1422 emitJump(fn, done) 1423 } 1424 fn.currentBlock = done 1425 } 1426 1427 func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) { 1428 if obj := fn.Pkg.info.Implicits[cc]; obj != nil { 1429 // In a switch y := x.(type), each case clause 1430 // implicitly declares a distinct object y. 1431 // In a single-type case, y has that type. 1432 // In multi-type cases, 'case nil' and default, 1433 // y has the same type as the interface operand. 1434 emitStore(fn, fn.addNamedLocal(obj), x, obj.Pos()) 1435 } 1436 fn.targets = &targets{ 1437 tail: fn.targets, 1438 _break: done, 1439 } 1440 b.stmtList(fn, cc.Body) 1441 fn.targets = fn.targets.tail 1442 emitJump(fn, done) 1443 } 1444 1445 // selectStmt emits to fn code for the select statement s, optionally 1446 // labelled by label. 1447 // 1448 func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) { 1449 // A blocking select of a single case degenerates to a 1450 // simple send or receive. 1451 // TODO(adonovan): opt: is this optimization worth its weight? 1452 if len(s.Body.List) == 1 { 1453 clause := s.Body.List[0].(*ast.CommClause) 1454 if clause.Comm != nil { 1455 b.stmt(fn, clause.Comm) 1456 done := fn.newBasicBlock("select.done") 1457 if label != nil { 1458 label._break = done 1459 } 1460 fn.targets = &targets{ 1461 tail: fn.targets, 1462 _break: done, 1463 } 1464 b.stmtList(fn, clause.Body) 1465 fn.targets = fn.targets.tail 1466 emitJump(fn, done) 1467 fn.currentBlock = done 1468 return 1469 } 1470 } 1471 1472 // First evaluate all channels in all cases, and find 1473 // the directions of each state. 1474 var states []*SelectState 1475 blocking := true 1476 debugInfo := fn.debugInfo() 1477 for _, clause := range s.Body.List { 1478 var st *SelectState 1479 switch comm := clause.(*ast.CommClause).Comm.(type) { 1480 case nil: // default case 1481 blocking = false 1482 continue 1483 1484 case *ast.SendStmt: // ch<- i 1485 ch := b.expr(fn, comm.Chan) 1486 st = &SelectState{ 1487 Dir: types.SendOnly, 1488 Chan: ch, 1489 Send: emitConv(fn, b.expr(fn, comm.Value), 1490 ch.Type().Underlying().(*types.Chan).Elem()), 1491 Pos: comm.Arrow, 1492 } 1493 if debugInfo { 1494 st.DebugNode = comm 1495 } 1496 1497 case *ast.AssignStmt: // x := <-ch 1498 recv := unparen(comm.Rhs[0]).(*ast.UnaryExpr) 1499 st = &SelectState{ 1500 Dir: types.RecvOnly, 1501 Chan: b.expr(fn, recv.X), 1502 Pos: recv.OpPos, 1503 } 1504 if debugInfo { 1505 st.DebugNode = recv 1506 } 1507 1508 case *ast.ExprStmt: // <-ch 1509 recv := unparen(comm.X).(*ast.UnaryExpr) 1510 st = &SelectState{ 1511 Dir: types.RecvOnly, 1512 Chan: b.expr(fn, recv.X), 1513 Pos: recv.OpPos, 1514 } 1515 if debugInfo { 1516 st.DebugNode = recv 1517 } 1518 } 1519 states = append(states, st) 1520 } 1521 1522 // We dispatch on the (fair) result of Select using a 1523 // sequential if-else chain, in effect: 1524 // 1525 // idx, recvOk, r0...r_n-1 := select(...) 1526 // if idx == 0 { // receive on channel 0 (first receive => r0) 1527 // x, ok := r0, recvOk 1528 // ...state0... 1529 // } else if v == 1 { // send on channel 1 1530 // ...state1... 1531 // } else { 1532 // ...default... 1533 // } 1534 sel := &Select{ 1535 States: states, 1536 Blocking: blocking, 1537 } 1538 sel.setPos(s.Select) 1539 var vars []*types.Var 1540 vars = append(vars, varIndex, varOk) 1541 for _, st := range states { 1542 if st.Dir == types.RecvOnly { 1543 tElem := st.Chan.Type().Underlying().(*types.Chan).Elem() 1544 vars = append(vars, anonVar(tElem)) 1545 } 1546 } 1547 sel.setType(types.NewTuple(vars...)) 1548 1549 fn.emit(sel) 1550 idx := emitExtract(fn, sel, 0) 1551 1552 done := fn.newBasicBlock("select.done") 1553 if label != nil { 1554 label._break = done 1555 } 1556 1557 var defaultBody *[]ast.Stmt 1558 state := 0 1559 r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV 1560 for _, cc := range s.Body.List { 1561 clause := cc.(*ast.CommClause) 1562 if clause.Comm == nil { 1563 defaultBody = &clause.Body 1564 continue 1565 } 1566 body := fn.newBasicBlock("select.body") 1567 next := fn.newBasicBlock("select.next") 1568 emitIf(fn, emitCompare(fn, token.EQL, idx, intConst(int64(state)), token.NoPos), body, next) 1569 fn.currentBlock = body 1570 fn.targets = &targets{ 1571 tail: fn.targets, 1572 _break: done, 1573 } 1574 switch comm := clause.Comm.(type) { 1575 case *ast.ExprStmt: // <-ch 1576 if debugInfo { 1577 v := emitExtract(fn, sel, r) 1578 emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) 1579 } 1580 r++ 1581 1582 case *ast.AssignStmt: // x := <-states[state].Chan 1583 if comm.Tok == token.DEFINE { 1584 fn.addLocalForIdent(comm.Lhs[0].(*ast.Ident)) 1585 } 1586 x := b.addr(fn, comm.Lhs[0], false) // non-escaping 1587 v := emitExtract(fn, sel, r) 1588 if debugInfo { 1589 emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) 1590 } 1591 x.store(fn, v) 1592 1593 if len(comm.Lhs) == 2 { // x, ok := ... 1594 if comm.Tok == token.DEFINE { 1595 fn.addLocalForIdent(comm.Lhs[1].(*ast.Ident)) 1596 } 1597 ok := b.addr(fn, comm.Lhs[1], false) // non-escaping 1598 ok.store(fn, emitExtract(fn, sel, 1)) 1599 } 1600 r++ 1601 } 1602 b.stmtList(fn, clause.Body) 1603 fn.targets = fn.targets.tail 1604 emitJump(fn, done) 1605 fn.currentBlock = next 1606 state++ 1607 } 1608 if defaultBody != nil { 1609 fn.targets = &targets{ 1610 tail: fn.targets, 1611 _break: done, 1612 } 1613 b.stmtList(fn, *defaultBody) 1614 fn.targets = fn.targets.tail 1615 } else { 1616 // A blocking select must match some case. 1617 // (This should really be a runtime.errorString, not a string.) 1618 fn.emit(&Panic{ 1619 X: emitConv(fn, stringConst("blocking select matched no case"), tEface), 1620 }) 1621 fn.currentBlock = fn.newBasicBlock("unreachable") 1622 } 1623 emitJump(fn, done) 1624 fn.currentBlock = done 1625 } 1626 1627 // forStmt emits to fn code for the for statement s, optionally 1628 // labelled by label. 1629 // 1630 func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) { 1631 // ...init... 1632 // jump loop 1633 // loop: 1634 // if cond goto body else done 1635 // body: 1636 // ...body... 1637 // jump post 1638 // post: (target of continue) 1639 // ...post... 1640 // jump loop 1641 // done: (target of break) 1642 if s.Init != nil { 1643 b.stmt(fn, s.Init) 1644 } 1645 body := fn.newBasicBlock("for.body") 1646 done := fn.newBasicBlock("for.done") // target of 'break' 1647 loop := body // target of back-edge 1648 if s.Cond != nil { 1649 loop = fn.newBasicBlock("for.loop") 1650 } 1651 cont := loop // target of 'continue' 1652 if s.Post != nil { 1653 cont = fn.newBasicBlock("for.post") 1654 } 1655 if label != nil { 1656 label._break = done 1657 label._continue = cont 1658 } 1659 emitJump(fn, loop) 1660 fn.currentBlock = loop 1661 if loop != body { 1662 b.cond(fn, s.Cond, body, done) 1663 fn.currentBlock = body 1664 } 1665 fn.targets = &targets{ 1666 tail: fn.targets, 1667 _break: done, 1668 _continue: cont, 1669 } 1670 b.stmt(fn, s.Body) 1671 fn.targets = fn.targets.tail 1672 emitJump(fn, cont) 1673 1674 if s.Post != nil { 1675 fn.currentBlock = cont 1676 b.stmt(fn, s.Post) 1677 emitJump(fn, loop) // back-edge 1678 } 1679 fn.currentBlock = done 1680 } 1681 1682 // rangeIndexed emits to fn the header for an integer-indexed loop 1683 // over array, *array or slice value x. 1684 // The v result is defined only if tv is non-nil. 1685 // forPos is the position of the "for" token. 1686 // 1687 func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) { 1688 // 1689 // length = len(x) 1690 // index = -1 1691 // loop: (target of continue) 1692 // index++ 1693 // if index < length goto body else done 1694 // body: 1695 // k = index 1696 // v = x[index] 1697 // ...body... 1698 // jump loop 1699 // done: (target of break) 1700 1701 // Determine number of iterations. 1702 var length Value 1703 if arr, ok := deref(x.Type()).Underlying().(*types.Array); ok { 1704 // For array or *array, the number of iterations is 1705 // known statically thanks to the type. We avoid a 1706 // data dependence upon x, permitting later dead-code 1707 // elimination if x is pure, static unrolling, etc. 1708 // Ranging over a nil *array may have >0 iterations. 1709 // We still generate code for x, in case it has effects. 1710 length = intConst(arr.Len()) 1711 } else { 1712 // length = len(x). 1713 var c Call 1714 c.Call.Value = makeLen(x.Type()) 1715 c.Call.Args = []Value{x} 1716 c.setType(tInt) 1717 length = fn.emit(&c) 1718 } 1719 1720 index := fn.addLocal(tInt, token.NoPos) 1721 emitStore(fn, index, intConst(-1), pos) 1722 1723 loop = fn.newBasicBlock("rangeindex.loop") 1724 emitJump(fn, loop) 1725 fn.currentBlock = loop 1726 1727 incr := &BinOp{ 1728 Op: token.ADD, 1729 X: emitLoad(fn, index), 1730 Y: vOne, 1731 } 1732 incr.setType(tInt) 1733 emitStore(fn, index, fn.emit(incr), pos) 1734 1735 body := fn.newBasicBlock("rangeindex.body") 1736 done = fn.newBasicBlock("rangeindex.done") 1737 emitIf(fn, emitCompare(fn, token.LSS, incr, length, token.NoPos), body, done) 1738 fn.currentBlock = body 1739 1740 k = emitLoad(fn, index) 1741 if tv != nil { 1742 switch t := x.Type().Underlying().(type) { 1743 case *types.Array: 1744 instr := &Index{ 1745 X: x, 1746 Index: k, 1747 } 1748 instr.setType(t.Elem()) 1749 v = fn.emit(instr) 1750 1751 case *types.Pointer: // *array 1752 instr := &IndexAddr{ 1753 X: x, 1754 Index: k, 1755 } 1756 instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem())) 1757 v = emitLoad(fn, fn.emit(instr)) 1758 1759 case *types.Slice: 1760 instr := &IndexAddr{ 1761 X: x, 1762 Index: k, 1763 } 1764 instr.setType(types.NewPointer(t.Elem())) 1765 v = emitLoad(fn, fn.emit(instr)) 1766 1767 default: 1768 panic("rangeIndexed x:" + t.String()) 1769 } 1770 } 1771 return 1772 } 1773 1774 // rangeIter emits to fn the header for a loop using 1775 // Range/Next/Extract to iterate over map or string value x. 1776 // tk and tv are the types of the key/value results k and v, or nil 1777 // if the respective component is not wanted. 1778 // 1779 func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) { 1780 // 1781 // it = range x 1782 // loop: (target of continue) 1783 // okv = next it (ok, key, value) 1784 // ok = extract okv #0 1785 // if ok goto body else done 1786 // body: 1787 // k = extract okv #1 1788 // v = extract okv #2 1789 // ...body... 1790 // jump loop 1791 // done: (target of break) 1792 // 1793 1794 if tk == nil { 1795 tk = tInvalid 1796 } 1797 if tv == nil { 1798 tv = tInvalid 1799 } 1800 1801 rng := &Range{X: x} 1802 rng.setPos(pos) 1803 rng.setType(tRangeIter) 1804 it := fn.emit(rng) 1805 1806 loop = fn.newBasicBlock("rangeiter.loop") 1807 emitJump(fn, loop) 1808 fn.currentBlock = loop 1809 1810 _, isString := x.Type().Underlying().(*types.Basic) 1811 1812 okv := &Next{ 1813 Iter: it, 1814 IsString: isString, 1815 } 1816 okv.setType(types.NewTuple( 1817 varOk, 1818 newVar("k", tk), 1819 newVar("v", tv), 1820 )) 1821 fn.emit(okv) 1822 1823 body := fn.newBasicBlock("rangeiter.body") 1824 done = fn.newBasicBlock("rangeiter.done") 1825 emitIf(fn, emitExtract(fn, okv, 0), body, done) 1826 fn.currentBlock = body 1827 1828 if tk != tInvalid { 1829 k = emitExtract(fn, okv, 1) 1830 } 1831 if tv != tInvalid { 1832 v = emitExtract(fn, okv, 2) 1833 } 1834 return 1835 } 1836 1837 // rangeChan emits to fn the header for a loop that receives from 1838 // channel x until it fails. 1839 // tk is the channel's element type, or nil if the k result is 1840 // not wanted 1841 // pos is the position of the '=' or ':=' token. 1842 // 1843 func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) { 1844 // 1845 // loop: (target of continue) 1846 // ko = <-x (key, ok) 1847 // ok = extract ko #1 1848 // if ok goto body else done 1849 // body: 1850 // k = extract ko #0 1851 // ... 1852 // goto loop 1853 // done: (target of break) 1854 1855 loop = fn.newBasicBlock("rangechan.loop") 1856 emitJump(fn, loop) 1857 fn.currentBlock = loop 1858 recv := &UnOp{ 1859 Op: token.ARROW, 1860 X: x, 1861 CommaOk: true, 1862 } 1863 recv.setPos(pos) 1864 recv.setType(types.NewTuple( 1865 newVar("k", x.Type().Underlying().(*types.Chan).Elem()), 1866 varOk, 1867 )) 1868 ko := fn.emit(recv) 1869 body := fn.newBasicBlock("rangechan.body") 1870 done = fn.newBasicBlock("rangechan.done") 1871 emitIf(fn, emitExtract(fn, ko, 1), body, done) 1872 fn.currentBlock = body 1873 if tk != nil { 1874 k = emitExtract(fn, ko, 0) 1875 } 1876 return 1877 } 1878 1879 // rangeStmt emits to fn code for the range statement s, optionally 1880 // labelled by label. 1881 // 1882 func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) { 1883 var tk, tv types.Type 1884 if s.Key != nil && !isBlankIdent(s.Key) { 1885 tk = fn.Pkg.typeOf(s.Key) 1886 } 1887 if s.Value != nil && !isBlankIdent(s.Value) { 1888 tv = fn.Pkg.typeOf(s.Value) 1889 } 1890 1891 // If iteration variables are defined (:=), this 1892 // occurs once outside the loop. 1893 // 1894 // Unlike a short variable declaration, a RangeStmt 1895 // using := never redeclares an existing variable; it 1896 // always creates a new one. 1897 if s.Tok == token.DEFINE { 1898 if tk != nil { 1899 fn.addLocalForIdent(s.Key.(*ast.Ident)) 1900 } 1901 if tv != nil { 1902 fn.addLocalForIdent(s.Value.(*ast.Ident)) 1903 } 1904 } 1905 1906 x := b.expr(fn, s.X) 1907 1908 var k, v Value 1909 var loop, done *BasicBlock 1910 switch rt := x.Type().Underlying().(type) { 1911 case *types.Slice, *types.Array, *types.Pointer: // *array 1912 k, v, loop, done = b.rangeIndexed(fn, x, tv, s.For) 1913 1914 case *types.Chan: 1915 k, loop, done = b.rangeChan(fn, x, tk, s.For) 1916 1917 case *types.Map, *types.Basic: // string 1918 k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For) 1919 1920 default: 1921 panic("Cannot range over: " + rt.String()) 1922 } 1923 1924 // Evaluate both LHS expressions before we update either. 1925 var kl, vl lvalue 1926 if tk != nil { 1927 kl = b.addr(fn, s.Key, false) // non-escaping 1928 } 1929 if tv != nil { 1930 vl = b.addr(fn, s.Value, false) // non-escaping 1931 } 1932 if tk != nil { 1933 kl.store(fn, k) 1934 } 1935 if tv != nil { 1936 vl.store(fn, v) 1937 } 1938 1939 if label != nil { 1940 label._break = done 1941 label._continue = loop 1942 } 1943 1944 fn.targets = &targets{ 1945 tail: fn.targets, 1946 _break: done, 1947 _continue: loop, 1948 } 1949 b.stmt(fn, s.Body) 1950 fn.targets = fn.targets.tail 1951 emitJump(fn, loop) // back-edge 1952 fn.currentBlock = done 1953 } 1954 1955 // stmt lowers statement s to SSA form, emitting code to fn. 1956 func (b *builder) stmt(fn *Function, _s ast.Stmt) { 1957 // The label of the current statement. If non-nil, its _goto 1958 // target is always set; its _break and _continue are set only 1959 // within the body of switch/typeswitch/select/for/range. 1960 // It is effectively an additional default-nil parameter of stmt(). 1961 var label *lblock 1962 start: 1963 switch s := _s.(type) { 1964 case *ast.EmptyStmt: 1965 // ignore. (Usually removed by gofmt.) 1966 1967 case *ast.DeclStmt: // Con, Var or Typ 1968 d := s.Decl.(*ast.GenDecl) 1969 if d.Tok == token.VAR { 1970 for _, spec := range d.Specs { 1971 if vs, ok := spec.(*ast.ValueSpec); ok { 1972 b.localValueSpec(fn, vs) 1973 } 1974 } 1975 } 1976 1977 case *ast.LabeledStmt: 1978 label = fn.labelledBlock(s.Label) 1979 emitJump(fn, label._goto) 1980 fn.currentBlock = label._goto 1981 _s = s.Stmt 1982 goto start // effectively: tailcall stmt(fn, s.Stmt, label) 1983 1984 case *ast.ExprStmt: 1985 b.expr(fn, s.X) 1986 1987 case *ast.SendStmt: 1988 fn.emit(&Send{ 1989 Chan: b.expr(fn, s.Chan), 1990 X: emitConv(fn, b.expr(fn, s.Value), 1991 fn.Pkg.typeOf(s.Chan).Underlying().(*types.Chan).Elem()), 1992 pos: s.Arrow, 1993 }) 1994 1995 case *ast.IncDecStmt: 1996 op := token.ADD 1997 if s.Tok == token.DEC { 1998 op = token.SUB 1999 } 2000 loc := b.addr(fn, s.X, false) 2001 b.assignOp(fn, loc, NewConst(exact.MakeInt64(1), loc.typ()), op, s.Pos()) 2002 2003 case *ast.AssignStmt: 2004 switch s.Tok { 2005 case token.ASSIGN, token.DEFINE: 2006 b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE) 2007 2008 default: // +=, etc. 2009 op := s.Tok + token.ADD - token.ADD_ASSIGN 2010 b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s.Pos()) 2011 } 2012 2013 case *ast.GoStmt: 2014 // The "intrinsics" new/make/len/cap are forbidden here. 2015 // panic is treated like an ordinary function call. 2016 v := Go{pos: s.Go} 2017 b.setCall(fn, s.Call, &v.Call) 2018 fn.emit(&v) 2019 2020 case *ast.DeferStmt: 2021 // The "intrinsics" new/make/len/cap are forbidden here. 2022 // panic is treated like an ordinary function call. 2023 v := Defer{pos: s.Defer} 2024 b.setCall(fn, s.Call, &v.Call) 2025 fn.emit(&v) 2026 2027 // A deferred call can cause recovery from panic, 2028 // and control resumes at the Recover block. 2029 createRecoverBlock(fn) 2030 2031 case *ast.ReturnStmt: 2032 var results []Value 2033 if len(s.Results) == 1 && fn.Signature.Results().Len() > 1 { 2034 // Return of one expression in a multi-valued function. 2035 tuple := b.exprN(fn, s.Results[0]) 2036 ttuple := tuple.Type().(*types.Tuple) 2037 for i, n := 0, ttuple.Len(); i < n; i++ { 2038 results = append(results, 2039 emitConv(fn, emitExtract(fn, tuple, i), 2040 fn.Signature.Results().At(i).Type())) 2041 } 2042 } else { 2043 // 1:1 return, or no-arg return in non-void function. 2044 for i, r := range s.Results { 2045 v := emitConv(fn, b.expr(fn, r), fn.Signature.Results().At(i).Type()) 2046 results = append(results, v) 2047 } 2048 } 2049 if fn.namedResults != nil { 2050 // Function has named result parameters (NRPs). 2051 // Perform parallel assignment of return operands to NRPs. 2052 for i, r := range results { 2053 emitStore(fn, fn.namedResults[i], r, s.Return) 2054 } 2055 } 2056 // Run function calls deferred in this 2057 // function when explicitly returning from it. 2058 fn.emit(new(RunDefers)) 2059 if fn.namedResults != nil { 2060 // Reload NRPs to form the result tuple. 2061 results = results[:0] 2062 for _, r := range fn.namedResults { 2063 results = append(results, emitLoad(fn, r)) 2064 } 2065 } 2066 fn.emit(&Return{Results: results, pos: s.Return}) 2067 fn.currentBlock = fn.newBasicBlock("unreachable") 2068 2069 case *ast.BranchStmt: 2070 var block *BasicBlock 2071 switch s.Tok { 2072 case token.BREAK: 2073 if s.Label != nil { 2074 block = fn.labelledBlock(s.Label)._break 2075 } else { 2076 for t := fn.targets; t != nil && block == nil; t = t.tail { 2077 block = t._break 2078 } 2079 } 2080 2081 case token.CONTINUE: 2082 if s.Label != nil { 2083 block = fn.labelledBlock(s.Label)._continue 2084 } else { 2085 for t := fn.targets; t != nil && block == nil; t = t.tail { 2086 block = t._continue 2087 } 2088 } 2089 2090 case token.FALLTHROUGH: 2091 for t := fn.targets; t != nil && block == nil; t = t.tail { 2092 block = t._fallthrough 2093 } 2094 2095 case token.GOTO: 2096 block = fn.labelledBlock(s.Label)._goto 2097 } 2098 emitJump(fn, block) 2099 fn.currentBlock = fn.newBasicBlock("unreachable") 2100 2101 case *ast.BlockStmt: 2102 b.stmtList(fn, s.List) 2103 2104 case *ast.IfStmt: 2105 if s.Init != nil { 2106 b.stmt(fn, s.Init) 2107 } 2108 then := fn.newBasicBlock("if.then") 2109 done := fn.newBasicBlock("if.done") 2110 els := done 2111 if s.Else != nil { 2112 els = fn.newBasicBlock("if.else") 2113 } 2114 b.cond(fn, s.Cond, then, els) 2115 fn.currentBlock = then 2116 b.stmt(fn, s.Body) 2117 emitJump(fn, done) 2118 2119 if s.Else != nil { 2120 fn.currentBlock = els 2121 b.stmt(fn, s.Else) 2122 emitJump(fn, done) 2123 } 2124 2125 fn.currentBlock = done 2126 2127 case *ast.SwitchStmt: 2128 b.switchStmt(fn, s, label) 2129 2130 case *ast.TypeSwitchStmt: 2131 b.typeSwitchStmt(fn, s, label) 2132 2133 case *ast.SelectStmt: 2134 b.selectStmt(fn, s, label) 2135 2136 case *ast.ForStmt: 2137 b.forStmt(fn, s, label) 2138 2139 case *ast.RangeStmt: 2140 b.rangeStmt(fn, s, label) 2141 2142 default: 2143 panic(fmt.Sprintf("unexpected statement kind: %T", s)) 2144 } 2145 } 2146 2147 // buildFunction builds SSA code for the body of function fn. Idempotent. 2148 func (b *builder) buildFunction(fn *Function) { 2149 if fn.Blocks != nil { 2150 return // building already started 2151 } 2152 2153 var recvField *ast.FieldList 2154 var body *ast.BlockStmt 2155 var functype *ast.FuncType 2156 switch n := fn.syntax.(type) { 2157 case nil: 2158 return // not a Go source function. (Synthetic, or from object file.) 2159 case *ast.FuncDecl: 2160 functype = n.Type 2161 recvField = n.Recv 2162 body = n.Body 2163 case *ast.FuncLit: 2164 functype = n.Type 2165 body = n.Body 2166 default: 2167 panic(n) 2168 } 2169 2170 if body == nil { 2171 // External function. 2172 if fn.Params == nil { 2173 // This condition ensures we add a non-empty 2174 // params list once only, but we may attempt 2175 // the degenerate empty case repeatedly. 2176 // TODO(adonovan): opt: don't do that. 2177 2178 // We set Function.Params even though there is no body 2179 // code to reference them. This simplifies clients. 2180 if recv := fn.Signature.Recv(); recv != nil { 2181 fn.addParamObj(recv) 2182 } 2183 params := fn.Signature.Params() 2184 for i, n := 0, params.Len(); i < n; i++ { 2185 fn.addParamObj(params.At(i)) 2186 } 2187 } 2188 return 2189 } 2190 if fn.Prog.mode&LogSource != 0 { 2191 defer logStack("build function %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))() 2192 } 2193 fn.startBody() 2194 fn.createSyntacticParams(recvField, functype) 2195 b.stmt(fn, body) 2196 if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) { 2197 // Control fell off the end of the function's body block. 2198 // 2199 // Block optimizations eliminate the current block, if 2200 // unreachable. It is a builder invariant that 2201 // if this no-arg return is ill-typed for 2202 // fn.Signature.Results, this block must be 2203 // unreachable. The sanity checker checks this. 2204 fn.emit(new(RunDefers)) 2205 fn.emit(new(Return)) 2206 } 2207 fn.finishBody() 2208 } 2209 2210 // buildFuncDecl builds SSA code for the function or method declared 2211 // by decl in package pkg. 2212 // 2213 func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) { 2214 id := decl.Name 2215 if isBlankIdent(id) { 2216 return // discard 2217 } 2218 fn := pkg.values[pkg.info.Defs[id]].(*Function) 2219 if decl.Recv == nil && id.Name == "init" { 2220 var v Call 2221 v.Call.Value = fn 2222 v.setType(types.NewTuple()) 2223 pkg.init.emit(&v) 2224 } 2225 b.buildFunction(fn) 2226 } 2227 2228 // Build calls Package.Build for each package in prog. 2229 // Building occurs in parallel unless the BuildSerially mode flag was set. 2230 // 2231 // Build is intended for whole-program analysis; a typical compiler 2232 // need only build a single package. 2233 // 2234 // Build is idempotent and thread-safe. 2235 // 2236 func (prog *Program) Build() { 2237 var wg sync.WaitGroup 2238 for _, p := range prog.packages { 2239 if prog.mode&BuildSerially != 0 { 2240 p.Build() 2241 } else { 2242 wg.Add(1) 2243 go func(p *Package) { 2244 p.Build() 2245 wg.Done() 2246 }(p) 2247 } 2248 } 2249 wg.Wait() 2250 } 2251 2252 // Build builds SSA code for all functions and vars in package p. 2253 // 2254 // Precondition: CreatePackage must have been called for all of p's 2255 // direct imports (and hence its direct imports must have been 2256 // error-free). 2257 // 2258 // Build is idempotent and thread-safe. 2259 // 2260 func (p *Package) Build() { p.buildOnce.Do(p.build) } 2261 2262 func (p *Package) build() { 2263 if p.info == nil { 2264 return // synthetic package, e.g. "testmain" 2265 } 2266 2267 // Ensure we have runtime type info for all exported members. 2268 // TODO(adonovan): ideally belongs in memberFromObject, but 2269 // that would require package creation in topological order. 2270 for name, mem := range p.Members { 2271 if ast.IsExported(name) { 2272 p.Prog.needMethodsOf(mem.Type()) 2273 } 2274 } 2275 if p.Prog.mode&LogSource != 0 { 2276 defer logStack("build %s", p)() 2277 } 2278 init := p.init 2279 init.startBody() 2280 2281 var done *BasicBlock 2282 2283 if p.Prog.mode&BareInits == 0 { 2284 // Make init() skip if package is already initialized. 2285 initguard := p.Var("init$guard") 2286 doinit := init.newBasicBlock("init.start") 2287 done = init.newBasicBlock("init.done") 2288 emitIf(init, emitLoad(init, initguard), done, doinit) 2289 init.currentBlock = doinit 2290 emitStore(init, initguard, vTrue, token.NoPos) 2291 2292 // Call the init() function of each package we import. 2293 for _, pkg := range p.Pkg.Imports() { 2294 prereq := p.Prog.packages[pkg] 2295 if prereq == nil { 2296 panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path())) 2297 } 2298 var v Call 2299 v.Call.Value = prereq.init 2300 v.Call.pos = init.pos 2301 v.setType(types.NewTuple()) 2302 init.emit(&v) 2303 } 2304 } 2305 2306 var b builder 2307 2308 // Initialize package-level vars in correct order. 2309 for _, varinit := range p.info.InitOrder { 2310 if init.Prog.mode&LogSource != 0 { 2311 fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n", 2312 varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos())) 2313 } 2314 if len(varinit.Lhs) == 1 { 2315 // 1:1 initialization: var x, y = a(), b() 2316 var lval lvalue 2317 if v := varinit.Lhs[0]; v.Name() != "_" { 2318 lval = &address{addr: p.values[v].(*Global), pos: v.Pos()} 2319 } else { 2320 lval = blank{} 2321 } 2322 b.assign(init, lval, varinit.Rhs, true, nil) 2323 } else { 2324 // n:1 initialization: var x, y := f() 2325 tuple := b.exprN(init, varinit.Rhs) 2326 for i, v := range varinit.Lhs { 2327 if v.Name() == "_" { 2328 continue 2329 } 2330 emitStore(init, p.values[v].(*Global), emitExtract(init, tuple, i), v.Pos()) 2331 } 2332 } 2333 } 2334 2335 // Build all package-level functions, init functions 2336 // and methods, including unreachable/blank ones. 2337 // We build them in source order, but it's not significant. 2338 for _, file := range p.files { 2339 for _, decl := range file.Decls { 2340 if decl, ok := decl.(*ast.FuncDecl); ok { 2341 b.buildFuncDecl(p, decl) 2342 } 2343 } 2344 } 2345 2346 // Finish up init(). 2347 if p.Prog.mode&BareInits == 0 { 2348 emitJump(init, done) 2349 init.currentBlock = done 2350 } 2351 init.emit(new(Return)) 2352 init.finishBody() 2353 2354 p.info = nil // We no longer need ASTs or go/types deductions. 2355 2356 if p.Prog.mode&SanityCheckFunctions != 0 { 2357 sanityCheckPackage(p) 2358 } 2359 } 2360 2361 // Like ObjectOf, but panics instead of returning nil. 2362 // Only valid during p's create and build phases. 2363 func (p *Package) objectOf(id *ast.Ident) types.Object { 2364 if o := p.info.ObjectOf(id); o != nil { 2365 return o 2366 } 2367 panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s", 2368 id.Name, p.Prog.Fset.Position(id.Pos()))) 2369 } 2370 2371 // Like TypeOf, but panics instead of returning nil. 2372 // Only valid during p's create and build phases. 2373 func (p *Package) typeOf(e ast.Expr) types.Type { 2374 if T := p.info.TypeOf(e); T != nil { 2375 return T 2376 } 2377 panic(fmt.Sprintf("no type for %T @ %s", 2378 e, p.Prog.Fset.Position(e.Pos()))) 2379 }