github.com/goplus/igop@v0.25.0/opblock.go (about)

     1  /*
     2   * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package igop
    18  
    19  import (
    20  	"fmt"
    21  	"go/token"
    22  	"go/types"
    23  	"io"
    24  	"reflect"
    25  	"strings"
    26  	"sync"
    27  	"sync/atomic"
    28  	"unsafe"
    29  
    30  	"github.com/goplus/igop/load"
    31  	"github.com/goplus/reflectx"
    32  	"github.com/visualfc/funcval"
    33  	"github.com/visualfc/xtype"
    34  	"golang.org/x/tools/go/ssa"
    35  )
    36  
    37  /*
    38  type Op int
    39  
    40  const (
    41  	OpInvalid Op = iota
    42  	// Value-defining instructions
    43  	OpAlloc
    44  	OpPhi
    45  	OpCall
    46  	OpBinOp
    47  	OpUnOp
    48  	OpChangeType
    49  	OpConvert
    50  	OpChangeInterface
    51  	OpSliceToArrayPointer
    52  	OpMakeInterface
    53  	OpMakeClosure
    54  	OpMakeMap
    55  	OpMakeChan
    56  	OpMakeSlice
    57  	OpSlice
    58  	OpFieldAddr
    59  	OpField
    60  	OpIndexAddr
    61  	OpIndex
    62  	OpLookup
    63  	OpSelect
    64  	OpRange
    65  	OpNext
    66  	OpTypeAssert
    67  	OpExtract
    68  	// Instructions executed for effect
    69  	OpJump
    70  	OpIf
    71  	OpReturn
    72  	OpRunDefers
    73  	OpPanic
    74  	OpGo
    75  	OpDefer
    76  	OpSend
    77  	OpStore
    78  	OpMapUpdate
    79  	OpDebugRef
    80  )
    81  */
    82  
    83  type kind int
    84  
    85  func (k kind) isStatic() bool {
    86  	return k == kindConst || k == kindGlobal || k == kindFunction
    87  }
    88  
    89  const (
    90  	kindInvalid kind = iota
    91  	kindConst
    92  	kindGlobal
    93  	kindFunction
    94  )
    95  
    96  type Value = value
    97  type Tuple = tuple
    98  
    99  type register int
   100  type value = interface{}
   101  type tuple []value
   102  
   103  type closure struct {
   104  	pfn *function
   105  	env []value
   106  }
   107  
   108  type function struct {
   109  	Interp     *Interp
   110  	Fn         *ssa.Function                // ssa function
   111  	Main       *ssa.BasicBlock              // Fn.Blocks[0]
   112  	pool       *sync.Pool                   // create frame pool
   113  	makeInstr  ssa.Instruction              // make instr check
   114  	index      map[ssa.Value]uint32         // stack value index 32bit: kind(2) reflect.Kind(6) index(24)
   115  	instrIndex map[ssa.Instruction][]uint32 // instr -> index
   116  	Instrs     []func(fr *frame)            // main instrs
   117  	Recover    []func(fr *frame)            // recover instrs
   118  	Blocks     []int                        // block offset
   119  	stack      []value                      // results args envs datas
   120  	ssaInstrs  []ssa.Instruction            // org ssa instr
   121  	base       int                          // base of interp
   122  	nres       int                          // results count
   123  	narg       int                          // arguments count
   124  	nenv       int                          // closure free vars count
   125  	used       int32                        // function used count
   126  	cached     int32                        // enable cached by pool
   127  }
   128  
   129  func (p *function) UnsafeRelease() {
   130  	p.Interp = nil
   131  	p.Fn = nil
   132  	p.pool = nil
   133  	p.index = nil
   134  	p.instrIndex = nil
   135  	p.Instrs = nil
   136  	p.Recover = nil
   137  	p.Blocks = nil
   138  	p.stack = nil
   139  	p.ssaInstrs = nil
   140  	p.Main = nil
   141  }
   142  
   143  func (p *function) initPool() {
   144  	p.pool = &sync.Pool{}
   145  	p.pool.New = func() interface{} {
   146  		fr := &frame{interp: p.Interp, pfn: p, block: p.Main}
   147  		fr.stack = append([]value{}, p.stack...)
   148  		return fr
   149  	}
   150  }
   151  
   152  func (p *function) allocFrame(caller *frame) *frame {
   153  	var fr *frame
   154  	if atomic.LoadInt32(&p.cached) == 1 {
   155  		fr = p.pool.Get().(*frame)
   156  		fr.block = p.Main
   157  		fr._defer = nil
   158  		fr._panic = nil
   159  		fr.ipc = 0
   160  		fr.pred = 0
   161  	} else {
   162  		if atomic.AddInt32(&p.used, 1) > int32(p.Interp.ctx.callForPool) {
   163  			atomic.StoreInt32(&p.cached, 1)
   164  		}
   165  		fr = &frame{interp: p.Interp, pfn: p, block: p.Main}
   166  		fr.stack = append([]value{}, p.stack...)
   167  	}
   168  	fr.caller = caller
   169  	fr.deferid = caller.deferid
   170  	caller.callee = fr
   171  	return fr
   172  }
   173  
   174  func (p *function) deleteFrame(caller *frame, fr *frame) {
   175  	if atomic.LoadInt32(&p.cached) == 1 {
   176  		p.pool.Put(fr)
   177  	} else {
   178  		caller.callee = nil
   179  	}
   180  	fr = nil
   181  }
   182  
   183  func (p *function) InstrForPC(pc int) ssa.Instruction {
   184  	if pc >= 0 && pc < len(p.ssaInstrs) {
   185  		return p.ssaInstrs[pc]
   186  	}
   187  	return nil
   188  }
   189  
   190  func (p *function) PosForPC(pc int) token.Pos {
   191  	if instr := p.InstrForPC(pc); instr != nil {
   192  		if _, ok := instr.(*ssa.RunDefers); ok {
   193  			return p.Fn.Syntax().End()
   194  		}
   195  		return instr.Pos()
   196  	}
   197  	return token.NoPos
   198  }
   199  
   200  func (p *function) PositionForPC(pc int) token.Position {
   201  	pos := p.PosForPC(pc)
   202  	return p.Fn.Prog.Fset.Position(pos)
   203  }
   204  
   205  func (p *function) regIndex3(v ssa.Value) (register, kind, value) {
   206  	instr := p.regInstr(v)
   207  	index := int(instr & 0xffffff)
   208  	return register(index), kind(instr >> 30), p.stack[index]
   209  }
   210  
   211  func (p *function) regIndex(v ssa.Value) register {
   212  	instr := p.regInstr(v)
   213  	return register(instr & 0xffffff)
   214  }
   215  
   216  func (p *function) regInstr(v ssa.Value) uint32 {
   217  	if i, ok := p.index[v]; ok {
   218  		return i
   219  	}
   220  	var vs interface{}
   221  	var vk kind
   222  	switch v := v.(type) {
   223  	case *ssa.Const:
   224  		vs = constToValue(p.Interp, v)
   225  		vk = kindConst
   226  	case *ssa.Global:
   227  		vs, _ = globalToValue(p.Interp, v)
   228  		vk = kindGlobal
   229  	case *ssa.Function:
   230  		vk = kindFunction
   231  		if v.Blocks != nil {
   232  			typ := p.Interp.preToType(v.Type())
   233  			pfn := p.Interp.loadFunction(v)
   234  			vs = pfn.makeFunction(typ, nil).Interface()
   235  		} else {
   236  			ext, ok := findExternFunc(p.Interp, v)
   237  			if !ok {
   238  				if v.Name() != "init" {
   239  					panic(fmt.Errorf("no code for function: %v", v))
   240  				}
   241  			} else {
   242  				vs = ext.Interface()
   243  			}
   244  		}
   245  	}
   246  	var kind reflect.Kind
   247  	if v != nil {
   248  		kind = toKind(v.Type())
   249  	}
   250  	i := uint32(len(p.stack) | int(vk<<30) | int(kind<<24))
   251  	p.stack = append(p.stack, vs)
   252  	p.index[v] = i
   253  	p.instrIndex[p.makeInstr] = append(p.instrIndex[p.makeInstr], i)
   254  	return i
   255  }
   256  
   257  func findExternValue(interp *Interp, name string) (ext reflect.Value, ok bool) {
   258  	// check override value
   259  	ext, ok = interp.ctx.override[name]
   260  	if !ok {
   261  		// check extern value
   262  		ext, ok = externValues[name]
   263  	}
   264  	return
   265  }
   266  
   267  func findExternLinkFunc(interp *Interp, link *load.Linkname) (ext reflect.Value, ok bool) {
   268  	fullName := link.PkgPath + "." + link.Name
   269  	// check override value
   270  	ext, ok = interp.ctx.override[fullName]
   271  	if ok {
   272  		return
   273  	}
   274  	// check extern value
   275  	ext, ok = externValues[fullName]
   276  	if ok {
   277  		return
   278  	}
   279  	// check install pkg
   280  	if pkg, found := interp.installed(link.PkgPath); found {
   281  		if recv := link.Recv; recv != "" {
   282  			var star bool
   283  			if recv[0] == '*' {
   284  				star = true
   285  				recv = recv[1:]
   286  			}
   287  			if typ, ok := pkg.NamedTypes[recv]; ok {
   288  				if star {
   289  					typ = reflect.PtrTo(typ)
   290  				}
   291  				if m, ok := reflectx.MethodByName(typ, link.Method); ok {
   292  					return m.Func, true
   293  				}
   294  			}
   295  			return
   296  		}
   297  		ext, ok = pkg.Funcs[link.Name]
   298  	}
   299  	return
   300  }
   301  
   302  func findExternVar(interp *Interp, pkgPath string, name string) (ext reflect.Value, ok bool) {
   303  	fullName := pkgPath + "." + name
   304  	// check override value
   305  	ext, ok = interp.ctx.override[fullName]
   306  	if ok {
   307  		return
   308  	}
   309  	// check extern value
   310  	ext, ok = externValues[fullName]
   311  	if ok {
   312  		return
   313  	}
   314  	// check install pkg
   315  	if pkg, found := interp.installed(pkgPath); found {
   316  		ext, ok = pkg.Vars[name]
   317  	}
   318  	return
   319  }
   320  
   321  func checkFuncCompatible(t1, t2 reflect.Type) bool {
   322  	i1 := t1.NumIn()
   323  	i2 := t2.NumIn()
   324  	if i1 != i2 {
   325  		return false
   326  	}
   327  	for i := 0; i < i1; i++ {
   328  		if t1.In(i).Size() != t2.In(i).Size() {
   329  			return false
   330  		}
   331  	}
   332  	return true
   333  }
   334  
   335  func findExternFunc(interp *Interp, fn *ssa.Function) (ext reflect.Value, ok bool) {
   336  	fnName := fn.String()
   337  	ext, ok = findExternValue(interp, fnName)
   338  	if ok {
   339  		typ := interp.preToType(fn.Type())
   340  		ftyp := ext.Type()
   341  		if typ != ftyp && checkFuncCompatible(typ, ftyp) {
   342  			ext = xtype.ConvertFunc(ext, xtype.TypeOfType(typ))
   343  		}
   344  		return
   345  	}
   346  	if fn.Pkg != nil {
   347  		if recv := fn.Signature.Recv(); recv == nil {
   348  			if pkg, found := interp.installed(fn.Pkg.Pkg.Path()); found {
   349  				ext, ok = pkg.Funcs[fn.Name()]
   350  			}
   351  		} else if typ, found := interp.ctx.Loader.LookupReflect(recv.Type()); found {
   352  			if m, found := reflectx.MethodByName(typ, fn.Name()); found {
   353  				ext, ok = m.Func, true
   354  			}
   355  		}
   356  	}
   357  	return
   358  }
   359  
   360  func makeInstr(interp *Interp, pfn *function, instr ssa.Instruction) func(fr *frame) {
   361  	switch instr := instr.(type) {
   362  	case *ssa.Alloc:
   363  		if instr.Heap {
   364  			typ := interp.preToType(instr.Type())
   365  			ir := pfn.regIndex(instr)
   366  			t := xtype.TypeOfType(typ.Elem())
   367  			pt := xtype.TypeOfType(typ)
   368  			return func(fr *frame) {
   369  				fr.setReg(ir, xtype.New(t, pt))
   370  			}
   371  		}
   372  		typ := interp.preToType(instr.Type())
   373  		ir := pfn.regIndex(instr)
   374  		t := xtype.TypeOfType(typ.Elem())
   375  		pt := xtype.TypeOfType(typ)
   376  		// ptr := xtype.NewPointer(t)
   377  		elem := reflect.New(typ.Elem()).Elem()
   378  		return func(fr *frame) {
   379  			if v := fr.reg(ir); v != nil {
   380  				reflect.ValueOf(v).Elem().Set(elem)
   381  			} else {
   382  				fr.setReg(ir, xtype.New(t, pt))
   383  			}
   384  		}
   385  	case *ssa.Phi:
   386  		ir := pfn.regIndex(instr)
   387  		ie := make([]register, len(instr.Edges))
   388  		for i, v := range instr.Edges {
   389  			ie[i] = pfn.regIndex(v)
   390  		}
   391  		return func(fr *frame) {
   392  			for i, pred := range instr.Block().Preds {
   393  				if fr.pred == pred.Index {
   394  					fr.setReg(ir, fr.reg(ie[i]))
   395  					break
   396  				}
   397  			}
   398  		}
   399  	case *ssa.Call:
   400  		return makeCallInstr(pfn, interp, instr, &instr.Call)
   401  	case *ssa.BinOp:
   402  		switch instr.Op {
   403  		case token.ADD:
   404  			return makeBinOpADD(pfn, instr)
   405  		case token.SUB:
   406  			return makeBinOpSUB(pfn, instr)
   407  		case token.MUL:
   408  			return makeBinOpMUL(pfn, instr)
   409  		case token.QUO:
   410  			return makeBinOpQUO(pfn, instr)
   411  		case token.REM:
   412  			return makeBinOpREM(pfn, instr)
   413  		case token.AND:
   414  			return makeBinOpAND(pfn, instr)
   415  		case token.OR:
   416  			return makeBinOpOR(pfn, instr)
   417  		case token.XOR:
   418  			return makeBinOpXOR(pfn, instr)
   419  		case token.AND_NOT:
   420  			return makeBinOpANDNOT(pfn, instr)
   421  		case token.LSS:
   422  			return makeBinOpLSS(pfn, instr)
   423  		case token.LEQ:
   424  			return makeBinOpLEQ(pfn, instr)
   425  		case token.GTR:
   426  			return makeBinOpGTR(pfn, instr)
   427  		case token.GEQ:
   428  			return makeBinOpGEQ(pfn, instr)
   429  		case token.EQL:
   430  			return makeBinOpEQL(pfn, instr)
   431  		case token.NEQ:
   432  			return makeBinOpNEQ(pfn, instr)
   433  		case token.SHL:
   434  			return makeBinOpSHL(pfn, instr)
   435  		case token.SHR:
   436  			return makeBinOpSHR(pfn, instr)
   437  		default:
   438  			panic("unreachable")
   439  		}
   440  	case *ssa.UnOp:
   441  		switch instr.Op {
   442  		case token.NOT:
   443  			return makeUnOpNOT(pfn, instr)
   444  		case token.SUB:
   445  			return makeUnOpSUB(pfn, instr)
   446  		case token.XOR:
   447  			return makeUnOpXOR(pfn, instr)
   448  		case token.ARROW:
   449  			return makeUnOpARROW(pfn, instr)
   450  		case token.MUL:
   451  			return makeUnOpMUL(pfn, instr)
   452  		default:
   453  			panic("unreachable")
   454  		}
   455  	case *ssa.ChangeInterface:
   456  		ir := pfn.regIndex(instr)
   457  		ix := pfn.regIndex(instr.X)
   458  		return func(fr *frame) {
   459  			fr.setReg(ir, fr.reg(ix))
   460  		}
   461  	case *ssa.ChangeType:
   462  		return makeTypeChangeInstr(pfn, instr)
   463  	case *ssa.Convert:
   464  		return makeConvertInstr(pfn, interp, instr)
   465  	case *ssa.MakeInterface:
   466  		typ := interp.preToType(instr.Type())
   467  		ir := pfn.regIndex(instr)
   468  		ix, kx, vx := pfn.regIndex3(instr.X)
   469  		if kx.isStatic() {
   470  			if typ == tyEmptyInterface {
   471  				return func(fr *frame) {
   472  					fr.setReg(ir, vx)
   473  				}
   474  			}
   475  			v := reflect.New(typ).Elem()
   476  			if vx != nil {
   477  				SetValue(v, reflect.ValueOf(vx))
   478  			}
   479  			vx = v.Interface()
   480  			return func(fr *frame) {
   481  				fr.setReg(ir, vx)
   482  			}
   483  		}
   484  		if typ == tyEmptyInterface {
   485  			return func(fr *frame) {
   486  				fr.setReg(ir, fr.reg(ix))
   487  			}
   488  		}
   489  		return func(fr *frame) {
   490  			v := reflect.New(typ).Elem()
   491  			if x := fr.reg(ix); x != nil {
   492  				vx := reflect.ValueOf(x)
   493  				SetValue(v, vx)
   494  			}
   495  			fr.setReg(ir, v.Interface())
   496  		}
   497  	case *ssa.MakeClosure:
   498  		fn := instr.Fn.(*ssa.Function)
   499  		typ := interp.preToType(fn.Type())
   500  		ir := pfn.regIndex(instr)
   501  		ib := make([]register, len(instr.Bindings))
   502  		for i, v := range instr.Bindings {
   503  			ib[i] = pfn.regIndex(v)
   504  		}
   505  		pfn := interp.loadFunction(fn)
   506  		return func(fr *frame) {
   507  			var bindings []value
   508  			for i := range instr.Bindings {
   509  				bindings = append(bindings, fr.reg(ib[i]))
   510  			}
   511  			v := pfn.makeFunction(typ, bindings)
   512  			fr.setReg(ir, v.Interface())
   513  		}
   514  	case *ssa.MakeChan:
   515  		typ := interp.preToType(instr.Type())
   516  		ir := pfn.regIndex(instr)
   517  		is := pfn.regIndex(instr.Size)
   518  		if typ.ChanDir() == reflect.BothDir {
   519  			return func(fr *frame) {
   520  				size := fr.reg(is)
   521  				buffer := asInt(size)
   522  				if buffer < 0 {
   523  					panic(runtimeError("makechan: size out of range"))
   524  				}
   525  				fr.setReg(ir, reflect.MakeChan(typ, buffer).Interface())
   526  			}
   527  		}
   528  		ctyp := reflect.ChanOf(reflect.BothDir, typ.Elem())
   529  		return func(fr *frame) {
   530  			size := fr.reg(is)
   531  			buffer := asInt(size)
   532  			if buffer < 0 {
   533  				panic(runtimeError("makechan: size out of range"))
   534  			}
   535  			fr.setReg(ir, reflect.MakeChan(ctyp, buffer).Convert(typ).Interface())
   536  		}
   537  	case *ssa.MakeMap:
   538  		typ := instr.Type()
   539  		rtyp := interp.preToType(typ)
   540  		ir := pfn.regIndex(instr)
   541  		if instr.Reserve == nil {
   542  			return func(fr *frame) {
   543  				fr.setReg(ir, reflect.MakeMap(rtyp).Interface())
   544  			}
   545  		}
   546  		iv := pfn.regIndex(instr.Reserve)
   547  		return func(fr *frame) {
   548  			reserve := asInt(fr.reg(iv))
   549  			fr.setReg(ir, reflect.MakeMapWithSize(rtyp, reserve).Interface())
   550  		}
   551  	case *ssa.MakeSlice:
   552  		typ := interp.preToType(instr.Type())
   553  		ir := pfn.regIndex(instr)
   554  		il := pfn.regIndex(instr.Len)
   555  		ic := pfn.regIndex(instr.Cap)
   556  		return func(fr *frame) {
   557  			Len := asInt(fr.reg(il))
   558  			if Len < 0 || Len >= maxMemLen {
   559  				panic(runtimeError("makeslice: len out of range"))
   560  			}
   561  			Cap := asInt(fr.reg(ic))
   562  			if Cap < 0 || Cap >= maxMemLen {
   563  				panic(runtimeError("makeslice: cap out of range"))
   564  			}
   565  			fr.setReg(ir, reflect.MakeSlice(typ, Len, Cap).Interface())
   566  		}
   567  	case *ssa.Slice:
   568  		typ := interp.preToType(instr.Type())
   569  		isNamed := typ.Kind() == reflect.Slice && typ != reflect.SliceOf(typ.Elem())
   570  		_, makesliceCheck := instr.X.(*ssa.Alloc)
   571  		ir := pfn.regIndex(instr)
   572  		ix := pfn.regIndex(instr.X)
   573  		ih := pfn.regIndex(instr.High)
   574  		il := pfn.regIndex(instr.Low)
   575  		im := pfn.regIndex(instr.Max)
   576  		if isNamed {
   577  			return func(fr *frame) {
   578  				fr.setReg(ir, slice(fr, instr, makesliceCheck, ix, ih, il, im).Convert(typ).Interface())
   579  			}
   580  		}
   581  		return func(fr *frame) {
   582  			fr.setReg(ir, slice(fr, instr, makesliceCheck, ix, ih, il, im).Interface())
   583  		}
   584  	case *ssa.FieldAddr:
   585  		ir := pfn.regIndex(instr)
   586  		ix := pfn.regIndex(instr.X)
   587  		return func(fr *frame) {
   588  			v, err := fieldAddrX(fr.reg(ix), instr.Field)
   589  			if err != nil {
   590  				panic(runtimeError(err.Error()))
   591  			}
   592  			fr.setReg(ir, v)
   593  		}
   594  	case *ssa.Field:
   595  		ir := pfn.regIndex(instr)
   596  		ix := pfn.regIndex(instr.X)
   597  		return func(fr *frame) {
   598  			v, err := fieldX(fr.reg(ix), instr.Field)
   599  			if err != nil {
   600  				panic(runtimeError(err.Error()))
   601  			}
   602  			fr.setReg(ir, v)
   603  		}
   604  	case *ssa.IndexAddr:
   605  		ir := pfn.regIndex(instr)
   606  		ix := pfn.regIndex(instr.X)
   607  		ii := pfn.regIndex(instr.Index)
   608  		return func(fr *frame) {
   609  			x := fr.reg(ix)
   610  			idx := fr.reg(ii)
   611  			v := reflect.ValueOf(x)
   612  			if v.Kind() == reflect.Ptr {
   613  				v = v.Elem()
   614  			}
   615  			switch v.Kind() {
   616  			case reflect.Slice:
   617  			case reflect.Array:
   618  			case reflect.Invalid:
   619  				panic(runtimeError("invalid memory address or nil pointer dereference"))
   620  			default:
   621  				panic(fmt.Sprintf("unexpected x type in IndexAddr: %T", x))
   622  			}
   623  			index := asInt(idx)
   624  			if index < 0 {
   625  				panic(runtimeError(fmt.Sprintf("index out of range [%v]", index)))
   626  			} else if length := v.Len(); index >= length {
   627  				panic(runtimeError(fmt.Sprintf("index out of range [%v] with length %v", index, length)))
   628  			}
   629  			fr.setReg(ir, v.Index(index).Addr().Interface())
   630  		}
   631  	case *ssa.Index:
   632  		ir := pfn.regIndex(instr)
   633  		ix := pfn.regIndex(instr.X)
   634  		ii := pfn.regIndex(instr.Index)
   635  		return func(fr *frame) {
   636  			x := fr.reg(ix)
   637  			idx := fr.reg(ii)
   638  			index := asInt(idx)
   639  			v := reflect.ValueOf(x)
   640  			if index < 0 {
   641  				panic(runtimeError(fmt.Sprintf("index out of range [%v]", index)))
   642  			} else if length := v.Len(); index >= length {
   643  				panic(runtimeError(fmt.Sprintf("index out of range [%v] with length %v", index, length)))
   644  			}
   645  			fr.setReg(ir, v.Index(index).Interface())
   646  		}
   647  	case *ssa.Lookup:
   648  		typ := interp.preToType(instr.X.Type())
   649  		ir := pfn.regIndex(instr)
   650  		ix := pfn.regIndex(instr.X)
   651  		ii := pfn.regIndex(instr.Index)
   652  		switch typ.Kind() {
   653  		case reflect.String:
   654  			return func(fr *frame) {
   655  				v := fr.reg(ix)
   656  				idx := fr.reg(ii)
   657  				fr.setReg(ir, reflect.ValueOf(v).String()[asInt(idx)])
   658  			}
   659  		case reflect.Map:
   660  			return func(fr *frame) {
   661  				m := fr.reg(ix)
   662  				idx := fr.reg(ii)
   663  				vm := reflect.ValueOf(m)
   664  				v := vm.MapIndex(reflect.ValueOf(idx))
   665  				ok := v.IsValid()
   666  				var rv value
   667  				if ok {
   668  					rv = v.Interface()
   669  				} else {
   670  					rv = reflect.New(typ.Elem()).Elem().Interface()
   671  				}
   672  				if instr.CommaOk {
   673  					fr.setReg(ir, tuple{rv, ok})
   674  				} else {
   675  					fr.setReg(ir, rv)
   676  				}
   677  			}
   678  		default:
   679  			panic("unreachable")
   680  		}
   681  	case *ssa.Select:
   682  		ir := pfn.regIndex(instr)
   683  		ic := make([]register, len(instr.States))
   684  		is := make([]register, len(instr.States))
   685  		for i, state := range instr.States {
   686  			ic[i] = pfn.regIndex(state.Chan)
   687  			if state.Send != nil {
   688  				is[i] = pfn.regIndex(state.Send)
   689  			}
   690  		}
   691  		return func(fr *frame) {
   692  			var cases []reflect.SelectCase
   693  			if !instr.Blocking {
   694  				cases = append(cases, reflect.SelectCase{
   695  					Dir: reflect.SelectDefault,
   696  				})
   697  			}
   698  			for i, state := range instr.States {
   699  				var dir reflect.SelectDir
   700  				if state.Dir == types.RecvOnly {
   701  					dir = reflect.SelectRecv
   702  				} else {
   703  					dir = reflect.SelectSend
   704  				}
   705  				ch := reflect.ValueOf(fr.reg(ic[i]))
   706  				var send reflect.Value
   707  				if state.Send != nil {
   708  					v := fr.reg(is[i])
   709  					if v == nil {
   710  						send = reflect.New(ch.Type().Elem()).Elem()
   711  					} else {
   712  						send = reflect.ValueOf(v)
   713  					}
   714  				}
   715  				cases = append(cases, reflect.SelectCase{
   716  					Dir:  dir,
   717  					Chan: ch,
   718  					Send: send,
   719  				})
   720  			}
   721  			chosen, recv, recvOk := reflect.Select(cases)
   722  			if !instr.Blocking {
   723  				chosen-- // default case should have index -1.
   724  			}
   725  			r := tuple{chosen, recvOk}
   726  			for n, st := range instr.States {
   727  				if st.Dir == types.RecvOnly {
   728  					var v value
   729  					if n == chosen && recvOk {
   730  						// No need to copy since send makes an unaliased copy.
   731  						v = recv.Interface()
   732  					} else {
   733  						typ := interp.toType(st.Chan.Type())
   734  						v = reflect.New(typ.Elem()).Elem().Interface()
   735  					}
   736  					r = append(r, v)
   737  				}
   738  			}
   739  			fr.setReg(ir, r)
   740  		}
   741  	case *ssa.SliceToArrayPointer:
   742  		typ := interp.preToType(instr.Type())
   743  		ir := pfn.regIndex(instr)
   744  		ix := pfn.regIndex(instr.X)
   745  		return func(fr *frame) {
   746  			x := fr.reg(ix)
   747  			v := reflect.ValueOf(x)
   748  			vLen := v.Len()
   749  			tLen := typ.Elem().Len()
   750  			if tLen > vLen {
   751  				panic(runtimeError(fmt.Sprintf(errSliceToArrayPointer, vLen, tLen)))
   752  			}
   753  			fr.setReg(ir, v.Convert(typ).Interface())
   754  		}
   755  	case *ssa.Range:
   756  		typ := interp.preToType(instr.X.Type())
   757  		ir := pfn.regIndex(instr)
   758  		ix := pfn.regIndex(instr.X)
   759  		switch typ.Kind() {
   760  		case reflect.String:
   761  			return func(fr *frame) {
   762  				v := fr.string(ix)
   763  				fr.setReg(ir, &stringIter{Reader: strings.NewReader(v)})
   764  			}
   765  		case reflect.Map:
   766  			return func(fr *frame) {
   767  				v := fr.reg(ix)
   768  				fr.setReg(ir, &mapIter{iter: reflect.ValueOf(v).MapRange()})
   769  			}
   770  		default:
   771  			panic("unreachable")
   772  		}
   773  	case *ssa.Next:
   774  		ir := pfn.regIndex(instr)
   775  		ii := pfn.regIndex(instr.Iter)
   776  		if instr.IsString {
   777  			return func(fr *frame) {
   778  				fr.setReg(ir, fr.reg(ii).(*stringIter).next())
   779  			}
   780  		}
   781  		return func(fr *frame) {
   782  			fr.setReg(ir, fr.reg(ii).(*mapIter).next())
   783  		}
   784  	case *ssa.TypeAssert:
   785  		typ := interp.preToType(instr.AssertedType)
   786  		xtyp := interp.preToType(instr.X.Type())
   787  		ir := pfn.regIndex(instr)
   788  		ix, kx, vx := pfn.regIndex3(instr.X)
   789  		if kx.isStatic() {
   790  			return func(fr *frame) {
   791  				fr.setReg(ir, typeAssert(interp, instr, typ, xtyp, vx))
   792  			}
   793  		}
   794  		return func(fr *frame) {
   795  			v := fr.reg(ix)
   796  			fr.setReg(ir, typeAssert(interp, instr, typ, xtyp, v))
   797  		}
   798  	case *ssa.Extract:
   799  		if *instr.Referrers() == nil {
   800  			return nil
   801  		}
   802  		ir := pfn.regIndex(instr)
   803  		it := pfn.regIndex(instr.Tuple)
   804  		return func(fr *frame) {
   805  			fr.setReg(ir, fr.reg(it).(tuple)[instr.Index])
   806  		}
   807  	// Instructions executed for effect
   808  	case *ssa.Jump:
   809  		return func(fr *frame) {
   810  			fr.pred, fr.block = fr.block.Index, fr.block.Succs[0]
   811  			fr.ipc = fr.pfn.Blocks[fr.block.Index]
   812  		}
   813  	case *ssa.If:
   814  		ic, kc, vc := pfn.regIndex3(instr.Cond)
   815  		if kc == kindConst {
   816  			if xtype.Bool(vc) {
   817  				return func(fr *frame) {
   818  					fr.pred = fr.block.Index
   819  					fr.block = fr.block.Succs[0]
   820  					fr.ipc = fr.pfn.Blocks[fr.block.Index]
   821  				}
   822  			}
   823  			return func(fr *frame) {
   824  				fr.pred = fr.block.Index
   825  				fr.block = fr.block.Succs[1]
   826  				fr.ipc = fr.pfn.Blocks[fr.block.Index]
   827  			}
   828  		}
   829  		switch instr.Cond.Type().(type) {
   830  		case *types.Basic:
   831  			return func(fr *frame) {
   832  				fr.pred = fr.block.Index
   833  				if fr.reg(ic).(bool) {
   834  					fr.block = fr.block.Succs[0]
   835  				} else {
   836  					fr.block = fr.block.Succs[1]
   837  				}
   838  				fr.ipc = fr.pfn.Blocks[fr.block.Index]
   839  			}
   840  		default:
   841  			return func(fr *frame) {
   842  				fr.pred = fr.block.Index
   843  				if fr.bool(ic) {
   844  					fr.block = fr.block.Succs[0]
   845  				} else {
   846  					fr.block = fr.block.Succs[1]
   847  				}
   848  				fr.ipc = fr.pfn.Blocks[fr.block.Index]
   849  			}
   850  		}
   851  	case *ssa.Return:
   852  		switch n := pfn.nres; n {
   853  		case 0:
   854  			return func(fr *frame) {
   855  				fr.ipc = -1
   856  			}
   857  		case 1:
   858  			ir, ik, iv := pfn.regIndex3(instr.Results[0])
   859  			if ik.isStatic() {
   860  				return func(fr *frame) {
   861  					fr.stack[0] = iv
   862  					fr.ipc = -1
   863  				}
   864  			}
   865  			return func(fr *frame) {
   866  				fr.stack[0] = fr.reg(ir)
   867  				fr.ipc = -1
   868  			}
   869  		case 2:
   870  			r1, k1, v1 := pfn.regIndex3(instr.Results[0])
   871  			r2, k2, v2 := pfn.regIndex3(instr.Results[1])
   872  			if k1.isStatic() && k2.isStatic() {
   873  				return func(fr *frame) {
   874  					fr.stack[0] = v1
   875  					fr.stack[1] = v2
   876  					fr.ipc = -1
   877  				}
   878  			} else if k1.isStatic() {
   879  				return func(fr *frame) {
   880  					fr.stack[0] = v1
   881  					fr.stack[1] = fr.reg(r2)
   882  					fr.ipc = -1
   883  				}
   884  			} else if k2.isStatic() {
   885  				return func(fr *frame) {
   886  					fr.stack[0] = fr.reg(r1)
   887  					fr.stack[1] = v2
   888  					fr.ipc = -1
   889  				}
   890  			}
   891  			return func(fr *frame) {
   892  				fr.stack[0] = fr.reg(r1)
   893  				fr.stack[1] = fr.reg(r2)
   894  				fr.ipc = -1
   895  			}
   896  		default:
   897  			ir := make([]register, n)
   898  			for i, v := range instr.Results {
   899  				ir[i] = pfn.regIndex(v)
   900  			}
   901  			return func(fr *frame) {
   902  				for i := 0; i < n; i++ {
   903  					fr.stack[i] = fr.reg(ir[i])
   904  				}
   905  				fr.ipc = -1
   906  			}
   907  		}
   908  	case *ssa.RunDefers:
   909  		return func(fr *frame) {
   910  			fr.runDefers()
   911  		}
   912  	case *ssa.Panic:
   913  		ix := pfn.regIndex(instr.X)
   914  		return func(fr *frame) {
   915  			panic(PanicError{stack: debugStack(fr), Value: fr.reg(ix)})
   916  		}
   917  	case *ssa.Go:
   918  		iv, ia, ib := getCallIndex(pfn, &instr.Call)
   919  		return func(fr *frame) {
   920  			fn, args := interp.prepareCall(fr, &instr.Call, iv, ia, ib)
   921  			atomic.AddInt32(&interp.goroutines, 1)
   922  			if interp.ctx.RunContext != nil {
   923  				go func() {
   924  					root := &frame{interp: interp}
   925  					switch f := fn.(type) {
   926  					case *ssa.Function:
   927  						root.pfn = interp.funcs[f]
   928  					case *closure:
   929  						root.pfn = f.pfn
   930  					}
   931  					defer func() {
   932  						e := recover()
   933  						if e != nil {
   934  							interp.cherror <- PanicError{stack: debugStack(root), Value: e}
   935  						}
   936  					}()
   937  					interp.callDiscardsResult(root, fn, args, instr.Call.Args)
   938  					atomic.AddInt32(&interp.goroutines, -1)
   939  				}()
   940  			} else {
   941  				go func() {
   942  					interp.callDiscardsResult(&frame{}, fn, args, instr.Call.Args)
   943  					atomic.AddInt32(&interp.goroutines, -1)
   944  				}()
   945  			}
   946  		}
   947  	case *ssa.Defer:
   948  		iv, ia, ib := getCallIndex(pfn, &instr.Call)
   949  		return func(fr *frame) {
   950  			fn, args := interp.prepareCall(fr, &instr.Call, iv, ia, ib)
   951  			fr._defer = &_defer{
   952  				fn:      fn,
   953  				args:    args,
   954  				ssaArgs: instr.Call.Args,
   955  				tail:    fr._defer,
   956  			}
   957  		}
   958  	case *ssa.Send:
   959  		ic := pfn.regIndex(instr.Chan)
   960  		ix := pfn.regIndex(instr.X)
   961  		return func(fr *frame) {
   962  			c := fr.reg(ic)
   963  			x := fr.reg(ix)
   964  			ch := reflect.ValueOf(c)
   965  			if x == nil {
   966  				ch.Send(reflect.New(ch.Type().Elem()).Elem())
   967  			} else {
   968  				ch.Send(reflect.ValueOf(x))
   969  			}
   970  		}
   971  	case *ssa.Store:
   972  		// skip struct field _
   973  		if addr, ok := instr.Addr.(*ssa.FieldAddr); ok {
   974  			if s, ok := addr.X.Type().(*types.Pointer).Elem().(*types.Struct); ok {
   975  				if s.Field(addr.Field).Name() == "_" {
   976  					return nil
   977  				}
   978  			}
   979  		}
   980  		if pfn.Fn.Name() == "init" && pfn.Fn.Synthetic == "package initializer" {
   981  			pfn.Interp.chkinit[instr.Addr.String()] = true
   982  		}
   983  		ia := pfn.regIndex(instr.Addr)
   984  		iv, kv, vv := pfn.regIndex3(instr.Val)
   985  		if kv.isStatic() {
   986  			if vv == nil {
   987  				return func(fr *frame) {
   988  					x := reflect.ValueOf(fr.reg(ia))
   989  					SetValue(x.Elem(), reflect.New(x.Elem().Type()).Elem())
   990  				}
   991  			}
   992  			return func(fr *frame) {
   993  				x := reflect.ValueOf(fr.reg(ia))
   994  				SetValue(x.Elem(), reflect.ValueOf(vv))
   995  			}
   996  		}
   997  		return func(fr *frame) {
   998  			x := reflect.ValueOf(fr.reg(ia))
   999  			val := fr.reg(iv)
  1000  			v := reflect.ValueOf(val)
  1001  			if v.IsValid() {
  1002  				SetValue(x.Elem(), v)
  1003  			} else {
  1004  				SetValue(x.Elem(), reflect.New(x.Elem().Type()).Elem())
  1005  			}
  1006  		}
  1007  	case *ssa.MapUpdate:
  1008  		im := pfn.regIndex(instr.Map)
  1009  		ik := pfn.regIndex(instr.Key)
  1010  		iv, kv, vv := pfn.regIndex3(instr.Value)
  1011  		if kv.isStatic() {
  1012  			return func(fr *frame) {
  1013  				vm := reflect.ValueOf(fr.reg(im))
  1014  				vk := reflect.ValueOf(fr.reg(ik))
  1015  				vm.SetMapIndex(vk, reflect.ValueOf(vv))
  1016  			}
  1017  		}
  1018  		return func(fr *frame) {
  1019  			vm := reflect.ValueOf(fr.reg(im))
  1020  			vk := reflect.ValueOf(fr.reg(ik))
  1021  			v := fr.reg(iv)
  1022  			vm.SetMapIndex(vk, reflect.ValueOf(v))
  1023  		}
  1024  	case *ssa.DebugRef:
  1025  		if v, ok := instr.Object().(*types.Var); ok {
  1026  			ix := pfn.regIndex(instr.X)
  1027  			return func(fr *frame) {
  1028  				ref := &DebugInfo{DebugRef: instr, fset: interp.ctx.FileSet}
  1029  				ref.toValue = func() (*types.Var, interface{}, bool) {
  1030  					return v, fr.reg(ix), true
  1031  				}
  1032  				interp.ctx.debugFunc(ref)
  1033  			}
  1034  		}
  1035  		return func(fr *frame) {
  1036  			ref := &DebugInfo{DebugRef: instr, fset: interp.ctx.FileSet}
  1037  			ref.toValue = func() (*types.Var, interface{}, bool) {
  1038  				return nil, nil, false
  1039  			}
  1040  			interp.ctx.debugFunc(ref)
  1041  		}
  1042  	default:
  1043  		panic(fmt.Errorf("unreachable %T", instr))
  1044  	}
  1045  }
  1046  
  1047  func getCallIndex(pfn *function, call *ssa.CallCommon) (iv register, ia []register, ib []register) {
  1048  	iv = pfn.regIndex(call.Value)
  1049  	ia = make([]register, len(call.Args))
  1050  	for i, v := range call.Args {
  1051  		ia[i] = pfn.regIndex(v)
  1052  	}
  1053  	if f, ok := call.Value.(*ssa.MakeClosure); ok {
  1054  		ib = make([]register, len(f.Bindings))
  1055  		for i, binding := range f.Bindings {
  1056  			ib[i] = pfn.regIndex(binding)
  1057  		}
  1058  	}
  1059  	return
  1060  }
  1061  
  1062  var (
  1063  	typFramePtr = reflect.TypeOf((*frame)(nil))
  1064  )
  1065  
  1066  func makeCallInstr(pfn *function, interp *Interp, instr ssa.Value, call *ssa.CallCommon) func(fr *frame) {
  1067  	ir := pfn.regIndex(instr)
  1068  	iv, ia, ib := getCallIndex(pfn, call)
  1069  	switch fn := call.Value.(type) {
  1070  	case *ssa.Builtin:
  1071  		fname := fn.Name()
  1072  		return func(fr *frame) {
  1073  			interp.callBuiltinByStack(fr, fname, call.Args, ir, ia)
  1074  		}
  1075  	case *ssa.MakeClosure:
  1076  		ifn := interp.loadFunction(fn.Fn.(*ssa.Function))
  1077  		ia = append(ia, ib...)
  1078  		if ifn.Recover == nil {
  1079  			switch ifn.nres {
  1080  			case 0:
  1081  				return func(fr *frame) {
  1082  					interp.callFunctionByStackNoRecover0(fr, ifn, ir, ia)
  1083  				}
  1084  			case 1:
  1085  				return func(fr *frame) {
  1086  					interp.callFunctionByStackNoRecover1(fr, ifn, ir, ia)
  1087  				}
  1088  			default:
  1089  				return func(fr *frame) {
  1090  					interp.callFunctionByStackNoRecoverN(fr, ifn, ir, ia)
  1091  				}
  1092  			}
  1093  		}
  1094  		switch ifn.nres {
  1095  		case 0:
  1096  			return func(fr *frame) {
  1097  				interp.callFunctionByStack0(fr, ifn, ir, ia)
  1098  			}
  1099  		case 1:
  1100  			return func(fr *frame) {
  1101  				interp.callFunctionByStack1(fr, ifn, ir, ia)
  1102  			}
  1103  		default:
  1104  			return func(fr *frame) {
  1105  				interp.callFunctionByStackN(fr, ifn, ir, ia)
  1106  			}
  1107  		}
  1108  	case *ssa.Function:
  1109  		// "static func/method call"
  1110  		if fn.Blocks == nil {
  1111  			ext, ok := findExternFunc(interp, fn)
  1112  			if !ok {
  1113  				// skip pkg.init
  1114  				if fn.Pkg != nil && fn.Name() == "init" {
  1115  					return nil
  1116  				}
  1117  				panic(fmt.Errorf("no code for function: %v", fn))
  1118  			}
  1119  			if typ := ext.Type(); typ.NumIn() > 0 && typ.In(0) == typFramePtr {
  1120  				return func(fr *frame) {
  1121  					interp.callExternalWithFrameByStack(fr, ext, ir, ia)
  1122  				}
  1123  			}
  1124  			return func(fr *frame) {
  1125  				interp.callExternalByStack(fr, ext, ir, ia)
  1126  			}
  1127  		}
  1128  		ifn := interp.loadFunction(fn)
  1129  		if ifn.Recover == nil {
  1130  			switch ifn.nres {
  1131  			case 0:
  1132  				return func(fr *frame) {
  1133  					interp.callFunctionByStackNoRecover0(fr, ifn, ir, ia)
  1134  				}
  1135  			case 1:
  1136  				return func(fr *frame) {
  1137  					interp.callFunctionByStackNoRecover1(fr, ifn, ir, ia)
  1138  				}
  1139  			default:
  1140  				return func(fr *frame) {
  1141  					interp.callFunctionByStackNoRecoverN(fr, ifn, ir, ia)
  1142  				}
  1143  			}
  1144  		}
  1145  		switch ifn.nres {
  1146  		case 0:
  1147  			return func(fr *frame) {
  1148  				interp.callFunctionByStack0(fr, ifn, ir, ia)
  1149  			}
  1150  		case 1:
  1151  			return func(fr *frame) {
  1152  				interp.callFunctionByStack1(fr, ifn, ir, ia)
  1153  			}
  1154  		default:
  1155  			return func(fr *frame) {
  1156  				interp.callFunctionByStackN(fr, ifn, ir, ia)
  1157  			}
  1158  		}
  1159  	}
  1160  	// "dynamic method call" // ("invoke" mode)
  1161  	if call.IsInvoke() {
  1162  		return makeCallMethodInstr(interp, instr, call, ir, iv, ia)
  1163  	}
  1164  	// dynamic func call
  1165  	typ := interp.preToType(call.Value.Type())
  1166  	if typ.Kind() != reflect.Func {
  1167  		panic("unsupport")
  1168  	}
  1169  	if !funcval.IsSupport {
  1170  		return func(fr *frame) {
  1171  			fn := fr.reg(iv)
  1172  			v := reflect.ValueOf(fn)
  1173  			interp.callExternalByStack(fr, v, ir, ia)
  1174  		}
  1175  	}
  1176  	return func(fr *frame) {
  1177  		fn := fr.reg(iv)
  1178  		if fv, n := funcval.Get(fn); n == 1 {
  1179  			c := (*makeFuncVal)(unsafe.Pointer(fv))
  1180  			if c.pfn.Recover == nil {
  1181  				interp.callFunctionByStackNoRecoverWithEnv(fr, c.pfn, ir, ia, c.env)
  1182  			} else {
  1183  				interp.callFunctionByStackWithEnv(fr, c.pfn, ir, ia, c.env)
  1184  			}
  1185  		} else {
  1186  			v := reflect.ValueOf(fn)
  1187  			interp.callExternalByStack(fr, v, ir, ia)
  1188  		}
  1189  	}
  1190  }
  1191  
  1192  // makeFuncVal sync with function.makeFunction
  1193  // func (pfn *function) makeFunction(typ reflect.Type, env []value) reflect.Value {
  1194  // 	return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value {
  1195  // 		return pfn.Interp.callFunctionByReflect(pfn.Interp.tryDeferFrame(), typ, pfn, args, env)
  1196  // 	})
  1197  // }
  1198  
  1199  type makeFuncVal struct {
  1200  	funcval.FuncVal
  1201  	pfn *function
  1202  	typ reflect.Type
  1203  	env []interface{}
  1204  }
  1205  
  1206  var (
  1207  	typeOfType      = reflect.TypeOf(reflect.TypeOf(0))
  1208  	vfnMethod       = reflect.ValueOf(reflectx.MethodByIndex)
  1209  	vfnMethodByName = reflect.ValueOf(reflectx.MethodByName)
  1210  )
  1211  
  1212  func findUserMethod(typ reflect.Type, name string) (ext reflect.Value, ok bool) {
  1213  	if m, ok := reflectx.MethodByName(typ, name); ok {
  1214  		return m.Func, true
  1215  	}
  1216  	return
  1217  }
  1218  
  1219  func findExternMethod(typ reflect.Type, name string) (ext reflect.Value, ok bool) {
  1220  	if typ == typeOfType {
  1221  		switch name {
  1222  		case "Method":
  1223  			return vfnMethod, true
  1224  		case "MethodByName":
  1225  			return vfnMethodByName, true
  1226  		}
  1227  	}
  1228  	if m, ok := typ.MethodByName(name); ok {
  1229  		return m.Func, true
  1230  	}
  1231  	return
  1232  }
  1233  
  1234  func (i *Interp) findMethod(typ reflect.Type, mname string) (fn *ssa.Function, ok bool) {
  1235  	if mset, mok := i.msets[typ]; mok {
  1236  		fn, ok = mset[mname]
  1237  	}
  1238  	return
  1239  }
  1240  
  1241  func makeCallMethodInstr(interp *Interp, instr ssa.Value, call *ssa.CallCommon, ir register, iv register, ia []register) func(fr *frame) {
  1242  	mname := call.Method.Name()
  1243  	ia = append([]register{iv}, ia...)
  1244  	var found bool
  1245  	var ext reflect.Value
  1246  	return func(fr *frame) {
  1247  		v := fr.reg(iv)
  1248  		rtype := reflect.TypeOf(v)
  1249  		// find user type method *ssa.Function
  1250  		if mset, ok := interp.msets[rtype]; ok {
  1251  			if fn, ok := mset[mname]; ok {
  1252  				interp.callFunctionByStack(fr, interp.funcs[fn], ir, ia)
  1253  				return
  1254  			}
  1255  			ext, found = findUserMethod(rtype, mname)
  1256  		} else {
  1257  			ext, found = findExternMethod(rtype, mname)
  1258  		}
  1259  		if !found {
  1260  			panic(fmt.Errorf("no code for method: %v.%v", rtype, mname))
  1261  		}
  1262  		interp.callExternalByStack(fr, ext, ir, ia)
  1263  	}
  1264  }
  1265  
  1266  type stringIter struct {
  1267  	*strings.Reader
  1268  	i int
  1269  }
  1270  
  1271  func (it *stringIter) next() tuple {
  1272  	okv := make(tuple, 3)
  1273  	ch, n, err := it.ReadRune()
  1274  	ok := err != io.EOF
  1275  	okv[0] = ok
  1276  	if ok {
  1277  		okv[1] = it.i
  1278  		okv[2] = ch
  1279  	}
  1280  	it.i += n
  1281  	return okv
  1282  }
  1283  
  1284  type mapIter struct {
  1285  	iter *reflect.MapIter
  1286  	ok   bool
  1287  }
  1288  
  1289  func (it *mapIter) next() tuple {
  1290  	it.ok = it.iter.Next()
  1291  	if !it.ok {
  1292  		return []value{false, nil, nil}
  1293  	}
  1294  	k, v := it.iter.Key().Interface(), it.iter.Value().Interface()
  1295  	return []value{true, k, v}
  1296  }
  1297  
  1298  func toKind(typ types.Type) reflect.Kind {
  1299  retry:
  1300  	switch t := typ.(type) {
  1301  	case *types.Basic:
  1302  		switch t.Kind() {
  1303  		case types.Bool:
  1304  			return reflect.Bool
  1305  		case types.Int:
  1306  			return reflect.Int
  1307  		case types.Int8:
  1308  			return reflect.Int8
  1309  		case types.Int16:
  1310  			return reflect.Int16
  1311  		case types.Int32:
  1312  			return reflect.Int32
  1313  		case types.Int64:
  1314  			return reflect.Int64
  1315  		case types.Uint:
  1316  			return reflect.Uint
  1317  		case types.Uint8:
  1318  			return reflect.Uint8
  1319  		case types.Uint16:
  1320  			return reflect.Uint16
  1321  		case types.Uint32:
  1322  			return reflect.Uint32
  1323  		case types.Uint64:
  1324  			return reflect.Uint64
  1325  		case types.Uintptr:
  1326  			return reflect.Uintptr
  1327  		case types.Float32:
  1328  			return reflect.Float32
  1329  		case types.Float64:
  1330  			return reflect.Float64
  1331  		case types.Complex64:
  1332  			return reflect.Complex64
  1333  		case types.Complex128:
  1334  			return reflect.Complex128
  1335  		case types.String:
  1336  			return reflect.String
  1337  		case types.UnsafePointer:
  1338  			return reflect.UnsafePointer
  1339  		// types for untyped values
  1340  		case types.UntypedBool:
  1341  			return reflect.Bool
  1342  		case types.UntypedInt:
  1343  			return reflect.Int
  1344  		case types.UntypedRune:
  1345  			return reflect.Int32
  1346  		case types.UntypedFloat:
  1347  			return reflect.Float64
  1348  		case types.UntypedComplex:
  1349  			return reflect.Complex128
  1350  		case types.UntypedString:
  1351  			return reflect.String
  1352  		case types.UntypedNil:
  1353  			return reflect.Invalid
  1354  		}
  1355  	case *types.Chan:
  1356  		return reflect.Chan
  1357  	case *types.Named:
  1358  		typ = t.Underlying()
  1359  		goto retry
  1360  	case *types.Signature:
  1361  		return reflect.Func
  1362  	case *types.Slice:
  1363  		return reflect.Slice
  1364  	case *types.Array:
  1365  		return reflect.Array
  1366  	case *types.Pointer:
  1367  		return reflect.Ptr
  1368  	case *types.Struct:
  1369  		return reflect.Struct
  1370  	case *types.Map:
  1371  		return reflect.Map
  1372  	case *types.Interface:
  1373  		return reflect.Interface
  1374  	case *types.Tuple:
  1375  		return reflect.Slice
  1376  	}
  1377  	return reflect.Invalid
  1378  }