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