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  }