github.com/goplus/gossa@v0.3.25/interp.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package ssa/interp defines an interpreter for the SSA
     6  // representation of Go programs.
     7  //
     8  // This interpreter is provided as an adjunct for testing the SSA
     9  // construction algorithm.  Its purpose is to provide a minimal
    10  // metacircular implementation of the dynamic semantics of each SSA
    11  // instruction.  It is not, and will never be, a production-quality Go
    12  // interpreter.
    13  //
    14  // The following is a partial list of Go features that are currently
    15  // unsupported or incomplete in the interpreter.
    16  //
    17  // * Unsafe operations, including all uses of unsafe.Pointer, are
    18  // impossible to support given the "boxed" value representation we
    19  // have chosen.
    20  //
    21  // * The reflect package is only partially implemented.
    22  //
    23  // * The "testing" package is no longer supported because it
    24  // depends on low-level details that change too often.
    25  //
    26  // * "sync/atomic" operations are not atomic due to the "boxed" value
    27  // representation: it is not possible to read, modify and write an
    28  // interface value atomically. As a consequence, Mutexes are currently
    29  // broken.
    30  //
    31  // * recover is only partially implemented.  Also, the interpreter
    32  // makes no attempt to distinguish target panics from interpreter
    33  // crashes.
    34  //
    35  // * the sizes of the int, uint and uintptr types in the target
    36  // program are assumed to be the same as those of the interpreter
    37  // itself.
    38  //
    39  // * all values occupy space, even those of types defined by the spec
    40  // to have zero size, e.g. struct{}.  This can cause asymptotic
    41  // performance degradation.
    42  //
    43  // * os.Exit is implemented using panic, causing deferred functions to
    44  // run.
    45  package gossa
    46  
    47  import (
    48  	"fmt"
    49  	"go/constant"
    50  	"go/token"
    51  	"go/types"
    52  	"reflect"
    53  	"runtime"
    54  	"sync"
    55  	"sync/atomic"
    56  	"unsafe"
    57  
    58  	"github.com/goplus/gossa/internal/xtype"
    59  	"github.com/petermattis/goid"
    60  	"golang.org/x/tools/go/ssa"
    61  )
    62  
    63  var (
    64  	maxMemLen int
    65  )
    66  
    67  const intSize = 32 << (^uint(0) >> 63)
    68  
    69  func init() {
    70  	if intSize == 32 {
    71  		maxMemLen = 1<<31 - 1
    72  	} else {
    73  		v := int64(1) << 59
    74  		maxMemLen = int(v)
    75  	}
    76  }
    77  
    78  type plainError string
    79  
    80  func (e plainError) Error() string {
    81  	return string(e)
    82  }
    83  
    84  type runtimeError string
    85  
    86  func (e runtimeError) RuntimeError() {}
    87  
    88  func (e runtimeError) Error() string {
    89  	return "runtime error: " + string(e)
    90  }
    91  
    92  // State shared between all interpreted goroutines.
    93  type Interp struct {
    94  	ctx          *Context
    95  	fset         *token.FileSet
    96  	prog         *ssa.Program                                // the SSA program
    97  	mainpkg      *ssa.Package                                // the SSA main package
    98  	globals      map[ssa.Value]value                         // addresses of global variables (immutable)
    99  	mode         Mode                                        // interpreter options
   100  	goroutines   int32                                       // atomically updated
   101  	deferCount   int32                                       // fast has defer check
   102  	preloadTypes map[types.Type]reflect.Type                 // preload types.Type -> reflect.Type
   103  	deferMap     sync.Map                                    // defer goroutine id -> call frame
   104  	loader       Loader                                      // loader types
   105  	record       *TypesRecord                                // lookup type and ToType
   106  	typesMutex   sync.RWMutex                                // findType/toType mutex
   107  	funcs        map[*ssa.Function]*function                 // ssa.Function -> *function
   108  	msets        map[reflect.Type](map[string]*ssa.Function) // user defined type method sets
   109  	mainid       int64                                       // main goroutine id
   110  	exitCode     int                                         // call os.Exit code
   111  	chexit       chan int                                    // call os.Exit code by chan for runtime.Goexit
   112  	goexited     int32                                       // is call runtime.Goexit
   113  	exited       int32                                       // is call os.Exit
   114  }
   115  
   116  func (i *Interp) installed(path string) (pkg *Package, ok bool) {
   117  	pkg, ok = i.loader.Installed(path)
   118  	return
   119  }
   120  
   121  func (i *Interp) loadFunction(fn *ssa.Function) *function {
   122  	if pfn, ok := i.funcs[fn]; ok {
   123  		return pfn
   124  	}
   125  	pfn := &function{
   126  		Interp:           i,
   127  		Fn:               fn,
   128  		Main:             fn.Blocks[0],
   129  		mapUnderscoreKey: make(map[types.Type]bool),
   130  		index:            make(map[ssa.Value]uint32),
   131  		narg:             len(fn.Params),
   132  		nenv:             len(fn.FreeVars),
   133  	}
   134  	if res := fn.Signature.Results(); res != nil {
   135  		pfn.nres = res.Len()
   136  		pfn.stack = make([]value, pfn.nres)
   137  	}
   138  	i.funcs[fn] = pfn
   139  	return pfn
   140  }
   141  
   142  func (i *Interp) findType(rt reflect.Type, local bool) (types.Type, bool) {
   143  	i.typesMutex.Lock()
   144  	defer i.typesMutex.Unlock()
   145  	if local {
   146  		return i.record.LookupLocalTypes(rt)
   147  	} else {
   148  		return i.record.LookupTypes(rt)
   149  	}
   150  }
   151  
   152  func (i *Interp) tryDeferFrame() *frame {
   153  	if atomic.LoadInt32(&i.deferCount) != 0 {
   154  		if f, ok := i.deferMap.Load(goroutineId()); ok {
   155  			return f.(*frame)
   156  		}
   157  	}
   158  	return nil
   159  }
   160  
   161  func (i *Interp) FindMethod(mtyp reflect.Type, fn *types.Func) func([]reflect.Value) []reflect.Value {
   162  	typ := fn.Type().(*types.Signature).Recv().Type()
   163  	if f := i.prog.LookupMethod(typ, fn.Pkg(), fn.Name()); f != nil {
   164  		pfn := i.loadFunction(f)
   165  		return func(args []reflect.Value) []reflect.Value {
   166  			return i.callFunctionByReflect(i.tryDeferFrame(), mtyp, pfn, args, nil)
   167  		}
   168  	}
   169  	name := fn.FullName()
   170  	if v, ok := externValues[name]; ok && v.Kind() == reflect.Func {
   171  		return func(args []reflect.Value) []reflect.Value {
   172  			return v.Call(args)
   173  		}
   174  	}
   175  	panic(fmt.Sprintf("Not found method %v", fn))
   176  }
   177  
   178  func (i *Interp) makeFunc(typ reflect.Type, pfn *function, env []value) reflect.Value {
   179  	return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value {
   180  		return i.callFunctionByReflect(i.tryDeferFrame(), typ, pfn, args, env)
   181  	})
   182  }
   183  
   184  type deferred struct {
   185  	fn      value
   186  	args    []value
   187  	ssaArgs []ssa.Value
   188  	instr   *ssa.Defer
   189  	tail    *deferred
   190  }
   191  
   192  type frame struct {
   193  	caller    *frame
   194  	pfn       *function
   195  	defers    *deferred
   196  	panicking *panicking
   197  	block     *ssa.BasicBlock
   198  	pc        int
   199  	pred      int
   200  	deferid   int64
   201  	stack     []value // result args env datas
   202  }
   203  
   204  func (fr *frame) setReg(ir register, v value) {
   205  	fr.stack[ir] = v
   206  }
   207  
   208  func (fr *frame) reg(ir register) value {
   209  	return fr.stack[ir]
   210  }
   211  
   212  func (fr *frame) bytes(ir register) []byte {
   213  	return xtype.Bytes(fr.stack[ir])
   214  }
   215  
   216  func (fr *frame) runes(ir register) []rune {
   217  	return xtype.Runes(fr.stack[ir])
   218  }
   219  
   220  func (fr *frame) bool(ir register) bool {
   221  	return xtype.Bool(fr.stack[ir])
   222  }
   223  
   224  func (fr *frame) int(ir register) int {
   225  	return xtype.Int(fr.stack[ir])
   226  }
   227  
   228  func (fr *frame) int8(ir register) int8 {
   229  	return xtype.Int8(fr.stack[ir])
   230  }
   231  
   232  func (fr *frame) int16(ir register) int16 {
   233  	return xtype.Int16(fr.stack[ir])
   234  }
   235  
   236  func (fr *frame) int32(ir register) int32 {
   237  	return xtype.Int32(fr.stack[ir])
   238  }
   239  
   240  func (fr *frame) int64(ir register) int64 {
   241  	return xtype.Int64(fr.stack[ir])
   242  }
   243  
   244  func (fr *frame) uint(ir register) uint {
   245  	return xtype.Uint(fr.stack[ir])
   246  }
   247  
   248  func (fr *frame) uint8(ir register) uint8 {
   249  	return xtype.Uint8(fr.stack[ir])
   250  }
   251  
   252  func (fr *frame) uint16(ir register) uint16 {
   253  	return xtype.Uint16(fr.stack[ir])
   254  }
   255  
   256  func (fr *frame) uint32(ir register) uint32 {
   257  	return xtype.Uint32(fr.stack[ir])
   258  }
   259  
   260  func (fr *frame) uint64(ir register) uint64 {
   261  	return xtype.Uint64(fr.stack[ir])
   262  }
   263  
   264  func (fr *frame) uintptr(ir register) uintptr {
   265  	return xtype.Uintptr(fr.stack[ir])
   266  }
   267  
   268  func (fr *frame) float32(ir register) float32 {
   269  	return xtype.Float32(fr.stack[ir])
   270  }
   271  
   272  func (fr *frame) float64(ir register) float64 {
   273  	return xtype.Float64(fr.stack[ir])
   274  }
   275  
   276  func (fr *frame) complex64(ir register) complex64 {
   277  	return xtype.Complex64(fr.stack[ir])
   278  }
   279  
   280  func (fr *frame) complex128(ir register) complex128 {
   281  	return xtype.Complex128(fr.stack[ir])
   282  }
   283  
   284  func (fr *frame) string(ir register) string {
   285  	return xtype.String(fr.stack[ir])
   286  }
   287  
   288  func (fr *frame) pointer(ir register) unsafe.Pointer {
   289  	return xtype.Pointer(fr.stack[ir])
   290  }
   291  
   292  func (fr *frame) copyReg(dst register, src register) {
   293  	fr.stack[dst] = fr.stack[src]
   294  }
   295  
   296  type panicking struct {
   297  	value interface{}
   298  }
   299  
   300  // runDefer runs a deferred call d.
   301  // It always returns normally, but may set or clear fr.panic.
   302  //
   303  func (fr *frame) runDefer(d *deferred) {
   304  	var ok bool
   305  	defer func() {
   306  		if !ok {
   307  			// Deferred call created a new state of panic.
   308  			fr.panicking = &panicking{recover()}
   309  		}
   310  	}()
   311  	fr.pfn.Interp.callDiscardsResult(fr, d.fn, d.args, d.ssaArgs)
   312  	ok = true
   313  }
   314  
   315  // runDefers executes fr's deferred function calls in LIFO order.
   316  //
   317  // On entry, fr.panicking indicates a state of panic; if
   318  // true, fr.panic contains the panic value.
   319  //
   320  // On completion, if a deferred call started a panic, or if no
   321  // deferred call recovered from a previous state of panic, then
   322  // runDefers itself panics after the last deferred call has run.
   323  //
   324  // If there was no initial state of panic, or it was recovered from,
   325  // runDefers returns normally.
   326  //
   327  func (fr *frame) runDefers() {
   328  	interp := fr.pfn.Interp
   329  	atomic.AddInt32(&interp.deferCount, 1)
   330  	fr.deferid = goroutineId()
   331  	interp.deferMap.Store(fr.deferid, fr)
   332  	for d := fr.defers; d != nil; d = d.tail {
   333  		fr.runDefer(d)
   334  	}
   335  	interp.deferMap.Delete(fr.deferid)
   336  	atomic.AddInt32(&interp.deferCount, -1)
   337  	fr.deferid = 0
   338  	// runtime.Goexit() fr.panic == nil
   339  	if fr.panicking != nil {
   340  		panic(fr.panicking.value) // new panic, or still panicking
   341  	}
   342  }
   343  
   344  // lookupMethod returns the method set for type typ, which may be one
   345  // of the interpreter's fake types.
   346  func lookupMethod(i *Interp, typ types.Type, meth *types.Func) *ssa.Function {
   347  	return i.prog.LookupMethod(typ, meth.Pkg(), meth.Name())
   348  }
   349  
   350  func SetValue(v reflect.Value, x reflect.Value) {
   351  	switch v.Kind() {
   352  	case reflect.Bool:
   353  		v.SetBool(x.Bool())
   354  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   355  		v.SetInt(x.Int())
   356  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   357  		v.SetUint(x.Uint())
   358  	case reflect.Uintptr:
   359  		v.SetUint(x.Uint())
   360  	case reflect.Float32, reflect.Float64:
   361  		v.SetFloat(x.Float())
   362  	case reflect.Complex64, reflect.Complex128:
   363  		v.SetComplex(x.Complex())
   364  	case reflect.String:
   365  		v.SetString(x.String())
   366  	case reflect.UnsafePointer:
   367  		v.SetPointer(unsafe.Pointer(x.Pointer()))
   368  	default:
   369  		v.Set(x)
   370  	}
   371  }
   372  
   373  func hasUnderscore(st *types.Struct) bool {
   374  	n := st.NumFields()
   375  	for i := 0; i < n; i++ {
   376  		if st.Field(i).Name() == "_" {
   377  			return true
   378  		}
   379  	}
   380  	return false
   381  }
   382  
   383  type DebugInfo struct {
   384  	*ssa.DebugRef
   385  	fset    *token.FileSet
   386  	toValue func() (*types.Var, interface{}, bool) // var object value
   387  }
   388  
   389  func (i *DebugInfo) Position() token.Position {
   390  	return i.fset.Position(i.Pos())
   391  }
   392  
   393  func (i *DebugInfo) AsVar() (*types.Var, interface{}, bool) {
   394  	return i.toValue()
   395  }
   396  
   397  func (i *DebugInfo) AsFunc() (*types.Func, bool) {
   398  	v, ok := i.Object().(*types.Func)
   399  	return v, ok
   400  }
   401  
   402  // prepareCall determines the function value and argument values for a
   403  // function call in a Call, Go or Defer instruction, performing
   404  // interface method lookup if needed.
   405  //
   406  func (i *Interp) prepareCall(fr *frame, call *ssa.CallCommon, iv register, ia []register, ib []register) (fv value, args []value) {
   407  	if call.Method == nil {
   408  		switch f := call.Value.(type) {
   409  		case *ssa.Builtin:
   410  			fv = f
   411  		case *ssa.Function:
   412  			if f.Blocks == nil {
   413  				ext, ok := findExternFunc(i, f)
   414  				if !ok {
   415  					// skip pkg.init
   416  					if f.Pkg != nil && f.Name() == "init" {
   417  						fv = func() {}
   418  					} else {
   419  						panic(fmt.Errorf("no code for function: %v", f))
   420  					}
   421  				} else {
   422  					fv = ext
   423  				}
   424  			} else {
   425  				fv = f
   426  			}
   427  		case *ssa.MakeClosure:
   428  			var bindings []value
   429  			for i, _ := range f.Bindings {
   430  				bindings = append(bindings, fr.reg(ib[i]))
   431  			}
   432  			fv = &closure{i.funcs[f.Fn.(*ssa.Function)], bindings}
   433  		default:
   434  			fv = fr.reg(iv)
   435  		}
   436  	} else {
   437  		v := fr.reg(iv)
   438  		rtype := reflect.TypeOf(v)
   439  		mname := call.Method.Name()
   440  		if mset, ok := i.msets[rtype]; ok {
   441  			if f, ok := mset[mname]; ok {
   442  				fv = f
   443  			} else {
   444  				ext, ok := findUserMethod(rtype, mname)
   445  				if !ok {
   446  					panic(fmt.Errorf("no code for method: %v.%v", rtype, mname))
   447  				}
   448  				fv = ext
   449  			}
   450  		} else {
   451  			ext, ok := findExternMethod(rtype, mname)
   452  			if !ok {
   453  				panic(fmt.Errorf("no code for method: %v.%v", rtype, mname))
   454  			}
   455  			fv = ext
   456  		}
   457  		args = append(args, v)
   458  	}
   459  	for i, _ := range call.Args {
   460  		v := fr.reg(ia[i])
   461  		args = append(args, v)
   462  	}
   463  	return
   464  }
   465  
   466  // call interprets a call to a function (function, builtin or closure)
   467  // fn with arguments args, returning its result.
   468  // callpos is the position of the callsite.
   469  //
   470  func (i *Interp) call(caller *frame, fn value, args []value, ssaArgs []ssa.Value) value {
   471  	switch fn := fn.(type) {
   472  	case *ssa.Function:
   473  		return i.callFunction(caller, i.funcs[fn], args, nil)
   474  	case *closure:
   475  		return i.callFunction(caller, fn.pfn, args, fn.env)
   476  	case *ssa.Builtin:
   477  		return i.callBuiltin(caller, fn, args, ssaArgs)
   478  	case reflect.Value:
   479  		return i.callExternal(caller, fn, args, nil)
   480  	default:
   481  		return i.callExternal(caller, reflect.ValueOf(fn), args, nil)
   482  	}
   483  	panic(fmt.Sprintf("cannot call %T %v", fn, reflect.ValueOf(fn).Kind()))
   484  }
   485  
   486  // call interprets a call to a function (function, builtin or closure)
   487  // fn with arguments args, returning its result.
   488  // callpos is the position of the callsite.
   489  //
   490  func (i *Interp) callDiscardsResult(caller *frame, fn value, args []value, ssaArgs []ssa.Value) {
   491  	switch fn := fn.(type) {
   492  	case *ssa.Function:
   493  		i.callFunctionDiscardsResult(caller, i.funcs[fn], args, nil)
   494  	case *closure:
   495  		i.callFunctionDiscardsResult(caller, fn.pfn, args, fn.env)
   496  	case *ssa.Builtin:
   497  		i.callBuiltinDiscardsResult(caller, fn, args, ssaArgs)
   498  	case reflect.Value:
   499  		i.callExternalDiscardsResult(caller, fn, args, nil)
   500  	default:
   501  		i.callExternalDiscardsResult(caller, reflect.ValueOf(fn), args, nil)
   502  	}
   503  }
   504  
   505  func (i *Interp) callFunction(caller *frame, pfn *function, args []value, env []value) (result value) {
   506  	fr := pfn.allocFrame(caller)
   507  	for i := 0; i < pfn.narg; i++ {
   508  		fr.stack[i+pfn.nres] = args[i]
   509  	}
   510  	for i := 0; i < pfn.nenv; i++ {
   511  		fr.stack[pfn.narg+i+pfn.nres] = env[i]
   512  	}
   513  	fr.run()
   514  	if pfn.nres == 1 {
   515  		result = fr.stack[0]
   516  	} else if pfn.nres > 1 {
   517  		result = tuple(fr.stack[0:pfn.nres])
   518  	}
   519  	pfn.deleteFrame(fr)
   520  	return
   521  }
   522  
   523  func (i *Interp) callFunctionByReflect(caller *frame, typ reflect.Type, pfn *function, args []reflect.Value, env []value) (results []reflect.Value) {
   524  	fr := pfn.allocFrame(caller)
   525  	for i := 0; i < pfn.narg; i++ {
   526  		fr.stack[i+pfn.nres] = args[i].Interface()
   527  	}
   528  	for i := 0; i < pfn.nenv; i++ {
   529  		fr.stack[pfn.narg+i+pfn.nres] = env[i]
   530  	}
   531  	fr.run()
   532  	if pfn.nres > 0 {
   533  		results = make([]reflect.Value, pfn.nres, pfn.nres)
   534  		for i := 0; i < pfn.nres; i++ {
   535  			v := fr.stack[i]
   536  			if v == nil {
   537  				results[i] = reflect.New(typ.Out(i)).Elem()
   538  			} else {
   539  				results[i] = reflect.ValueOf(v)
   540  			}
   541  		}
   542  	}
   543  	pfn.deleteFrame(fr)
   544  	return
   545  }
   546  
   547  func (i *Interp) callFunctionDiscardsResult(caller *frame, pfn *function, args []value, env []value) {
   548  	fr := pfn.allocFrame(caller)
   549  	for i := 0; i < pfn.narg; i++ {
   550  		fr.stack[i+pfn.nres] = args[i]
   551  	}
   552  	for i := 0; i < pfn.nenv; i++ {
   553  		fr.stack[pfn.narg+i+pfn.nres] = env[i]
   554  	}
   555  	fr.run()
   556  	pfn.deleteFrame(fr)
   557  }
   558  
   559  func (i *Interp) callFunctionByStack0(caller *frame, pfn *function, ir register, ia []register) {
   560  	fr := pfn.allocFrame(caller)
   561  	for i := 0; i < len(ia); i++ {
   562  		fr.stack[i] = caller.reg(ia[i])
   563  	}
   564  	fr.run()
   565  	pfn.deleteFrame(fr)
   566  }
   567  
   568  func (i *Interp) callFunctionByStack1(caller *frame, pfn *function, ir register, ia []register) {
   569  	fr := pfn.allocFrame(caller)
   570  	for i := 0; i < len(ia); i++ {
   571  		fr.stack[i+1] = caller.reg(ia[i])
   572  	}
   573  	fr.run()
   574  	caller.setReg(ir, fr.stack[0])
   575  	pfn.deleteFrame(fr)
   576  }
   577  
   578  func (i *Interp) callFunctionByStackN(caller *frame, pfn *function, ir register, ia []register) {
   579  	fr := pfn.allocFrame(caller)
   580  	for i := 0; i < len(ia); i++ {
   581  		fr.stack[i+pfn.nres] = caller.reg(ia[i])
   582  	}
   583  	fr.run()
   584  	caller.setReg(ir, tuple(fr.stack[0:pfn.nres]))
   585  	pfn.deleteFrame(fr)
   586  }
   587  
   588  func (i *Interp) callFunctionByStack(caller *frame, pfn *function, ir register, ia []register) {
   589  	fr := pfn.allocFrame(caller)
   590  	for i := 0; i < len(ia); i++ {
   591  		fr.stack[i+pfn.nres] = caller.reg(ia[i])
   592  	}
   593  	fr.run()
   594  	if pfn.nres == 1 {
   595  		caller.setReg(ir, fr.stack[0])
   596  	} else if pfn.nres > 1 {
   597  		caller.setReg(ir, tuple(fr.stack[0:pfn.nres]))
   598  	}
   599  	pfn.deleteFrame(fr)
   600  }
   601  
   602  func (i *Interp) callFunctionByStackNoRecover0(caller *frame, pfn *function, ir register, ia []register) {
   603  	fr := pfn.allocFrame(caller)
   604  	for i := 0; i < len(ia); i++ {
   605  		fr.stack[i] = caller.reg(ia[i])
   606  	}
   607  	for fr.pc != -1 {
   608  		fn := fr.pfn.Instrs[fr.pc]
   609  		fr.pc++
   610  		fn(fr)
   611  	}
   612  	pfn.deleteFrame(fr)
   613  }
   614  
   615  func (i *Interp) callFunctionByStackNoRecover1(caller *frame, pfn *function, ir register, ia []register) {
   616  	fr := pfn.allocFrame(caller)
   617  	for i := 0; i < len(ia); i++ {
   618  		fr.stack[i+1] = caller.reg(ia[i])
   619  	}
   620  	for fr.pc != -1 {
   621  		fn := fr.pfn.Instrs[fr.pc]
   622  		fr.pc++
   623  		fn(fr)
   624  	}
   625  	caller.setReg(ir, fr.stack[0])
   626  	pfn.deleteFrame(fr)
   627  }
   628  
   629  func (i *Interp) callFunctionByStackNoRecoverN(caller *frame, pfn *function, ir register, ia []register) {
   630  	fr := pfn.allocFrame(caller)
   631  	for i := 0; i < len(ia); i++ {
   632  		fr.stack[i+pfn.nres] = caller.reg(ia[i])
   633  	}
   634  	for fr.pc != -1 {
   635  		fn := fr.pfn.Instrs[fr.pc]
   636  		fr.pc++
   637  		fn(fr)
   638  	}
   639  	caller.setReg(ir, tuple(fr.stack[0:pfn.nres]))
   640  	pfn.deleteFrame(fr)
   641  }
   642  
   643  func (i *Interp) callFunctionByStackWithEnv(caller *frame, pfn *function, ir register, ia []register, env []value) {
   644  	fr := pfn.allocFrame(caller)
   645  	for i := 0; i < pfn.narg; i++ {
   646  		fr.stack[i+pfn.nres] = caller.reg(ia[i])
   647  	}
   648  	for i := 0; i < pfn.nenv; i++ {
   649  		fr.stack[pfn.narg+i+pfn.nres] = env[i]
   650  	}
   651  	fr.run()
   652  	if pfn.nres == 1 {
   653  		caller.setReg(ir, fr.stack[0])
   654  	} else if pfn.nres > 1 {
   655  		caller.setReg(ir, tuple(fr.stack[0:pfn.nres]))
   656  	}
   657  	pfn.deleteFrame(fr)
   658  }
   659  
   660  func (i *Interp) callFunctionByStackNoRecoverWithEnv(caller *frame, pfn *function, ir register, ia []register, env []value) {
   661  	fr := pfn.allocFrame(caller)
   662  	for i := 0; i < pfn.narg; i++ {
   663  		fr.stack[i+pfn.nres] = caller.reg(ia[i])
   664  	}
   665  	for i := 0; i < pfn.nenv; i++ {
   666  		fr.stack[pfn.narg+i+pfn.nres] = env[i]
   667  	}
   668  	for fr.pc != -1 {
   669  		fn := fr.pfn.Instrs[fr.pc]
   670  		fr.pc++
   671  		fn(fr)
   672  	}
   673  	if pfn.nres == 1 {
   674  		caller.setReg(ir, fr.stack[0])
   675  	} else if pfn.nres > 1 {
   676  		caller.setReg(ir, tuple(fr.stack[0:pfn.nres]))
   677  	}
   678  	pfn.deleteFrame(fr)
   679  }
   680  
   681  func (i *Interp) callExternal(caller *frame, fn reflect.Value, args []value, env []value) value {
   682  	if caller != nil && caller.deferid != 0 {
   683  		i.deferMap.Store(caller.deferid, caller)
   684  	}
   685  	var ins []reflect.Value
   686  	typ := fn.Type()
   687  	isVariadic := fn.Type().IsVariadic()
   688  	if isVariadic {
   689  		for i := 0; i < len(args)-1; i++ {
   690  			if args[i] == nil {
   691  				ins = append(ins, reflect.New(typ.In(i)).Elem())
   692  			} else {
   693  				ins = append(ins, reflect.ValueOf(args[i]))
   694  			}
   695  		}
   696  		ins = append(ins, reflect.ValueOf(args[len(args)-1]))
   697  	} else {
   698  		ins = make([]reflect.Value, len(args), len(args))
   699  		for i := 0; i < len(args); i++ {
   700  			if args[i] == nil {
   701  				ins[i] = reflect.New(typ.In(i)).Elem()
   702  			} else {
   703  				ins[i] = reflect.ValueOf(args[i])
   704  			}
   705  		}
   706  	}
   707  	var results []reflect.Value
   708  	if isVariadic {
   709  		results = fn.CallSlice(ins)
   710  	} else {
   711  		results = fn.Call(ins)
   712  	}
   713  	switch len(results) {
   714  	case 0:
   715  		return nil
   716  	case 1:
   717  		return results[0].Interface()
   718  	default:
   719  		var res []value
   720  		for _, r := range results {
   721  			res = append(res, r.Interface())
   722  		}
   723  		return tuple(res)
   724  	}
   725  }
   726  func (i *Interp) callExternalDiscardsResult(caller *frame, fn reflect.Value, args []value, env []value) {
   727  	if caller != nil && caller.deferid != 0 {
   728  		i.deferMap.Store(caller.deferid, caller)
   729  	}
   730  	var ins []reflect.Value
   731  	typ := fn.Type()
   732  	isVariadic := fn.Type().IsVariadic()
   733  	if isVariadic {
   734  		for i := 0; i < len(args)-1; i++ {
   735  			if args[i] == nil {
   736  				ins = append(ins, reflect.New(typ.In(i)).Elem())
   737  			} else {
   738  				ins = append(ins, reflect.ValueOf(args[i]))
   739  			}
   740  		}
   741  		ins = append(ins, reflect.ValueOf(args[len(args)-1]))
   742  		fn.CallSlice(ins)
   743  	} else {
   744  		ins = make([]reflect.Value, len(args), len(args))
   745  		for i := 0; i < len(args); i++ {
   746  			if args[i] == nil {
   747  				ins[i] = reflect.New(typ.In(i)).Elem()
   748  			} else {
   749  				ins[i] = reflect.ValueOf(args[i])
   750  			}
   751  		}
   752  		fn.Call(ins)
   753  	}
   754  }
   755  
   756  func (i *Interp) callExternalByStack(caller *frame, fn reflect.Value, ir register, ia []register) {
   757  	if caller.deferid != 0 {
   758  		i.deferMap.Store(caller.deferid, caller)
   759  	}
   760  	var ins []reflect.Value
   761  	typ := fn.Type()
   762  	isVariadic := fn.Type().IsVariadic()
   763  	if isVariadic {
   764  		var i int
   765  		for n := len(ia) - 1; i < n; i++ {
   766  			arg := caller.reg(ia[i])
   767  			if arg == nil {
   768  				ins = append(ins, reflect.New(typ.In(i)).Elem())
   769  			} else {
   770  				ins = append(ins, reflect.ValueOf(arg))
   771  			}
   772  		}
   773  		ins = append(ins, reflect.ValueOf(caller.reg(ia[i])))
   774  	} else {
   775  		n := len(ia)
   776  		ins = make([]reflect.Value, n, n)
   777  		for i := 0; i < n; i++ {
   778  			arg := caller.reg(ia[i])
   779  			if arg == nil {
   780  				ins[i] = reflect.New(typ.In(i)).Elem()
   781  			} else {
   782  				ins[i] = reflect.ValueOf(arg)
   783  			}
   784  		}
   785  	}
   786  	var results []reflect.Value
   787  	if isVariadic {
   788  		results = fn.CallSlice(ins)
   789  	} else {
   790  		results = fn.Call(ins)
   791  	}
   792  	switch len(results) {
   793  	case 0:
   794  	case 1:
   795  		caller.setReg(ir, results[0].Interface())
   796  	default:
   797  		var res []value
   798  		for _, r := range results {
   799  			res = append(res, r.Interface())
   800  		}
   801  		caller.setReg(ir, tuple(res))
   802  	}
   803  }
   804  
   805  // runFrame executes SSA instructions starting at fr.block and
   806  // continuing until a return, a panic, or a recovered panic.
   807  //
   808  // After a panic, runFrame panics.
   809  //
   810  // After a normal return, fr.result contains the result of the call
   811  // and fr.block is nil.
   812  //
   813  // A recovered panic in a function without named return parameters
   814  // (NRPs) becomes a normal return of the zero value of the function's
   815  // result type.
   816  //
   817  // After a recovered panic in a function with NRPs, fr.result is
   818  // undefined and fr.block contains the block at which to resume
   819  // control.
   820  //
   821  func (fr *frame) run() {
   822  	if fr.pfn.Recover != nil {
   823  		defer func() {
   824  			if fr.pc == -1 {
   825  				return // normal return
   826  			}
   827  			fr.panicking = &panicking{recover()}
   828  			fr.runDefers()
   829  			for _, fn := range fr.pfn.Recover {
   830  				fn(fr)
   831  			}
   832  		}()
   833  	}
   834  
   835  	for fr.pc != -1 {
   836  		fn := fr.pfn.Instrs[fr.pc]
   837  		fr.pc++
   838  		fn(fr)
   839  	}
   840  }
   841  
   842  // doRecover implements the recover() built-in.
   843  func doRecover(caller *frame) value {
   844  	// recover() must be exactly one level beneath the deferred
   845  	// function (two levels beneath the panicking function) to
   846  	// have any effect.  Thus we ignore both "defer recover()" and
   847  	// "defer f() -> g() -> recover()".
   848  	if caller.pfn.Interp.mode&DisableRecover == 0 &&
   849  		caller.panicking == nil &&
   850  		caller.caller != nil && caller.caller.panicking != nil {
   851  		p := caller.caller.panicking.value
   852  		caller.caller.panicking = nil
   853  		// TODO(adonovan): support runtime.Goexit.
   854  		switch p := p.(type) {
   855  		case targetPanic:
   856  			// The target program explicitly called panic().
   857  			return p.v
   858  		case runtime.Error:
   859  			// The interpreter encountered a runtime error.
   860  			return p
   861  			//return iface{caller.i.runtimeErrorString, p.Error()}
   862  		case string:
   863  			return p
   864  		case plainError:
   865  			return p
   866  		case runtimeError:
   867  			return p
   868  		case *reflect.ValueError:
   869  			return p
   870  		default:
   871  			panic(fmt.Sprintf("unexpected panic type %T in target call to recover()", p))
   872  		}
   873  	}
   874  	return nil //iface{}
   875  }
   876  
   877  // setGlobal sets the value of a system-initialized global variable.
   878  func setGlobal(i *Interp, pkg *ssa.Package, name string, v value) {
   879  	// if g, ok := i.globals[pkg.Var(name)]; ok {
   880  	// 	*g = v
   881  	// 	return
   882  	// }
   883  	panic("no global variable: " + pkg.Pkg.Path() + "." + name)
   884  }
   885  
   886  // Interpret interprets the Go program whose main package is mainpkg.
   887  // mode specifies various interpreter options.  filename and args are
   888  // the initial values of os.Args for the target program.  sizes is the
   889  // effective type-sizing function for this program.
   890  //
   891  // Interpret returns the exit code of the program: 2 for panic (like
   892  // gc does), or the argument to os.Exit for normal termination.
   893  //
   894  // The SSA program must include the "runtime" package.
   895  //
   896  
   897  func NewInterp(ctx *Context, mainpkg *ssa.Package) (*Interp, error) {
   898  	return newInterp(ctx, mainpkg, nil)
   899  }
   900  
   901  func newInterp(ctx *Context, mainpkg *ssa.Package, globals map[string]interface{}) (*Interp, error) {
   902  	i := &Interp{
   903  		ctx:          ctx,
   904  		fset:         mainpkg.Prog.Fset,
   905  		prog:         mainpkg.Prog,
   906  		mainpkg:      mainpkg,
   907  		globals:      make(map[ssa.Value]value),
   908  		mode:         ctx.Mode,
   909  		loader:       ctx.Loader,
   910  		goroutines:   1,
   911  		preloadTypes: make(map[types.Type]reflect.Type),
   912  		funcs:        make(map[*ssa.Function]*function),
   913  		msets:        make(map[reflect.Type](map[string]*ssa.Function)),
   914  		chexit:       make(chan int),
   915  		mainid:       goroutineId(),
   916  	}
   917  	i.record = NewTypesRecord(i.loader, i)
   918  	i.record.Load(mainpkg)
   919  
   920  	var pkgs []*ssa.Package
   921  	for _, pkg := range mainpkg.Prog.AllPackages() {
   922  		// skip external pkg
   923  		if pkg.Func("init").Blocks == nil {
   924  			continue
   925  		}
   926  		pkgs = append(pkgs, pkg)
   927  		// Initialize global storage.
   928  		for _, m := range pkg.Members {
   929  			switch v := m.(type) {
   930  			case *ssa.Global:
   931  				typ := i.preToType(deref(v.Type()))
   932  				i.globals[v] = reflect.New(typ).Interface()
   933  			}
   934  		}
   935  	}
   936  	if globals != nil {
   937  		for k, _ := range i.globals {
   938  			if fv, ok := globals[k.String()]; ok {
   939  				i.globals[k] = fv
   940  			}
   941  		}
   942  	}
   943  
   944  	// static types check
   945  	err := checkPackages(i, pkgs)
   946  	if err != nil {
   947  		return i, err
   948  	}
   949  	return i, err
   950  }
   951  
   952  func (i *Interp) loadType(typ types.Type) {
   953  	if _, ok := i.preloadTypes[typ]; !ok {
   954  		i.preloadTypes[typ] = i.record.ToType(typ)
   955  	}
   956  }
   957  
   958  func (i *Interp) preToType(typ types.Type) reflect.Type {
   959  	if t, ok := i.preloadTypes[typ]; ok {
   960  		return t
   961  	}
   962  	t := i.record.ToType(typ)
   963  	i.preloadTypes[typ] = t
   964  	return t
   965  }
   966  
   967  func (i *Interp) toType(typ types.Type) reflect.Type {
   968  	if t, ok := i.preloadTypes[typ]; ok {
   969  		return t
   970  	}
   971  	// log.Panicf("toType %v %p\n", typ, typ)
   972  	i.typesMutex.Lock()
   973  	defer i.typesMutex.Unlock()
   974  	return i.record.ToType(typ)
   975  }
   976  
   977  func (i *Interp) RunFunc(name string, args ...Value) (r Value, err error) {
   978  	defer func() {
   979  		if i.mode&DisableRecover != 0 {
   980  			return
   981  		}
   982  		switch p := recover().(type) {
   983  		case nil:
   984  			// nothing
   985  		case exitPanic:
   986  			i.exitCode = int(p)
   987  			atomic.StoreInt32(&i.exited, 1)
   988  		case goexitPanic:
   989  			// check goroutines
   990  			if atomic.LoadInt32(&i.goroutines) == 1 {
   991  				err = ErrGoexitDeadlock
   992  			} else {
   993  				i.exitCode = <-i.chexit
   994  				atomic.StoreInt32(&i.exited, 1)
   995  			}
   996  		case targetPanic:
   997  			err = p
   998  		case runtime.Error:
   999  			err = p
  1000  		case string:
  1001  			err = plainError(p)
  1002  		case plainError:
  1003  			err = p
  1004  		default:
  1005  			err = fmt.Errorf("unexpected type: %T: %v", p, p)
  1006  		}
  1007  	}()
  1008  	if fn := i.mainpkg.Func(name); fn != nil {
  1009  		r = i.call(nil, fn, args, nil)
  1010  	} else {
  1011  		err = fmt.Errorf("no function %v", name)
  1012  	}
  1013  	return
  1014  }
  1015  
  1016  func (i *Interp) ExitCode() int {
  1017  	return i.exitCode
  1018  }
  1019  
  1020  func (i *Interp) RunInit() (err error) {
  1021  	i.goexited = 0
  1022  	i.exitCode = 0
  1023  	i.exited = 0
  1024  	_, err = i.RunFunc("init")
  1025  	return
  1026  }
  1027  
  1028  func (i *Interp) RunMain() (exitCode int, err error) {
  1029  	if atomic.LoadInt32(&i.exited) == 1 {
  1030  		return i.exitCode, nil
  1031  	}
  1032  	_, err = i.RunFunc("main")
  1033  	if err != nil {
  1034  		exitCode = 2
  1035  	}
  1036  	if atomic.LoadInt32(&i.exited) == 1 {
  1037  		exitCode = i.exitCode
  1038  	}
  1039  	return
  1040  }
  1041  
  1042  func (i *Interp) GetFunc(key string) (interface{}, bool) {
  1043  	m, ok := i.mainpkg.Members[key]
  1044  	if !ok {
  1045  		return nil, false
  1046  	}
  1047  	fn, ok := m.(*ssa.Function)
  1048  	if !ok {
  1049  		return nil, false
  1050  	}
  1051  	return i.makeFunc(i.toType(fn.Type()), i.funcs[fn], nil).Interface(), true
  1052  }
  1053  
  1054  func (i *Interp) GetVarAddr(key string) (interface{}, bool) {
  1055  	m, ok := i.mainpkg.Members[key]
  1056  	if !ok {
  1057  		return nil, false
  1058  	}
  1059  	v, ok := m.(*ssa.Global)
  1060  	if !ok {
  1061  		return nil, false
  1062  	}
  1063  	p, ok := i.globals[v]
  1064  	return p, ok
  1065  }
  1066  
  1067  func (i *Interp) GetConst(key string) (constant.Value, bool) {
  1068  	m, ok := i.mainpkg.Members[key]
  1069  	if !ok {
  1070  		return nil, false
  1071  	}
  1072  	v, ok := m.(*ssa.NamedConst)
  1073  	if !ok {
  1074  		return nil, false
  1075  	}
  1076  	return v.Value.Value, true
  1077  }
  1078  
  1079  func (i *Interp) GetType(key string) (reflect.Type, bool) {
  1080  	m, ok := i.mainpkg.Members[key]
  1081  	if !ok {
  1082  		return nil, false
  1083  	}
  1084  	t, ok := m.(*ssa.Type)
  1085  	if !ok {
  1086  		return nil, false
  1087  	}
  1088  	return i.toType(t.Type()), true
  1089  }
  1090  
  1091  // deref returns a pointer's element type; otherwise it returns typ.
  1092  // TODO(adonovan): Import from ssa?
  1093  func deref(typ types.Type) types.Type {
  1094  	if p, ok := typ.Underlying().(*types.Pointer); ok {
  1095  		return p.Elem()
  1096  	}
  1097  	return typ
  1098  }
  1099  
  1100  func goroutineId() int64 {
  1101  	return goid.Get()
  1102  }