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