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