github.com/HaHadaxigua/yaegi@v1.0.1/interp/cfg.go (about) 1 package interp 2 3 import ( 4 "fmt" 5 "go/constant" 6 "log" 7 "math" 8 "path/filepath" 9 "reflect" 10 "strings" 11 "unicode" 12 ) 13 14 // A cfgError represents an error during CFG build stage. 15 type cfgError struct { 16 *node 17 error 18 } 19 20 func (c *cfgError) Error() string { return c.error.Error() } 21 22 var constOp = map[action]func(*node){ 23 aAdd: addConst, 24 aSub: subConst, 25 aMul: mulConst, 26 aQuo: quoConst, 27 aRem: remConst, 28 aAnd: andConst, 29 aOr: orConst, 30 aShl: shlConst, 31 aShr: shrConst, 32 aAndNot: andNotConst, 33 aXor: xorConst, 34 aNot: notConst, 35 aBitNot: bitNotConst, 36 aNeg: negConst, 37 aPos: posConst, 38 } 39 40 var constBltn = map[string]func(*node){ 41 bltnComplex: complexConst, 42 bltnImag: imagConst, 43 bltnReal: realConst, 44 } 45 46 const nilIdent = "nil" 47 48 // cfg generates a control flow graph (CFG) from AST (wiring successors in AST) 49 // and pre-compute frame sizes and indexes for all un-named (temporary) and named 50 // variables. A list of nodes of init functions is returned. 51 // Following this pass, the CFG is ready to run. 52 func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string) ([]*node, error) { 53 if sc == nil { 54 sc = interp.initScopePkg(importPath, pkgName) 55 } 56 check := typecheck{scope: sc} 57 var initNodes []*node 58 var err error 59 60 baseName := filepath.Base(interp.fset.Position(root.pos).Filename) 61 62 root.Walk(func(n *node) bool { 63 // Pre-order processing 64 if err != nil { 65 return false 66 } 67 if n.scope == nil { 68 n.scope = sc 69 } 70 switch n.kind { 71 case binaryExpr, unaryExpr, parenExpr: 72 if isBoolAction(n) { 73 break 74 } 75 // Gather assigned type if set, to give context for type propagation at post-order. 76 switch n.anc.kind { 77 case assignStmt, defineStmt: 78 a := n.anc 79 i := childPos(n) - a.nright 80 if i < 0 { 81 break 82 } 83 if len(a.child) > a.nright+a.nleft { 84 i-- 85 } 86 dest := a.child[i] 87 if dest.typ == nil { 88 break 89 } 90 if dest.typ.incomplete { 91 err = n.cfgErrorf("invalid type declaration") 92 return false 93 } 94 if !isInterface(dest.typ) { 95 // Interface type are not propagated, and will be resolved at post-order. 96 n.typ = dest.typ 97 } 98 case binaryExpr, unaryExpr, parenExpr: 99 n.typ = n.anc.typ 100 } 101 102 case defineStmt: 103 // Determine type of variables initialized at declaration, so it can be propagated. 104 if n.nleft+n.nright == len(n.child) { 105 // No type was specified on the left hand side, it will resolved at post-order. 106 break 107 } 108 n.typ, err = nodeType(interp, sc, n.child[n.nleft]) 109 if err != nil { 110 break 111 } 112 for i := 0; i < n.nleft; i++ { 113 n.child[i].typ = n.typ 114 } 115 116 case blockStmt: 117 if n.anc != nil && n.anc.kind == rangeStmt { 118 // For range block: ensure that array or map type is propagated to iterators 119 // prior to process block. We cannot perform this at RangeStmt pre-order because 120 // type of array like value is not yet known. This could be fixed in ast structure 121 // by setting array/map node as 1st child of ForRangeStmt instead of 3rd child of 122 // RangeStmt. The following workaround is less elegant but ok. 123 c := n.anc.child[1] 124 if c != nil && c.typ != nil && isSendChan(c.typ) { 125 err = c.cfgErrorf("invalid operation: range %s receive from send-only channel", c.ident) 126 return false 127 } 128 129 if t := sc.rangeChanType(n.anc); t != nil { 130 // range over channel 131 e := n.anc.child[0] 132 index := sc.add(t.val) 133 sc.sym[e.ident] = &symbol{index: index, kind: varSym, typ: t.val} 134 e.typ = t.val 135 e.findex = index 136 n.anc.gen = rangeChan 137 } else { 138 // range over array or map 139 var ktyp, vtyp *itype 140 var k, v, o *node 141 if len(n.anc.child) == 4 { 142 k, v, o = n.anc.child[0], n.anc.child[1], n.anc.child[2] 143 } else { 144 k, o = n.anc.child[0], n.anc.child[1] 145 } 146 147 switch o.typ.cat { 148 case valueT: 149 typ := o.typ.rtype 150 switch typ.Kind() { 151 case reflect.Map: 152 n.anc.gen = rangeMap 153 ityp := valueTOf(reflect.TypeOf((*reflect.MapIter)(nil))) 154 sc.add(ityp) 155 ktyp = valueTOf(typ.Key()) 156 vtyp = valueTOf(typ.Elem()) 157 case reflect.String: 158 sc.add(sc.getType("int")) // Add a dummy type to store array shallow copy for range 159 sc.add(sc.getType("int")) // Add a dummy type to store index for range 160 ktyp = sc.getType("int") 161 vtyp = sc.getType("rune") 162 case reflect.Array, reflect.Slice: 163 sc.add(sc.getType("int")) // Add a dummy type to store array shallow copy for range 164 ktyp = sc.getType("int") 165 vtyp = valueTOf(typ.Elem()) 166 } 167 case mapT: 168 n.anc.gen = rangeMap 169 ityp := valueTOf(reflect.TypeOf((*reflect.MapIter)(nil))) 170 sc.add(ityp) 171 ktyp = o.typ.key 172 vtyp = o.typ.val 173 case ptrT: 174 ktyp = sc.getType("int") 175 vtyp = o.typ.val 176 if vtyp.cat == valueT { 177 vtyp = valueTOf(vtyp.rtype.Elem()) 178 } else { 179 vtyp = vtyp.val 180 } 181 case stringT: 182 sc.add(sc.getType("int")) // Add a dummy type to store array shallow copy for range 183 sc.add(sc.getType("int")) // Add a dummy type to store index for range 184 ktyp = sc.getType("int") 185 vtyp = sc.getType("rune") 186 case arrayT, sliceT, variadicT: 187 sc.add(sc.getType("int")) // Add a dummy type to store array shallow copy for range 188 ktyp = sc.getType("int") 189 vtyp = o.typ.val 190 } 191 192 kindex := sc.add(ktyp) 193 sc.sym[k.ident] = &symbol{index: kindex, kind: varSym, typ: ktyp} 194 k.typ = ktyp 195 k.findex = kindex 196 197 if v != nil { 198 vindex := sc.add(vtyp) 199 sc.sym[v.ident] = &symbol{index: vindex, kind: varSym, typ: vtyp} 200 v.typ = vtyp 201 v.findex = vindex 202 } 203 } 204 } 205 206 n.findex = -1 207 n.val = nil 208 sc = sc.pushBloc() 209 // Pre-define symbols for labels defined in this block, so we are sure that 210 // they are already defined when met. 211 // TODO(marc): labels must be stored outside of symbols to avoid collisions. 212 for _, c := range n.child { 213 if c.kind != labeledStmt { 214 continue 215 } 216 label := c.child[0].ident 217 sym := &symbol{kind: labelSym, node: c, index: -1} 218 sc.sym[label] = sym 219 c.sym = sym 220 } 221 222 case breakStmt, continueStmt, gotoStmt: 223 if len(n.child) == 0 { 224 break 225 } 226 // Handle labeled statements. 227 label := n.child[0].ident 228 if sym, _, ok := sc.lookup(label); ok { 229 if sym.kind != labelSym { 230 err = n.child[0].cfgErrorf("label %s not defined", label) 231 break 232 } 233 n.sym = sym 234 } else { 235 n.sym = &symbol{kind: labelSym, index: -1} 236 sc.sym[label] = n.sym 237 } 238 if n.kind == gotoStmt { 239 n.sym.from = append(n.sym.from, n) // To allow forward goto statements. 240 } 241 242 case caseClause: 243 sc = sc.pushBloc() 244 if sn := n.anc.anc; sn.kind == typeSwitch && sn.child[1].action == aAssign { 245 // Type switch clause with a var defined in switch guard. 246 var typ *itype 247 if len(n.child) == 2 { 248 // 1 type in clause: define the var with this type in the case clause scope. 249 switch { 250 case n.child[0].ident == nilIdent: 251 typ = sc.getType("interface{}") 252 case !n.child[0].isType(sc): 253 err = n.cfgErrorf("%s is not a type", n.child[0].ident) 254 default: 255 typ, err = nodeType(interp, sc, n.child[0]) 256 } 257 } else { 258 // Define the var with the type in the switch guard expression. 259 typ = sn.child[1].child[1].child[0].typ 260 } 261 if err != nil { 262 return false 263 } 264 nod := n.lastChild().child[0] 265 index := sc.add(typ) 266 sc.sym[nod.ident] = &symbol{index: index, kind: varSym, typ: typ} 267 nod.findex = index 268 nod.typ = typ 269 } 270 271 case commClauseDefault: 272 sc = sc.pushBloc() 273 274 case commClause: 275 sc = sc.pushBloc() 276 if len(n.child) > 0 && n.child[0].action == aAssign { 277 ch := n.child[0].child[1].child[0] 278 var typ *itype 279 if typ, err = nodeType(interp, sc, ch); err != nil { 280 return false 281 } 282 if !isChan(typ) { 283 err = n.cfgErrorf("invalid operation: receive from non-chan type") 284 return false 285 } 286 elem := chanElement(typ) 287 assigned := n.child[0].child[0] 288 index := sc.add(elem) 289 sc.sym[assigned.ident] = &symbol{index: index, kind: varSym, typ: elem} 290 assigned.findex = index 291 assigned.typ = elem 292 } 293 294 case compositeLitExpr: 295 if len(n.child) > 0 && n.child[0].isType(sc) { 296 // Get type from 1st child. 297 if n.typ, err = nodeType(interp, sc, n.child[0]); err != nil { 298 return false 299 } 300 // Indicate that the first child is the type. 301 n.nleft = 1 302 } else { 303 // Get type from ancestor (implicit type) 304 if n.anc.kind == keyValueExpr && n == n.anc.child[0] { 305 n.typ = n.anc.typ.key 306 } else if atyp := n.anc.typ; atyp != nil { 307 if atyp.cat == valueT && hasElem(atyp.rtype) { 308 n.typ = valueTOf(atyp.rtype.Elem()) 309 } else { 310 n.typ = atyp.val 311 } 312 } 313 if n.typ == nil { 314 err = n.cfgErrorf("undefined type") 315 return false 316 } 317 } 318 319 child := n.child 320 if n.nleft > 0 { 321 n.child[0].typ = n.typ 322 child = n.child[1:] 323 } 324 // Propagate type to children, to handle implicit types 325 for _, c := range child { 326 if isBlank(c) { 327 err = n.cfgErrorf("cannot use _ as value") 328 return false 329 } 330 switch c.kind { 331 case binaryExpr, unaryExpr, compositeLitExpr: 332 // Do not attempt to propagate composite type to operator expressions, 333 // it breaks constant folding. 334 case keyValueExpr, typeAssertExpr, indexExpr: 335 c.typ = n.typ 336 default: 337 if c.ident == nilIdent { 338 c.typ = sc.getType(nilIdent) 339 continue 340 } 341 if c.typ, err = nodeType(interp, sc, c); err != nil { 342 return false 343 } 344 } 345 } 346 347 case forStmt0, forStmt1, forStmt2, forStmt3, forStmt4, forStmt5, forStmt6, forStmt7, forRangeStmt: 348 sc = sc.pushBloc() 349 sc.loop, sc.loopRestart = n, n.lastChild() 350 351 case funcLit: 352 n.typ = nil // to force nodeType to recompute the type 353 if n.typ, err = nodeType(interp, sc, n); err != nil { 354 return false 355 } 356 n.findex = sc.add(n.typ) 357 fallthrough 358 359 case funcDecl: 360 n.val = n 361 // Compute function type before entering local scope to avoid 362 // possible collisions with function argument names. 363 n.child[2].typ, err = nodeType(interp, sc, n.child[2]) 364 // Add a frame indirection level as we enter in a func 365 sc = sc.pushFunc() 366 sc.def = n 367 if len(n.child[2].child) == 2 { 368 // Allocate frame space for return values, define output symbols 369 for _, c := range n.child[2].child[1].child { 370 var typ *itype 371 if typ, err = nodeType(interp, sc, c.lastChild()); err != nil { 372 return false 373 } 374 if len(c.child) > 1 { 375 for _, cc := range c.child[:len(c.child)-1] { 376 sc.sym[cc.ident] = &symbol{index: sc.add(typ), kind: varSym, typ: typ} 377 } 378 } else { 379 sc.add(typ) 380 } 381 } 382 } 383 if len(n.child[0].child) > 0 { 384 // define receiver symbol 385 var typ *itype 386 fr := n.child[0].child[0] 387 recvTypeNode := fr.lastChild() 388 if typ, err = nodeType(interp, sc, recvTypeNode); err != nil { 389 return false 390 } 391 recvTypeNode.typ = typ 392 n.child[2].typ.recv = typ 393 n.typ.recv = typ 394 index := sc.add(typ) 395 if len(fr.child) > 1 { 396 sc.sym[fr.child[0].ident] = &symbol{index: index, kind: varSym, typ: typ} 397 } 398 } 399 for _, c := range n.child[2].child[0].child { 400 // define input parameter symbols 401 var typ *itype 402 if typ, err = nodeType(interp, sc, c.lastChild()); err != nil { 403 return false 404 } 405 for _, cc := range c.child[:len(c.child)-1] { 406 sc.sym[cc.ident] = &symbol{index: sc.add(typ), kind: varSym, typ: typ} 407 } 408 } 409 if n.child[1].ident == "init" && len(n.child[0].child) == 0 { 410 initNodes = append(initNodes, n) 411 } 412 413 case ifStmt0, ifStmt1, ifStmt2, ifStmt3: 414 sc = sc.pushBloc() 415 416 case switchStmt, switchIfStmt, typeSwitch: 417 // Make sure default clause is in last position. 418 c := n.lastChild().child 419 if i, l := getDefault(n), len(c)-1; i >= 0 && i != l { 420 c[i], c[l] = c[l], c[i] 421 } 422 sc = sc.pushBloc() 423 sc.loop = n 424 425 case importSpec: 426 // Already all done in GTA. 427 return false 428 429 case typeSpec: 430 // Processing already done in GTA pass for global types, only parses inlined types. 431 if sc.def == nil { 432 return false 433 } 434 typeName := n.child[0].ident 435 var typ *itype 436 if typ, err = nodeType(interp, sc, n.child[1]); err != nil { 437 return false 438 } 439 if typ.incomplete { 440 // Type may still be incomplete in case of a local recursive struct declaration. 441 if typ, err = typ.finalize(); err != nil { 442 err = n.cfgErrorf("invalid type declaration") 443 return false 444 } 445 } 446 447 switch n.child[1].kind { 448 case identExpr, selectorExpr: 449 n.typ = namedOf(typ, pkgName, typeName) 450 default: 451 n.typ = typ 452 n.typ.name = typeName 453 } 454 sc.sym[typeName] = &symbol{kind: typeSym, typ: n.typ} 455 return false 456 457 case constDecl: 458 // Early parse of constDecl subtrees, to compute all constant 459 // values which may be used in further declarations. 460 if !sc.global { 461 for _, c := range n.child { 462 if _, err = interp.cfg(c, sc, importPath, pkgName); err != nil { 463 // No error processing here, to allow recovery in subtree nodes. 464 err = nil 465 } 466 } 467 } 468 469 case arrayType, basicLit, chanType, chanTypeRecv, chanTypeSend, funcType, interfaceType, mapType, structType: 470 n.typ, err = nodeType(interp, sc, n) 471 return false 472 } 473 return true 474 }, func(n *node) { 475 // Post-order processing 476 if err != nil { 477 return 478 } 479 480 defer func() { 481 if r := recover(); r != nil { 482 // Display the exact location in input source which triggered the panic 483 panic(n.cfgErrorf("CFG post-order panic: %v", r)) 484 } 485 }() 486 487 switch n.kind { 488 case addressExpr: 489 if isBlank(n.child[0]) { 490 err = n.cfgErrorf("cannot use _ as value") 491 break 492 } 493 wireChild(n) 494 495 err = check.addressExpr(n) 496 if err != nil { 497 break 498 } 499 500 n.typ = ptrOf(n.child[0].typ) 501 n.findex = sc.add(n.typ) 502 503 case assignStmt, defineStmt: 504 if n.anc.kind == typeSwitch && n.anc.child[1] == n { 505 // type switch guard assignment: assign dest to concrete value of src 506 n.gen = nop 507 break 508 } 509 510 var atyp *itype 511 if n.nleft+n.nright < len(n.child) { 512 if atyp, err = nodeType(interp, sc, n.child[n.nleft]); err != nil { 513 break 514 } 515 } 516 517 var sbase int 518 if n.nright > 0 { 519 sbase = len(n.child) - n.nright 520 } 521 522 wireChild(n) 523 for i := 0; i < n.nleft; i++ { 524 dest, src := n.child[i], n.child[sbase+i] 525 updateSym := false 526 var sym *symbol 527 var level int 528 529 if isBlank(src) { 530 err = n.cfgErrorf("cannot use _ as value") 531 break 532 } 533 if n.kind == defineStmt || (n.kind == assignStmt && dest.ident == "_") { 534 if atyp != nil { 535 dest.typ = atyp 536 } else { 537 if src.typ, err = nodeType(interp, sc, src); err != nil { 538 return 539 } 540 if src.typ.isBinMethod { 541 dest.typ = valueTOf(src.typ.methodCallType()) 542 } else { 543 // In a new definition, propagate the source type to the destination 544 // type. If the source is an untyped constant, make sure that the 545 // type matches a default type. 546 dest.typ = sc.fixType(src.typ) 547 } 548 } 549 if dest.typ.incomplete { 550 return 551 } 552 if sc.global { 553 // Do not overload existing symbols (defined in GTA) in global scope 554 sym, _, _ = sc.lookup(dest.ident) 555 } 556 if sym == nil { 557 sym = &symbol{index: sc.add(dest.typ), kind: varSym, typ: dest.typ} 558 sc.sym[dest.ident] = sym 559 } 560 dest.val = src.val 561 dest.recv = src.recv 562 dest.findex = sym.index 563 updateSym = true 564 } else { 565 sym, level, _ = sc.lookup(dest.ident) 566 } 567 568 err = check.assignExpr(n, dest, src) 569 if err != nil { 570 break 571 } 572 573 if updateSym { 574 sym.typ = dest.typ 575 sym.rval = src.rval 576 // As we are updating the sym type, we need to update the sc.type 577 // when the sym has an index. 578 if sym.index >= 0 { 579 sc.types[sym.index] = sym.typ.frameType() 580 } 581 } 582 n.findex = dest.findex 583 n.level = dest.level 584 585 // In the following, we attempt to optimize by skipping the assign 586 // operation and setting the source location directly to the destination 587 // location in the frame. 588 // 589 switch { 590 case n.action != aAssign: 591 // Do not skip assign operation if it is combined with another operator. 592 case src.rval.IsValid(): 593 // Do not skip assign operation if setting from a constant value. 594 case isMapEntry(dest): 595 // Setting a map entry requires an additional step, do not optimize. 596 // As we only write, skip the default useless getIndexMap dest action. 597 dest.gen = nop 598 case isFuncField(dest): 599 // Setting a struct field of function type requires an extra step. Do not optimize. 600 case isCall(src) && !isInterfaceSrc(dest.typ) && n.kind != defineStmt: 601 // Call action may perform the assignment directly. 602 if dest.typ.id() != src.typ.id() { 603 // Skip optimitization if returned type doesn't match assigned one. 604 break 605 } 606 n.gen = nop 607 src.level = level 608 src.findex = dest.findex 609 if src.typ.untyped && !dest.typ.untyped { 610 src.typ = dest.typ 611 } 612 case src.action == aRecv: 613 // Assign by reading from a receiving channel. 614 n.gen = nop 615 src.findex = dest.findex // Set recv address to LHS. 616 dest.typ = src.typ 617 case src.action == aCompositeLit: 618 if dest.typ.cat == valueT && dest.typ.rtype.Kind() == reflect.Interface { 619 // Skip optimisation for assigned interface. 620 break 621 } 622 if dest.action == aGetIndex || dest.action == aStar { 623 // Skip optimization, as it does not work when assigning to a struct field or a dereferenced pointer. 624 break 625 } 626 n.gen = nop 627 src.findex = dest.findex 628 src.level = level 629 case len(n.child) < 4 && isArithmeticAction(src): 630 // Optimize single assignments from some arithmetic operations. 631 src.typ = dest.typ 632 src.findex = dest.findex 633 src.level = level 634 n.gen = nop 635 case src.kind == basicLit: 636 // Assign to nil. 637 src.rval = reflect.New(dest.typ.TypeOf()).Elem() 638 case n.nright == 0: 639 n.gen = reset 640 } 641 642 n.typ = dest.typ 643 if sym != nil { 644 sym.typ = n.typ 645 sym.recv = src.recv 646 } 647 648 n.level = level 649 650 if n.anc.kind == constDecl { 651 n.gen = nop 652 n.findex = notInFrame 653 if sym, _, ok := sc.lookup(dest.ident); ok { 654 sym.kind = constSym 655 } 656 if childPos(n) == len(n.anc.child)-1 { 657 sc.iota = 0 658 } else { 659 sc.iota++ 660 } 661 } 662 } 663 664 case incDecStmt: 665 err = check.unaryExpr(n) 666 if err != nil { 667 break 668 } 669 wireChild(n) 670 n.findex = n.child[0].findex 671 n.level = n.child[0].level 672 n.typ = n.child[0].typ 673 if sym, level, ok := sc.lookup(n.child[0].ident); ok { 674 sym.typ = n.typ 675 n.level = level 676 } 677 678 case assignXStmt: 679 wireChild(n) 680 l := len(n.child) - 1 681 switch lc := n.child[l]; lc.kind { 682 case callExpr: 683 if n.child[l-1].isType(sc) { 684 l-- 685 } 686 if r := lc.child[0].typ.numOut(); r != l { 687 err = n.cfgErrorf("assignment mismatch: %d variables but %s returns %d values", l, lc.child[0].name(), r) 688 } 689 if isBinCall(lc, sc) { 690 n.gen = nop 691 } else { 692 // TODO (marc): skip if no conversion or wrapping is needed. 693 n.gen = assignFromCall 694 } 695 case indexExpr: 696 lc.gen = getIndexMap2 697 n.gen = nop 698 case typeAssertExpr: 699 if n.child[0].ident == "_" { 700 lc.gen = typeAssertStatus 701 } else { 702 lc.gen = typeAssertLong 703 } 704 n.gen = nop 705 case unaryExpr: 706 if lc.action == aRecv { 707 lc.gen = recv2 708 n.gen = nop 709 } 710 } 711 712 case defineXStmt: 713 wireChild(n) 714 if sc.def == nil { 715 // In global scope, type definition already handled by GTA. 716 break 717 } 718 err = compDefineX(sc, n) 719 720 case binaryExpr: 721 wireChild(n) 722 nilSym := interp.universe.sym[nilIdent] 723 c0, c1 := n.child[0], n.child[1] 724 725 err = check.binaryExpr(n) 726 if err != nil { 727 break 728 } 729 730 switch n.action { 731 case aRem: 732 n.typ = c0.typ 733 case aShl, aShr: 734 if c0.typ.untyped { 735 break 736 } 737 n.typ = c0.typ 738 case aEqual, aNotEqual: 739 n.typ = sc.getType("bool") 740 if c0.sym == nilSym || c1.sym == nilSym { 741 if n.action == aEqual { 742 n.gen = isNil 743 } else { 744 n.gen = isNotNil 745 } 746 } 747 case aGreater, aGreaterEqual, aLower, aLowerEqual: 748 n.typ = sc.getType("bool") 749 } 750 if err != nil { 751 break 752 } 753 if n.typ == nil { 754 if n.typ, err = nodeType(interp, sc, n); err != nil { 755 break 756 } 757 } 758 if c0.rval.IsValid() && c1.rval.IsValid() && (!isInterface(n.typ)) && constOp[n.action] != nil { 759 n.typ.TypeOf() // Force compute of reflection type. 760 constOp[n.action](n) // Compute a constant result now rather than during exec. 761 } 762 switch { 763 case n.rval.IsValid(): 764 // This operation involved constants, and the result is already computed 765 // by constOp and available in n.rval. Nothing else to do at execution. 766 n.gen = nop 767 n.findex = notInFrame 768 case n.anc.kind == assignStmt && n.anc.action == aAssign && n.anc.nleft == 1: 769 // To avoid a copy in frame, if the result is to be assigned, store it directly 770 // at the frame location of destination. 771 dest := n.anc.child[childPos(n)-n.anc.nright] 772 n.typ = dest.typ 773 n.findex = dest.findex 774 n.level = dest.level 775 case n.anc.kind == returnStmt: 776 // To avoid a copy in frame, if the result is to be returned, store it directly 777 // at the frame location reserved for output arguments. 778 pos := childPos(n) 779 n.typ = sc.def.typ.ret[pos] 780 n.findex = pos 781 default: 782 // Allocate a new location in frame, and store the result here. 783 n.findex = sc.add(n.typ) 784 } 785 786 case indexExpr: 787 if isBlank(n.child[0]) { 788 err = n.cfgErrorf("cannot use _ as value") 789 break 790 } 791 wireChild(n) 792 t := n.child[0].typ 793 switch t.cat { 794 case aliasT: 795 if isString(t.val.TypeOf()) { 796 n.typ = sc.getType("byte") 797 break 798 } 799 fallthrough 800 case ptrT: 801 n.typ = t.val 802 if t.val.cat == valueT { 803 n.typ = valueTOf(t.val.rtype.Elem()) 804 } else { 805 n.typ = t.val.val 806 } 807 case stringT: 808 n.typ = sc.getType("byte") 809 case valueT: 810 if t.rtype.Kind() == reflect.String { 811 n.typ = sc.getType("byte") 812 } else { 813 n.typ = valueTOf(t.rtype.Elem()) 814 } 815 default: 816 n.typ = t.val 817 } 818 n.findex = sc.add(n.typ) 819 typ := t.TypeOf() 820 if typ.Kind() == reflect.Map { 821 err = check.assignment(n.child[1], t.key, "map index") 822 n.gen = getIndexMap 823 break 824 } 825 826 l := -1 827 switch k := typ.Kind(); k { 828 case reflect.Array: 829 l = typ.Len() 830 fallthrough 831 case reflect.Slice, reflect.String: 832 n.gen = getIndexArray 833 case reflect.Ptr: 834 if typ2 := typ.Elem(); typ2.Kind() == reflect.Array { 835 l = typ2.Len() 836 n.gen = getIndexArray 837 } else { 838 err = n.cfgErrorf("type %v does not support indexing", typ) 839 } 840 default: 841 err = n.cfgErrorf("type is not an array, slice, string or map: %v", t.id()) 842 } 843 844 err = check.index(n.child[1], l) 845 846 case blockStmt: 847 wireChild(n) 848 if len(n.child) > 0 { 849 l := n.lastChild() 850 n.findex = l.findex 851 n.level = l.level 852 n.val = l.val 853 n.sym = l.sym 854 n.typ = l.typ 855 n.rval = l.rval 856 } 857 sc = sc.pop() 858 859 case constDecl: 860 wireChild(n) 861 862 case varDecl: 863 // Global varDecl do not need to be wired as this 864 // will be handled after cfg. 865 if n.anc.kind == fileStmt { 866 break 867 } 868 wireChild(n) 869 870 case declStmt, exprStmt, sendStmt: 871 wireChild(n) 872 l := n.lastChild() 873 n.findex = l.findex 874 n.level = l.level 875 n.val = l.val 876 n.sym = l.sym 877 n.typ = l.typ 878 n.rval = l.rval 879 880 case breakStmt: 881 if len(n.child) == 0 { 882 n.tnext = sc.loop 883 break 884 } 885 if !n.hasAnc(n.sym.node) { 886 err = n.cfgErrorf("invalid break label %s", n.child[0].ident) 887 break 888 } 889 n.tnext = n.sym.node 890 891 case continueStmt: 892 if len(n.child) == 0 { 893 n.tnext = sc.loopRestart 894 break 895 } 896 if !n.hasAnc(n.sym.node) { 897 err = n.cfgErrorf("invalid continue label %s", n.child[0].ident) 898 break 899 } 900 n.tnext = n.sym.node.child[1].lastChild().start 901 902 case gotoStmt: 903 if n.sym.node == nil { 904 // It can be only due to a forward goto, to be resolved at labeledStmt. 905 // Invalid goto labels are catched at AST parsing. 906 break 907 } 908 n.tnext = n.sym.node.start 909 910 case labeledStmt: 911 wireChild(n) 912 if len(n.child) > 1 { 913 n.start = n.child[1].start 914 } 915 for _, c := range n.sym.from { 916 c.tnext = n.start // Resolve forward goto. 917 } 918 919 case callExpr: 920 for _, c := range n.child { 921 if isBlank(c) { 922 err = n.cfgErrorf("cannot use _ as value") 923 return 924 } 925 } 926 wireChild(n) 927 switch { 928 case isBuiltinCall(n, sc): 929 c0 := n.child[0] 930 bname := c0.ident 931 err = check.builtin(bname, n, n.child[1:], n.action == aCallSlice) 932 if err != nil { 933 break 934 } 935 936 n.gen = c0.sym.builtin 937 c0.typ = &itype{cat: builtinT} 938 if n.typ, err = nodeType(interp, sc, n); err != nil { 939 return 940 } 941 switch { 942 case n.typ.cat == builtinT: 943 n.findex = notInFrame 944 n.val = nil 945 case n.anc.kind == returnStmt: 946 // Store result directly to frame output location, to avoid a frame copy. 947 n.findex = 0 948 case bname == "cap" && isInConstOrTypeDecl(n): 949 t := n.child[1].typ.TypeOf() 950 for t.Kind() == reflect.Ptr { 951 t = t.Elem() 952 } 953 switch t.Kind() { 954 case reflect.Array, reflect.Chan: 955 capConst(n) 956 default: 957 err = n.cfgErrorf("cap argument is not an array or channel") 958 } 959 n.findex = notInFrame 960 n.gen = nop 961 case bname == "len" && isInConstOrTypeDecl(n): 962 t := n.child[1].typ.TypeOf() 963 for t.Kind() == reflect.Ptr { 964 t = t.Elem() 965 } 966 switch t.Kind() { 967 case reflect.Array, reflect.Chan, reflect.String: 968 lenConst(n) 969 default: 970 err = n.cfgErrorf("len argument is not an array, channel or string") 971 } 972 n.findex = notInFrame 973 n.gen = nop 974 default: 975 n.findex = sc.add(n.typ) 976 } 977 if op, ok := constBltn[bname]; ok && n.anc.action != aAssign { 978 op(n) // pre-compute non-assigned constant : 979 } 980 case n.child[0].isType(sc): 981 // Type conversion expression 982 c0, c1 := n.child[0], n.child[1] 983 switch len(n.child) { 984 case 1: 985 err = n.cfgErrorf("missing argument in conversion to %s", c0.typ.id()) 986 case 2: 987 err = check.conversion(c1, c0.typ) 988 default: 989 err = n.cfgErrorf("too many arguments in conversion to %s", c0.typ.id()) 990 } 991 if err != nil { 992 break 993 } 994 995 n.action = aConvert 996 switch { 997 case isInterface(c0.typ) && !c1.isNil(): 998 // Convert to interface: just check that all required methods are defined by concrete type. 999 if !c1.typ.implements(c0.typ) { 1000 err = n.cfgErrorf("type %v does not implement interface %v", c1.typ.id(), c0.typ.id()) 1001 } 1002 // Convert type to interface while keeping a reference to the original concrete type. 1003 // besides type, the node value remains preserved. 1004 n.gen = nop 1005 t := *c0.typ 1006 n.typ = &t 1007 n.typ.val = c1.typ 1008 n.findex = c1.findex 1009 n.level = c1.level 1010 n.val = c1.val 1011 n.rval = c1.rval 1012 case c1.rval.IsValid() && isConstType(c0.typ): 1013 n.gen = nop 1014 n.findex = notInFrame 1015 n.typ = c0.typ 1016 if c, ok := c1.rval.Interface().(constant.Value); ok { 1017 i, _ := constant.Int64Val(constant.ToInt(c)) 1018 n.rval = reflect.ValueOf(i).Convert(c0.typ.rtype) 1019 } else { 1020 n.rval = c1.rval.Convert(c0.typ.rtype) 1021 } 1022 default: 1023 n.gen = convert 1024 n.typ = c0.typ 1025 n.findex = sc.add(n.typ) 1026 } 1027 case isBinCall(n, sc): 1028 err = check.arguments(n, n.child[1:], n.child[0], n.action == aCallSlice) 1029 if err != nil { 1030 break 1031 } 1032 1033 n.gen = callBin 1034 typ := n.child[0].typ.rtype 1035 if typ.NumOut() > 0 { 1036 if funcType := n.child[0].typ.val; funcType != nil { 1037 // Use the original unwrapped function type, to allow future field and 1038 // methods resolutions, otherwise impossible on the opaque bin type. 1039 n.typ = funcType.ret[0] 1040 n.findex = sc.add(n.typ) 1041 for i := 1; i < len(funcType.ret); i++ { 1042 sc.add(funcType.ret[i]) 1043 } 1044 } else { 1045 n.typ = valueTOf(typ.Out(0)) 1046 if n.anc.kind == returnStmt { 1047 n.findex = childPos(n) 1048 } else { 1049 n.findex = sc.add(n.typ) 1050 for i := 1; i < typ.NumOut(); i++ { 1051 sc.add(valueTOf(typ.Out(i))) 1052 } 1053 } 1054 } 1055 } 1056 case isOffsetof(n): 1057 if len(n.child) != 2 || n.child[1].kind != selectorExpr || !isStruct(n.child[1].child[0].typ) { 1058 err = n.cfgErrorf("Offsetof argument: invalid expression") 1059 break 1060 } 1061 c1 := n.child[1] 1062 field, ok := c1.child[0].typ.rtype.FieldByName(c1.child[1].ident) 1063 if !ok { 1064 err = n.cfgErrorf("struct does not contain field: %s", c1.child[1].ident) 1065 break 1066 } 1067 n.typ = valueTOf(reflect.TypeOf(field.Offset)) 1068 n.rval = reflect.ValueOf(field.Offset) 1069 n.gen = nop 1070 default: 1071 err = check.arguments(n, n.child[1:], n.child[0], n.action == aCallSlice) 1072 if err != nil { 1073 break 1074 } 1075 1076 if n.child[0].action == aGetFunc { 1077 // Allocate a frame entry to store the anonymous function definition. 1078 sc.add(n.child[0].typ) 1079 } 1080 if typ := n.child[0].typ; len(typ.ret) > 0 { 1081 n.typ = typ.ret[0] 1082 if n.anc.kind == returnStmt && n.typ.id() == sc.def.typ.ret[0].id() { 1083 // Store the result directly to the return value area of frame. 1084 // It can be done only if no type conversion at return is involved. 1085 n.findex = childPos(n) 1086 } else { 1087 n.findex = sc.add(n.typ) 1088 for _, t := range typ.ret[1:] { 1089 sc.add(t) 1090 } 1091 } 1092 } else { 1093 n.findex = notInFrame 1094 } 1095 } 1096 1097 case caseBody: 1098 wireChild(n) 1099 switch { 1100 case typeSwichAssign(n) && len(n.child) > 1: 1101 n.start = n.child[1].start 1102 case len(n.child) == 0: 1103 // Empty case body: jump to switch node (exit node). 1104 n.start = n.anc.anc.anc 1105 default: 1106 n.start = n.child[0].start 1107 } 1108 1109 case caseClause: 1110 sc = sc.pop() 1111 1112 case commClauseDefault: 1113 wireChild(n) 1114 sc = sc.pop() 1115 if len(n.child) == 0 { 1116 return 1117 } 1118 n.start = n.child[0].start 1119 n.lastChild().tnext = n.anc.anc // exit node is selectStmt 1120 1121 case commClause: 1122 wireChild(n) 1123 sc = sc.pop() 1124 if len(n.child) == 0 { 1125 return 1126 } 1127 if len(n.child) > 1 { 1128 n.start = n.child[1].start // Skip chan operation, performed by select 1129 } 1130 n.lastChild().tnext = n.anc.anc // exit node is selectStmt 1131 1132 case compositeLitExpr: 1133 wireChild(n) 1134 1135 child := n.child 1136 if n.nleft > 0 { 1137 child = child[1:] 1138 } 1139 1140 switch n.typ.cat { 1141 case arrayT, sliceT: 1142 err = check.arrayLitExpr(child, n.typ) 1143 case mapT: 1144 err = check.mapLitExpr(child, n.typ.key, n.typ.val) 1145 case structT: 1146 err = check.structLitExpr(child, n.typ) 1147 case valueT: 1148 rtype := n.typ.rtype 1149 switch rtype.Kind() { 1150 case reflect.Struct: 1151 err = check.structBinLitExpr(child, rtype) 1152 case reflect.Map: 1153 ktyp := valueTOf(rtype.Key()) 1154 vtyp := valueTOf(rtype.Elem()) 1155 err = check.mapLitExpr(child, ktyp, vtyp) 1156 } 1157 } 1158 if err != nil { 1159 break 1160 } 1161 1162 n.findex = sc.add(n.typ) 1163 // TODO: Check that composite literal expr matches corresponding type 1164 n.gen = compositeGenerator(n, n.typ, nil) 1165 1166 case fallthroughtStmt: 1167 if n.anc.kind != caseBody { 1168 err = n.cfgErrorf("fallthrough statement out of place") 1169 } 1170 1171 case fileStmt: 1172 wireChild(n, varDecl) 1173 sc = sc.pop() 1174 n.findex = notInFrame 1175 1176 case forStmt0: // for {} 1177 body := n.child[0] 1178 n.start = body.start 1179 body.tnext = n.start 1180 sc = sc.pop() 1181 1182 case forStmt1: // for init; ; {} 1183 init, body := n.child[0], n.child[1] 1184 n.start = init.start 1185 init.tnext = body.start 1186 body.tnext = n.start 1187 sc = sc.pop() 1188 1189 case forStmt2: // for cond {} 1190 cond, body := n.child[0], n.child[1] 1191 if !isBool(cond.typ) { 1192 err = cond.cfgErrorf("non-bool used as for condition") 1193 } 1194 if cond.rval.IsValid() { 1195 // Condition is known at compile time, bypass test. 1196 if cond.rval.Bool() { 1197 n.start = body.start 1198 body.tnext = body.start 1199 } 1200 } else { 1201 n.start = cond.start 1202 cond.tnext = body.start 1203 body.tnext = cond.start 1204 } 1205 setFNext(cond, n) 1206 sc = sc.pop() 1207 1208 case forStmt3: // for init; cond; {} 1209 init, cond, body := n.child[0], n.child[1], n.child[2] 1210 if !isBool(cond.typ) { 1211 err = cond.cfgErrorf("non-bool used as for condition") 1212 } 1213 n.start = init.start 1214 if cond.rval.IsValid() { 1215 // Condition is known at compile time, bypass test. 1216 if cond.rval.Bool() { 1217 init.tnext = body.start 1218 body.tnext = body.start 1219 } else { 1220 init.tnext = n 1221 } 1222 } else { 1223 init.tnext = cond.start 1224 body.tnext = cond.start 1225 } 1226 cond.tnext = body.start 1227 setFNext(cond, n) 1228 sc = sc.pop() 1229 1230 case forStmt4: // for ; ; post {} 1231 post, body := n.child[0], n.child[1] 1232 n.start = body.start 1233 post.tnext = body.start 1234 body.tnext = post.start 1235 sc = sc.pop() 1236 1237 case forStmt5: // for ; cond; post {} 1238 cond, post, body := n.child[0], n.child[1], n.child[2] 1239 if !isBool(cond.typ) { 1240 err = cond.cfgErrorf("non-bool used as for condition") 1241 } 1242 if cond.rval.IsValid() { 1243 // Condition is known at compile time, bypass test. 1244 if cond.rval.Bool() { 1245 n.start = body.start 1246 post.tnext = body.start 1247 } 1248 } else { 1249 n.start = cond.start 1250 post.tnext = cond.start 1251 } 1252 cond.tnext = body.start 1253 setFNext(cond, n) 1254 body.tnext = post.start 1255 sc = sc.pop() 1256 1257 case forStmt6: // for init; ; post {} 1258 init, post, body := n.child[0], n.child[1], n.child[2] 1259 n.start = init.start 1260 init.tnext = body.start 1261 body.tnext = post.start 1262 post.tnext = body.start 1263 sc = sc.pop() 1264 1265 case forStmt7: // for init; cond; post {} 1266 init, cond, post, body := n.child[0], n.child[1], n.child[2], n.child[3] 1267 if !isBool(cond.typ) { 1268 err = cond.cfgErrorf("non-bool used as for condition") 1269 } 1270 n.start = init.start 1271 if cond.rval.IsValid() { 1272 // Condition is known at compile time, bypass test. 1273 if cond.rval.Bool() { 1274 init.tnext = body.start 1275 post.tnext = body.start 1276 } else { 1277 init.tnext = n 1278 } 1279 } else { 1280 init.tnext = cond.start 1281 post.tnext = cond.start 1282 } 1283 cond.tnext = body.start 1284 setFNext(cond, n) 1285 body.tnext = post.start 1286 sc = sc.pop() 1287 1288 case forRangeStmt: 1289 n.start = n.child[0].start 1290 setFNext(n.child[0], n) 1291 sc = sc.pop() 1292 1293 case funcDecl: 1294 n.start = n.child[3].start 1295 n.types, n.scope = sc.types, sc 1296 sc = sc.pop() 1297 funcName := n.child[1].ident 1298 if sym := sc.sym[funcName]; !isMethod(n) && sym != nil { 1299 sym.index = -1 // to force value to n.val 1300 sym.typ = n.typ 1301 sym.kind = funcSym 1302 sym.node = n 1303 } 1304 1305 case funcLit: 1306 n.types, n.scope = sc.types, sc 1307 sc = sc.pop() 1308 err = genRun(n) 1309 1310 case deferStmt, goStmt: 1311 wireChild(n) 1312 1313 case identExpr: 1314 if isKey(n) || isNewDefine(n, sc) { 1315 break 1316 } 1317 if n.anc.kind == funcDecl && n.anc.child[1] == n { 1318 // Dont process a function name identExpr. 1319 break 1320 } 1321 1322 sym, level, found := sc.lookup(n.ident) 1323 if !found { 1324 // retry with the filename, in case ident is a package name. 1325 sym, level, found = sc.lookup(filepath.Join(n.ident, baseName)) 1326 if !found { 1327 err = n.cfgErrorf("undefined: %s", n.ident) 1328 break 1329 } 1330 } 1331 // Found symbol, populate node info 1332 n.sym, n.typ, n.findex, n.level = sym, sym.typ, sym.index, level 1333 if n.findex < 0 { 1334 n.val = sym.node 1335 } else { 1336 switch { 1337 case sym.kind == constSym && sym.rval.IsValid(): 1338 n.rval = sym.rval 1339 n.kind = basicLit 1340 case n.ident == "iota": 1341 n.rval = reflect.ValueOf(constant.MakeInt64(int64(sc.iota))) 1342 n.kind = basicLit 1343 case n.ident == nilIdent: 1344 n.kind = basicLit 1345 case sym.kind == binSym: 1346 n.typ = sym.typ 1347 n.rval = sym.rval 1348 case sym.kind == bltnSym: 1349 if n.anc.kind != callExpr { 1350 err = n.cfgErrorf("use of builtin %s not in function call", n.ident) 1351 } 1352 } 1353 } 1354 if n.sym != nil { 1355 n.recv = n.sym.recv 1356 } 1357 1358 case ifStmt0: // if cond {} 1359 cond, tbody := n.child[0], n.child[1] 1360 if !isBool(cond.typ) { 1361 err = cond.cfgErrorf("non-bool used as if condition") 1362 } 1363 if cond.rval.IsValid() { 1364 // Condition is known at compile time, bypass test. 1365 if cond.rval.Bool() { 1366 n.start = tbody.start 1367 } 1368 } else { 1369 n.start = cond.start 1370 cond.tnext = tbody.start 1371 } 1372 setFNext(cond, n) 1373 tbody.tnext = n 1374 sc = sc.pop() 1375 1376 case ifStmt1: // if cond {} else {} 1377 cond, tbody, fbody := n.child[0], n.child[1], n.child[2] 1378 if !isBool(cond.typ) { 1379 err = cond.cfgErrorf("non-bool used as if condition") 1380 } 1381 if cond.rval.IsValid() { 1382 // Condition is known at compile time, bypass test and the useless branch. 1383 if cond.rval.Bool() { 1384 n.start = tbody.start 1385 } else { 1386 n.start = fbody.start 1387 } 1388 } else { 1389 n.start = cond.start 1390 cond.tnext = tbody.start 1391 setFNext(cond, fbody.start) 1392 } 1393 tbody.tnext = n 1394 fbody.tnext = n 1395 sc = sc.pop() 1396 1397 case ifStmt2: // if init; cond {} 1398 init, cond, tbody := n.child[0], n.child[1], n.child[2] 1399 if !isBool(cond.typ) { 1400 err = cond.cfgErrorf("non-bool used as if condition") 1401 } 1402 n.start = init.start 1403 if cond.rval.IsValid() { 1404 // Condition is known at compile time, bypass test. 1405 if cond.rval.Bool() { 1406 init.tnext = tbody.start 1407 } else { 1408 init.tnext = n 1409 } 1410 } else { 1411 init.tnext = cond.start 1412 cond.tnext = tbody.start 1413 } 1414 tbody.tnext = n 1415 setFNext(cond, n) 1416 sc = sc.pop() 1417 1418 case ifStmt3: // if init; cond {} else {} 1419 init, cond, tbody, fbody := n.child[0], n.child[1], n.child[2], n.child[3] 1420 if !isBool(cond.typ) { 1421 err = cond.cfgErrorf("non-bool used as if condition") 1422 } 1423 n.start = init.start 1424 if cond.rval.IsValid() { 1425 // Condition is known at compile time, bypass test. 1426 if cond.rval.Bool() { 1427 init.tnext = tbody.start 1428 } else { 1429 init.tnext = fbody.start 1430 } 1431 } else { 1432 init.tnext = cond.start 1433 cond.tnext = tbody.start 1434 setFNext(cond, fbody.start) 1435 } 1436 tbody.tnext = n 1437 fbody.tnext = n 1438 sc = sc.pop() 1439 1440 case keyValueExpr: 1441 if isBlank(n.child[1]) { 1442 err = n.cfgErrorf("cannot use _ as value") 1443 break 1444 } 1445 wireChild(n) 1446 1447 case landExpr: 1448 if isBlank(n.child[0]) || isBlank(n.child[1]) { 1449 err = n.cfgErrorf("cannot use _ as value") 1450 break 1451 } 1452 n.start = n.child[0].start 1453 n.child[0].tnext = n.child[1].start 1454 setFNext(n.child[0], n) 1455 n.child[1].tnext = n 1456 n.typ = n.child[0].typ 1457 n.findex = sc.add(n.typ) 1458 if n.start.action == aNop { 1459 n.start.gen = branch 1460 } 1461 1462 case lorExpr: 1463 if isBlank(n.child[0]) || isBlank(n.child[1]) { 1464 err = n.cfgErrorf("cannot use _ as value") 1465 break 1466 } 1467 n.start = n.child[0].start 1468 n.child[0].tnext = n 1469 setFNext(n.child[0], n.child[1].start) 1470 n.child[1].tnext = n 1471 n.typ = n.child[0].typ 1472 n.findex = sc.add(n.typ) 1473 if n.start.action == aNop { 1474 n.start.gen = branch 1475 } 1476 1477 case parenExpr: 1478 wireChild(n) 1479 c := n.lastChild() 1480 n.findex = c.findex 1481 n.level = c.level 1482 n.typ = c.typ 1483 n.rval = c.rval 1484 1485 case rangeStmt: 1486 if sc.rangeChanType(n) != nil { 1487 n.start = n.child[1].start // Get chan 1488 n.child[1].tnext = n // then go to range function 1489 n.tnext = n.child[2].start // then go to range body 1490 n.child[2].tnext = n // then body go to range function (loop) 1491 n.child[0].gen = empty 1492 } else { 1493 var k, o, body *node 1494 if len(n.child) == 4 { 1495 k, o, body = n.child[0], n.child[2], n.child[3] 1496 } else { 1497 k, o, body = n.child[0], n.child[1], n.child[2] 1498 } 1499 n.start = o.start // Get array or map object 1500 o.tnext = k.start // then go to iterator init 1501 k.tnext = n // then go to range function 1502 n.tnext = body.start // then go to range body 1503 body.tnext = n // then body go to range function (loop) 1504 k.gen = empty // init filled later by generator 1505 } 1506 1507 case returnStmt: 1508 if len(n.child) > sc.def.typ.numOut() { 1509 err = n.cfgErrorf("too many arguments to return") 1510 break 1511 } 1512 for _, c := range n.child { 1513 if isBlank(c) { 1514 err = n.cfgErrorf("cannot use _ as value") 1515 return 1516 } 1517 } 1518 returnSig := sc.def.child[2] 1519 if mustReturnValue(returnSig) { 1520 nret := len(n.child) 1521 if nret == 1 && isCall(n.child[0]) { 1522 nret = n.child[0].child[0].typ.numOut() 1523 } 1524 if nret < sc.def.typ.numOut() { 1525 err = n.cfgErrorf("not enough arguments to return") 1526 break 1527 } 1528 } 1529 wireChild(n) 1530 n.tnext = nil 1531 n.val = sc.def 1532 for i, c := range n.child { 1533 var typ *itype 1534 typ, err = nodeType(interp, sc.upperLevel(), returnSig.child[1].fieldType(i)) 1535 if err != nil { 1536 return 1537 } 1538 // TODO(mpl): move any of that code to typecheck? 1539 c.typ.node = c 1540 if !c.typ.assignableTo(typ) { 1541 err = c.cfgErrorf("cannot use %v (type %v) as type %v in return argument", c.ident, c.typ.cat, typ.cat) 1542 return 1543 } 1544 if c.typ.cat == nilT { 1545 // nil: Set node value to zero of return type 1546 if typ.cat == funcT { 1547 // Wrap the typed nil value in a node, as per other interpreter functions 1548 c.rval = reflect.ValueOf(&node{kind: basicLit, rval: reflect.New(typ.TypeOf()).Elem()}) 1549 } else { 1550 c.rval = reflect.New(typ.TypeOf()).Elem() 1551 } 1552 } 1553 } 1554 1555 case selectorExpr: 1556 wireChild(n) 1557 n.typ = n.child[0].typ 1558 n.recv = n.child[0].recv 1559 if n.typ == nil { 1560 err = n.cfgErrorf("undefined type") 1561 break 1562 } 1563 switch { 1564 case n.typ.cat == binPkgT: 1565 // Resolve binary package symbol: a type or a value 1566 name := n.child[1].ident 1567 pkg := n.child[0].sym.typ.path 1568 if s, ok := interp.binPkg[pkg][name]; ok { 1569 if isBinType(s) { 1570 n.typ = valueTOf(s.Type().Elem()) 1571 } else { 1572 n.typ = valueTOf(fixPossibleConstType(s.Type()), withUntyped(isValueUntyped(s))) 1573 n.rval = s 1574 } 1575 n.action = aGetSym 1576 n.gen = nop 1577 } else { 1578 err = n.cfgErrorf("package %s \"%s\" has no symbol %s", n.child[0].ident, pkg, name) 1579 } 1580 case n.typ.cat == srcPkgT: 1581 pkg, name := n.child[0].sym.typ.path, n.child[1].ident 1582 // Resolve source package symbol 1583 if sym, ok := interp.srcPkg[pkg][name]; ok { 1584 n.findex = sym.index 1585 if sym.global { 1586 n.level = globalFrame 1587 } 1588 n.val = sym.node 1589 n.gen = nop 1590 n.action = aGetSym 1591 n.typ = sym.typ 1592 n.sym = sym 1593 n.recv = sym.recv 1594 n.rval = sym.rval 1595 } else { 1596 err = n.cfgErrorf("undefined selector: %s.%s", pkg, name) 1597 } 1598 case isStruct(n.typ) || isInterfaceSrc(n.typ): 1599 // Find a matching field. 1600 if ti := n.typ.lookupField(n.child[1].ident); len(ti) > 0 { 1601 if isStruct(n.typ) { 1602 // If a method of the same name exists, use it if it is shallower than the struct field. 1603 // if method's depth is the same as field's, this is an error. 1604 d := n.typ.methodDepth(n.child[1].ident) 1605 if d >= 0 && d < len(ti) { 1606 goto tryMethods 1607 } 1608 if d == len(ti) { 1609 err = n.cfgErrorf("ambiguous selector: %s", n.child[1].ident) 1610 break 1611 } 1612 } 1613 n.val = ti 1614 switch { 1615 case isInterfaceSrc(n.typ): 1616 n.typ = n.typ.fieldSeq(ti) 1617 n.gen = getMethodByName 1618 n.action = aMethod 1619 case n.typ.cat == ptrT: 1620 n.typ = n.typ.fieldSeq(ti) 1621 n.gen = getPtrIndexSeq 1622 if n.typ.cat == funcT { 1623 // Function in a struct field is always wrapped in reflect.Value. 1624 n.typ = wrapperValueTOf(n.typ.TypeOf(), n.typ) 1625 } 1626 default: 1627 n.gen = getIndexSeq 1628 n.typ = n.typ.fieldSeq(ti) 1629 if n.typ.cat == funcT { 1630 // Function in a struct field is always wrapped in reflect.Value. 1631 n.typ = wrapperValueTOf(n.typ.TypeOf(), n.typ) 1632 } 1633 } 1634 break 1635 } 1636 if s, lind, ok := n.typ.lookupBinField(n.child[1].ident); ok { 1637 // Handle an embedded binary field into a struct field. 1638 n.gen = getIndexSeqField 1639 lind = append(lind, s.Index...) 1640 if isStruct(n.typ) { 1641 // If a method of the same name exists, use it if it is shallower than the struct field. 1642 // if method's depth is the same as field's, this is an error. 1643 d := n.typ.methodDepth(n.child[1].ident) 1644 if d >= 0 && d < len(lind) { 1645 goto tryMethods 1646 } 1647 if d == len(lind) { 1648 err = n.cfgErrorf("ambiguous selector: %s", n.child[1].ident) 1649 break 1650 } 1651 } 1652 n.val = lind 1653 n.typ = valueTOf(s.Type) 1654 break 1655 } 1656 // No field (embedded or not) matched. Try to match a method. 1657 tryMethods: 1658 fallthrough 1659 default: 1660 // Find a matching method. 1661 // TODO (marc): simplify the following if/elseif blocks. 1662 if n.typ.cat == valueT || n.typ.cat == errorT { 1663 switch method, ok := n.typ.rtype.MethodByName(n.child[1].ident); { 1664 case ok: 1665 hasRecvType := n.typ.rtype.Kind() != reflect.Interface 1666 n.val = method.Index 1667 n.gen = getIndexBinMethod 1668 n.action = aGetMethod 1669 n.recv = &receiver{node: n.child[0]} 1670 n.typ = valueTOf(method.Type, isBinMethod()) 1671 if hasRecvType { 1672 n.typ.recv = n.typ 1673 } 1674 case n.typ.rtype.Kind() == reflect.Ptr: 1675 if field, ok := n.typ.rtype.Elem().FieldByName(n.child[1].ident); ok { 1676 n.typ = valueTOf(field.Type) 1677 n.val = field.Index 1678 n.gen = getPtrIndexSeq 1679 break 1680 } 1681 err = n.cfgErrorf("undefined field or method: %s", n.child[1].ident) 1682 case n.typ.rtype.Kind() == reflect.Struct: 1683 if field, ok := n.typ.rtype.FieldByName(n.child[1].ident); ok { 1684 n.typ = valueTOf(field.Type) 1685 n.val = field.Index 1686 n.gen = getIndexSeq 1687 break 1688 } 1689 fallthrough 1690 default: 1691 // method lookup failed on type, now lookup on pointer to type 1692 pt := reflect.PtrTo(n.typ.rtype) 1693 if m2, ok2 := pt.MethodByName(n.child[1].ident); ok2 { 1694 n.val = m2.Index 1695 n.gen = getIndexBinPtrMethod 1696 n.typ = valueTOf(m2.Type, isBinMethod(), withRecv(valueTOf(pt))) 1697 n.recv = &receiver{node: n.child[0]} 1698 n.action = aGetMethod 1699 break 1700 } 1701 err = n.cfgErrorf("undefined field or method: %s", n.child[1].ident) 1702 } 1703 } else if n.typ.cat == ptrT && (n.typ.val.cat == valueT || n.typ.val.cat == errorT) { 1704 // Handle pointer on object defined in runtime 1705 if method, ok := n.typ.val.rtype.MethodByName(n.child[1].ident); ok { 1706 n.val = method.Index 1707 n.typ = valueTOf(method.Type, isBinMethod(), withRecv(n.typ)) 1708 n.recv = &receiver{node: n.child[0]} 1709 n.gen = getIndexBinElemMethod 1710 n.action = aGetMethod 1711 } else if method, ok := reflect.PtrTo(n.typ.val.rtype).MethodByName(n.child[1].ident); ok { 1712 n.val = method.Index 1713 n.gen = getIndexBinMethod 1714 n.typ = valueTOf(method.Type, withRecv(valueTOf(reflect.PtrTo(n.typ.val.rtype), isBinMethod()))) 1715 n.recv = &receiver{node: n.child[0]} 1716 n.action = aGetMethod 1717 } else if field, ok := n.typ.val.rtype.FieldByName(n.child[1].ident); ok { 1718 n.typ = valueTOf(field.Type) 1719 n.val = field.Index 1720 n.gen = getPtrIndexSeq 1721 } else { 1722 err = n.cfgErrorf("undefined selector: %s", n.child[1].ident) 1723 } 1724 } else if m, lind := n.typ.lookupMethod(n.child[1].ident); m != nil { 1725 n.action = aGetMethod 1726 if n.child[0].isType(sc) { 1727 // Handle method as a function with receiver in 1st argument 1728 n.val = m 1729 n.findex = notInFrame 1730 n.gen = nop 1731 n.typ = &itype{} 1732 *n.typ = *m.typ 1733 n.typ.arg = append([]*itype{n.child[0].typ}, m.typ.arg...) 1734 } else { 1735 // Handle method with receiver 1736 n.gen = getMethod 1737 n.val = m 1738 n.typ = m.typ 1739 n.recv = &receiver{node: n.child[0], index: lind} 1740 } 1741 } else if m, lind, isPtr, ok := n.typ.lookupBinMethod(n.child[1].ident); ok { 1742 n.action = aGetMethod 1743 switch { 1744 case isPtr && n.typ.fieldSeq(lind).cat != ptrT: 1745 n.gen = getIndexSeqPtrMethod 1746 case isInterfaceSrc(n.typ): 1747 n.gen = getMethodByName 1748 default: 1749 n.gen = getIndexSeqMethod 1750 } 1751 n.recv = &receiver{node: n.child[0], index: lind} 1752 n.val = append([]int{m.Index}, lind...) 1753 n.typ = valueTOf(m.Type, isBinMethod(), withRecv(n.child[0].typ)) 1754 } else { 1755 err = n.cfgErrorf("undefined selector: %s", n.child[1].ident) 1756 } 1757 } 1758 if err == nil && n.findex != -1 { 1759 n.findex = sc.add(n.typ) 1760 } 1761 1762 case selectStmt: 1763 wireChild(n) 1764 // Move action to block statement, so select node can be an exit point. 1765 n.child[0].gen = _select 1766 // Chain channel init actions in commClauses prior to invoke select. 1767 var cur *node 1768 for _, c := range n.child[0].child { 1769 var an, pn *node // channel init action nodes 1770 if len(c.child) > 0 { 1771 switch c0 := c.child[0]; { 1772 case c0.kind == exprStmt && len(c0.child) == 1 && c0.child[0].action == aRecv: 1773 an = c0.child[0].child[0] 1774 pn = an 1775 case c0.action == aAssign: 1776 an = c0.lastChild().child[0] 1777 pn = an 1778 case c0.kind == sendStmt: 1779 an = c0.child[0] 1780 pn = c0.child[1] 1781 } 1782 } 1783 if an == nil { 1784 continue 1785 } 1786 if cur == nil { 1787 // First channel init action, the entry point for the select block. 1788 n.start = an.start 1789 } else { 1790 // Chain channel init action to the previous one. 1791 cur.tnext = an.start 1792 } 1793 if pn != nil { 1794 // Chain channect init action to send data init action. 1795 // (already done by wireChild, but let's be explicit). 1796 an.tnext = pn 1797 cur = pn 1798 } 1799 } 1800 if cur == nil { 1801 // There is no channel init action, call select directly. 1802 n.start = n.child[0] 1803 } else { 1804 // Select is called after the last channel init action. 1805 cur.tnext = n.child[0] 1806 } 1807 1808 case starExpr: 1809 if isBlank(n.child[0]) { 1810 err = n.cfgErrorf("cannot use _ as value") 1811 break 1812 } 1813 switch { 1814 case n.anc.kind == defineStmt && len(n.anc.child) == 3 && n.anc.child[1] == n: 1815 // pointer type expression in a var definition 1816 n.gen = nop 1817 case n.anc.kind == valueSpec && n.anc.lastChild() == n: 1818 // pointer type expression in a value spec 1819 n.gen = nop 1820 case n.anc.kind == fieldExpr: 1821 // pointer type expression in a field expression (arg or struct field) 1822 n.gen = nop 1823 case n.child[0].isType(sc): 1824 // pointer type expression 1825 n.gen = nop 1826 n.typ = ptrOf(n.child[0].typ) 1827 default: 1828 // dereference expression 1829 wireChild(n) 1830 1831 err = check.starExpr(n.child[0]) 1832 if err != nil { 1833 break 1834 } 1835 1836 if c0 := n.child[0]; c0.typ.cat == valueT { 1837 n.typ = valueTOf(c0.typ.rtype.Elem()) 1838 } else { 1839 n.typ = c0.typ.val 1840 } 1841 n.findex = sc.add(n.typ) 1842 } 1843 1844 case typeSwitch: 1845 // Check that cases expressions are all different 1846 usedCase := map[string]bool{} 1847 for _, c := range n.lastChild().child { 1848 for _, t := range c.child[:len(c.child)-1] { 1849 tid := t.typ.id() 1850 if usedCase[tid] { 1851 err = c.cfgErrorf("duplicate case %s in type switch", t.ident) 1852 return 1853 } 1854 usedCase[tid] = true 1855 } 1856 } 1857 fallthrough 1858 1859 case switchStmt: 1860 sc = sc.pop() 1861 sbn := n.lastChild() // switch block node 1862 clauses := sbn.child 1863 l := len(clauses) 1864 if l == 0 { 1865 // Switch is empty 1866 break 1867 } 1868 // Chain case clauses. 1869 for i := l - 1; i >= 0; i-- { 1870 c := clauses[i] 1871 if len(c.child) == 0 { 1872 c.tnext = n // Clause body is empty, exit. 1873 } else { 1874 body := c.lastChild() 1875 c.tnext = body.start 1876 c.child[0].tnext = c 1877 c.start = c.child[0].start 1878 1879 if i < l-1 && len(body.child) > 0 && body.lastChild().kind == fallthroughtStmt { 1880 if n.kind == typeSwitch { 1881 err = body.lastChild().cfgErrorf("cannot fallthrough in type switch") 1882 } 1883 if len(clauses[i+1].child) == 0 { 1884 body.tnext = n // Fallthrough to next with empty body, just exit. 1885 } else { 1886 body.tnext = clauses[i+1].lastChild().start 1887 } 1888 } else { 1889 body.tnext = n // Exit switch at end of clause body. 1890 } 1891 } 1892 1893 if i == l-1 { 1894 setFNext(clauses[i], n) 1895 continue 1896 } 1897 if len(clauses[i+1].child) > 1 { 1898 setFNext(c, clauses[i+1].start) 1899 } else { 1900 setFNext(c, clauses[i+1]) 1901 } 1902 } 1903 sbn.start = clauses[0].start 1904 n.start = n.child[0].start 1905 n.child[0].tnext = sbn.start 1906 1907 case switchIfStmt: // like an if-else chain 1908 sc = sc.pop() 1909 sbn := n.lastChild() // switch block node 1910 clauses := sbn.child 1911 l := len(clauses) 1912 if l == 0 { 1913 // Switch is empty 1914 break 1915 } 1916 // Wire case clauses in reverse order so the next start node is already resolved when used. 1917 for i := l - 1; i >= 0; i-- { 1918 c := clauses[i] 1919 c.gen = nop 1920 if len(c.child) == 0 { 1921 c.tnext = n 1922 c.fnext = n 1923 } else { 1924 body := c.lastChild() 1925 if len(c.child) > 1 { 1926 cond := c.child[0] 1927 cond.tnext = body.start 1928 if i == l-1 { 1929 setFNext(cond, n) 1930 } else { 1931 setFNext(cond, clauses[i+1].start) 1932 } 1933 c.start = cond.start 1934 } else { 1935 c.start = body.start 1936 } 1937 // If last case body statement is a fallthrough, then jump to next case body 1938 if i < l-1 && len(body.child) > 0 && body.lastChild().kind == fallthroughtStmt { 1939 body.tnext = clauses[i+1].lastChild().start 1940 } else { 1941 body.tnext = n 1942 } 1943 } 1944 } 1945 sbn.start = clauses[0].start 1946 n.start = n.child[0].start 1947 n.child[0].tnext = sbn.start 1948 1949 case typeAssertExpr: 1950 if len(n.child) == 1 { 1951 // The "o.(type)" is handled by typeSwitch. 1952 n.gen = nop 1953 break 1954 } 1955 1956 wireChild(n) 1957 c0, c1 := n.child[0], n.child[1] 1958 if isBlank(c0) || isBlank(c1) { 1959 err = n.cfgErrorf("cannot use _ as value") 1960 break 1961 } 1962 if c1.typ == nil { 1963 if c1.typ, err = nodeType(interp, sc, c1); err != nil { 1964 return 1965 } 1966 } 1967 1968 err = check.typeAssertionExpr(c0, c1.typ) 1969 if err != nil { 1970 break 1971 } 1972 1973 if n.anc.action != aAssignX { 1974 if c0.typ.cat == valueT && isFunc(c1.typ) { 1975 // Avoid special wrapping of interfaces and func types. 1976 n.typ = valueTOf(c1.typ.TypeOf()) 1977 } else { 1978 n.typ = c1.typ 1979 } 1980 n.findex = sc.add(n.typ) 1981 } 1982 1983 case sliceExpr: 1984 wireChild(n) 1985 1986 err = check.sliceExpr(n) 1987 if err != nil { 1988 break 1989 } 1990 1991 if n.typ, err = nodeType(interp, sc, n); err != nil { 1992 return 1993 } 1994 n.findex = sc.add(n.typ) 1995 1996 case unaryExpr: 1997 wireChild(n) 1998 1999 err = check.unaryExpr(n) 2000 if err != nil { 2001 break 2002 } 2003 2004 n.typ = n.child[0].typ 2005 if n.action == aRecv { 2006 // Channel receive operation: set type to the channel data type 2007 if n.typ.cat == valueT { 2008 n.typ = valueTOf(n.typ.rtype.Elem()) 2009 } else { 2010 n.typ = n.typ.val 2011 } 2012 } 2013 if n.typ == nil { 2014 if n.typ, err = nodeType(interp, sc, n); err != nil { 2015 return 2016 } 2017 } 2018 2019 // TODO: Optimisation: avoid allocation if boolean branch op (i.e. '!' in an 'if' expr) 2020 if n.child[0].rval.IsValid() && !isInterface(n.typ) && constOp[n.action] != nil { 2021 n.typ.TypeOf() // init reflect type 2022 constOp[n.action](n) 2023 } 2024 switch { 2025 case n.rval.IsValid(): 2026 n.gen = nop 2027 n.findex = notInFrame 2028 case n.anc.kind == assignStmt && n.anc.action == aAssign && n.anc.nright == 1: 2029 dest := n.anc.child[childPos(n)-n.anc.nright] 2030 n.typ = dest.typ 2031 n.findex = dest.findex 2032 n.level = dest.level 2033 case n.anc.kind == returnStmt: 2034 pos := childPos(n) 2035 n.typ = sc.def.typ.ret[pos] 2036 n.findex = pos 2037 default: 2038 n.findex = sc.add(n.typ) 2039 } 2040 2041 case valueSpec: 2042 n.gen = reset 2043 l := len(n.child) - 1 2044 if n.typ = n.child[l].typ; n.typ == nil { 2045 if n.typ, err = nodeType(interp, sc, n.child[l]); err != nil { 2046 return 2047 } 2048 } 2049 2050 for _, c := range n.child[:l] { 2051 var index int 2052 if sc.global { 2053 // Global object allocation is already performed in GTA. 2054 index = sc.sym[c.ident].index 2055 c.level = globalFrame 2056 } else { 2057 index = sc.add(n.typ) 2058 sc.sym[c.ident] = &symbol{index: index, kind: varSym, typ: n.typ} 2059 } 2060 c.typ = n.typ 2061 c.findex = index 2062 } 2063 } 2064 }) 2065 2066 if sc != interp.universe { 2067 sc.pop() 2068 } 2069 return initNodes, err 2070 } 2071 2072 func compDefineX(sc *scope, n *node) error { 2073 l := len(n.child) - 1 2074 types := []*itype{} 2075 2076 switch src := n.child[l]; src.kind { 2077 case callExpr: 2078 funtype, err := nodeType(n.interp, sc, src.child[0]) 2079 if err != nil { 2080 return err 2081 } 2082 for funtype.cat == valueT && funtype.val != nil { 2083 // Retrieve original interpreter type from a wrapped function. 2084 // Struct fields of function types are always wrapped in valueT to ensure 2085 // their possible use in runtime. In that case, the val field retains the 2086 // original interpreter type, which is used now. 2087 funtype = funtype.val 2088 } 2089 if funtype.cat == valueT { 2090 // Handle functions imported from runtime. 2091 for i := 0; i < funtype.rtype.NumOut(); i++ { 2092 types = append(types, valueTOf(funtype.rtype.Out(i))) 2093 } 2094 } else { 2095 types = funtype.ret 2096 } 2097 if n.anc.kind == varDecl && n.child[l-1].isType(sc) { 2098 l-- 2099 } 2100 if len(types) != l { 2101 return n.cfgErrorf("assignment mismatch: %d variables but %s returns %d values", l, src.child[0].name(), len(types)) 2102 } 2103 if isBinCall(src, sc) { 2104 n.gen = nop 2105 } else { 2106 // TODO (marc): skip if no conversion or wrapping is needed. 2107 n.gen = assignFromCall 2108 } 2109 2110 case indexExpr: 2111 types = append(types, src.typ, sc.getType("bool")) 2112 n.child[l].gen = getIndexMap2 2113 n.gen = nop 2114 2115 case typeAssertExpr: 2116 if n.child[0].ident == "_" { 2117 n.child[l].gen = typeAssertStatus 2118 } else { 2119 n.child[l].gen = typeAssertLong 2120 } 2121 types = append(types, n.child[l].child[1].typ, sc.getType("bool")) 2122 n.gen = nop 2123 2124 case unaryExpr: 2125 if n.child[l].action == aRecv { 2126 types = append(types, src.typ, sc.getType("bool")) 2127 n.child[l].gen = recv2 2128 n.gen = nop 2129 } 2130 2131 default: 2132 return n.cfgErrorf("unsupported assign expression") 2133 } 2134 2135 for i, t := range types { 2136 var index int 2137 id := n.child[i].ident 2138 if sym, level, ok := sc.lookup(id); ok && level == n.child[i].level && sym.kind == varSym && sym.typ.id() == t.id() { 2139 // Reuse symbol in case of a variable redeclaration with the same type. 2140 index = sym.index 2141 } else { 2142 index = sc.add(t) 2143 sc.sym[id] = &symbol{index: index, kind: varSym, typ: t} 2144 } 2145 n.child[i].typ = t 2146 n.child[i].findex = index 2147 } 2148 return nil 2149 } 2150 2151 // TODO used for allocation optimization, temporarily disabled 2152 // func isAncBranch(n *node) bool { 2153 // switch n.anc.kind { 2154 // case If0, If1, If2, If3: 2155 // return true 2156 // } 2157 // return false 2158 // } 2159 2160 func childPos(n *node) int { 2161 for i, c := range n.anc.child { 2162 if n == c { 2163 return i 2164 } 2165 } 2166 return -1 2167 } 2168 2169 func (n *node) cfgErrorf(format string, a ...interface{}) *cfgError { 2170 pos := n.interp.fset.Position(n.pos) 2171 posString := n.interp.fset.Position(n.pos).String() 2172 if pos.Filename == DefaultSourceName { 2173 posString = strings.TrimPrefix(posString, DefaultSourceName+":") 2174 } 2175 a = append([]interface{}{posString}, a...) 2176 return &cfgError{n, fmt.Errorf("%s: "+format, a...)} 2177 } 2178 2179 func genRun(nod *node) error { 2180 var err error 2181 2182 nod.Walk(func(n *node) bool { 2183 if err != nil { 2184 return false 2185 } 2186 switch n.kind { 2187 case funcType: 2188 if len(n.anc.child) == 4 { 2189 // function body entry point 2190 setExec(n.anc.child[3].start) 2191 } 2192 // continue in function body as there may be inner function definitions 2193 case constDecl, varDecl: 2194 setExec(n.start) 2195 return false 2196 } 2197 return true 2198 }, nil) 2199 2200 return err 2201 } 2202 2203 func genGlobalVars(roots []*node, sc *scope) (*node, error) { 2204 var vars []*node 2205 for _, n := range roots { 2206 vars = append(vars, getVars(n)...) 2207 } 2208 2209 if len(vars) == 0 { 2210 return nil, nil 2211 } 2212 2213 varNode, err := genGlobalVarDecl(vars, sc) 2214 if err != nil { 2215 return nil, err 2216 } 2217 setExec(varNode.start) 2218 return varNode, nil 2219 } 2220 2221 func getVars(n *node) (vars []*node) { 2222 for _, child := range n.child { 2223 if child.kind == varDecl { 2224 vars = append(vars, child.child...) 2225 } 2226 } 2227 return vars 2228 } 2229 2230 func genGlobalVarDecl(nodes []*node, sc *scope) (*node, error) { 2231 varNode := &node{kind: varDecl, action: aNop, gen: nop} 2232 2233 deps := map[*node][]*node{} 2234 for _, n := range nodes { 2235 deps[n] = getVarDependencies(n, sc) 2236 } 2237 2238 inited := map[*node]bool{} 2239 revisit := []*node{} 2240 for { 2241 for _, n := range nodes { 2242 canInit := true 2243 for _, d := range deps[n] { 2244 if !inited[d] { 2245 canInit = false 2246 } 2247 } 2248 if !canInit { 2249 revisit = append(revisit, n) 2250 continue 2251 } 2252 2253 varNode.child = append(varNode.child, n) 2254 inited[n] = true 2255 } 2256 2257 if len(revisit) == 0 || equalNodes(nodes, revisit) { 2258 break 2259 } 2260 2261 nodes = revisit 2262 revisit = []*node{} 2263 } 2264 2265 if len(revisit) > 0 { 2266 return nil, revisit[0].cfgErrorf("variable definition loop") 2267 } 2268 wireChild(varNode) 2269 return varNode, nil 2270 } 2271 2272 func getVarDependencies(nod *node, sc *scope) (deps []*node) { 2273 nod.Walk(func(n *node) bool { 2274 if n.kind == identExpr { 2275 if sym, _, ok := sc.lookup(n.ident); ok { 2276 if sym.kind != varSym || !sym.global || sym.node == nod { 2277 return false 2278 } 2279 deps = append(deps, sym.node) 2280 } 2281 } 2282 return true 2283 }, nil) 2284 return deps 2285 } 2286 2287 // setFnext sets the cond fnext field to next, propagates it for parenthesis blocks 2288 // and sets the action to branch. 2289 func setFNext(cond, next *node) { 2290 if cond.action == aNop { 2291 cond.action = aBranch 2292 cond.gen = branch 2293 cond.fnext = next 2294 } 2295 if cond.kind == parenExpr { 2296 setFNext(cond.lastChild(), next) 2297 return 2298 } 2299 cond.fnext = next 2300 } 2301 2302 // GetDefault return the index of default case clause in a switch statement, or -1. 2303 func getDefault(n *node) int { 2304 for i, c := range n.lastChild().child { 2305 switch len(c.child) { 2306 case 0: 2307 return i 2308 case 1: 2309 if c.child[0].kind == caseBody { 2310 return i 2311 } 2312 } 2313 } 2314 return -1 2315 } 2316 2317 func isBinType(v reflect.Value) bool { return v.IsValid() && v.Kind() == reflect.Ptr && v.IsNil() } 2318 2319 // isType returns true if node refers to a type definition, false otherwise. 2320 func (n *node) isType(sc *scope) bool { 2321 switch n.kind { 2322 case arrayType, chanType, chanTypeRecv, chanTypeSend, funcType, interfaceType, mapType, structType: 2323 return true 2324 case parenExpr, starExpr: 2325 if len(n.child) == 1 { 2326 return n.child[0].isType(sc) 2327 } 2328 case selectorExpr: 2329 pkg, name := n.child[0].ident, n.child[1].ident 2330 baseName := filepath.Base(n.interp.fset.Position(n.pos).Filename) 2331 suffixedPkg := filepath.Join(pkg, baseName) 2332 sym, _, ok := sc.lookup(suffixedPkg) 2333 if !ok { 2334 sym, _, ok = sc.lookup(pkg) 2335 if !ok { 2336 return false 2337 } 2338 } 2339 if sym.kind != pkgSym { 2340 return false 2341 } 2342 path := sym.typ.path 2343 if p, ok := n.interp.binPkg[path]; ok && isBinType(p[name]) { 2344 return true // Imported binary type 2345 } 2346 if p, ok := n.interp.srcPkg[path]; ok && p[name] != nil && p[name].kind == typeSym { 2347 return true // Imported source type 2348 } 2349 case identExpr: 2350 return sc.getType(n.ident) != nil 2351 } 2352 return false 2353 } 2354 2355 // wireChild wires AST nodes for CFG in subtree. 2356 func wireChild(n *node, exclude ...nkind) { 2357 child := excludeNodeKind(n.child, exclude) 2358 2359 // Set start node, in subtree (propagated to ancestors by post-order processing) 2360 for _, c := range child { 2361 switch c.kind { 2362 case arrayType, chanType, chanTypeRecv, chanTypeSend, funcDecl, importDecl, mapType, basicLit, identExpr, typeDecl: 2363 continue 2364 default: 2365 n.start = c.start 2366 } 2367 break 2368 } 2369 2370 // Chain sequential operations inside a block (next is right sibling) 2371 for i := 1; i < len(child); i++ { 2372 switch child[i].kind { 2373 case funcDecl: 2374 child[i-1].tnext = child[i] 2375 default: 2376 switch child[i-1].kind { 2377 case breakStmt, continueStmt, gotoStmt, returnStmt: 2378 // tnext is already computed, no change 2379 default: 2380 child[i-1].tnext = child[i].start 2381 } 2382 } 2383 } 2384 2385 // Chain subtree next to self 2386 for i := len(child) - 1; i >= 0; i-- { 2387 switch child[i].kind { 2388 case arrayType, chanType, chanTypeRecv, chanTypeSend, importDecl, mapType, funcDecl, basicLit, identExpr, typeDecl: 2389 continue 2390 case breakStmt, continueStmt, gotoStmt, returnStmt: 2391 // tnext is already computed, no change 2392 default: 2393 child[i].tnext = n 2394 } 2395 break 2396 } 2397 } 2398 2399 func excludeNodeKind(child []*node, kinds []nkind) []*node { 2400 if len(kinds) == 0 { 2401 return child 2402 } 2403 var res []*node 2404 for _, c := range child { 2405 exclude := false 2406 for _, k := range kinds { 2407 if c.kind == k { 2408 exclude = true 2409 } 2410 } 2411 if !exclude { 2412 res = append(res, c) 2413 } 2414 } 2415 return res 2416 } 2417 2418 func (n *node) name() (s string) { 2419 switch { 2420 case n.ident != "": 2421 s = n.ident 2422 case n.action == aGetSym: 2423 s = n.child[0].ident + "." + n.child[1].ident 2424 } 2425 return s 2426 } 2427 2428 // isNatural returns true if node type is natural, false otherwise. 2429 func (n *node) isNatural() bool { 2430 if isUint(n.typ.TypeOf()) { 2431 return true 2432 } 2433 if n.rval.IsValid() { 2434 t := n.rval.Type() 2435 if isUint(t) { 2436 return true 2437 } 2438 if isInt(t) && n.rval.Int() >= 0 { 2439 // positive untyped integer constant is ok 2440 return true 2441 } 2442 if isFloat(t) { 2443 // positive untyped float constant with null decimal part is ok 2444 f := n.rval.Float() 2445 if f == math.Trunc(f) && f >= 0 { 2446 n.rval = reflect.ValueOf(uint(f)) 2447 n.typ.rtype = n.rval.Type() 2448 return true 2449 } 2450 } 2451 if isConstantValue(t) { 2452 c := n.rval.Interface().(constant.Value) 2453 switch c.Kind() { 2454 case constant.Int: 2455 i, _ := constant.Int64Val(c) 2456 if i >= 0 { 2457 return true 2458 } 2459 case constant.Float: 2460 f, _ := constant.Float64Val(c) 2461 if f == math.Trunc(f) { 2462 n.rval = reflect.ValueOf(constant.ToInt(c)) 2463 n.typ.rtype = n.rval.Type() 2464 return true 2465 } 2466 } 2467 } 2468 } 2469 return false 2470 } 2471 2472 // isNil returns true if node is a literal nil value, false otherwise. 2473 func (n *node) isNil() bool { return n.kind == basicLit && !n.rval.IsValid() } 2474 2475 // fieldType returns the nth parameter field node (type) of a fieldList node. 2476 func (n *node) fieldType(m int) *node { 2477 k := 0 2478 l := len(n.child) 2479 for i := 0; i < l; i++ { 2480 cl := len(n.child[i].child) 2481 if cl < 2 { 2482 if k == m { 2483 return n.child[i].lastChild() 2484 } 2485 k++ 2486 continue 2487 } 2488 for j := 0; j < cl-1; j++ { 2489 if k == m { 2490 return n.child[i].lastChild() 2491 } 2492 k++ 2493 } 2494 } 2495 return nil 2496 } 2497 2498 // lastChild returns the last child of a node. 2499 func (n *node) lastChild() *node { return n.child[len(n.child)-1] } 2500 2501 func (n *node) hasAnc(nod *node) bool { 2502 for a := n.anc; a != nil; a = a.anc { 2503 if a == nod { 2504 return true 2505 } 2506 } 2507 return false 2508 } 2509 2510 func isKey(n *node) bool { 2511 return n.anc.kind == fileStmt || 2512 (n.anc.kind == selectorExpr && n.anc.child[0] != n) || 2513 (n.anc.kind == funcDecl && isMethod(n.anc)) || 2514 (n.anc.kind == keyValueExpr && isStruct(n.anc.typ) && n.anc.child[0] == n) || 2515 (n.anc.kind == fieldExpr && len(n.anc.child) > 1 && n.anc.child[0] == n) 2516 } 2517 2518 func isField(n *node) bool { 2519 return n.kind == selectorExpr && len(n.child) > 0 && n.child[0].typ != nil && isStruct(n.child[0].typ) 2520 } 2521 2522 func isInConstOrTypeDecl(n *node) bool { 2523 anc := n.anc 2524 for anc != nil { 2525 switch anc.kind { 2526 case constDecl, typeDecl, arrayType, chanType: 2527 return true 2528 case varDecl, funcDecl: 2529 return false 2530 } 2531 anc = anc.anc 2532 } 2533 return false 2534 } 2535 2536 // isNewDefine returns true if node refers to a new definition. 2537 func isNewDefine(n *node, sc *scope) bool { 2538 if n.ident == "_" { 2539 return true 2540 } 2541 if (n.anc.kind == defineXStmt || n.anc.kind == defineStmt || n.anc.kind == valueSpec) && childPos(n) < n.anc.nleft { 2542 return true 2543 } 2544 if n.anc.kind == rangeStmt { 2545 if n.anc.child[0] == n { 2546 return true // array or map key, or chan element 2547 } 2548 if sc.rangeChanType(n.anc) == nil && n.anc.child[1] == n && len(n.anc.child) == 4 { 2549 return true // array or map value 2550 } 2551 return false // array, map or channel are always pre-defined in range expression 2552 } 2553 return false 2554 } 2555 2556 func isMethod(n *node) bool { 2557 return len(n.child[0].child) > 0 // receiver defined 2558 } 2559 2560 func isFuncField(n *node) bool { 2561 return isField(n) && isFunc(n.typ) 2562 } 2563 2564 func isMapEntry(n *node) bool { 2565 return n.action == aGetIndex && isMap(n.child[0].typ) 2566 } 2567 2568 func isCall(n *node) bool { 2569 return n.action == aCall || n.action == aCallSlice 2570 } 2571 2572 func isBinCall(n *node, sc *scope) bool { 2573 if !isCall(n) || len(n.child) == 0 { 2574 return false 2575 } 2576 c0 := n.child[0] 2577 if c0.typ == nil { 2578 // If called early in parsing, child type may not be known yet. 2579 c0.typ, _ = nodeType(n.interp, sc, c0) 2580 if c0.typ == nil { 2581 return false 2582 } 2583 } 2584 return c0.typ.cat == valueT && c0.typ.rtype.Kind() == reflect.Func 2585 } 2586 2587 func isOffsetof(n *node) bool { 2588 return isCall(n) && n.child[0].typ.cat == valueT && n.child[0].rval.String() == "Offsetof" 2589 } 2590 2591 func mustReturnValue(n *node) bool { 2592 if len(n.child) < 2 { 2593 return false 2594 } 2595 for _, f := range n.child[1].child { 2596 if len(f.child) > 1 { 2597 return false 2598 } 2599 } 2600 return true 2601 } 2602 2603 func isRegularCall(n *node) bool { 2604 return isCall(n) && n.child[0].typ.cat == funcT 2605 } 2606 2607 func variadicPos(n *node) int { 2608 if len(n.child[0].typ.arg) == 0 { 2609 return -1 2610 } 2611 last := len(n.child[0].typ.arg) - 1 2612 if n.child[0].typ.arg[last].cat == variadicT { 2613 return last 2614 } 2615 return -1 2616 } 2617 2618 func canExport(name string) bool { 2619 if r := []rune(name); len(r) > 0 && unicode.IsUpper(r[0]) { 2620 return true 2621 } 2622 return false 2623 } 2624 2625 func getExec(n *node) bltn { 2626 if n == nil { 2627 return nil 2628 } 2629 if n.exec == nil { 2630 setExec(n) 2631 } 2632 return n.exec 2633 } 2634 2635 // setExec recursively sets the node exec builtin function by walking the CFG 2636 // from the entry point (first node to exec). 2637 func setExec(n *node) { 2638 if n.exec != nil { 2639 return 2640 } 2641 seen := map[*node]bool{} 2642 var set func(n *node) 2643 2644 set = func(n *node) { 2645 if n == nil || n.exec != nil { 2646 return 2647 } 2648 seen[n] = true 2649 if n.tnext != nil && n.tnext.exec == nil { 2650 if seen[n.tnext] { 2651 m := n.tnext 2652 n.tnext.exec = func(f *frame) bltn { return m.exec(f) } 2653 } else { 2654 set(n.tnext) 2655 } 2656 } 2657 if n.fnext != nil && n.fnext.exec == nil { 2658 if seen[n.fnext] { 2659 m := n.fnext 2660 n.fnext.exec = func(f *frame) bltn { return m.exec(f) } 2661 } else { 2662 set(n.fnext) 2663 } 2664 } 2665 n.gen(n) 2666 } 2667 2668 set(n) 2669 } 2670 2671 func typeSwichAssign(n *node) bool { 2672 ts := n.anc.anc.anc 2673 return ts.kind == typeSwitch && ts.child[1].action == aAssign 2674 } 2675 2676 func compositeGenerator(n *node, typ *itype, rtyp reflect.Type) (gen bltnGenerator) { 2677 switch typ.cat { 2678 case aliasT, ptrT: 2679 gen = compositeGenerator(n, typ.val, rtyp) 2680 case arrayT, sliceT: 2681 gen = arrayLit 2682 case mapT: 2683 gen = mapLit 2684 case structT: 2685 switch { 2686 case len(n.child) == 0: 2687 gen = compositeLitNotype 2688 case n.lastChild().kind == keyValueExpr: 2689 if n.nleft == 1 { 2690 gen = compositeLitKeyed 2691 } else { 2692 gen = compositeLitKeyedNotype 2693 } 2694 default: 2695 if n.nleft == 1 { 2696 gen = compositeLit 2697 } else { 2698 gen = compositeLitNotype 2699 } 2700 } 2701 case valueT: 2702 if rtyp == nil { 2703 rtyp = n.typ.TypeOf() 2704 } 2705 switch k := rtyp.Kind(); k { 2706 case reflect.Struct: 2707 if n.nleft == 1 { 2708 gen = compositeBinStruct 2709 } else { 2710 gen = compositeBinStructNotype 2711 } 2712 case reflect.Map: 2713 // TODO(mpl): maybe needs a NoType version too 2714 gen = compositeBinMap 2715 case reflect.Ptr: 2716 gen = compositeGenerator(n, typ, n.typ.val.rtype) 2717 case reflect.Slice, reflect.Array: 2718 gen = compositeBinSlice 2719 default: 2720 log.Panic(n.cfgErrorf("compositeGenerator not implemented for type kind: %s", k)) 2721 } 2722 } 2723 return gen 2724 } 2725 2726 // arrayTypeLen returns the node's array length. If the expression is an 2727 // array variable it is determined from the value's type, otherwise it is 2728 // computed from the source definition. 2729 func arrayTypeLen(n *node, sc *scope) (int, error) { 2730 if n.typ != nil && n.typ.cat == arrayT { 2731 return n.typ.length, nil 2732 } 2733 max := -1 2734 for _, c := range n.child[1:] { 2735 var r int 2736 2737 if c.kind != keyValueExpr { 2738 r = max + 1 2739 max = r 2740 continue 2741 } 2742 2743 c0 := c.child[0] 2744 v := c0.rval 2745 if v.IsValid() { 2746 r = int(v.Int()) 2747 } else { 2748 // Resolve array key value as a constant. 2749 if c0.kind == identExpr { 2750 // Key is defined by a symbol which must be a constant integer. 2751 sym, _, ok := sc.lookup(c0.ident) 2752 if !ok { 2753 return 0, c0.cfgErrorf("undefined: %s", c0.ident) 2754 } 2755 if sym.kind != constSym { 2756 return 0, c0.cfgErrorf("non-constant array bound %q", c0.ident) 2757 } 2758 r = int(vInt(sym.rval)) 2759 } else { 2760 // Key is defined by a numeric constant expression. 2761 if _, err := c0.interp.cfg(c0, sc, sc.pkgID, sc.pkgName); err != nil { 2762 return 0, err 2763 } 2764 cv, ok := c0.rval.Interface().(constant.Value) 2765 if !ok { 2766 return 0, c0.cfgErrorf("non-constant expression") 2767 } 2768 r = constToInt(cv) 2769 } 2770 } 2771 2772 if r > max { 2773 max = r 2774 } 2775 } 2776 return max + 1, nil 2777 } 2778 2779 // isValueUntyped returns true if value is untyped. 2780 func isValueUntyped(v reflect.Value) bool { 2781 // Consider only constant values. 2782 if v.CanSet() { 2783 return false 2784 } 2785 return v.Type().Implements(constVal) 2786 } 2787 2788 // isArithmeticAction returns true if the node action is an arithmetic operator. 2789 func isArithmeticAction(n *node) bool { 2790 switch n.action { 2791 case aAdd, aAnd, aAndNot, aBitNot, aMul, aNeg, aOr, aPos, aQuo, aRem, aShl, aShr, aSub, aXor: 2792 return true 2793 } 2794 return false 2795 } 2796 2797 func isBoolAction(n *node) bool { 2798 switch n.action { 2799 case aEqual, aGreater, aGreaterEqual, aLand, aLor, aLower, aLowerEqual, aNot, aNotEqual: 2800 return true 2801 } 2802 return false 2803 } 2804 2805 func isBlank(n *node) bool { 2806 if n.kind == parenExpr && len(n.child) > 0 { 2807 return isBlank(n.child[0]) 2808 } 2809 return n.ident == "_" 2810 }