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