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