github.com/goplus/igop@v0.25.0/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 igop
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/constant"
    11  	"go/token"
    12  	"go/types"
    13  	"reflect"
    14  	"unsafe"
    15  
    16  	"golang.org/x/tools/go/ssa"
    17  )
    18  
    19  // If the target program panics, the interpreter panics with this type.
    20  type PanicError struct {
    21  	stack []byte
    22  	Value value
    23  }
    24  
    25  func (p PanicError) Error() string {
    26  	var buf bytes.Buffer
    27  	writeany(&buf, p.Value)
    28  	return buf.String()
    29  }
    30  
    31  func (p PanicError) Stack() []byte {
    32  	return p.stack
    33  }
    34  
    35  // If the target program calls exit, the interpreter panics with this type.
    36  type exitPanic int
    37  
    38  type goexitPanic int
    39  
    40  func xtypeValue(c *ssa.Const, kind types.BasicKind) value {
    41  	switch kind {
    42  	case types.Bool, types.UntypedBool:
    43  		return constant.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() == constant.String {
    79  			return constant.StringVal(c.Value)
    80  		}
    81  		return string(rune(c.Int64()))
    82  	case types.UnsafePointer:
    83  		return unsafe.Pointer(uintptr(c.Uint64()))
    84  	}
    85  	panic("unreachable")
    86  }
    87  
    88  // constValue returns the value of the constant with the
    89  // dynamic type tag appropriate for c.Type().
    90  func constToValue(i *Interp, c *ssa.Const) value {
    91  	typ := c.Type()
    92  	if c.Value == nil {
    93  		if xtype, ok := typ.(*types.Basic); ok && xtype.Kind() == types.UntypedNil {
    94  			return nil
    95  		}
    96  		return reflect.Zero(i.preToType(typ)).Interface()
    97  	}
    98  	if xtype, ok := typ.(*types.Basic); ok {
    99  		return xtypeValue(c, xtype.Kind())
   100  	} else if xtype, ok := typ.Underlying().(*types.Basic); ok {
   101  		v := xtypeValue(c, xtype.Kind())
   102  		nv := reflect.New(i.preToType(typ)).Elem()
   103  		SetValue(nv, reflect.ValueOf(v))
   104  		return nv.Interface()
   105  	}
   106  	panic(fmt.Sprintf("unparser constValue: %s", c))
   107  }
   108  
   109  func globalToValue(i *Interp, key *ssa.Global) (interface{}, bool) {
   110  	if key.Pkg != nil {
   111  		pkgpath := key.Pkg.Pkg.Path()
   112  		if pkg, ok := i.installed(pkgpath); ok {
   113  			if ext, ok := pkg.Vars[key.Name()]; ok {
   114  				return ext.Interface(), true
   115  			}
   116  		}
   117  	}
   118  	if v, ok := i.globals[key.String()]; ok {
   119  		return v, true
   120  	}
   121  	return nil, false
   122  }
   123  
   124  func staticToValue(i *Interp, value ssa.Value) (interface{}, bool) {
   125  	switch v := value.(type) {
   126  	case *ssa.Global:
   127  		return globalToValue(i, v)
   128  	case *ssa.Const:
   129  		return constToValue(i, v), true
   130  	}
   131  	return nil, false
   132  }
   133  
   134  // asInt converts x, which must be an integer, to an int suitable for
   135  // use as a slice or array index or operand to make().
   136  func asInt(x value) int {
   137  	switch x := x.(type) {
   138  	case int:
   139  		return x
   140  	case int8:
   141  		return int(x)
   142  	case int16:
   143  		return int(x)
   144  	case int32:
   145  		return int(x)
   146  	case int64:
   147  		return int(x)
   148  	case uint:
   149  		return int(x)
   150  	case uint8:
   151  		return int(x)
   152  	case uint16:
   153  		return int(x)
   154  	case uint32:
   155  		return int(x)
   156  	case uint64:
   157  		return int(x)
   158  	case uintptr:
   159  		return int(x)
   160  	default:
   161  		v := reflect.ValueOf(x)
   162  		switch v.Kind() {
   163  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   164  			return int(v.Int())
   165  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   166  			return int(v.Uint())
   167  		}
   168  	}
   169  	panic(fmt.Sprintf("cannot convert %T to int", x))
   170  }
   171  
   172  // asUint64 converts x, which must be an unsigned integer, to a uint64
   173  // suitable for use as a bitwise shift count.
   174  func asUint64(x value) uint64 {
   175  	switch x := x.(type) {
   176  	case int:
   177  		if x >= 0 {
   178  			return uint64(x)
   179  		}
   180  	case int8:
   181  		if x >= 0 {
   182  			return uint64(x)
   183  		}
   184  	case int16:
   185  		if x >= 0 {
   186  			return uint64(x)
   187  		}
   188  	case int32:
   189  		if x >= 0 {
   190  			return uint64(x)
   191  		}
   192  	case int64:
   193  		if x >= 0 {
   194  			return uint64(x)
   195  		}
   196  	case uint:
   197  		return uint64(x)
   198  	case uint8:
   199  		return uint64(x)
   200  	case uint16:
   201  		return uint64(x)
   202  	case uint32:
   203  		return uint64(x)
   204  	case uint64:
   205  		return x
   206  	case uintptr:
   207  		return uint64(x)
   208  	default:
   209  		v := reflect.ValueOf(x)
   210  		switch v.Kind() {
   211  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   212  			return v.Uint()
   213  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   214  			x := v.Int()
   215  			if x >= 0 {
   216  				return uint64(x)
   217  			}
   218  		default:
   219  			panic(fmt.Sprintf("cannot convert %T to uint64", x))
   220  		}
   221  	}
   222  	panic(runtimeError("negative shift amount"))
   223  }
   224  
   225  // slice returns x[lo:hi:max].  Any of lo, hi and max may be nil.
   226  func slice(fr *frame, instr *ssa.Slice, makesliceCheck bool, ix, ih, il, im register) reflect.Value {
   227  	// x := fr.get(instr.X)
   228  	x := fr.reg(ix)
   229  	var Len, Cap int
   230  	v := reflect.ValueOf(x)
   231  	// *array
   232  	if v.Kind() == reflect.Ptr {
   233  		v = v.Elem()
   234  	}
   235  	kind := v.Kind()
   236  	switch kind {
   237  	case reflect.String:
   238  		Len = v.Len()
   239  		Cap = Len
   240  	case reflect.Slice, reflect.Array:
   241  		Len = v.Len()
   242  		Cap = v.Cap()
   243  	}
   244  
   245  	lo := 0
   246  	hi := Len
   247  	max := Cap
   248  	var slice3 bool
   249  	if instr.Low != nil {
   250  		// lo = asInt(fr.get(instr.Low))
   251  		lo = asInt(fr.reg(il))
   252  	}
   253  	if instr.High != nil {
   254  		// hi = asInt(fr.get(instr.High))
   255  		hi = asInt(fr.reg(ih))
   256  	}
   257  	if instr.Max != nil {
   258  		// max = asInt(fr.get(instr.Max))
   259  		max = asInt(fr.reg(im))
   260  		slice3 = true
   261  	}
   262  
   263  	if makesliceCheck {
   264  		if hi < 0 {
   265  			panic(runtimeError("makeslice: len out of range"))
   266  		} else if hi > max {
   267  			panic(runtimeError("makeslice: cap out of range"))
   268  		}
   269  	} else {
   270  		if slice3 {
   271  			if max < 0 {
   272  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v]", max)))
   273  			} else if max > Cap {
   274  				if kind == reflect.Slice {
   275  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with capacity %v", max, Cap)))
   276  				} else {
   277  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with length %v", max, Cap)))
   278  				}
   279  			} else if hi < 0 {
   280  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:]", hi)))
   281  			} else if hi > max {
   282  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:%v]", hi, max)))
   283  			} else if lo < 0 {
   284  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v::]", lo)))
   285  			} else if lo > hi {
   286  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v:]", lo, hi)))
   287  			}
   288  		} else {
   289  			if hi < 0 {
   290  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v]", hi)))
   291  			} else if hi > Cap {
   292  				if kind == reflect.Slice {
   293  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with capacity %v", hi, Cap)))
   294  				} else {
   295  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with length %v", hi, Cap)))
   296  				}
   297  			} else if lo < 0 {
   298  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:]", lo)))
   299  			} else if lo > hi {
   300  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v]", lo, hi)))
   301  			}
   302  		}
   303  	}
   304  	switch kind {
   305  	case reflect.String:
   306  		// optimization x[len(x):], see $GOROOT/test/slicecap.go
   307  		if lo == hi {
   308  			return v.Slice(0, 0)
   309  		}
   310  		return v.Slice(lo, hi)
   311  	case reflect.Slice, reflect.Array:
   312  		return v.Slice3(lo, hi, max)
   313  	}
   314  	panic(fmt.Sprintf("slice: unexpected X type: %T", x))
   315  }
   316  
   317  func opADD(x, y value) value {
   318  	switch x.(type) {
   319  	case int:
   320  		return x.(int) + y.(int)
   321  	case int8:
   322  		return x.(int8) + y.(int8)
   323  	case int16:
   324  		return x.(int16) + y.(int16)
   325  	case int32:
   326  		return x.(int32) + y.(int32)
   327  	case int64:
   328  		return x.(int64) + y.(int64)
   329  	case uint:
   330  		return x.(uint) + y.(uint)
   331  	case uint8:
   332  		return x.(uint8) + y.(uint8)
   333  	case uint16:
   334  		return x.(uint16) + y.(uint16)
   335  	case uint32:
   336  		return x.(uint32) + y.(uint32)
   337  	case uint64:
   338  		return x.(uint64) + y.(uint64)
   339  	case uintptr:
   340  		return x.(uintptr) + y.(uintptr)
   341  	case float32:
   342  		return x.(float32) + y.(float32)
   343  	case float64:
   344  		return x.(float64) + y.(float64)
   345  	case complex64:
   346  		return x.(complex64) + y.(complex64)
   347  	case complex128:
   348  		return x.(complex128) + y.(complex128)
   349  	case string:
   350  		return x.(string) + y.(string)
   351  	default:
   352  		vx := reflect.ValueOf(x)
   353  		vy := reflect.ValueOf(y)
   354  		if kind := vx.Kind(); kind == vy.Kind() {
   355  			r := reflect.New(vx.Type()).Elem()
   356  			switch kind {
   357  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   358  				r.SetInt(vx.Int() + vy.Int())
   359  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   360  				r.SetUint(vx.Uint() + vy.Uint())
   361  			case reflect.Float32, reflect.Float64:
   362  				r.SetFloat(vx.Float() + vy.Float())
   363  			case reflect.Complex64, reflect.Complex128:
   364  				r.SetComplex(vx.Complex() + vy.Complex())
   365  			case reflect.String:
   366  				r.SetString(vx.String() + vy.String())
   367  			default:
   368  				goto failed
   369  			}
   370  			return r.Interface()
   371  		}
   372  	}
   373  failed:
   374  	panic(fmt.Sprintf("invalid binary op: %T + %T", x, y))
   375  }
   376  
   377  func opSUB(x, y value) value {
   378  	switch x.(type) {
   379  	case int:
   380  		return x.(int) - y.(int)
   381  	case int8:
   382  		return x.(int8) - y.(int8)
   383  	case int16:
   384  		return x.(int16) - y.(int16)
   385  	case int32:
   386  		return x.(int32) - y.(int32)
   387  	case int64:
   388  		return x.(int64) - y.(int64)
   389  	case uint:
   390  		return x.(uint) - y.(uint)
   391  	case uint8:
   392  		return x.(uint8) - y.(uint8)
   393  	case uint16:
   394  		return x.(uint16) - y.(uint16)
   395  	case uint32:
   396  		return x.(uint32) - y.(uint32)
   397  	case uint64:
   398  		return x.(uint64) - y.(uint64)
   399  	case uintptr:
   400  		return x.(uintptr) - y.(uintptr)
   401  	case float32:
   402  		return x.(float32) - y.(float32)
   403  	case float64:
   404  		return x.(float64) - y.(float64)
   405  	case complex64:
   406  		return x.(complex64) - y.(complex64)
   407  	case complex128:
   408  		return x.(complex128) - y.(complex128)
   409  	default:
   410  		vx := reflect.ValueOf(x)
   411  		vy := reflect.ValueOf(y)
   412  		if kind := vx.Kind(); kind == vy.Kind() {
   413  			r := reflect.New(vx.Type()).Elem()
   414  			switch kind {
   415  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   416  				r.SetInt(vx.Int() - vy.Int())
   417  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   418  				r.SetUint(vx.Uint() - vy.Uint())
   419  			case reflect.Float32, reflect.Float64:
   420  				r.SetFloat(vx.Float() - vy.Float())
   421  			case reflect.Complex64, reflect.Complex128:
   422  				r.SetComplex(vx.Complex() - vy.Complex())
   423  			default:
   424  				goto failed
   425  			}
   426  			return r.Interface()
   427  		}
   428  	}
   429  failed:
   430  	panic(fmt.Sprintf("invalid binary op: %T - %T", x, y))
   431  }
   432  
   433  func opMUL(x, y value) value {
   434  	switch x.(type) {
   435  	case int:
   436  		return x.(int) * y.(int)
   437  	case int8:
   438  		return x.(int8) * y.(int8)
   439  	case int16:
   440  		return x.(int16) * y.(int16)
   441  	case int32:
   442  		return x.(int32) * y.(int32)
   443  	case int64:
   444  		return x.(int64) * y.(int64)
   445  	case uint:
   446  		return x.(uint) * y.(uint)
   447  	case uint8:
   448  		return x.(uint8) * y.(uint8)
   449  	case uint16:
   450  		return x.(uint16) * y.(uint16)
   451  	case uint32:
   452  		return x.(uint32) * y.(uint32)
   453  	case uint64:
   454  		return x.(uint64) * y.(uint64)
   455  	case uintptr:
   456  		return x.(uintptr) * y.(uintptr)
   457  	case float32:
   458  		return x.(float32) * y.(float32)
   459  	case float64:
   460  		return x.(float64) * y.(float64)
   461  	case complex64:
   462  		return x.(complex64) * y.(complex64)
   463  	case complex128:
   464  		return x.(complex128) * y.(complex128)
   465  	default:
   466  		vx := reflect.ValueOf(x)
   467  		vy := reflect.ValueOf(y)
   468  		if kind := vx.Kind(); kind == vy.Kind() {
   469  			r := reflect.New(vx.Type()).Elem()
   470  			switch kind {
   471  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   472  				r.SetInt(vx.Int() * vy.Int())
   473  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   474  				r.SetUint(vx.Uint() * vy.Uint())
   475  			case reflect.Float32, reflect.Float64:
   476  				r.SetFloat(vx.Float() * vy.Float())
   477  			case reflect.Complex64, reflect.Complex128:
   478  				r.SetComplex(vx.Complex() * vy.Complex())
   479  			default:
   480  				goto failed
   481  			}
   482  			return r.Interface()
   483  		}
   484  	}
   485  failed:
   486  	panic(fmt.Sprintf("invalid binary op: %T * %T", x, y))
   487  }
   488  
   489  func opQuo(x, y value) value {
   490  	switch x.(type) {
   491  	case int:
   492  		return x.(int) / y.(int)
   493  	case int8:
   494  		return x.(int8) / y.(int8)
   495  	case int16:
   496  		return x.(int16) / y.(int16)
   497  	case int32:
   498  		return x.(int32) / y.(int32)
   499  	case int64:
   500  		return x.(int64) / y.(int64)
   501  	case uint:
   502  		return x.(uint) / y.(uint)
   503  	case uint8:
   504  		return x.(uint8) / y.(uint8)
   505  	case uint16:
   506  		return x.(uint16) / y.(uint16)
   507  	case uint32:
   508  		return x.(uint32) / y.(uint32)
   509  	case uint64:
   510  		return x.(uint64) / y.(uint64)
   511  	case uintptr:
   512  		return x.(uintptr) / y.(uintptr)
   513  	case float32:
   514  		return x.(float32) / y.(float32)
   515  	case float64:
   516  		return x.(float64) / y.(float64)
   517  	case complex64:
   518  		return x.(complex64) / y.(complex64)
   519  	case complex128:
   520  		return x.(complex128) / y.(complex128)
   521  	default:
   522  		vx := reflect.ValueOf(x)
   523  		vy := reflect.ValueOf(y)
   524  		if kind := vx.Kind(); kind == vy.Kind() {
   525  			r := reflect.New(vx.Type()).Elem()
   526  			switch kind {
   527  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   528  				r.SetInt(vx.Int() / vy.Int())
   529  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   530  				r.SetUint(vx.Uint() / vy.Uint())
   531  			case reflect.Float32, reflect.Float64:
   532  				r.SetFloat(vx.Float() / vy.Float())
   533  			case reflect.Complex64, reflect.Complex128:
   534  				r.SetComplex(vx.Complex() / vy.Complex())
   535  			default:
   536  				goto failed
   537  			}
   538  			return r.Interface()
   539  		}
   540  	}
   541  failed:
   542  	panic(fmt.Sprintf("invalid binary op: %T / %T", x, y))
   543  }
   544  
   545  func opREM(x, y value) value {
   546  	switch x.(type) {
   547  	case int:
   548  		return x.(int) % y.(int)
   549  	case int8:
   550  		return x.(int8) % y.(int8)
   551  	case int16:
   552  		return x.(int16) % y.(int16)
   553  	case int32:
   554  		return x.(int32) % y.(int32)
   555  	case int64:
   556  		return x.(int64) % y.(int64)
   557  	case uint:
   558  		return x.(uint) % y.(uint)
   559  	case uint8:
   560  		return x.(uint8) % y.(uint8)
   561  	case uint16:
   562  		return x.(uint16) % y.(uint16)
   563  	case uint32:
   564  		return x.(uint32) % y.(uint32)
   565  	case uint64:
   566  		return x.(uint64) % y.(uint64)
   567  	case uintptr:
   568  		return x.(uintptr) % y.(uintptr)
   569  	default:
   570  		vx := reflect.ValueOf(x)
   571  		vy := reflect.ValueOf(y)
   572  		if kind := vx.Kind(); kind == vy.Kind() {
   573  			r := reflect.New(vx.Type()).Elem()
   574  			switch kind {
   575  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   576  				r.SetInt(vx.Int() % vy.Int())
   577  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   578  				r.SetUint(vx.Uint() % vy.Uint())
   579  			default:
   580  				goto failed
   581  			}
   582  			return r.Interface()
   583  		}
   584  	}
   585  failed:
   586  	panic(fmt.Sprintf("invalid binary op: %T %% %T", x, y))
   587  }
   588  
   589  func opAND(x, y value) value {
   590  	switch x.(type) {
   591  	case int:
   592  		return x.(int) & y.(int)
   593  	case int8:
   594  		return x.(int8) & y.(int8)
   595  	case int16:
   596  		return x.(int16) & y.(int16)
   597  	case int32:
   598  		return x.(int32) & y.(int32)
   599  	case int64:
   600  		return x.(int64) & y.(int64)
   601  	case uint:
   602  		return x.(uint) & y.(uint)
   603  	case uint8:
   604  		return x.(uint8) & y.(uint8)
   605  	case uint16:
   606  		return x.(uint16) & y.(uint16)
   607  	case uint32:
   608  		return x.(uint32) & y.(uint32)
   609  	case uint64:
   610  		return x.(uint64) & y.(uint64)
   611  	case uintptr:
   612  		return x.(uintptr) & y.(uintptr)
   613  	default:
   614  		vx := reflect.ValueOf(x)
   615  		vy := reflect.ValueOf(y)
   616  		if kind := vx.Kind(); kind == vy.Kind() {
   617  			r := reflect.New(vx.Type()).Elem()
   618  			switch kind {
   619  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   620  				r.SetInt(vx.Int() & vy.Int())
   621  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   622  				r.SetUint(vx.Uint() & vy.Uint())
   623  			default:
   624  				goto failed
   625  			}
   626  			return r.Interface()
   627  		}
   628  	}
   629  failed:
   630  	panic(fmt.Sprintf("invalid binary op: %T && %T", x, y))
   631  }
   632  
   633  func opOR(x, y value) value {
   634  	switch x.(type) {
   635  	case int:
   636  		return x.(int) | y.(int)
   637  	case int8:
   638  		return x.(int8) | y.(int8)
   639  	case int16:
   640  		return x.(int16) | y.(int16)
   641  	case int32:
   642  		return x.(int32) | y.(int32)
   643  	case int64:
   644  		return x.(int64) | y.(int64)
   645  	case uint:
   646  		return x.(uint) | y.(uint)
   647  	case uint8:
   648  		return x.(uint8) | y.(uint8)
   649  	case uint16:
   650  		return x.(uint16) | y.(uint16)
   651  	case uint32:
   652  		return x.(uint32) | y.(uint32)
   653  	case uint64:
   654  		return x.(uint64) | y.(uint64)
   655  	case uintptr:
   656  		return x.(uintptr) | y.(uintptr)
   657  	default:
   658  		vx := reflect.ValueOf(x)
   659  		vy := reflect.ValueOf(y)
   660  		if kind := vx.Kind(); kind == vy.Kind() {
   661  			r := reflect.New(vx.Type()).Elem()
   662  			switch kind {
   663  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   664  				r.SetInt(vx.Int() | vy.Int())
   665  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   666  				r.SetUint(vx.Uint() | vy.Uint())
   667  			default:
   668  				goto failed
   669  			}
   670  			return r.Interface()
   671  		}
   672  	}
   673  failed:
   674  	panic(fmt.Sprintf("invalid binary op: %T | %T", x, y))
   675  }
   676  
   677  func opXOR(x, y value) value {
   678  	switch x.(type) {
   679  	case int:
   680  		return x.(int) ^ y.(int)
   681  	case int8:
   682  		return x.(int8) ^ y.(int8)
   683  	case int16:
   684  		return x.(int16) ^ y.(int16)
   685  	case int32:
   686  		return x.(int32) ^ y.(int32)
   687  	case int64:
   688  		return x.(int64) ^ y.(int64)
   689  	case uint:
   690  		return x.(uint) ^ y.(uint)
   691  	case uint8:
   692  		return x.(uint8) ^ y.(uint8)
   693  	case uint16:
   694  		return x.(uint16) ^ y.(uint16)
   695  	case uint32:
   696  		return x.(uint32) ^ y.(uint32)
   697  	case uint64:
   698  		return x.(uint64) ^ y.(uint64)
   699  	case uintptr:
   700  		return x.(uintptr) ^ y.(uintptr)
   701  	default:
   702  		vx := reflect.ValueOf(x)
   703  		vy := reflect.ValueOf(y)
   704  		if kind := vx.Kind(); kind == vy.Kind() {
   705  			r := reflect.New(vx.Type()).Elem()
   706  			switch kind {
   707  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   708  				r.SetInt(vx.Int() ^ vy.Int())
   709  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   710  				r.SetUint(vx.Uint() ^ vy.Uint())
   711  			default:
   712  				goto failed
   713  			}
   714  			return r.Interface()
   715  		}
   716  	}
   717  failed:
   718  	panic(fmt.Sprintf("invalid binary op: %T ^ %T", x, y))
   719  }
   720  
   721  func opANDNOT(x, y value) value {
   722  	switch x.(type) {
   723  	case int:
   724  		return x.(int) &^ y.(int)
   725  	case int8:
   726  		return x.(int8) &^ y.(int8)
   727  	case int16:
   728  		return x.(int16) &^ y.(int16)
   729  	case int32:
   730  		return x.(int32) &^ y.(int32)
   731  	case int64:
   732  		return x.(int64) &^ y.(int64)
   733  	case uint:
   734  		return x.(uint) &^ y.(uint)
   735  	case uint8:
   736  		return x.(uint8) &^ y.(uint8)
   737  	case uint16:
   738  		return x.(uint16) &^ y.(uint16)
   739  	case uint32:
   740  		return x.(uint32) &^ y.(uint32)
   741  	case uint64:
   742  		return x.(uint64) &^ y.(uint64)
   743  	case uintptr:
   744  		return x.(uintptr) &^ y.(uintptr)
   745  	default:
   746  		vx := reflect.ValueOf(x)
   747  		vy := reflect.ValueOf(y)
   748  		if kind := vx.Kind(); kind == vy.Kind() {
   749  			r := reflect.New(vx.Type()).Elem()
   750  			switch kind {
   751  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   752  				r.SetInt(vx.Int() &^ vy.Int())
   753  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   754  				r.SetUint(vx.Uint() &^ vy.Uint())
   755  			default:
   756  				goto failed
   757  			}
   758  			return r.Interface()
   759  		}
   760  	}
   761  failed:
   762  	panic(fmt.Sprintf("invalid binary op: %T &^ %T", x, y))
   763  }
   764  
   765  func opSHL(x, _y value) value {
   766  	y := asUint64(_y)
   767  	switch x.(type) {
   768  	case int:
   769  		return x.(int) << y
   770  	case int8:
   771  		return x.(int8) << y
   772  	case int16:
   773  		return x.(int16) << y
   774  	case int32:
   775  		return x.(int32) << y
   776  	case int64:
   777  		return x.(int64) << y
   778  	case uint:
   779  		return x.(uint) << y
   780  	case uint8:
   781  		return x.(uint8) << y
   782  	case uint16:
   783  		return x.(uint16) << y
   784  	case uint32:
   785  		return x.(uint32) << y
   786  	case uint64:
   787  		return x.(uint64) << y
   788  	case uintptr:
   789  		return x.(uintptr) << y
   790  	default:
   791  		vx := reflect.ValueOf(x)
   792  		r := reflect.New(vx.Type()).Elem()
   793  		switch vx.Kind() {
   794  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   795  			r.SetInt(vx.Int() << y)
   796  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   797  			r.SetUint(vx.Uint() << y)
   798  		default:
   799  			goto failed
   800  		}
   801  		return r.Interface()
   802  	}
   803  failed:
   804  	panic(fmt.Sprintf("invalid binary op: %T << %T", x, y))
   805  }
   806  
   807  func opSHR(x, _y value) value {
   808  	y := asUint64(_y)
   809  	switch x.(type) {
   810  	case int:
   811  		return x.(int) >> y
   812  	case int8:
   813  		return x.(int8) >> y
   814  	case int16:
   815  		return x.(int16) >> y
   816  	case int32:
   817  		return x.(int32) >> y
   818  	case int64:
   819  		return x.(int64) >> y
   820  	case uint:
   821  		return x.(uint) >> y
   822  	case uint8:
   823  		return x.(uint8) >> y
   824  	case uint16:
   825  		return x.(uint16) >> y
   826  	case uint32:
   827  		return x.(uint32) >> y
   828  	case uint64:
   829  		return x.(uint64) >> y
   830  	case uintptr:
   831  		return x.(uintptr) >> y
   832  	default:
   833  		vx := reflect.ValueOf(x)
   834  		r := reflect.New(vx.Type()).Elem()
   835  		switch vx.Kind() {
   836  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   837  			r.SetInt(vx.Int() >> y)
   838  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   839  			r.SetUint(vx.Uint() >> y)
   840  		default:
   841  			goto failed
   842  		}
   843  		return r.Interface()
   844  	}
   845  failed:
   846  	panic(fmt.Sprintf("invalid binary op: %T >> %T", x, y))
   847  }
   848  
   849  func opLSS(x, y value) value {
   850  	switch x.(type) {
   851  	case int:
   852  		return x.(int) < y.(int)
   853  	case int8:
   854  		return x.(int8) < y.(int8)
   855  	case int16:
   856  		return x.(int16) < y.(int16)
   857  	case int32:
   858  		return x.(int32) < y.(int32)
   859  	case int64:
   860  		return x.(int64) < y.(int64)
   861  	case uint:
   862  		return x.(uint) < y.(uint)
   863  	case uint8:
   864  		return x.(uint8) < y.(uint8)
   865  	case uint16:
   866  		return x.(uint16) < y.(uint16)
   867  	case uint32:
   868  		return x.(uint32) < y.(uint32)
   869  	case uint64:
   870  		return x.(uint64) < y.(uint64)
   871  	case uintptr:
   872  		return x.(uintptr) < y.(uintptr)
   873  	case float32:
   874  		return x.(float32) < y.(float32)
   875  	case float64:
   876  		return x.(float64) < y.(float64)
   877  	case string:
   878  		return x.(string) < y.(string)
   879  	default:
   880  		vx := reflect.ValueOf(x)
   881  		vy := reflect.ValueOf(y)
   882  		if kind := vx.Kind(); kind == vy.Kind() {
   883  			switch kind {
   884  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   885  				return vx.Int() < vy.Int()
   886  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   887  				return vx.Uint() < vy.Uint()
   888  			case reflect.Float32, reflect.Float64:
   889  				return vx.Float() < vy.Float()
   890  			case reflect.String:
   891  				return vx.String() < vy.String()
   892  			default:
   893  				goto failed
   894  			}
   895  		}
   896  	}
   897  failed:
   898  	panic(fmt.Sprintf("invalid binary op: %T < %T", x, y))
   899  }
   900  
   901  func opLEQ(x, y value) value {
   902  	switch x.(type) {
   903  	case int:
   904  		return x.(int) <= y.(int)
   905  	case int8:
   906  		return x.(int8) <= y.(int8)
   907  	case int16:
   908  		return x.(int16) <= y.(int16)
   909  	case int32:
   910  		return x.(int32) <= y.(int32)
   911  	case int64:
   912  		return x.(int64) <= y.(int64)
   913  	case uint:
   914  		return x.(uint) <= y.(uint)
   915  	case uint8:
   916  		return x.(uint8) <= y.(uint8)
   917  	case uint16:
   918  		return x.(uint16) <= y.(uint16)
   919  	case uint32:
   920  		return x.(uint32) <= y.(uint32)
   921  	case uint64:
   922  		return x.(uint64) <= y.(uint64)
   923  	case uintptr:
   924  		return x.(uintptr) <= y.(uintptr)
   925  	case float32:
   926  		return x.(float32) <= y.(float32)
   927  	case float64:
   928  		return x.(float64) <= y.(float64)
   929  	case string:
   930  		return x.(string) <= y.(string)
   931  	default:
   932  		vx := reflect.ValueOf(x)
   933  		vy := reflect.ValueOf(y)
   934  		if kind := vx.Kind(); kind == vy.Kind() {
   935  			switch kind {
   936  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   937  				return vx.Int() <= vy.Int()
   938  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   939  				return vx.Uint() <= vy.Uint()
   940  			case reflect.Float32, reflect.Float64:
   941  				return vx.Float() <= vy.Float()
   942  			case reflect.String:
   943  				return vx.String() <= vy.String()
   944  			default:
   945  				goto failed
   946  			}
   947  		}
   948  	}
   949  failed:
   950  	panic(fmt.Sprintf("invalid binary op: %T <= %T", x, y))
   951  }
   952  
   953  func opGTR(x, y value) value {
   954  	switch x.(type) {
   955  	case int:
   956  		return x.(int) > y.(int)
   957  	case int8:
   958  		return x.(int8) > y.(int8)
   959  	case int16:
   960  		return x.(int16) > y.(int16)
   961  	case int32:
   962  		return x.(int32) > y.(int32)
   963  	case int64:
   964  		return x.(int64) > y.(int64)
   965  	case uint:
   966  		return x.(uint) > y.(uint)
   967  	case uint8:
   968  		return x.(uint8) > y.(uint8)
   969  	case uint16:
   970  		return x.(uint16) > y.(uint16)
   971  	case uint32:
   972  		return x.(uint32) > y.(uint32)
   973  	case uint64:
   974  		return x.(uint64) > y.(uint64)
   975  	case uintptr:
   976  		return x.(uintptr) > y.(uintptr)
   977  	case float32:
   978  		return x.(float32) > y.(float32)
   979  	case float64:
   980  		return x.(float64) > y.(float64)
   981  	case string:
   982  		return x.(string) > y.(string)
   983  	default:
   984  		vx := reflect.ValueOf(x)
   985  		vy := reflect.ValueOf(y)
   986  		if kind := vx.Kind(); kind == vy.Kind() {
   987  			switch kind {
   988  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   989  				return vx.Int() > vy.Int()
   990  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   991  				return vx.Uint() > vy.Uint()
   992  			case reflect.Float32, reflect.Float64:
   993  				return vx.Float() > vy.Float()
   994  			case reflect.String:
   995  				return vx.String() > vy.String()
   996  			default:
   997  				goto failed
   998  			}
   999  		}
  1000  	}
  1001  failed:
  1002  	panic(fmt.Sprintf("invalid binary op: %T > %T", x, y))
  1003  }
  1004  
  1005  func opGEQ(x, y value) value {
  1006  	switch x.(type) {
  1007  	case int:
  1008  		return x.(int) >= y.(int)
  1009  	case int8:
  1010  		return x.(int8) >= y.(int8)
  1011  	case int16:
  1012  		return x.(int16) >= y.(int16)
  1013  	case int32:
  1014  		return x.(int32) >= y.(int32)
  1015  	case int64:
  1016  		return x.(int64) >= y.(int64)
  1017  	case uint:
  1018  		return x.(uint) >= y.(uint)
  1019  	case uint8:
  1020  		return x.(uint8) >= y.(uint8)
  1021  	case uint16:
  1022  		return x.(uint16) >= y.(uint16)
  1023  	case uint32:
  1024  		return x.(uint32) >= y.(uint32)
  1025  	case uint64:
  1026  		return x.(uint64) >= y.(uint64)
  1027  	case uintptr:
  1028  		return x.(uintptr) >= y.(uintptr)
  1029  	case float32:
  1030  		return x.(float32) >= y.(float32)
  1031  	case float64:
  1032  		return x.(float64) >= y.(float64)
  1033  	case string:
  1034  		return x.(string) >= y.(string)
  1035  	default:
  1036  		vx := reflect.ValueOf(x)
  1037  		vy := reflect.ValueOf(y)
  1038  		if kind := vx.Kind(); kind == vy.Kind() {
  1039  			switch kind {
  1040  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1041  				return vx.Int() >= vy.Int()
  1042  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1043  				return vx.Uint() >= vy.Uint()
  1044  			case reflect.Float32, reflect.Float64:
  1045  				return vx.Float() >= vy.Float()
  1046  			case reflect.String:
  1047  				return vx.String() >= vy.String()
  1048  			default:
  1049  				goto failed
  1050  			}
  1051  		}
  1052  	}
  1053  failed:
  1054  	panic(fmt.Sprintf("invalid binary op: %T >= %T", x, y))
  1055  }
  1056  
  1057  // binop implements all arithmetic and logical binary operators for
  1058  // numeric datatypes and strings.  Both operands must have identical
  1059  // dynamic type.
  1060  func binop(instr *ssa.BinOp, t types.Type, x, y value) value {
  1061  	switch instr.Op {
  1062  	case token.ADD:
  1063  		return opADD(x, y)
  1064  	case token.SUB:
  1065  		return opSUB(x, y)
  1066  	case token.MUL:
  1067  		return opMUL(x, y)
  1068  	case token.QUO:
  1069  		return opQuo(x, y)
  1070  	case token.REM:
  1071  		return opREM(x, y)
  1072  	case token.AND:
  1073  		return opAND(x, y)
  1074  	case token.OR:
  1075  		return opOR(x, y)
  1076  	case token.XOR:
  1077  		return opXOR(x, y)
  1078  	case token.AND_NOT:
  1079  		return opANDNOT(x, y)
  1080  	case token.SHL:
  1081  		return opSHL(x, y)
  1082  	case token.SHR:
  1083  		return opSHR(x, y)
  1084  	case token.LSS:
  1085  		return opLSS(x, y)
  1086  	case token.LEQ:
  1087  		return opLEQ(x, y)
  1088  	case token.EQL:
  1089  		return opEQL(instr, x, y)
  1090  	case token.NEQ:
  1091  		return !opEQL(instr, x, y)
  1092  	case token.GTR:
  1093  		return opGTR(x, y)
  1094  	case token.GEQ:
  1095  		return opGEQ(x, y)
  1096  	}
  1097  	panic(fmt.Sprintf("invalid binary op: %T %s %T", x, instr.Op, y))
  1098  }
  1099  
  1100  func IsConstNil(v ssa.Value) bool {
  1101  	switch c := v.(type) {
  1102  	case *ssa.Const:
  1103  		return c.IsNil()
  1104  	}
  1105  	return false
  1106  }
  1107  
  1108  func IsNil(v reflect.Value) bool {
  1109  	switch v.Kind() {
  1110  	case reflect.Invalid:
  1111  		return true
  1112  	case reflect.Slice, reflect.Map, reflect.Func:
  1113  		return v.IsNil()
  1114  	case reflect.Chan, reflect.Ptr, reflect.UnsafePointer, reflect.Interface:
  1115  		return v.IsNil()
  1116  	default:
  1117  		return false
  1118  	}
  1119  }
  1120  
  1121  func opEQL(instr *ssa.BinOp, x, y interface{}) bool {
  1122  	vx := reflect.ValueOf(x)
  1123  	vy := reflect.ValueOf(y)
  1124  	if vx.Kind() != vy.Kind() {
  1125  		return false
  1126  	}
  1127  	if IsConstNil(instr.X) {
  1128  		return IsNil(vy)
  1129  	} else if IsConstNil(instr.Y) {
  1130  		return IsNil(vx)
  1131  	}
  1132  	return equalValue(vx, vy)
  1133  }
  1134  
  1135  func equalNil(vx, vy reflect.Value) bool {
  1136  	if IsNil(vx) {
  1137  		return IsNil(vy)
  1138  	} else if IsNil(vy) {
  1139  		return IsNil(vx)
  1140  	}
  1141  	return equalValue(vx, vy)
  1142  }
  1143  
  1144  func equalValue(vx, vy reflect.Value) bool {
  1145  	if kind := vx.Kind(); kind == vy.Kind() {
  1146  		switch kind {
  1147  		case reflect.Invalid:
  1148  			return true
  1149  		case reflect.Chan:
  1150  			dirx := vx.Type().ChanDir()
  1151  			diry := vy.Type().ChanDir()
  1152  			if dirx != diry {
  1153  				if dirx == reflect.BothDir {
  1154  					return vy.Interface() == vx.Convert(vy.Type()).Interface()
  1155  				} else if diry == reflect.BothDir {
  1156  					return vx.Interface() == vy.Convert(vx.Type()).Interface()
  1157  				}
  1158  			} else {
  1159  				return vx.Interface() == vy.Interface()
  1160  			}
  1161  		case reflect.Ptr:
  1162  			return vx.Pointer() == vy.Pointer()
  1163  		case reflect.Struct:
  1164  			return equalStruct(vx, vy)
  1165  		case reflect.Array:
  1166  			return equalArray(vx, vy)
  1167  		default:
  1168  			return vx.Interface() == vy.Interface()
  1169  		}
  1170  	}
  1171  	return false
  1172  }
  1173  
  1174  func equalArray(vx, vy reflect.Value) bool {
  1175  	xlen := vx.Len()
  1176  	if xlen != vy.Len() {
  1177  		return false
  1178  	}
  1179  	if vx.Type().Elem() != vy.Type().Elem() {
  1180  		return false
  1181  	}
  1182  	for i := 0; i < xlen; i++ {
  1183  		fx := vx.Index(i)
  1184  		fy := vy.Index(i)
  1185  		if !equalNil(fx, fy) {
  1186  			return false
  1187  		}
  1188  	}
  1189  	return true
  1190  }
  1191  
  1192  func equalStruct(vx, vy reflect.Value) bool {
  1193  	typ := vx.Type()
  1194  	if typ != vy.Type() {
  1195  		return false
  1196  	}
  1197  	return vx.Interface() == vy.Interface()
  1198  }
  1199  
  1200  func unop(instr *ssa.UnOp, x value) value {
  1201  	switch instr.Op {
  1202  	case token.ARROW: // receive
  1203  		vx := reflect.ValueOf(x)
  1204  		v, ok := vx.Recv()
  1205  		if !ok {
  1206  			v = reflect.New(vx.Type().Elem()).Elem()
  1207  		}
  1208  		if instr.CommaOk {
  1209  			return tuple{v.Interface(), ok}
  1210  		}
  1211  		return v.Interface()
  1212  		// if !ok {
  1213  		// 	v = zero(instr.X.Type().Underlying().(*types.Chan).Elem())
  1214  		// }
  1215  		// if instr.CommaOk {
  1216  		// 	v = tuple{v, ok}
  1217  		// }
  1218  		// return v
  1219  	case token.SUB:
  1220  		switch x := x.(type) {
  1221  		case int:
  1222  			return -x
  1223  		case int8:
  1224  			return -x
  1225  		case int16:
  1226  			return -x
  1227  		case int32:
  1228  			return -x
  1229  		case int64:
  1230  			return -x
  1231  		case uint:
  1232  			return -x
  1233  		case uint8:
  1234  			return -x
  1235  		case uint16:
  1236  			return -x
  1237  		case uint32:
  1238  			return -x
  1239  		case uint64:
  1240  			return -x
  1241  		case uintptr:
  1242  			return -x
  1243  		case float32:
  1244  			return -x
  1245  		case float64:
  1246  			return -x
  1247  		case complex64:
  1248  			return -x
  1249  		case complex128:
  1250  			return -x
  1251  		default:
  1252  			v := reflect.ValueOf(x)
  1253  			r := reflect.New(v.Type()).Elem()
  1254  			switch v.Kind() {
  1255  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1256  				r.SetInt(-v.Int())
  1257  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1258  				r.SetUint(-v.Uint())
  1259  			case reflect.Float32, reflect.Float64:
  1260  				r.SetFloat(-v.Float())
  1261  			case reflect.Complex64, reflect.Complex128:
  1262  				r.SetComplex(-v.Complex())
  1263  			}
  1264  			return r.Interface()
  1265  		}
  1266  	case token.MUL:
  1267  		v := reflect.ValueOf(x).Elem()
  1268  		if !v.IsValid() {
  1269  			panic(runtimeError("invalid memory address or nil pointer dereference"))
  1270  		}
  1271  		return v.Interface()
  1272  		//return load(deref(instr.X.Type()), x.(*value))
  1273  	case token.NOT:
  1274  		switch x := x.(type) {
  1275  		case bool:
  1276  			return !x
  1277  		default:
  1278  			v := reflect.ValueOf(x)
  1279  			if v.Kind() == reflect.Bool {
  1280  				r := reflect.New(v.Type()).Elem()
  1281  				if v.Bool() {
  1282  					return v.Interface()
  1283  				}
  1284  				r.SetBool(true)
  1285  				return r.Interface()
  1286  			}
  1287  		}
  1288  		// return !x.(bool)
  1289  	case token.XOR:
  1290  		switch x := x.(type) {
  1291  		case int:
  1292  			return ^x
  1293  		case int8:
  1294  			return ^x
  1295  		case int16:
  1296  			return ^x
  1297  		case int32:
  1298  			return ^x
  1299  		case int64:
  1300  			return ^x
  1301  		case uint:
  1302  			return ^x
  1303  		case uint8:
  1304  			return ^x
  1305  		case uint16:
  1306  			return ^x
  1307  		case uint32:
  1308  			return ^x
  1309  		case uint64:
  1310  			return ^x
  1311  		case uintptr:
  1312  			return ^x
  1313  		default:
  1314  			vx := reflect.ValueOf(x)
  1315  			r := reflect.New(vx.Type()).Elem()
  1316  			switch vx.Kind() {
  1317  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1318  				r.SetInt(^r.Int())
  1319  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1320  				r.SetUint(^r.Uint())
  1321  			default:
  1322  				goto failed
  1323  			}
  1324  			return r.Interface()
  1325  		}
  1326  	}
  1327  failed:
  1328  	panic(fmt.Sprintf("invalid unary op %s %T", instr.Op, x))
  1329  }
  1330  
  1331  // typeAssert checks whether dynamic type of itf is instr.AssertedType.
  1332  // It returns the extracted value on success, and panics on failure,
  1333  // unless instr.CommaOk, in which case it always returns a "value,ok" tuple.
  1334  func typeAssert(i *Interp, instr *ssa.TypeAssert, typ reflect.Type, xtyp reflect.Type, iv interface{}) value {
  1335  	var v value
  1336  	var err error
  1337  	if iv == nil {
  1338  		if xtyp == tyErrorInterface {
  1339  			err = runtimeError("invalid memory address or nil pointer dereference")
  1340  		} else if xtyp == typ {
  1341  			err = plainError(fmt.Sprintf("interface conversion: interface is nil, not %v", typ))
  1342  		} else {
  1343  			err = plainError(fmt.Sprintf("interface conversion: %v is nil, not %v", xtyp, typ))
  1344  		}
  1345  		// }
  1346  	} else {
  1347  		rv := reflect.ValueOf(iv)
  1348  		rt := rv.Type()
  1349  		if typ == rt {
  1350  			v = iv
  1351  		} else {
  1352  			if !rt.AssignableTo(typ) {
  1353  				err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v", xtyp, rt, typ))
  1354  				if itype, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
  1355  					if it, ok := i.findType(rt, false); ok {
  1356  						if meth, _ := types.MissingMethod(it, itype, true); meth != nil {
  1357  							err = runtimeError(fmt.Sprintf("interface conversion: %v is not %v: missing method %s",
  1358  								rt, instr.AssertedType, meth.Name()))
  1359  						}
  1360  					}
  1361  				} else if typ.PkgPath() == rt.PkgPath() && typ.Name() == rt.Name() {
  1362  					t1, ok1 := i.findType(typ, false)
  1363  					t2, ok2 := i.findType(rt, false)
  1364  					if ok1 && ok2 {
  1365  						n1, ok1 := t1.(*types.Named)
  1366  						n2, ok2 := t2.(*types.Named)
  1367  						if ok1 && ok2 && n1.Obj().Parent() != n2.Obj().Parent() {
  1368  							err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v (types from different scopes)", xtyp, rt, typ))
  1369  						}
  1370  					}
  1371  				}
  1372  			} else {
  1373  				v = rv.Convert(typ).Interface()
  1374  			}
  1375  		}
  1376  	}
  1377  	if err != nil {
  1378  		if !instr.CommaOk {
  1379  			panic(err)
  1380  		}
  1381  		return tuple{reflect.New(typ).Elem().Interface(), false}
  1382  	}
  1383  	if instr.CommaOk {
  1384  		return tuple{v, true}
  1385  	}
  1386  	return v
  1387  	// err := ""
  1388  	// if itf.t == nil {
  1389  	// 	err = fmt.Sprintf("interface conversion: interface is nil, not %s", instr.AssertedType)
  1390  
  1391  	// } else if idst, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
  1392  	// 	v = itf
  1393  	// 	err = checkInterface(i, idst, itf)
  1394  
  1395  	// } else if types.Identical(itf.t, instr.AssertedType) {
  1396  	// 	v = itf.v // extract value
  1397  
  1398  	// } else {
  1399  	// 	err = fmt.Sprintf("interface conversion: interface is %s, not %s", itf.t, instr.AssertedType)
  1400  	// }
  1401  
  1402  	// if err != "" {
  1403  	// 	if !instr.CommaOk {
  1404  	// 		panic(err)
  1405  	// 	}
  1406  	// 	return tuple{zero(instr.AssertedType), false}
  1407  	// }
  1408  	// if instr.CommaOk {
  1409  	// 	return tuple{v, true}
  1410  	// }
  1411  	// return v
  1412  }
  1413  
  1414  // widen widens a xtype typed value x to the widest type of its
  1415  // category, one of:
  1416  //
  1417  //	bool, int64, uint64, float64, complex128, string.
  1418  //
  1419  // This is inefficient but reduces the size of the cross-product of
  1420  // cases we have to consider.
  1421  func widen(x value) value {
  1422  	switch y := x.(type) {
  1423  	case bool, int64, uint64, float64, complex128, string, unsafe.Pointer:
  1424  		return x
  1425  	case int:
  1426  		return int64(y)
  1427  	case int8:
  1428  		return int64(y)
  1429  	case int16:
  1430  		return int64(y)
  1431  	case int32:
  1432  		return int64(y)
  1433  	case uint:
  1434  		return uint64(y)
  1435  	case uint8:
  1436  		return uint64(y)
  1437  	case uint16:
  1438  		return uint64(y)
  1439  	case uint32:
  1440  		return uint64(y)
  1441  	case uintptr:
  1442  		return uint64(y)
  1443  	case float32:
  1444  		return float64(y)
  1445  	case complex64:
  1446  		return complex128(y)
  1447  	}
  1448  	panic(fmt.Sprintf("cannot widen %T", x))
  1449  }
  1450  
  1451  //go:nocheckptr
  1452  func toUnsafePointer(v uintptr) unsafe.Pointer {
  1453  	return unsafe.Pointer(v)
  1454  }
  1455  
  1456  type reflectValue struct {
  1457  	typ  unsafe.Pointer
  1458  	ptr  unsafe.Pointer
  1459  	flag uintptr
  1460  }
  1461  
  1462  func convert(x interface{}, typ reflect.Type) interface{} {
  1463  	v := reflect.ValueOf(x)
  1464  	vk := v.Kind()
  1465  	switch typ.Kind() {
  1466  	case reflect.UnsafePointer:
  1467  		if vk == reflect.Uintptr {
  1468  			return toUnsafePointer(uintptr(v.Uint()))
  1469  		} else if vk == reflect.Ptr {
  1470  			return unsafe.Pointer(v.Pointer())
  1471  		}
  1472  	case reflect.Uintptr:
  1473  		if vk == reflect.UnsafePointer {
  1474  			return v.Pointer()
  1475  		}
  1476  	case reflect.Ptr:
  1477  		if vk == reflect.UnsafePointer {
  1478  			return reflect.NewAt(typ.Elem(), unsafe.Pointer(v.Pointer())).Interface()
  1479  		}
  1480  	case reflect.Slice:
  1481  		if v.Kind() == reflect.String {
  1482  			elem := typ.Elem()
  1483  			switch elem.Kind() {
  1484  			case reflect.Uint8:
  1485  				if elem.PkgPath() != "" {
  1486  					dst := reflect.New(typ).Elem()
  1487  					dst.SetBytes([]byte(v.String()))
  1488  					return dst.Interface()
  1489  				}
  1490  			case reflect.Int32:
  1491  				if elem.PkgPath() != "" {
  1492  					dst := reflect.New(typ).Elem()
  1493  					*(*[]rune)((*reflectValue)(unsafe.Pointer(&dst)).ptr) = []rune(v.String())
  1494  					return dst.Interface()
  1495  				}
  1496  			}
  1497  		}
  1498  	case reflect.String:
  1499  		if v.Kind() == reflect.Slice {
  1500  			elem := v.Type().Elem()
  1501  			switch elem.Kind() {
  1502  			case reflect.Uint8:
  1503  				if elem.PkgPath() != "" {
  1504  					v = reflect.ValueOf(string(v.Bytes()))
  1505  				}
  1506  			case reflect.Int32:
  1507  				if elem.PkgPath() != "" {
  1508  					v = reflect.ValueOf(*(*[]rune)(((*reflectValue)(unsafe.Pointer(&v))).ptr))
  1509  				}
  1510  			}
  1511  		}
  1512  	}
  1513  	return v.Convert(typ).Interface()
  1514  }