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