...

Source file src/golang.org/x/tools/go/ssa/interp/ops.go

Documentation: golang.org/x/tools/go/ssa/interp

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

View as plain text