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