github.com/jd-ly/tools@v0.5.7/go/ssa/interp/ops.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 interp
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/constant"
    11  	"go/token"
    12  	"go/types"
    13  	"os"
    14  	"reflect"
    15  	"strings"
    16  	"sync"
    17  	"unsafe"
    18  
    19  	"github.com/jd-ly/tools/go/ssa"
    20  )
    21  
    22  // If the target program panics, the interpreter panics with this type.
    23  type targetPanic struct {
    24  	v value
    25  }
    26  
    27  func (p targetPanic) String() string {
    28  	return toString(p.v)
    29  }
    30  
    31  // If the target program calls exit, the interpreter panics with this type.
    32  type exitPanic int
    33  
    34  // constValue returns the value of the constant with the
    35  // dynamic type tag appropriate for c.Type().
    36  func constValue(c *ssa.Const) value {
    37  	if c.IsNil() {
    38  		return zero(c.Type()) // typed nil
    39  	}
    40  
    41  	if t, ok := c.Type().Underlying().(*types.Basic); ok {
    42  		// TODO(adonovan): eliminate untyped constants from SSA form.
    43  		switch t.Kind() {
    44  		case types.Bool, types.UntypedBool:
    45  			return constant.BoolVal(c.Value)
    46  		case types.Int, types.UntypedInt:
    47  			// Assume sizeof(int) is same on host and target.
    48  			return int(c.Int64())
    49  		case types.Int8:
    50  			return int8(c.Int64())
    51  		case types.Int16:
    52  			return int16(c.Int64())
    53  		case types.Int32, types.UntypedRune:
    54  			return int32(c.Int64())
    55  		case types.Int64:
    56  			return c.Int64()
    57  		case types.Uint:
    58  			// Assume sizeof(uint) is same on host and target.
    59  			return uint(c.Uint64())
    60  		case types.Uint8:
    61  			return uint8(c.Uint64())
    62  		case types.Uint16:
    63  			return uint16(c.Uint64())
    64  		case types.Uint32:
    65  			return uint32(c.Uint64())
    66  		case types.Uint64:
    67  			return c.Uint64()
    68  		case types.Uintptr:
    69  			// Assume sizeof(uintptr) is same on host and target.
    70  			return uintptr(c.Uint64())
    71  		case types.Float32:
    72  			return float32(c.Float64())
    73  		case types.Float64, types.UntypedFloat:
    74  			return c.Float64()
    75  		case types.Complex64:
    76  			return complex64(c.Complex128())
    77  		case types.Complex128, types.UntypedComplex:
    78  			return c.Complex128()
    79  		case types.String, types.UntypedString:
    80  			if c.Value.Kind() == constant.String {
    81  				return constant.StringVal(c.Value)
    82  			}
    83  			return string(rune(c.Int64()))
    84  		}
    85  	}
    86  
    87  	panic(fmt.Sprintf("constValue: %s", c))
    88  }
    89  
    90  // asInt converts x, which must be an integer, to an int suitable for
    91  // use as a slice or array index or operand to make().
    92  func asInt(x value) int {
    93  	switch x := x.(type) {
    94  	case int:
    95  		return x
    96  	case int8:
    97  		return int(x)
    98  	case int16:
    99  		return int(x)
   100  	case int32:
   101  		return int(x)
   102  	case int64:
   103  		return int(x)
   104  	case uint:
   105  		return int(x)
   106  	case uint8:
   107  		return int(x)
   108  	case uint16:
   109  		return int(x)
   110  	case uint32:
   111  		return int(x)
   112  	case uint64:
   113  		return int(x)
   114  	case uintptr:
   115  		return int(x)
   116  	}
   117  	panic(fmt.Sprintf("cannot convert %T to int", x))
   118  }
   119  
   120  // asUint64 converts x, which must be an unsigned integer, to a uint64
   121  // suitable for use as a bitwise shift count.
   122  func asUint64(x value) uint64 {
   123  	switch x := x.(type) {
   124  	case uint:
   125  		return uint64(x)
   126  	case uint8:
   127  		return uint64(x)
   128  	case uint16:
   129  		return uint64(x)
   130  	case uint32:
   131  		return uint64(x)
   132  	case uint64:
   133  		return x
   134  	case uintptr:
   135  		return uint64(x)
   136  	}
   137  	panic(fmt.Sprintf("cannot convert %T to uint64", x))
   138  }
   139  
   140  // zero returns a new "zero" value of the specified type.
   141  func zero(t types.Type) value {
   142  	switch t := t.(type) {
   143  	case *types.Basic:
   144  		if t.Kind() == types.UntypedNil {
   145  			panic("untyped nil has no zero value")
   146  		}
   147  		if t.Info()&types.IsUntyped != 0 {
   148  			// TODO(adonovan): make it an invariant that
   149  			// this is unreachable.  Currently some
   150  			// constants have 'untyped' types when they
   151  			// should be defaulted by the typechecker.
   152  			t = types.Default(t).(*types.Basic)
   153  		}
   154  		switch t.Kind() {
   155  		case types.Bool:
   156  			return false
   157  		case types.Int:
   158  			return int(0)
   159  		case types.Int8:
   160  			return int8(0)
   161  		case types.Int16:
   162  			return int16(0)
   163  		case types.Int32:
   164  			return int32(0)
   165  		case types.Int64:
   166  			return int64(0)
   167  		case types.Uint:
   168  			return uint(0)
   169  		case types.Uint8:
   170  			return uint8(0)
   171  		case types.Uint16:
   172  			return uint16(0)
   173  		case types.Uint32:
   174  			return uint32(0)
   175  		case types.Uint64:
   176  			return uint64(0)
   177  		case types.Uintptr:
   178  			return uintptr(0)
   179  		case types.Float32:
   180  			return float32(0)
   181  		case types.Float64:
   182  			return float64(0)
   183  		case types.Complex64:
   184  			return complex64(0)
   185  		case types.Complex128:
   186  			return complex128(0)
   187  		case types.String:
   188  			return ""
   189  		case types.UnsafePointer:
   190  			return unsafe.Pointer(nil)
   191  		default:
   192  			panic(fmt.Sprint("zero for unexpected type:", t))
   193  		}
   194  	case *types.Pointer:
   195  		return (*value)(nil)
   196  	case *types.Array:
   197  		a := make(array, t.Len())
   198  		for i := range a {
   199  			a[i] = zero(t.Elem())
   200  		}
   201  		return a
   202  	case *types.Named:
   203  		return zero(t.Underlying())
   204  	case *types.Interface:
   205  		return iface{} // nil type, methodset and value
   206  	case *types.Slice:
   207  		return []value(nil)
   208  	case *types.Struct:
   209  		s := make(structure, t.NumFields())
   210  		for i := range s {
   211  			s[i] = zero(t.Field(i).Type())
   212  		}
   213  		return s
   214  	case *types.Tuple:
   215  		if t.Len() == 1 {
   216  			return zero(t.At(0).Type())
   217  		}
   218  		s := make(tuple, t.Len())
   219  		for i := range s {
   220  			s[i] = zero(t.At(i).Type())
   221  		}
   222  		return s
   223  	case *types.Chan:
   224  		return chan value(nil)
   225  	case *types.Map:
   226  		if usesBuiltinMap(t.Key()) {
   227  			return map[value]value(nil)
   228  		}
   229  		return (*hashmap)(nil)
   230  	case *types.Signature:
   231  		return (*ssa.Function)(nil)
   232  	}
   233  	panic(fmt.Sprint("zero: unexpected ", t))
   234  }
   235  
   236  // slice returns x[lo:hi:max].  Any of lo, hi and max may be nil.
   237  func slice(x, lo, hi, max value) value {
   238  	var Len, Cap int
   239  	switch x := x.(type) {
   240  	case string:
   241  		Len = len(x)
   242  	case []value:
   243  		Len = len(x)
   244  		Cap = cap(x)
   245  	case *value: // *array
   246  		a := (*x).(array)
   247  		Len = len(a)
   248  		Cap = cap(a)
   249  	}
   250  
   251  	l := 0
   252  	if lo != nil {
   253  		l = asInt(lo)
   254  	}
   255  
   256  	h := Len
   257  	if hi != nil {
   258  		h = asInt(hi)
   259  	}
   260  
   261  	m := Cap
   262  	if max != nil {
   263  		m = asInt(max)
   264  	}
   265  
   266  	switch x := x.(type) {
   267  	case string:
   268  		return x[l:h]
   269  	case []value:
   270  		return x[l:h:m]
   271  	case *value: // *array
   272  		a := (*x).(array)
   273  		return []value(a)[l:h:m]
   274  	}
   275  	panic(fmt.Sprintf("slice: unexpected X type: %T", x))
   276  }
   277  
   278  // lookup returns x[idx] where x is a map or string.
   279  func lookup(instr *ssa.Lookup, x, idx value) value {
   280  	switch x := x.(type) { // map or string
   281  	case map[value]value, *hashmap:
   282  		var v value
   283  		var ok bool
   284  		switch x := x.(type) {
   285  		case map[value]value:
   286  			v, ok = x[idx]
   287  		case *hashmap:
   288  			v = x.lookup(idx.(hashable))
   289  			ok = v != nil
   290  		}
   291  		if !ok {
   292  			v = zero(instr.X.Type().Underlying().(*types.Map).Elem())
   293  		}
   294  		if instr.CommaOk {
   295  			v = tuple{v, ok}
   296  		}
   297  		return v
   298  	case string:
   299  		return x[asInt(idx)]
   300  	}
   301  	panic(fmt.Sprintf("unexpected x type in Lookup: %T", x))
   302  }
   303  
   304  // binop implements all arithmetic and logical binary operators for
   305  // numeric datatypes and strings.  Both operands must have identical
   306  // dynamic type.
   307  //
   308  func binop(op token.Token, t types.Type, x, y value) value {
   309  	switch op {
   310  	case token.ADD:
   311  		switch x.(type) {
   312  		case int:
   313  			return x.(int) + y.(int)
   314  		case int8:
   315  			return x.(int8) + y.(int8)
   316  		case int16:
   317  			return x.(int16) + y.(int16)
   318  		case int32:
   319  			return x.(int32) + y.(int32)
   320  		case int64:
   321  			return x.(int64) + y.(int64)
   322  		case uint:
   323  			return x.(uint) + y.(uint)
   324  		case uint8:
   325  			return x.(uint8) + y.(uint8)
   326  		case uint16:
   327  			return x.(uint16) + y.(uint16)
   328  		case uint32:
   329  			return x.(uint32) + y.(uint32)
   330  		case uint64:
   331  			return x.(uint64) + y.(uint64)
   332  		case uintptr:
   333  			return x.(uintptr) + y.(uintptr)
   334  		case float32:
   335  			return x.(float32) + y.(float32)
   336  		case float64:
   337  			return x.(float64) + y.(float64)
   338  		case complex64:
   339  			return x.(complex64) + y.(complex64)
   340  		case complex128:
   341  			return x.(complex128) + y.(complex128)
   342  		case string:
   343  			return x.(string) + y.(string)
   344  		}
   345  
   346  	case token.SUB:
   347  		switch x.(type) {
   348  		case int:
   349  			return x.(int) - y.(int)
   350  		case int8:
   351  			return x.(int8) - y.(int8)
   352  		case int16:
   353  			return x.(int16) - y.(int16)
   354  		case int32:
   355  			return x.(int32) - y.(int32)
   356  		case int64:
   357  			return x.(int64) - y.(int64)
   358  		case uint:
   359  			return x.(uint) - y.(uint)
   360  		case uint8:
   361  			return x.(uint8) - y.(uint8)
   362  		case uint16:
   363  			return x.(uint16) - y.(uint16)
   364  		case uint32:
   365  			return x.(uint32) - y.(uint32)
   366  		case uint64:
   367  			return x.(uint64) - y.(uint64)
   368  		case uintptr:
   369  			return x.(uintptr) - y.(uintptr)
   370  		case float32:
   371  			return x.(float32) - y.(float32)
   372  		case float64:
   373  			return x.(float64) - y.(float64)
   374  		case complex64:
   375  			return x.(complex64) - y.(complex64)
   376  		case complex128:
   377  			return x.(complex128) - y.(complex128)
   378  		}
   379  
   380  	case token.MUL:
   381  		switch x.(type) {
   382  		case int:
   383  			return x.(int) * y.(int)
   384  		case int8:
   385  			return x.(int8) * y.(int8)
   386  		case int16:
   387  			return x.(int16) * y.(int16)
   388  		case int32:
   389  			return x.(int32) * y.(int32)
   390  		case int64:
   391  			return x.(int64) * y.(int64)
   392  		case uint:
   393  			return x.(uint) * y.(uint)
   394  		case uint8:
   395  			return x.(uint8) * y.(uint8)
   396  		case uint16:
   397  			return x.(uint16) * y.(uint16)
   398  		case uint32:
   399  			return x.(uint32) * y.(uint32)
   400  		case uint64:
   401  			return x.(uint64) * y.(uint64)
   402  		case uintptr:
   403  			return x.(uintptr) * y.(uintptr)
   404  		case float32:
   405  			return x.(float32) * y.(float32)
   406  		case float64:
   407  			return x.(float64) * y.(float64)
   408  		case complex64:
   409  			return x.(complex64) * y.(complex64)
   410  		case complex128:
   411  			return x.(complex128) * y.(complex128)
   412  		}
   413  
   414  	case token.QUO:
   415  		switch x.(type) {
   416  		case int:
   417  			return x.(int) / y.(int)
   418  		case int8:
   419  			return x.(int8) / y.(int8)
   420  		case int16:
   421  			return x.(int16) / y.(int16)
   422  		case int32:
   423  			return x.(int32) / y.(int32)
   424  		case int64:
   425  			return x.(int64) / y.(int64)
   426  		case uint:
   427  			return x.(uint) / y.(uint)
   428  		case uint8:
   429  			return x.(uint8) / y.(uint8)
   430  		case uint16:
   431  			return x.(uint16) / y.(uint16)
   432  		case uint32:
   433  			return x.(uint32) / y.(uint32)
   434  		case uint64:
   435  			return x.(uint64) / y.(uint64)
   436  		case uintptr:
   437  			return x.(uintptr) / y.(uintptr)
   438  		case float32:
   439  			return x.(float32) / y.(float32)
   440  		case float64:
   441  			return x.(float64) / y.(float64)
   442  		case complex64:
   443  			return x.(complex64) / y.(complex64)
   444  		case complex128:
   445  			return x.(complex128) / y.(complex128)
   446  		}
   447  
   448  	case token.REM:
   449  		switch x.(type) {
   450  		case int:
   451  			return x.(int) % y.(int)
   452  		case int8:
   453  			return x.(int8) % y.(int8)
   454  		case int16:
   455  			return x.(int16) % y.(int16)
   456  		case int32:
   457  			return x.(int32) % y.(int32)
   458  		case int64:
   459  			return x.(int64) % y.(int64)
   460  		case uint:
   461  			return x.(uint) % y.(uint)
   462  		case uint8:
   463  			return x.(uint8) % y.(uint8)
   464  		case uint16:
   465  			return x.(uint16) % y.(uint16)
   466  		case uint32:
   467  			return x.(uint32) % y.(uint32)
   468  		case uint64:
   469  			return x.(uint64) % y.(uint64)
   470  		case uintptr:
   471  			return x.(uintptr) % y.(uintptr)
   472  		}
   473  
   474  	case token.AND:
   475  		switch x.(type) {
   476  		case int:
   477  			return x.(int) & y.(int)
   478  		case int8:
   479  			return x.(int8) & y.(int8)
   480  		case int16:
   481  			return x.(int16) & y.(int16)
   482  		case int32:
   483  			return x.(int32) & y.(int32)
   484  		case int64:
   485  			return x.(int64) & y.(int64)
   486  		case uint:
   487  			return x.(uint) & y.(uint)
   488  		case uint8:
   489  			return x.(uint8) & y.(uint8)
   490  		case uint16:
   491  			return x.(uint16) & y.(uint16)
   492  		case uint32:
   493  			return x.(uint32) & y.(uint32)
   494  		case uint64:
   495  			return x.(uint64) & y.(uint64)
   496  		case uintptr:
   497  			return x.(uintptr) & y.(uintptr)
   498  		}
   499  
   500  	case token.OR:
   501  		switch x.(type) {
   502  		case int:
   503  			return x.(int) | y.(int)
   504  		case int8:
   505  			return x.(int8) | y.(int8)
   506  		case int16:
   507  			return x.(int16) | y.(int16)
   508  		case int32:
   509  			return x.(int32) | y.(int32)
   510  		case int64:
   511  			return x.(int64) | y.(int64)
   512  		case uint:
   513  			return x.(uint) | y.(uint)
   514  		case uint8:
   515  			return x.(uint8) | y.(uint8)
   516  		case uint16:
   517  			return x.(uint16) | y.(uint16)
   518  		case uint32:
   519  			return x.(uint32) | y.(uint32)
   520  		case uint64:
   521  			return x.(uint64) | y.(uint64)
   522  		case uintptr:
   523  			return x.(uintptr) | y.(uintptr)
   524  		}
   525  
   526  	case token.XOR:
   527  		switch x.(type) {
   528  		case int:
   529  			return x.(int) ^ y.(int)
   530  		case int8:
   531  			return x.(int8) ^ y.(int8)
   532  		case int16:
   533  			return x.(int16) ^ y.(int16)
   534  		case int32:
   535  			return x.(int32) ^ y.(int32)
   536  		case int64:
   537  			return x.(int64) ^ y.(int64)
   538  		case uint:
   539  			return x.(uint) ^ y.(uint)
   540  		case uint8:
   541  			return x.(uint8) ^ y.(uint8)
   542  		case uint16:
   543  			return x.(uint16) ^ y.(uint16)
   544  		case uint32:
   545  			return x.(uint32) ^ y.(uint32)
   546  		case uint64:
   547  			return x.(uint64) ^ y.(uint64)
   548  		case uintptr:
   549  			return x.(uintptr) ^ y.(uintptr)
   550  		}
   551  
   552  	case token.AND_NOT:
   553  		switch x.(type) {
   554  		case int:
   555  			return x.(int) &^ y.(int)
   556  		case int8:
   557  			return x.(int8) &^ y.(int8)
   558  		case int16:
   559  			return x.(int16) &^ y.(int16)
   560  		case int32:
   561  			return x.(int32) &^ y.(int32)
   562  		case int64:
   563  			return x.(int64) &^ y.(int64)
   564  		case uint:
   565  			return x.(uint) &^ y.(uint)
   566  		case uint8:
   567  			return x.(uint8) &^ y.(uint8)
   568  		case uint16:
   569  			return x.(uint16) &^ y.(uint16)
   570  		case uint32:
   571  			return x.(uint32) &^ y.(uint32)
   572  		case uint64:
   573  			return x.(uint64) &^ y.(uint64)
   574  		case uintptr:
   575  			return x.(uintptr) &^ y.(uintptr)
   576  		}
   577  
   578  	case token.SHL:
   579  		y := asUint64(y)
   580  		switch x.(type) {
   581  		case int:
   582  			return x.(int) << y
   583  		case int8:
   584  			return x.(int8) << y
   585  		case int16:
   586  			return x.(int16) << y
   587  		case int32:
   588  			return x.(int32) << y
   589  		case int64:
   590  			return x.(int64) << y
   591  		case uint:
   592  			return x.(uint) << y
   593  		case uint8:
   594  			return x.(uint8) << y
   595  		case uint16:
   596  			return x.(uint16) << y
   597  		case uint32:
   598  			return x.(uint32) << y
   599  		case uint64:
   600  			return x.(uint64) << y
   601  		case uintptr:
   602  			return x.(uintptr) << y
   603  		}
   604  
   605  	case token.SHR:
   606  		y := asUint64(y)
   607  		switch x.(type) {
   608  		case int:
   609  			return x.(int) >> y
   610  		case int8:
   611  			return x.(int8) >> y
   612  		case int16:
   613  			return x.(int16) >> y
   614  		case int32:
   615  			return x.(int32) >> y
   616  		case int64:
   617  			return x.(int64) >> y
   618  		case uint:
   619  			return x.(uint) >> y
   620  		case uint8:
   621  			return x.(uint8) >> y
   622  		case uint16:
   623  			return x.(uint16) >> y
   624  		case uint32:
   625  			return x.(uint32) >> y
   626  		case uint64:
   627  			return x.(uint64) >> y
   628  		case uintptr:
   629  			return x.(uintptr) >> y
   630  		}
   631  
   632  	case token.LSS:
   633  		switch x.(type) {
   634  		case int:
   635  			return x.(int) < y.(int)
   636  		case int8:
   637  			return x.(int8) < y.(int8)
   638  		case int16:
   639  			return x.(int16) < y.(int16)
   640  		case int32:
   641  			return x.(int32) < y.(int32)
   642  		case int64:
   643  			return x.(int64) < y.(int64)
   644  		case uint:
   645  			return x.(uint) < y.(uint)
   646  		case uint8:
   647  			return x.(uint8) < y.(uint8)
   648  		case uint16:
   649  			return x.(uint16) < y.(uint16)
   650  		case uint32:
   651  			return x.(uint32) < y.(uint32)
   652  		case uint64:
   653  			return x.(uint64) < y.(uint64)
   654  		case uintptr:
   655  			return x.(uintptr) < y.(uintptr)
   656  		case float32:
   657  			return x.(float32) < y.(float32)
   658  		case float64:
   659  			return x.(float64) < y.(float64)
   660  		case string:
   661  			return x.(string) < y.(string)
   662  		}
   663  
   664  	case token.LEQ:
   665  		switch x.(type) {
   666  		case int:
   667  			return x.(int) <= y.(int)
   668  		case int8:
   669  			return x.(int8) <= y.(int8)
   670  		case int16:
   671  			return x.(int16) <= y.(int16)
   672  		case int32:
   673  			return x.(int32) <= y.(int32)
   674  		case int64:
   675  			return x.(int64) <= y.(int64)
   676  		case uint:
   677  			return x.(uint) <= y.(uint)
   678  		case uint8:
   679  			return x.(uint8) <= y.(uint8)
   680  		case uint16:
   681  			return x.(uint16) <= y.(uint16)
   682  		case uint32:
   683  			return x.(uint32) <= y.(uint32)
   684  		case uint64:
   685  			return x.(uint64) <= y.(uint64)
   686  		case uintptr:
   687  			return x.(uintptr) <= y.(uintptr)
   688  		case float32:
   689  			return x.(float32) <= y.(float32)
   690  		case float64:
   691  			return x.(float64) <= y.(float64)
   692  		case string:
   693  			return x.(string) <= y.(string)
   694  		}
   695  
   696  	case token.EQL:
   697  		return eqnil(t, x, y)
   698  
   699  	case token.NEQ:
   700  		return !eqnil(t, x, y)
   701  
   702  	case token.GTR:
   703  		switch x.(type) {
   704  		case int:
   705  			return x.(int) > y.(int)
   706  		case int8:
   707  			return x.(int8) > y.(int8)
   708  		case int16:
   709  			return x.(int16) > y.(int16)
   710  		case int32:
   711  			return x.(int32) > y.(int32)
   712  		case int64:
   713  			return x.(int64) > y.(int64)
   714  		case uint:
   715  			return x.(uint) > y.(uint)
   716  		case uint8:
   717  			return x.(uint8) > y.(uint8)
   718  		case uint16:
   719  			return x.(uint16) > y.(uint16)
   720  		case uint32:
   721  			return x.(uint32) > y.(uint32)
   722  		case uint64:
   723  			return x.(uint64) > y.(uint64)
   724  		case uintptr:
   725  			return x.(uintptr) > y.(uintptr)
   726  		case float32:
   727  			return x.(float32) > y.(float32)
   728  		case float64:
   729  			return x.(float64) > y.(float64)
   730  		case string:
   731  			return x.(string) > y.(string)
   732  		}
   733  
   734  	case token.GEQ:
   735  		switch x.(type) {
   736  		case int:
   737  			return x.(int) >= y.(int)
   738  		case int8:
   739  			return x.(int8) >= y.(int8)
   740  		case int16:
   741  			return x.(int16) >= y.(int16)
   742  		case int32:
   743  			return x.(int32) >= y.(int32)
   744  		case int64:
   745  			return x.(int64) >= y.(int64)
   746  		case uint:
   747  			return x.(uint) >= y.(uint)
   748  		case uint8:
   749  			return x.(uint8) >= y.(uint8)
   750  		case uint16:
   751  			return x.(uint16) >= y.(uint16)
   752  		case uint32:
   753  			return x.(uint32) >= y.(uint32)
   754  		case uint64:
   755  			return x.(uint64) >= y.(uint64)
   756  		case uintptr:
   757  			return x.(uintptr) >= y.(uintptr)
   758  		case float32:
   759  			return x.(float32) >= y.(float32)
   760  		case float64:
   761  			return x.(float64) >= y.(float64)
   762  		case string:
   763  			return x.(string) >= y.(string)
   764  		}
   765  	}
   766  	panic(fmt.Sprintf("invalid binary op: %T %s %T", x, op, y))
   767  }
   768  
   769  // eqnil returns the comparison x == y using the equivalence relation
   770  // appropriate for type t.
   771  // If t is a reference type, at most one of x or y may be a nil value
   772  // of that type.
   773  //
   774  func eqnil(t types.Type, x, y value) bool {
   775  	switch t.Underlying().(type) {
   776  	case *types.Map, *types.Signature, *types.Slice:
   777  		// Since these types don't support comparison,
   778  		// one of the operands must be a literal nil.
   779  		switch x := x.(type) {
   780  		case *hashmap:
   781  			return (x != nil) == (y.(*hashmap) != nil)
   782  		case map[value]value:
   783  			return (x != nil) == (y.(map[value]value) != nil)
   784  		case *ssa.Function:
   785  			switch y := y.(type) {
   786  			case *ssa.Function:
   787  				return (x != nil) == (y != nil)
   788  			case *closure:
   789  				return true
   790  			}
   791  		case *closure:
   792  			return (x != nil) == (y.(*ssa.Function) != nil)
   793  		case []value:
   794  			return (x != nil) == (y.([]value) != nil)
   795  		}
   796  		panic(fmt.Sprintf("eqnil(%s): illegal dynamic type: %T", t, x))
   797  	}
   798  
   799  	return equals(t, x, y)
   800  }
   801  
   802  func unop(instr *ssa.UnOp, x value) value {
   803  	switch instr.Op {
   804  	case token.ARROW: // receive
   805  		v, ok := <-x.(chan value)
   806  		if !ok {
   807  			v = zero(instr.X.Type().Underlying().(*types.Chan).Elem())
   808  		}
   809  		if instr.CommaOk {
   810  			v = tuple{v, ok}
   811  		}
   812  		return v
   813  	case token.SUB:
   814  		switch x := x.(type) {
   815  		case int:
   816  			return -x
   817  		case int8:
   818  			return -x
   819  		case int16:
   820  			return -x
   821  		case int32:
   822  			return -x
   823  		case int64:
   824  			return -x
   825  		case uint:
   826  			return -x
   827  		case uint8:
   828  			return -x
   829  		case uint16:
   830  			return -x
   831  		case uint32:
   832  			return -x
   833  		case uint64:
   834  			return -x
   835  		case uintptr:
   836  			return -x
   837  		case float32:
   838  			return -x
   839  		case float64:
   840  			return -x
   841  		case complex64:
   842  			return -x
   843  		case complex128:
   844  			return -x
   845  		}
   846  	case token.MUL:
   847  		return load(deref(instr.X.Type()), x.(*value))
   848  	case token.NOT:
   849  		return !x.(bool)
   850  	case token.XOR:
   851  		switch x := x.(type) {
   852  		case int:
   853  			return ^x
   854  		case int8:
   855  			return ^x
   856  		case int16:
   857  			return ^x
   858  		case int32:
   859  			return ^x
   860  		case int64:
   861  			return ^x
   862  		case uint:
   863  			return ^x
   864  		case uint8:
   865  			return ^x
   866  		case uint16:
   867  			return ^x
   868  		case uint32:
   869  			return ^x
   870  		case uint64:
   871  			return ^x
   872  		case uintptr:
   873  			return ^x
   874  		}
   875  	}
   876  	panic(fmt.Sprintf("invalid unary op %s %T", instr.Op, x))
   877  }
   878  
   879  // typeAssert checks whether dynamic type of itf is instr.AssertedType.
   880  // It returns the extracted value on success, and panics on failure,
   881  // unless instr.CommaOk, in which case it always returns a "value,ok" tuple.
   882  //
   883  func typeAssert(i *interpreter, instr *ssa.TypeAssert, itf iface) value {
   884  	var v value
   885  	err := ""
   886  	if itf.t == nil {
   887  		err = fmt.Sprintf("interface conversion: interface is nil, not %s", instr.AssertedType)
   888  
   889  	} else if idst, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
   890  		v = itf
   891  		err = checkInterface(i, idst, itf)
   892  
   893  	} else if types.Identical(itf.t, instr.AssertedType) {
   894  		v = itf.v // extract value
   895  
   896  	} else {
   897  		err = fmt.Sprintf("interface conversion: interface is %s, not %s", itf.t, instr.AssertedType)
   898  	}
   899  
   900  	if err != "" {
   901  		if !instr.CommaOk {
   902  			panic(err)
   903  		}
   904  		return tuple{zero(instr.AssertedType), false}
   905  	}
   906  	if instr.CommaOk {
   907  		return tuple{v, true}
   908  	}
   909  	return v
   910  }
   911  
   912  // If CapturedOutput is non-nil, all writes by the interpreted program
   913  // to file descriptors 1 and 2 will also be written to CapturedOutput.
   914  //
   915  // (The $GOROOT/test system requires that the test be considered a
   916  // failure if "BUG" appears in the combined stdout/stderr output, even
   917  // if it exits zero.  This is a global variable shared by all
   918  // interpreters in the same process.)
   919  //
   920  var CapturedOutput *bytes.Buffer
   921  var capturedOutputMu sync.Mutex
   922  
   923  // write writes bytes b to the target program's standard output.
   924  // The print/println built-ins and the write() system call funnel
   925  // through here so they can be captured by the test driver.
   926  func print(b []byte) (int, error) {
   927  	if CapturedOutput != nil {
   928  		capturedOutputMu.Lock()
   929  		CapturedOutput.Write(b) // ignore errors
   930  		capturedOutputMu.Unlock()
   931  	}
   932  	return os.Stdout.Write(b)
   933  }
   934  
   935  // callBuiltin interprets a call to builtin fn with arguments args,
   936  // returning its result.
   937  func callBuiltin(caller *frame, callpos token.Pos, fn *ssa.Builtin, args []value) value {
   938  	switch fn.Name() {
   939  	case "append":
   940  		if len(args) == 1 {
   941  			return args[0]
   942  		}
   943  		if s, ok := args[1].(string); ok {
   944  			// append([]byte, ...string) []byte
   945  			arg0 := args[0].([]value)
   946  			for i := 0; i < len(s); i++ {
   947  				arg0 = append(arg0, s[i])
   948  			}
   949  			return arg0
   950  		}
   951  		// append([]T, ...[]T) []T
   952  		return append(args[0].([]value), args[1].([]value)...)
   953  
   954  	case "copy": // copy([]T, []T) int or copy([]byte, string) int
   955  		src := args[1]
   956  		if _, ok := src.(string); ok {
   957  			params := fn.Type().(*types.Signature).Params()
   958  			src = conv(params.At(0).Type(), params.At(1).Type(), src)
   959  		}
   960  		return copy(args[0].([]value), src.([]value))
   961  
   962  	case "close": // close(chan T)
   963  		close(args[0].(chan value))
   964  		return nil
   965  
   966  	case "delete": // delete(map[K]value, K)
   967  		switch m := args[0].(type) {
   968  		case map[value]value:
   969  			delete(m, args[1])
   970  		case *hashmap:
   971  			m.delete(args[1].(hashable))
   972  		default:
   973  			panic(fmt.Sprintf("illegal map type: %T", m))
   974  		}
   975  		return nil
   976  
   977  	case "print", "println": // print(any, ...)
   978  		ln := fn.Name() == "println"
   979  		var buf bytes.Buffer
   980  		for i, arg := range args {
   981  			if i > 0 && ln {
   982  				buf.WriteRune(' ')
   983  			}
   984  			buf.WriteString(toString(arg))
   985  		}
   986  		if ln {
   987  			buf.WriteRune('\n')
   988  		}
   989  		print(buf.Bytes())
   990  		return nil
   991  
   992  	case "len":
   993  		switch x := args[0].(type) {
   994  		case string:
   995  			return len(x)
   996  		case array:
   997  			return len(x)
   998  		case *value:
   999  			return len((*x).(array))
  1000  		case []value:
  1001  			return len(x)
  1002  		case map[value]value:
  1003  			return len(x)
  1004  		case *hashmap:
  1005  			return x.len()
  1006  		case chan value:
  1007  			return len(x)
  1008  		default:
  1009  			panic(fmt.Sprintf("len: illegal operand: %T", x))
  1010  		}
  1011  
  1012  	case "cap":
  1013  		switch x := args[0].(type) {
  1014  		case array:
  1015  			return cap(x)
  1016  		case *value:
  1017  			return cap((*x).(array))
  1018  		case []value:
  1019  			return cap(x)
  1020  		case chan value:
  1021  			return cap(x)
  1022  		default:
  1023  			panic(fmt.Sprintf("cap: illegal operand: %T", x))
  1024  		}
  1025  
  1026  	case "real":
  1027  		switch c := args[0].(type) {
  1028  		case complex64:
  1029  			return real(c)
  1030  		case complex128:
  1031  			return real(c)
  1032  		default:
  1033  			panic(fmt.Sprintf("real: illegal operand: %T", c))
  1034  		}
  1035  
  1036  	case "imag":
  1037  		switch c := args[0].(type) {
  1038  		case complex64:
  1039  			return imag(c)
  1040  		case complex128:
  1041  			return imag(c)
  1042  		default:
  1043  			panic(fmt.Sprintf("imag: illegal operand: %T", c))
  1044  		}
  1045  
  1046  	case "complex":
  1047  		switch f := args[0].(type) {
  1048  		case float32:
  1049  			return complex(f, args[1].(float32))
  1050  		case float64:
  1051  			return complex(f, args[1].(float64))
  1052  		default:
  1053  			panic(fmt.Sprintf("complex: illegal operand: %T", f))
  1054  		}
  1055  
  1056  	case "panic":
  1057  		// ssa.Panic handles most cases; this is only for "go
  1058  		// panic" or "defer panic".
  1059  		panic(targetPanic{args[0]})
  1060  
  1061  	case "recover":
  1062  		return doRecover(caller)
  1063  
  1064  	case "ssa:wrapnilchk":
  1065  		recv := args[0]
  1066  		if recv.(*value) == nil {
  1067  			recvType := args[1]
  1068  			methodName := args[2]
  1069  			panic(fmt.Sprintf("value method (%s).%s called using nil *%s pointer",
  1070  				recvType, methodName, recvType))
  1071  		}
  1072  		return recv
  1073  	}
  1074  
  1075  	panic("unknown built-in: " + fn.Name())
  1076  }
  1077  
  1078  func rangeIter(x value, t types.Type) iter {
  1079  	switch x := x.(type) {
  1080  	case map[value]value:
  1081  		return &mapIter{iter: reflect.ValueOf(x).MapRange()}
  1082  	case *hashmap:
  1083  		return &hashmapIter{iter: reflect.ValueOf(x.entries()).MapRange()}
  1084  	case string:
  1085  		return &stringIter{Reader: strings.NewReader(x)}
  1086  	}
  1087  	panic(fmt.Sprintf("cannot range over %T", x))
  1088  }
  1089  
  1090  // widen widens a basic typed value x to the widest type of its
  1091  // category, one of:
  1092  //   bool, int64, uint64, float64, complex128, string.
  1093  // This is inefficient but reduces the size of the cross-product of
  1094  // cases we have to consider.
  1095  //
  1096  func widen(x value) value {
  1097  	switch y := x.(type) {
  1098  	case bool, int64, uint64, float64, complex128, string, unsafe.Pointer:
  1099  		return x
  1100  	case int:
  1101  		return int64(y)
  1102  	case int8:
  1103  		return int64(y)
  1104  	case int16:
  1105  		return int64(y)
  1106  	case int32:
  1107  		return int64(y)
  1108  	case uint:
  1109  		return uint64(y)
  1110  	case uint8:
  1111  		return uint64(y)
  1112  	case uint16:
  1113  		return uint64(y)
  1114  	case uint32:
  1115  		return uint64(y)
  1116  	case uintptr:
  1117  		return uint64(y)
  1118  	case float32:
  1119  		return float64(y)
  1120  	case complex64:
  1121  		return complex128(y)
  1122  	}
  1123  	panic(fmt.Sprintf("cannot widen %T", x))
  1124  }
  1125  
  1126  // conv converts the value x of type t_src to type t_dst and returns
  1127  // the result.
  1128  // Possible cases are described with the ssa.Convert operator.
  1129  //
  1130  func conv(t_dst, t_src types.Type, x value) value {
  1131  	ut_src := t_src.Underlying()
  1132  	ut_dst := t_dst.Underlying()
  1133  
  1134  	// Destination type is not an "untyped" type.
  1135  	if b, ok := ut_dst.(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
  1136  		panic("oops: conversion to 'untyped' type: " + b.String())
  1137  	}
  1138  
  1139  	// Nor is it an interface type.
  1140  	if _, ok := ut_dst.(*types.Interface); ok {
  1141  		if _, ok := ut_src.(*types.Interface); ok {
  1142  			panic("oops: Convert should be ChangeInterface")
  1143  		} else {
  1144  			panic("oops: Convert should be MakeInterface")
  1145  		}
  1146  	}
  1147  
  1148  	// Remaining conversions:
  1149  	//    + untyped string/number/bool constant to a specific
  1150  	//      representation.
  1151  	//    + conversions between non-complex numeric types.
  1152  	//    + conversions between complex numeric types.
  1153  	//    + integer/[]byte/[]rune -> string.
  1154  	//    + string -> []byte/[]rune.
  1155  	//
  1156  	// All are treated the same: first we extract the value to the
  1157  	// widest representation (int64, uint64, float64, complex128,
  1158  	// or string), then we convert it to the desired type.
  1159  
  1160  	switch ut_src := ut_src.(type) {
  1161  	case *types.Pointer:
  1162  		switch ut_dst := ut_dst.(type) {
  1163  		case *types.Basic:
  1164  			// *value to unsafe.Pointer?
  1165  			if ut_dst.Kind() == types.UnsafePointer {
  1166  				return unsafe.Pointer(x.(*value))
  1167  			}
  1168  		}
  1169  
  1170  	case *types.Slice:
  1171  		// []byte or []rune -> string
  1172  		// TODO(adonovan): fix: type B byte; conv([]B -> string).
  1173  		switch ut_src.Elem().(*types.Basic).Kind() {
  1174  		case types.Byte:
  1175  			x := x.([]value)
  1176  			b := make([]byte, 0, len(x))
  1177  			for i := range x {
  1178  				b = append(b, x[i].(byte))
  1179  			}
  1180  			return string(b)
  1181  
  1182  		case types.Rune:
  1183  			x := x.([]value)
  1184  			r := make([]rune, 0, len(x))
  1185  			for i := range x {
  1186  				r = append(r, x[i].(rune))
  1187  			}
  1188  			return string(r)
  1189  		}
  1190  
  1191  	case *types.Basic:
  1192  		x = widen(x)
  1193  
  1194  		// integer -> string?
  1195  		// TODO(adonovan): fix: test integer -> named alias of string.
  1196  		if ut_src.Info()&types.IsInteger != 0 {
  1197  			if ut_dst, ok := ut_dst.(*types.Basic); ok && ut_dst.Kind() == types.String {
  1198  				return fmt.Sprintf("%c", x)
  1199  			}
  1200  		}
  1201  
  1202  		// string -> []rune, []byte or string?
  1203  		if s, ok := x.(string); ok {
  1204  			switch ut_dst := ut_dst.(type) {
  1205  			case *types.Slice:
  1206  				var res []value
  1207  				// TODO(adonovan): fix: test named alias of rune, byte.
  1208  				switch ut_dst.Elem().(*types.Basic).Kind() {
  1209  				case types.Rune:
  1210  					for _, r := range []rune(s) {
  1211  						res = append(res, r)
  1212  					}
  1213  					return res
  1214  				case types.Byte:
  1215  					for _, b := range []byte(s) {
  1216  						res = append(res, b)
  1217  					}
  1218  					return res
  1219  				}
  1220  			case *types.Basic:
  1221  				if ut_dst.Kind() == types.String {
  1222  					return x.(string)
  1223  				}
  1224  			}
  1225  			break // fail: no other conversions for string
  1226  		}
  1227  
  1228  		// unsafe.Pointer -> *value
  1229  		if ut_src.Kind() == types.UnsafePointer {
  1230  			// TODO(adonovan): this is wrong and cannot
  1231  			// really be fixed with the current design.
  1232  			//
  1233  			// return (*value)(x.(unsafe.Pointer))
  1234  			// creates a new pointer of a different
  1235  			// type but the underlying interface value
  1236  			// knows its "true" type and so cannot be
  1237  			// meaningfully used through the new pointer.
  1238  			//
  1239  			// To make this work, the interpreter needs to
  1240  			// simulate the memory layout of a real
  1241  			// compiled implementation.
  1242  			//
  1243  			// To at least preserve type-safety, we'll
  1244  			// just return the zero value of the
  1245  			// destination type.
  1246  			return zero(t_dst)
  1247  		}
  1248  
  1249  		// Conversions between complex numeric types?
  1250  		if ut_src.Info()&types.IsComplex != 0 {
  1251  			switch ut_dst.(*types.Basic).Kind() {
  1252  			case types.Complex64:
  1253  				return complex64(x.(complex128))
  1254  			case types.Complex128:
  1255  				return x.(complex128)
  1256  			}
  1257  			break // fail: no other conversions for complex
  1258  		}
  1259  
  1260  		// Conversions between non-complex numeric types?
  1261  		if ut_src.Info()&types.IsNumeric != 0 {
  1262  			kind := ut_dst.(*types.Basic).Kind()
  1263  			switch x := x.(type) {
  1264  			case int64: // signed integer -> numeric?
  1265  				switch kind {
  1266  				case types.Int:
  1267  					return int(x)
  1268  				case types.Int8:
  1269  					return int8(x)
  1270  				case types.Int16:
  1271  					return int16(x)
  1272  				case types.Int32:
  1273  					return int32(x)
  1274  				case types.Int64:
  1275  					return int64(x)
  1276  				case types.Uint:
  1277  					return uint(x)
  1278  				case types.Uint8:
  1279  					return uint8(x)
  1280  				case types.Uint16:
  1281  					return uint16(x)
  1282  				case types.Uint32:
  1283  					return uint32(x)
  1284  				case types.Uint64:
  1285  					return uint64(x)
  1286  				case types.Uintptr:
  1287  					return uintptr(x)
  1288  				case types.Float32:
  1289  					return float32(x)
  1290  				case types.Float64:
  1291  					return float64(x)
  1292  				}
  1293  
  1294  			case uint64: // unsigned integer -> numeric?
  1295  				switch kind {
  1296  				case types.Int:
  1297  					return int(x)
  1298  				case types.Int8:
  1299  					return int8(x)
  1300  				case types.Int16:
  1301  					return int16(x)
  1302  				case types.Int32:
  1303  					return int32(x)
  1304  				case types.Int64:
  1305  					return int64(x)
  1306  				case types.Uint:
  1307  					return uint(x)
  1308  				case types.Uint8:
  1309  					return uint8(x)
  1310  				case types.Uint16:
  1311  					return uint16(x)
  1312  				case types.Uint32:
  1313  					return uint32(x)
  1314  				case types.Uint64:
  1315  					return uint64(x)
  1316  				case types.Uintptr:
  1317  					return uintptr(x)
  1318  				case types.Float32:
  1319  					return float32(x)
  1320  				case types.Float64:
  1321  					return float64(x)
  1322  				}
  1323  
  1324  			case float64: // floating point -> numeric?
  1325  				switch kind {
  1326  				case types.Int:
  1327  					return int(x)
  1328  				case types.Int8:
  1329  					return int8(x)
  1330  				case types.Int16:
  1331  					return int16(x)
  1332  				case types.Int32:
  1333  					return int32(x)
  1334  				case types.Int64:
  1335  					return int64(x)
  1336  				case types.Uint:
  1337  					return uint(x)
  1338  				case types.Uint8:
  1339  					return uint8(x)
  1340  				case types.Uint16:
  1341  					return uint16(x)
  1342  				case types.Uint32:
  1343  					return uint32(x)
  1344  				case types.Uint64:
  1345  					return uint64(x)
  1346  				case types.Uintptr:
  1347  					return uintptr(x)
  1348  				case types.Float32:
  1349  					return float32(x)
  1350  				case types.Float64:
  1351  					return float64(x)
  1352  				}
  1353  			}
  1354  		}
  1355  	}
  1356  
  1357  	panic(fmt.Sprintf("unsupported conversion: %s  -> %s, dynamic type %T", t_src, t_dst, x))
  1358  }
  1359  
  1360  // checkInterface checks that the method set of x implements the
  1361  // interface itype.
  1362  // On success it returns "", on failure, an error message.
  1363  //
  1364  func checkInterface(i *interpreter, itype *types.Interface, x iface) string {
  1365  	if meth, _ := types.MissingMethod(x.t, itype, true); meth != nil {
  1366  		return fmt.Sprintf("interface conversion: %v is not %v: missing method %s",
  1367  			x.t, itype, meth.Name())
  1368  	}
  1369  	return "" // ok
  1370  }