github.com/goplus/gossa@v0.3.25/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 gossa
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/constant"
    11  	"go/token"
    12  	"go/types"
    13  	"reflect"
    14  	"strings"
    15  	"unsafe"
    16  
    17  	"github.com/goplus/reflectx"
    18  	"golang.org/x/tools/go/ssa"
    19  )
    20  
    21  // If the target program panics, the interpreter panics with this type.
    22  type targetPanic struct {
    23  	v value
    24  }
    25  
    26  func (p targetPanic) Error() string {
    27  	var buf bytes.Buffer
    28  	writeany(&buf, p.v)
    29  	return buf.String()
    30  }
    31  
    32  // If the target program calls exit, the interpreter panics with this type.
    33  type exitPanic int
    34  
    35  type goexitPanic int
    36  
    37  func xtypeValue(c *ssa.Const, kind types.BasicKind) value {
    38  	switch kind {
    39  	case types.Bool, types.UntypedBool:
    40  		return constant.BoolVal(c.Value)
    41  	case types.Int, types.UntypedInt:
    42  		// Assume sizeof(int) is same on host and target.
    43  		return int(c.Int64())
    44  	case types.Int8:
    45  		return int8(c.Int64())
    46  	case types.Int16:
    47  		return int16(c.Int64())
    48  	case types.Int32, types.UntypedRune:
    49  		return int32(c.Int64())
    50  	case types.Int64:
    51  		return c.Int64()
    52  	case types.Uint:
    53  		// Assume sizeof(uint) is same on host and target.
    54  		return uint(c.Uint64())
    55  	case types.Uint8:
    56  		return uint8(c.Uint64())
    57  	case types.Uint16:
    58  		return uint16(c.Uint64())
    59  	case types.Uint32:
    60  		return uint32(c.Uint64())
    61  	case types.Uint64:
    62  		return c.Uint64()
    63  	case types.Uintptr:
    64  		// Assume sizeof(uintptr) is same on host and target.
    65  		return uintptr(c.Uint64())
    66  	case types.Float32:
    67  		return float32(c.Float64())
    68  	case types.Float64, types.UntypedFloat:
    69  		return c.Float64()
    70  	case types.Complex64:
    71  		return complex64(c.Complex128())
    72  	case types.Complex128, types.UntypedComplex:
    73  		return c.Complex128()
    74  	case types.String, types.UntypedString:
    75  		if c.Value.Kind() == constant.String {
    76  			return constant.StringVal(c.Value)
    77  		}
    78  		return string(rune(c.Int64()))
    79  	case types.UnsafePointer:
    80  		return unsafe.Pointer(uintptr(c.Uint64()))
    81  	}
    82  	panic("unreachable")
    83  }
    84  
    85  // constValue returns the value of the constant with the
    86  // dynamic type tag appropriate for c.Type().
    87  func constToValue(i *Interp, c *ssa.Const) value {
    88  	typ := c.Type()
    89  	if c.IsNil() {
    90  		if xtype, ok := typ.(*types.Basic); ok && xtype.Kind() == types.UntypedNil {
    91  			return nil
    92  		}
    93  		return reflect.Zero(i.preToType(typ)).Interface()
    94  	}
    95  	if xtype, ok := typ.(*types.Basic); ok {
    96  		return xtypeValue(c, xtype.Kind())
    97  	} else if xtype, ok := typ.Underlying().(*types.Basic); ok {
    98  		v := xtypeValue(c, xtype.Kind())
    99  		nv := reflect.New(i.preToType(typ)).Elem()
   100  		SetValue(nv, reflect.ValueOf(v))
   101  		return nv.Interface()
   102  	}
   103  	panic(fmt.Sprintf("unparser constValue: %s", c))
   104  }
   105  
   106  func globalToValue(i *Interp, key *ssa.Global) (interface{}, bool) {
   107  	if key.Pkg != nil {
   108  		pkgpath := key.Pkg.Pkg.Path()
   109  		if pkg, ok := i.installed(pkgpath); ok {
   110  			if ext, ok := pkg.Vars[key.Name()]; ok {
   111  				return ext.Interface(), true
   112  			}
   113  		}
   114  	}
   115  	if v, ok := i.globals[key]; ok {
   116  		return v, true
   117  	}
   118  	return nil, false
   119  }
   120  
   121  func staticToValue(i *Interp, value ssa.Value) (interface{}, bool) {
   122  	switch v := value.(type) {
   123  	case *ssa.Global:
   124  		return globalToValue(i, v)
   125  	case *ssa.Const:
   126  		return constToValue(i, v), true
   127  	}
   128  	return nil, false
   129  }
   130  
   131  // asInt converts x, which must be an integer, to an int suitable for
   132  // use as a slice or array index or operand to make().
   133  func asInt(x value) int {
   134  	switch x := x.(type) {
   135  	case int:
   136  		return x
   137  	case int8:
   138  		return int(x)
   139  	case int16:
   140  		return int(x)
   141  	case int32:
   142  		return int(x)
   143  	case int64:
   144  		return int(x)
   145  	case uint:
   146  		return int(x)
   147  	case uint8:
   148  		return int(x)
   149  	case uint16:
   150  		return int(x)
   151  	case uint32:
   152  		return int(x)
   153  	case uint64:
   154  		return int(x)
   155  	case uintptr:
   156  		return int(x)
   157  	default:
   158  		v := reflect.ValueOf(x)
   159  		switch v.Kind() {
   160  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   161  			return int(v.Int())
   162  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   163  			return int(v.Uint())
   164  		}
   165  	}
   166  	panic(fmt.Sprintf("cannot convert %T to int", x))
   167  }
   168  
   169  // asUint64 converts x, which must be an unsigned integer, to a uint64
   170  // suitable for use as a bitwise shift count.
   171  func asUint64(x value) uint64 {
   172  	switch x := x.(type) {
   173  	case int:
   174  		if x >= 0 {
   175  			return uint64(x)
   176  		}
   177  	case int8:
   178  		if x >= 0 {
   179  			return uint64(x)
   180  		}
   181  	case int16:
   182  		if x >= 0 {
   183  			return uint64(x)
   184  		}
   185  	case int32:
   186  		if x >= 0 {
   187  			return uint64(x)
   188  		}
   189  	case int64:
   190  		if x >= 0 {
   191  			return uint64(x)
   192  		}
   193  	case uint:
   194  		return uint64(x)
   195  	case uint8:
   196  		return uint64(x)
   197  	case uint16:
   198  		return uint64(x)
   199  	case uint32:
   200  		return uint64(x)
   201  	case uint64:
   202  		return x
   203  	case uintptr:
   204  		return uint64(x)
   205  	default:
   206  		v := reflect.ValueOf(x)
   207  		switch v.Kind() {
   208  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   209  			return v.Uint()
   210  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   211  			x := v.Int()
   212  			if x >= 0 {
   213  				return uint64(x)
   214  			}
   215  		default:
   216  			panic(fmt.Sprintf("cannot convert %T to uint64", x))
   217  		}
   218  	}
   219  	panic(runtimeError("negative shift amount"))
   220  }
   221  
   222  // slice returns x[lo:hi:max].  Any of lo, hi and max may be nil.
   223  func slice(fr *frame, instr *ssa.Slice, makesliceCheck bool, ix, ih, il, im register) reflect.Value {
   224  	// x := fr.get(instr.X)
   225  	x := fr.reg(ix)
   226  	var Len, Cap int
   227  	v := reflect.ValueOf(x)
   228  	// *array
   229  	if v.Kind() == reflect.Ptr {
   230  		v = v.Elem()
   231  	}
   232  	kind := v.Kind()
   233  	switch kind {
   234  	case reflect.String:
   235  		Len = v.Len()
   236  		Cap = Len
   237  	case reflect.Slice, reflect.Array:
   238  		Len = v.Len()
   239  		Cap = v.Cap()
   240  	}
   241  
   242  	lo := 0
   243  	hi := Len
   244  	max := Cap
   245  	var slice3 bool
   246  	if instr.Low != nil {
   247  		// lo = asInt(fr.get(instr.Low))
   248  		lo = asInt(fr.reg(il))
   249  	}
   250  	if instr.High != nil {
   251  		// hi = asInt(fr.get(instr.High))
   252  		hi = asInt(fr.reg(ih))
   253  	}
   254  	if instr.Max != nil {
   255  		// max = asInt(fr.get(instr.Max))
   256  		max = asInt(fr.reg(im))
   257  		slice3 = true
   258  	}
   259  
   260  	if makesliceCheck {
   261  		if hi < 0 {
   262  			panic(runtimeError("makeslice: len out of range"))
   263  		} else if hi > max {
   264  			panic(runtimeError("makeslice: cap out of range"))
   265  		}
   266  	} else {
   267  		if slice3 {
   268  			if max < 0 {
   269  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v]", max)))
   270  			} else if max > Cap {
   271  				if kind == reflect.Slice {
   272  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with capacity %v", max, Cap)))
   273  				} else {
   274  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [::%v] with length %v", max, Cap)))
   275  				}
   276  			} else if hi < 0 {
   277  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:]", hi)))
   278  			} else if hi > max {
   279  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v:%v]", hi, max)))
   280  			} else if lo < 0 {
   281  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v::]", lo)))
   282  			} else if lo > hi {
   283  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v:]", lo, hi)))
   284  			}
   285  		} else {
   286  			if hi < 0 {
   287  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v]", hi)))
   288  			} else if hi > Cap {
   289  				if kind == reflect.Slice {
   290  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with capacity %v", hi, Cap)))
   291  				} else {
   292  					panic(runtimeError(fmt.Sprintf("slice bounds out of range [:%v] with length %v", hi, Cap)))
   293  				}
   294  			} else if lo < 0 {
   295  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:]", lo)))
   296  			} else if lo > hi {
   297  				panic(runtimeError(fmt.Sprintf("slice bounds out of range [%v:%v]", lo, hi)))
   298  			}
   299  		}
   300  	}
   301  	switch kind {
   302  	case reflect.String:
   303  		// optimization x[len(x):], see $GOROOT/test/slicecap.go
   304  		if lo == hi {
   305  			return v.Slice(0, 0)
   306  		}
   307  		return v.Slice(lo, hi)
   308  	case reflect.Slice, reflect.Array:
   309  		return v.Slice3(lo, hi, max)
   310  	}
   311  	panic(fmt.Sprintf("slice: unexpected X type: %T", x))
   312  }
   313  
   314  func opADD(x, y value) value {
   315  	switch x.(type) {
   316  	case int:
   317  		return x.(int) + y.(int)
   318  	case int8:
   319  		return x.(int8) + y.(int8)
   320  	case int16:
   321  		return x.(int16) + y.(int16)
   322  	case int32:
   323  		return x.(int32) + y.(int32)
   324  	case int64:
   325  		return x.(int64) + y.(int64)
   326  	case uint:
   327  		return x.(uint) + y.(uint)
   328  	case uint8:
   329  		return x.(uint8) + y.(uint8)
   330  	case uint16:
   331  		return x.(uint16) + y.(uint16)
   332  	case uint32:
   333  		return x.(uint32) + y.(uint32)
   334  	case uint64:
   335  		return x.(uint64) + y.(uint64)
   336  	case uintptr:
   337  		return x.(uintptr) + y.(uintptr)
   338  	case float32:
   339  		return x.(float32) + y.(float32)
   340  	case float64:
   341  		return x.(float64) + y.(float64)
   342  	case complex64:
   343  		return x.(complex64) + y.(complex64)
   344  	case complex128:
   345  		return x.(complex128) + y.(complex128)
   346  	case string:
   347  		return x.(string) + y.(string)
   348  	default:
   349  		vx := reflect.ValueOf(x)
   350  		vy := reflect.ValueOf(y)
   351  		if kind := vx.Kind(); kind == vy.Kind() {
   352  			r := reflect.New(vx.Type()).Elem()
   353  			switch kind {
   354  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   355  				r.SetInt(vx.Int() + vy.Int())
   356  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   357  				r.SetUint(vx.Uint() + vy.Uint())
   358  			case reflect.Float32, reflect.Float64:
   359  				r.SetFloat(vx.Float() + vy.Float())
   360  			case reflect.Complex64, reflect.Complex128:
   361  				r.SetComplex(vx.Complex() + vy.Complex())
   362  			case reflect.String:
   363  				r.SetString(vx.String() + vy.String())
   364  			default:
   365  				goto failed
   366  			}
   367  			return r.Interface()
   368  		}
   369  	}
   370  failed:
   371  	panic(fmt.Sprintf("invalid binary op: %T + %T", x, y))
   372  }
   373  
   374  func opSUB(x, y value) value {
   375  	switch x.(type) {
   376  	case int:
   377  		return x.(int) - y.(int)
   378  	case int8:
   379  		return x.(int8) - y.(int8)
   380  	case int16:
   381  		return x.(int16) - y.(int16)
   382  	case int32:
   383  		return x.(int32) - y.(int32)
   384  	case int64:
   385  		return x.(int64) - y.(int64)
   386  	case uint:
   387  		return x.(uint) - y.(uint)
   388  	case uint8:
   389  		return x.(uint8) - y.(uint8)
   390  	case uint16:
   391  		return x.(uint16) - y.(uint16)
   392  	case uint32:
   393  		return x.(uint32) - y.(uint32)
   394  	case uint64:
   395  		return x.(uint64) - y.(uint64)
   396  	case uintptr:
   397  		return x.(uintptr) - y.(uintptr)
   398  	case float32:
   399  		return x.(float32) - y.(float32)
   400  	case float64:
   401  		return x.(float64) - y.(float64)
   402  	case complex64:
   403  		return x.(complex64) - y.(complex64)
   404  	case complex128:
   405  		return x.(complex128) - y.(complex128)
   406  	default:
   407  		vx := reflect.ValueOf(x)
   408  		vy := reflect.ValueOf(y)
   409  		if kind := vx.Kind(); kind == vy.Kind() {
   410  			r := reflect.New(vx.Type()).Elem()
   411  			switch kind {
   412  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   413  				r.SetInt(vx.Int() - vy.Int())
   414  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   415  				r.SetUint(vx.Uint() - vy.Uint())
   416  			case reflect.Float32, reflect.Float64:
   417  				r.SetFloat(vx.Float() - vy.Float())
   418  			case reflect.Complex64, reflect.Complex128:
   419  				r.SetComplex(vx.Complex() - vy.Complex())
   420  			default:
   421  				goto failed
   422  			}
   423  			return r.Interface()
   424  		}
   425  	}
   426  failed:
   427  	panic(fmt.Sprintf("invalid binary op: %T - %T", x, y))
   428  }
   429  
   430  func opMUL(x, y value) value {
   431  	switch x.(type) {
   432  	case int:
   433  		return x.(int) * y.(int)
   434  	case int8:
   435  		return x.(int8) * y.(int8)
   436  	case int16:
   437  		return x.(int16) * y.(int16)
   438  	case int32:
   439  		return x.(int32) * y.(int32)
   440  	case int64:
   441  		return x.(int64) * y.(int64)
   442  	case uint:
   443  		return x.(uint) * y.(uint)
   444  	case uint8:
   445  		return x.(uint8) * y.(uint8)
   446  	case uint16:
   447  		return x.(uint16) * y.(uint16)
   448  	case uint32:
   449  		return x.(uint32) * y.(uint32)
   450  	case uint64:
   451  		return x.(uint64) * y.(uint64)
   452  	case uintptr:
   453  		return x.(uintptr) * y.(uintptr)
   454  	case float32:
   455  		return x.(float32) * y.(float32)
   456  	case float64:
   457  		return x.(float64) * y.(float64)
   458  	case complex64:
   459  		return x.(complex64) * y.(complex64)
   460  	case complex128:
   461  		return x.(complex128) * y.(complex128)
   462  	default:
   463  		vx := reflect.ValueOf(x)
   464  		vy := reflect.ValueOf(y)
   465  		if kind := vx.Kind(); kind == vy.Kind() {
   466  			r := reflect.New(vx.Type()).Elem()
   467  			switch kind {
   468  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   469  				r.SetInt(vx.Int() * vy.Int())
   470  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   471  				r.SetUint(vx.Uint() * vy.Uint())
   472  			case reflect.Float32, reflect.Float64:
   473  				r.SetFloat(vx.Float() * vy.Float())
   474  			case reflect.Complex64, reflect.Complex128:
   475  				r.SetComplex(vx.Complex() * vy.Complex())
   476  			default:
   477  				goto failed
   478  			}
   479  			return r.Interface()
   480  		}
   481  	}
   482  failed:
   483  	panic(fmt.Sprintf("invalid binary op: %T * %T", x, y))
   484  }
   485  
   486  func opQuo(x, y value) value {
   487  	switch x.(type) {
   488  	case int:
   489  		return x.(int) / y.(int)
   490  	case int8:
   491  		return x.(int8) / y.(int8)
   492  	case int16:
   493  		return x.(int16) / y.(int16)
   494  	case int32:
   495  		return x.(int32) / y.(int32)
   496  	case int64:
   497  		return x.(int64) / y.(int64)
   498  	case uint:
   499  		return x.(uint) / y.(uint)
   500  	case uint8:
   501  		return x.(uint8) / y.(uint8)
   502  	case uint16:
   503  		return x.(uint16) / y.(uint16)
   504  	case uint32:
   505  		return x.(uint32) / y.(uint32)
   506  	case uint64:
   507  		return x.(uint64) / y.(uint64)
   508  	case uintptr:
   509  		return x.(uintptr) / y.(uintptr)
   510  	case float32:
   511  		return x.(float32) / y.(float32)
   512  	case float64:
   513  		return x.(float64) / y.(float64)
   514  	case complex64:
   515  		return x.(complex64) / y.(complex64)
   516  	case complex128:
   517  		return x.(complex128) / y.(complex128)
   518  	default:
   519  		vx := reflect.ValueOf(x)
   520  		vy := reflect.ValueOf(y)
   521  		if kind := vx.Kind(); kind == vy.Kind() {
   522  			r := reflect.New(vx.Type()).Elem()
   523  			switch kind {
   524  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   525  				r.SetInt(vx.Int() / vy.Int())
   526  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   527  				r.SetUint(vx.Uint() / vy.Uint())
   528  			case reflect.Float32, reflect.Float64:
   529  				r.SetFloat(vx.Float() / vy.Float())
   530  			case reflect.Complex64, reflect.Complex128:
   531  				r.SetComplex(vx.Complex() / vy.Complex())
   532  			default:
   533  				goto failed
   534  			}
   535  			return r.Interface()
   536  		}
   537  	}
   538  failed:
   539  	panic(fmt.Sprintf("invalid binary op: %T / %T", x, y))
   540  }
   541  
   542  func opREM(x, y value) value {
   543  	switch x.(type) {
   544  	case int:
   545  		return x.(int) % y.(int)
   546  	case int8:
   547  		return x.(int8) % y.(int8)
   548  	case int16:
   549  		return x.(int16) % y.(int16)
   550  	case int32:
   551  		return x.(int32) % y.(int32)
   552  	case int64:
   553  		return x.(int64) % y.(int64)
   554  	case uint:
   555  		return x.(uint) % y.(uint)
   556  	case uint8:
   557  		return x.(uint8) % y.(uint8)
   558  	case uint16:
   559  		return x.(uint16) % y.(uint16)
   560  	case uint32:
   561  		return x.(uint32) % y.(uint32)
   562  	case uint64:
   563  		return x.(uint64) % y.(uint64)
   564  	case uintptr:
   565  		return x.(uintptr) % y.(uintptr)
   566  	default:
   567  		vx := reflect.ValueOf(x)
   568  		vy := reflect.ValueOf(y)
   569  		if kind := vx.Kind(); kind == vy.Kind() {
   570  			r := reflect.New(vx.Type()).Elem()
   571  			switch kind {
   572  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   573  				r.SetInt(vx.Int() % vy.Int())
   574  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   575  				r.SetUint(vx.Uint() % vy.Uint())
   576  			default:
   577  				goto failed
   578  			}
   579  			return r.Interface()
   580  		}
   581  	}
   582  failed:
   583  	panic(fmt.Sprintf("invalid binary op: %T %% %T", x, y))
   584  }
   585  
   586  func opAND(x, y value) value {
   587  	switch x.(type) {
   588  	case int:
   589  		return x.(int) & y.(int)
   590  	case int8:
   591  		return x.(int8) & y.(int8)
   592  	case int16:
   593  		return x.(int16) & y.(int16)
   594  	case int32:
   595  		return x.(int32) & y.(int32)
   596  	case int64:
   597  		return x.(int64) & y.(int64)
   598  	case uint:
   599  		return x.(uint) & y.(uint)
   600  	case uint8:
   601  		return x.(uint8) & y.(uint8)
   602  	case uint16:
   603  		return x.(uint16) & y.(uint16)
   604  	case uint32:
   605  		return x.(uint32) & y.(uint32)
   606  	case uint64:
   607  		return x.(uint64) & y.(uint64)
   608  	case uintptr:
   609  		return x.(uintptr) & y.(uintptr)
   610  	default:
   611  		vx := reflect.ValueOf(x)
   612  		vy := reflect.ValueOf(y)
   613  		if kind := vx.Kind(); kind == vy.Kind() {
   614  			r := reflect.New(vx.Type()).Elem()
   615  			switch kind {
   616  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   617  				r.SetInt(vx.Int() & vy.Int())
   618  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   619  				r.SetUint(vx.Uint() & vy.Uint())
   620  			default:
   621  				goto failed
   622  			}
   623  			return r.Interface()
   624  		}
   625  	}
   626  failed:
   627  	panic(fmt.Sprintf("invalid binary op: %T && %T", x, y))
   628  }
   629  
   630  func opOR(x, y value) value {
   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  	default:
   655  		vx := reflect.ValueOf(x)
   656  		vy := reflect.ValueOf(y)
   657  		if kind := vx.Kind(); kind == vy.Kind() {
   658  			r := reflect.New(vx.Type()).Elem()
   659  			switch kind {
   660  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   661  				r.SetInt(vx.Int() | vy.Int())
   662  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   663  				r.SetUint(vx.Uint() | vy.Uint())
   664  			default:
   665  				goto failed
   666  			}
   667  			return r.Interface()
   668  		}
   669  	}
   670  failed:
   671  	panic(fmt.Sprintf("invalid binary op: %T | %T", x, y))
   672  }
   673  
   674  func opXOR(x, y value) value {
   675  	switch x.(type) {
   676  	case int:
   677  		return x.(int) ^ y.(int)
   678  	case int8:
   679  		return x.(int8) ^ y.(int8)
   680  	case int16:
   681  		return x.(int16) ^ y.(int16)
   682  	case int32:
   683  		return x.(int32) ^ y.(int32)
   684  	case int64:
   685  		return x.(int64) ^ y.(int64)
   686  	case uint:
   687  		return x.(uint) ^ y.(uint)
   688  	case uint8:
   689  		return x.(uint8) ^ y.(uint8)
   690  	case uint16:
   691  		return x.(uint16) ^ y.(uint16)
   692  	case uint32:
   693  		return x.(uint32) ^ y.(uint32)
   694  	case uint64:
   695  		return x.(uint64) ^ y.(uint64)
   696  	case uintptr:
   697  		return x.(uintptr) ^ y.(uintptr)
   698  	default:
   699  		vx := reflect.ValueOf(x)
   700  		vy := reflect.ValueOf(y)
   701  		if kind := vx.Kind(); kind == vy.Kind() {
   702  			r := reflect.New(vx.Type()).Elem()
   703  			switch kind {
   704  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   705  				r.SetInt(vx.Int() ^ vy.Int())
   706  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   707  				r.SetUint(vx.Uint() ^ vy.Uint())
   708  			default:
   709  				goto failed
   710  			}
   711  			return r.Interface()
   712  		}
   713  	}
   714  failed:
   715  	panic(fmt.Sprintf("invalid binary op: %T ^ %T", x, y))
   716  }
   717  
   718  func opANDNOT(x, y value) value {
   719  	switch x.(type) {
   720  	case int:
   721  		return x.(int) &^ y.(int)
   722  	case int8:
   723  		return x.(int8) &^ y.(int8)
   724  	case int16:
   725  		return x.(int16) &^ y.(int16)
   726  	case int32:
   727  		return x.(int32) &^ y.(int32)
   728  	case int64:
   729  		return x.(int64) &^ y.(int64)
   730  	case uint:
   731  		return x.(uint) &^ y.(uint)
   732  	case uint8:
   733  		return x.(uint8) &^ y.(uint8)
   734  	case uint16:
   735  		return x.(uint16) &^ y.(uint16)
   736  	case uint32:
   737  		return x.(uint32) &^ y.(uint32)
   738  	case uint64:
   739  		return x.(uint64) &^ y.(uint64)
   740  	case uintptr:
   741  		return x.(uintptr) &^ y.(uintptr)
   742  	default:
   743  		vx := reflect.ValueOf(x)
   744  		vy := reflect.ValueOf(y)
   745  		if kind := vx.Kind(); kind == vy.Kind() {
   746  			r := reflect.New(vx.Type()).Elem()
   747  			switch kind {
   748  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   749  				r.SetInt(vx.Int() &^ vy.Int())
   750  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   751  				r.SetUint(vx.Uint() &^ vy.Uint())
   752  			default:
   753  				goto failed
   754  			}
   755  			return r.Interface()
   756  		}
   757  	}
   758  failed:
   759  	panic(fmt.Sprintf("invalid binary op: %T &^ %T", x, y))
   760  }
   761  
   762  func opSHL(x, _y value) value {
   763  	y := asUint64(_y)
   764  	switch x.(type) {
   765  	case int:
   766  		return x.(int) << y
   767  	case int8:
   768  		return x.(int8) << y
   769  	case int16:
   770  		return x.(int16) << y
   771  	case int32:
   772  		return x.(int32) << y
   773  	case int64:
   774  		return x.(int64) << y
   775  	case uint:
   776  		return x.(uint) << y
   777  	case uint8:
   778  		return x.(uint8) << y
   779  	case uint16:
   780  		return x.(uint16) << y
   781  	case uint32:
   782  		return x.(uint32) << y
   783  	case uint64:
   784  		return x.(uint64) << y
   785  	case uintptr:
   786  		return x.(uintptr) << y
   787  	default:
   788  		vx := reflect.ValueOf(x)
   789  		r := reflect.New(vx.Type()).Elem()
   790  		switch vx.Kind() {
   791  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   792  			r.SetInt(vx.Int() << y)
   793  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   794  			r.SetUint(vx.Uint() << y)
   795  		default:
   796  			goto failed
   797  		}
   798  		return r.Interface()
   799  	}
   800  failed:
   801  	panic(fmt.Sprintf("invalid binary op: %T << %T", x, y))
   802  }
   803  
   804  func opSHR(x, _y value) value {
   805  	y := asUint64(_y)
   806  	switch x.(type) {
   807  	case int:
   808  		return x.(int) >> y
   809  	case int8:
   810  		return x.(int8) >> y
   811  	case int16:
   812  		return x.(int16) >> y
   813  	case int32:
   814  		return x.(int32) >> y
   815  	case int64:
   816  		return x.(int64) >> y
   817  	case uint:
   818  		return x.(uint) >> y
   819  	case uint8:
   820  		return x.(uint8) >> y
   821  	case uint16:
   822  		return x.(uint16) >> y
   823  	case uint32:
   824  		return x.(uint32) >> y
   825  	case uint64:
   826  		return x.(uint64) >> y
   827  	case uintptr:
   828  		return x.(uintptr) >> y
   829  	default:
   830  		vx := reflect.ValueOf(x)
   831  		r := reflect.New(vx.Type()).Elem()
   832  		switch vx.Kind() {
   833  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   834  			r.SetInt(vx.Int() >> y)
   835  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   836  			r.SetUint(vx.Uint() >> y)
   837  		default:
   838  			goto failed
   839  		}
   840  		return r.Interface()
   841  	}
   842  failed:
   843  	panic(fmt.Sprintf("invalid binary op: %T >> %T", x, y))
   844  }
   845  
   846  func opLSS(x, y value) value {
   847  	switch x.(type) {
   848  	case int:
   849  		return x.(int) < y.(int)
   850  	case int8:
   851  		return x.(int8) < y.(int8)
   852  	case int16:
   853  		return x.(int16) < y.(int16)
   854  	case int32:
   855  		return x.(int32) < y.(int32)
   856  	case int64:
   857  		return x.(int64) < y.(int64)
   858  	case uint:
   859  		return x.(uint) < y.(uint)
   860  	case uint8:
   861  		return x.(uint8) < y.(uint8)
   862  	case uint16:
   863  		return x.(uint16) < y.(uint16)
   864  	case uint32:
   865  		return x.(uint32) < y.(uint32)
   866  	case uint64:
   867  		return x.(uint64) < y.(uint64)
   868  	case uintptr:
   869  		return x.(uintptr) < y.(uintptr)
   870  	case float32:
   871  		return x.(float32) < y.(float32)
   872  	case float64:
   873  		return x.(float64) < y.(float64)
   874  	case string:
   875  		return x.(string) < y.(string)
   876  	default:
   877  		vx := reflect.ValueOf(x)
   878  		vy := reflect.ValueOf(y)
   879  		if kind := vx.Kind(); kind == vy.Kind() {
   880  			switch kind {
   881  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   882  				return vx.Int() < vy.Int()
   883  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   884  				return vx.Uint() < vy.Uint()
   885  			case reflect.Float32, reflect.Float64:
   886  				return vx.Float() < vy.Float()
   887  			case reflect.String:
   888  				return vx.String() < vy.String()
   889  			default:
   890  				goto failed
   891  			}
   892  		}
   893  	}
   894  failed:
   895  	panic(fmt.Sprintf("invalid binary op: %T < %T", x, y))
   896  }
   897  
   898  func opLEQ(x, y value) value {
   899  	switch x.(type) {
   900  	case int:
   901  		return x.(int) <= y.(int)
   902  	case int8:
   903  		return x.(int8) <= y.(int8)
   904  	case int16:
   905  		return x.(int16) <= y.(int16)
   906  	case int32:
   907  		return x.(int32) <= y.(int32)
   908  	case int64:
   909  		return x.(int64) <= y.(int64)
   910  	case uint:
   911  		return x.(uint) <= y.(uint)
   912  	case uint8:
   913  		return x.(uint8) <= y.(uint8)
   914  	case uint16:
   915  		return x.(uint16) <= y.(uint16)
   916  	case uint32:
   917  		return x.(uint32) <= y.(uint32)
   918  	case uint64:
   919  		return x.(uint64) <= y.(uint64)
   920  	case uintptr:
   921  		return x.(uintptr) <= y.(uintptr)
   922  	case float32:
   923  		return x.(float32) <= y.(float32)
   924  	case float64:
   925  		return x.(float64) <= y.(float64)
   926  	case string:
   927  		return x.(string) <= y.(string)
   928  	default:
   929  		vx := reflect.ValueOf(x)
   930  		vy := reflect.ValueOf(y)
   931  		if kind := vx.Kind(); kind == vy.Kind() {
   932  			switch kind {
   933  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   934  				return vx.Int() <= vy.Int()
   935  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   936  				return vx.Uint() <= vy.Uint()
   937  			case reflect.Float32, reflect.Float64:
   938  				return vx.Float() <= vy.Float()
   939  			case reflect.String:
   940  				return vx.String() <= vy.String()
   941  			default:
   942  				goto failed
   943  			}
   944  		}
   945  	}
   946  failed:
   947  	panic(fmt.Sprintf("invalid binary op: %T <= %T", x, y))
   948  }
   949  
   950  func opGTR(x, y value) value {
   951  	switch x.(type) {
   952  	case int:
   953  		return x.(int) > y.(int)
   954  	case int8:
   955  		return x.(int8) > y.(int8)
   956  	case int16:
   957  		return x.(int16) > y.(int16)
   958  	case int32:
   959  		return x.(int32) > y.(int32)
   960  	case int64:
   961  		return x.(int64) > y.(int64)
   962  	case uint:
   963  		return x.(uint) > y.(uint)
   964  	case uint8:
   965  		return x.(uint8) > y.(uint8)
   966  	case uint16:
   967  		return x.(uint16) > y.(uint16)
   968  	case uint32:
   969  		return x.(uint32) > y.(uint32)
   970  	case uint64:
   971  		return x.(uint64) > y.(uint64)
   972  	case uintptr:
   973  		return x.(uintptr) > y.(uintptr)
   974  	case float32:
   975  		return x.(float32) > y.(float32)
   976  	case float64:
   977  		return x.(float64) > y.(float64)
   978  	case string:
   979  		return x.(string) > y.(string)
   980  	default:
   981  		vx := reflect.ValueOf(x)
   982  		vy := reflect.ValueOf(y)
   983  		if kind := vx.Kind(); kind == vy.Kind() {
   984  			switch kind {
   985  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   986  				return vx.Int() > vy.Int()
   987  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   988  				return vx.Uint() > vy.Uint()
   989  			case reflect.Float32, reflect.Float64:
   990  				return vx.Float() > vy.Float()
   991  			case reflect.String:
   992  				return vx.String() > vy.String()
   993  			default:
   994  				goto failed
   995  			}
   996  		}
   997  	}
   998  failed:
   999  	panic(fmt.Sprintf("invalid binary op: %T > %T", x, y))
  1000  }
  1001  
  1002  func opGEQ(x, y value) value {
  1003  	switch x.(type) {
  1004  	case int:
  1005  		return x.(int) >= y.(int)
  1006  	case int8:
  1007  		return x.(int8) >= y.(int8)
  1008  	case int16:
  1009  		return x.(int16) >= y.(int16)
  1010  	case int32:
  1011  		return x.(int32) >= y.(int32)
  1012  	case int64:
  1013  		return x.(int64) >= y.(int64)
  1014  	case uint:
  1015  		return x.(uint) >= y.(uint)
  1016  	case uint8:
  1017  		return x.(uint8) >= y.(uint8)
  1018  	case uint16:
  1019  		return x.(uint16) >= y.(uint16)
  1020  	case uint32:
  1021  		return x.(uint32) >= y.(uint32)
  1022  	case uint64:
  1023  		return x.(uint64) >= y.(uint64)
  1024  	case uintptr:
  1025  		return x.(uintptr) >= y.(uintptr)
  1026  	case float32:
  1027  		return x.(float32) >= y.(float32)
  1028  	case float64:
  1029  		return x.(float64) >= y.(float64)
  1030  	case string:
  1031  		return x.(string) >= y.(string)
  1032  	default:
  1033  		vx := reflect.ValueOf(x)
  1034  		vy := reflect.ValueOf(y)
  1035  		if kind := vx.Kind(); kind == vy.Kind() {
  1036  			switch kind {
  1037  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1038  				return vx.Int() >= vy.Int()
  1039  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1040  				return vx.Uint() >= vy.Uint()
  1041  			case reflect.Float32, reflect.Float64:
  1042  				return vx.Float() >= vy.Float()
  1043  			case reflect.String:
  1044  				return vx.String() >= vy.String()
  1045  			default:
  1046  				goto failed
  1047  			}
  1048  		}
  1049  	}
  1050  failed:
  1051  	panic(fmt.Sprintf("invalid binary op: %T >= %T", x, y))
  1052  }
  1053  
  1054  // binop implements all arithmetic and logical binary operators for
  1055  // numeric datatypes and strings.  Both operands must have identical
  1056  // dynamic type.
  1057  //
  1058  func binop(instr *ssa.BinOp, t types.Type, x, y value) value {
  1059  	switch instr.Op {
  1060  	case token.ADD:
  1061  		return opADD(x, y)
  1062  	case token.SUB:
  1063  		return opSUB(x, y)
  1064  	case token.MUL:
  1065  		return opMUL(x, y)
  1066  	case token.QUO:
  1067  		return opQuo(x, y)
  1068  	case token.REM:
  1069  		return opREM(x, y)
  1070  	case token.AND:
  1071  		return opAND(x, y)
  1072  	case token.OR:
  1073  		return opOR(x, y)
  1074  	case token.XOR:
  1075  		return opXOR(x, y)
  1076  	case token.AND_NOT:
  1077  		return opANDNOT(x, y)
  1078  	case token.SHL:
  1079  		return opSHL(x, y)
  1080  	case token.SHR:
  1081  		return opSHR(x, y)
  1082  	case token.LSS:
  1083  		return opLSS(x, y)
  1084  	case token.LEQ:
  1085  		return opLEQ(x, y)
  1086  	case token.EQL:
  1087  		return opEQL(instr, x, y)
  1088  	case token.NEQ:
  1089  		return !opEQL(instr, x, y)
  1090  	case token.GTR:
  1091  		return opGTR(x, y)
  1092  	case token.GEQ:
  1093  		return opGEQ(x, y)
  1094  	}
  1095  	panic(fmt.Sprintf("invalid binary op: %T %s %T", x, instr.Op, y))
  1096  }
  1097  
  1098  func IsConstNil(v ssa.Value) bool {
  1099  	switch c := v.(type) {
  1100  	case *ssa.Const:
  1101  		return c.IsNil()
  1102  	}
  1103  	return false
  1104  }
  1105  
  1106  func IsNil(v reflect.Value) bool {
  1107  	switch v.Kind() {
  1108  	case reflect.Invalid:
  1109  		return true
  1110  	case reflect.Slice, reflect.Map, reflect.Func:
  1111  		return v.IsNil()
  1112  	case reflect.Chan, reflect.Ptr, reflect.UnsafePointer, reflect.Interface:
  1113  		return v.IsNil()
  1114  	default:
  1115  		return false
  1116  	}
  1117  }
  1118  
  1119  func opEQL(instr *ssa.BinOp, x, y interface{}) bool {
  1120  	vx := reflect.ValueOf(x)
  1121  	vy := reflect.ValueOf(y)
  1122  	if vx.Kind() != vy.Kind() {
  1123  		return false
  1124  	}
  1125  	if IsConstNil(instr.X) {
  1126  		return IsNil(vy)
  1127  	} else if IsConstNil(instr.Y) {
  1128  		return IsNil(vx)
  1129  	}
  1130  	return equalValue(vx, vy)
  1131  }
  1132  
  1133  func equalNil(vx, vy reflect.Value) bool {
  1134  	if IsNil(vx) {
  1135  		return IsNil(vy)
  1136  	} else if IsNil(vy) {
  1137  		return IsNil(vx)
  1138  	}
  1139  	return equalValue(vx, vy)
  1140  }
  1141  
  1142  func equalValue(vx, vy reflect.Value) bool {
  1143  	if kind := vx.Kind(); kind == vy.Kind() {
  1144  		switch kind {
  1145  		case reflect.Invalid:
  1146  			return true
  1147  		case reflect.Chan:
  1148  			dirx := vx.Type().ChanDir()
  1149  			diry := vy.Type().ChanDir()
  1150  			if dirx != diry {
  1151  				if dirx == reflect.BothDir {
  1152  					return vy.Interface() == vx.Convert(vy.Type()).Interface()
  1153  				} else if diry == reflect.BothDir {
  1154  					return vx.Interface() == vy.Convert(vx.Type()).Interface()
  1155  				}
  1156  			} else {
  1157  				return vx.Interface() == vy.Interface()
  1158  			}
  1159  		case reflect.Ptr:
  1160  			return vx.Pointer() == vy.Pointer()
  1161  		case reflect.Struct:
  1162  			return equalStruct(vx, vy)
  1163  		case reflect.Array:
  1164  			return equalArray(vx, vy)
  1165  		default:
  1166  			return vx.Interface() == vy.Interface()
  1167  		}
  1168  	}
  1169  	return false
  1170  }
  1171  
  1172  func equalArray(vx, vy reflect.Value) bool {
  1173  	xlen := vx.Len()
  1174  	if xlen != vy.Len() {
  1175  		return false
  1176  	}
  1177  	if vx.Type().Elem() != vy.Type().Elem() {
  1178  		return false
  1179  	}
  1180  	for i := 0; i < xlen; i++ {
  1181  		fx := vx.Index(i)
  1182  		fy := vy.Index(i)
  1183  		if !equalNil(fx, fy) {
  1184  			return false
  1185  		}
  1186  	}
  1187  	return true
  1188  }
  1189  
  1190  func equalStruct(vx, vy reflect.Value) bool {
  1191  	typ := vx.Type()
  1192  	if typ != vy.Type() {
  1193  		return false
  1194  	}
  1195  	n := typ.NumField()
  1196  	for i := 0; i < n; i++ {
  1197  		f := typ.Field(i)
  1198  		if f.Name == "_" {
  1199  			continue
  1200  		}
  1201  		fx := reflectx.FieldByIndexX(vx, f.Index)
  1202  		fy := reflectx.FieldByIndexX(vy, f.Index)
  1203  		// check uncomparable
  1204  		switch f.Type.Kind() {
  1205  		case reflect.Slice, reflect.Map, reflect.Func:
  1206  			if fx.Interface() != fy.Interface() {
  1207  				return false
  1208  			}
  1209  		}
  1210  		if !equalNil(fx, fy) {
  1211  			return false
  1212  		}
  1213  	}
  1214  	return true
  1215  }
  1216  
  1217  func unop(instr *ssa.UnOp, x value) value {
  1218  	switch instr.Op {
  1219  	case token.ARROW: // receive
  1220  		vx := reflect.ValueOf(x)
  1221  		v, ok := vx.Recv()
  1222  		if !ok {
  1223  			v = reflect.New(vx.Type().Elem()).Elem()
  1224  		}
  1225  		if instr.CommaOk {
  1226  			return tuple{v.Interface(), ok}
  1227  		}
  1228  		return v.Interface()
  1229  		// if !ok {
  1230  		// 	v = zero(instr.X.Type().Underlying().(*types.Chan).Elem())
  1231  		// }
  1232  		// if instr.CommaOk {
  1233  		// 	v = tuple{v, ok}
  1234  		// }
  1235  		// return v
  1236  	case token.SUB:
  1237  		switch x := x.(type) {
  1238  		case int:
  1239  			return -x
  1240  		case int8:
  1241  			return -x
  1242  		case int16:
  1243  			return -x
  1244  		case int32:
  1245  			return -x
  1246  		case int64:
  1247  			return -x
  1248  		case uint:
  1249  			return -x
  1250  		case uint8:
  1251  			return -x
  1252  		case uint16:
  1253  			return -x
  1254  		case uint32:
  1255  			return -x
  1256  		case uint64:
  1257  			return -x
  1258  		case uintptr:
  1259  			return -x
  1260  		case float32:
  1261  			return -x
  1262  		case float64:
  1263  			return -x
  1264  		case complex64:
  1265  			return -x
  1266  		case complex128:
  1267  			return -x
  1268  		default:
  1269  			v := reflect.ValueOf(x)
  1270  			r := reflect.New(v.Type()).Elem()
  1271  			switch v.Kind() {
  1272  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1273  				r.SetInt(-v.Int())
  1274  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1275  				r.SetUint(-v.Uint())
  1276  			case reflect.Float32, reflect.Float64:
  1277  				r.SetFloat(-v.Float())
  1278  			case reflect.Complex64, reflect.Complex128:
  1279  				r.SetComplex(-v.Complex())
  1280  			}
  1281  			return r.Interface()
  1282  		}
  1283  	case token.MUL:
  1284  		v := reflect.ValueOf(x).Elem()
  1285  		if !v.IsValid() {
  1286  			panic(runtimeError("invalid memory address or nil pointer dereference"))
  1287  		}
  1288  		return v.Interface()
  1289  		//return load(deref(instr.X.Type()), x.(*value))
  1290  	case token.NOT:
  1291  		switch x := x.(type) {
  1292  		case bool:
  1293  			return !x
  1294  		default:
  1295  			v := reflect.ValueOf(x)
  1296  			if v.Kind() == reflect.Bool {
  1297  				r := reflect.New(v.Type()).Elem()
  1298  				if v.Bool() {
  1299  					return v.Interface()
  1300  				}
  1301  				r.SetBool(true)
  1302  				return r.Interface()
  1303  			}
  1304  		}
  1305  		// return !x.(bool)
  1306  	case token.XOR:
  1307  		switch x := x.(type) {
  1308  		case int:
  1309  			return ^x
  1310  		case int8:
  1311  			return ^x
  1312  		case int16:
  1313  			return ^x
  1314  		case int32:
  1315  			return ^x
  1316  		case int64:
  1317  			return ^x
  1318  		case uint:
  1319  			return ^x
  1320  		case uint8:
  1321  			return ^x
  1322  		case uint16:
  1323  			return ^x
  1324  		case uint32:
  1325  			return ^x
  1326  		case uint64:
  1327  			return ^x
  1328  		case uintptr:
  1329  			return ^x
  1330  		default:
  1331  			vx := reflect.ValueOf(x)
  1332  			r := reflect.New(vx.Type()).Elem()
  1333  			switch vx.Kind() {
  1334  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1335  				r.SetInt(^r.Int())
  1336  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1337  				r.SetUint(^r.Uint())
  1338  			default:
  1339  				goto failed
  1340  			}
  1341  			return r.Interface()
  1342  		}
  1343  	}
  1344  failed:
  1345  	panic(fmt.Sprintf("invalid unary op %s %T", instr.Op, x))
  1346  }
  1347  
  1348  // typeAssert checks whether dynamic type of itf is instr.AssertedType.
  1349  // It returns the extracted value on success, and panics on failure,
  1350  // unless instr.CommaOk, in which case it always returns a "value,ok" tuple.
  1351  //
  1352  func typeAssert(i *Interp, instr *ssa.TypeAssert, typ reflect.Type, iv interface{}) value {
  1353  	var v value
  1354  	var err error
  1355  	if iv == nil {
  1356  		err = plainError(fmt.Sprintf("interface conversion: interface is nil, not %v", typ))
  1357  	} else {
  1358  		rv := reflect.ValueOf(iv)
  1359  		rt := rv.Type()
  1360  		if typ == rt {
  1361  			v = iv
  1362  		} else {
  1363  			if !rt.AssignableTo(typ) {
  1364  				err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v", instr.X.Type(), rt, typ))
  1365  				if itype, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
  1366  					if it, ok := i.findType(rt, false); ok {
  1367  						if meth, _ := types.MissingMethod(it, itype, true); meth != nil {
  1368  							err = runtimeError(fmt.Sprintf("interface conversion: %v is not %v: missing method %s",
  1369  								rt, instr.AssertedType, meth.Name()))
  1370  						}
  1371  					}
  1372  				} else if typ.PkgPath() == rt.PkgPath() && typ.Name() == rt.Name() {
  1373  					t1, ok1 := i.findType(typ, false)
  1374  					t2, ok2 := i.findType(rt, false)
  1375  					if ok1 && ok2 {
  1376  						n1, ok1 := t1.(*types.Named)
  1377  						n2, ok2 := t2.(*types.Named)
  1378  						if ok1 && ok2 && n1.Obj().Parent() != n2.Obj().Parent() {
  1379  							err = runtimeError(fmt.Sprintf("interface conversion: %v is %v, not %v (types from different scopes)", instr.X.Type(), rt, typ))
  1380  						}
  1381  					}
  1382  				}
  1383  			} else {
  1384  				v = rv.Convert(typ).Interface()
  1385  			}
  1386  		}
  1387  	}
  1388  	if err != nil {
  1389  		if !instr.CommaOk {
  1390  			panic(err)
  1391  		}
  1392  		return tuple{reflect.New(typ).Elem().Interface(), false}
  1393  	}
  1394  	if instr.CommaOk {
  1395  		return tuple{v, true}
  1396  	}
  1397  	return v
  1398  	// err := ""
  1399  	// if itf.t == nil {
  1400  	// 	err = fmt.Sprintf("interface conversion: interface is nil, not %s", instr.AssertedType)
  1401  
  1402  	// } else if idst, ok := instr.AssertedType.Underlying().(*types.Interface); ok {
  1403  	// 	v = itf
  1404  	// 	err = checkInterface(i, idst, itf)
  1405  
  1406  	// } else if types.Identical(itf.t, instr.AssertedType) {
  1407  	// 	v = itf.v // extract value
  1408  
  1409  	// } else {
  1410  	// 	err = fmt.Sprintf("interface conversion: interface is %s, not %s", itf.t, instr.AssertedType)
  1411  	// }
  1412  
  1413  	// if err != "" {
  1414  	// 	if !instr.CommaOk {
  1415  	// 		panic(err)
  1416  	// 	}
  1417  	// 	return tuple{zero(instr.AssertedType), false}
  1418  	// }
  1419  	// if instr.CommaOk {
  1420  	// 	return tuple{v, true}
  1421  	// }
  1422  	// return v
  1423  }
  1424  
  1425  // callBuiltin interprets a call to builtin fn with arguments args,
  1426  // returning its result.
  1427  func (inter *Interp) callBuiltin(caller *frame, fn *ssa.Builtin, args []value, ssaArgs []ssa.Value) value {
  1428  	switch fnName := fn.Name(); fnName {
  1429  	case "append":
  1430  		if len(args) == 1 {
  1431  			return args[0]
  1432  		}
  1433  		if s, ok := args[1].(string); ok {
  1434  			// append([]byte, ...string) []byte
  1435  			args[1] = []byte(s)
  1436  		}
  1437  		v0 := reflect.ValueOf(args[0])
  1438  		v1 := reflect.ValueOf(args[1])
  1439  		i0 := v0.Len()
  1440  		i1 := v1.Len()
  1441  		if i0+i1 < i0 {
  1442  			panic(runtimeError("growslice: cap out of range"))
  1443  		}
  1444  		return reflect.AppendSlice(v0, v1).Interface()
  1445  
  1446  	case "copy": // copy([]T, []T) int or copy([]byte, string) int
  1447  		return reflect.Copy(reflect.ValueOf(args[0]), reflect.ValueOf(args[1]))
  1448  
  1449  	case "close": // close(chan T)
  1450  		reflect.ValueOf(args[0]).Close()
  1451  		return nil
  1452  
  1453  	case "delete": // delete(map[K]value, K)
  1454  		reflect.ValueOf(args[0]).SetMapIndex(reflect.ValueOf(args[1]), reflect.Value{})
  1455  		return nil
  1456  
  1457  	case "print", "println": // print(any, ...)
  1458  		ln := fn.Name() == "println"
  1459  		var buf bytes.Buffer
  1460  		for i, arg := range args {
  1461  			if i > 0 && ln {
  1462  				buf.WriteRune(' ')
  1463  			}
  1464  			if len(ssaArgs) > i {
  1465  				typ := inter.toType(ssaArgs[i].Type())
  1466  				if typ.Kind() == reflect.Interface {
  1467  					writeinterface(&buf, arg)
  1468  					continue
  1469  				}
  1470  			}
  1471  			writevalue(&buf, arg, inter.mode&EnablePrintAny != 0)
  1472  		}
  1473  		if ln {
  1474  			buf.WriteRune('\n')
  1475  		}
  1476  		inter.ctx.writeOutput(buf.Bytes())
  1477  		return nil
  1478  
  1479  	case "len":
  1480  		return reflect.ValueOf(args[0]).Len()
  1481  
  1482  	case "cap":
  1483  		return reflect.ValueOf(args[0]).Cap()
  1484  
  1485  	case "real":
  1486  		c := reflect.ValueOf(args[0])
  1487  		switch c.Kind() {
  1488  		case reflect.Complex64:
  1489  			return real(complex64(c.Complex()))
  1490  		case reflect.Complex128:
  1491  			return real(c.Complex())
  1492  		default:
  1493  			panic(fmt.Sprintf("real: illegal operand: %T", c))
  1494  		}
  1495  
  1496  	case "imag":
  1497  		c := reflect.ValueOf(args[0])
  1498  		switch c.Kind() {
  1499  		case reflect.Complex64:
  1500  			return imag(complex64(c.Complex()))
  1501  		case reflect.Complex128:
  1502  			return imag(c.Complex())
  1503  		default:
  1504  			panic(fmt.Sprintf("imag: illegal operand: %T", c))
  1505  		}
  1506  
  1507  	case "complex":
  1508  		r := reflect.ValueOf(args[0])
  1509  		i := reflect.ValueOf(args[1])
  1510  		switch r.Kind() {
  1511  		case reflect.Float32:
  1512  			return complex(float32(r.Float()), float32(i.Float()))
  1513  		case reflect.Float64:
  1514  			return complex(r.Float(), i.Float())
  1515  		default:
  1516  			panic(fmt.Sprintf("complex: illegal operand: %v", r.Kind()))
  1517  		}
  1518  
  1519  	case "panic":
  1520  		// ssa.Panic handles most cases; this is only for "go
  1521  		// panic" or "defer panic".
  1522  		panic(targetPanic{args[0]})
  1523  
  1524  	case "recover":
  1525  		return doRecover(caller)
  1526  
  1527  	case "ssa:wrapnilchk":
  1528  		recv := args[0]
  1529  		if reflect.ValueOf(recv).IsNil() {
  1530  			recvType := args[1]
  1531  			methodName := args[2]
  1532  			var info value
  1533  			if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") {
  1534  				info = s[5:]
  1535  			} else {
  1536  				info = recvType
  1537  			}
  1538  			panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer",
  1539  				recvType, methodName, info)))
  1540  		}
  1541  		return recv
  1542  
  1543  	case "Add":
  1544  		ptr := args[0].(unsafe.Pointer)
  1545  		length := asInt(args[1])
  1546  		return unsafe.Pointer(uintptr(ptr) + uintptr(length))
  1547  	case "Slice":
  1548  		//func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
  1549  		//(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
  1550  		ptr := reflect.ValueOf(args[0])
  1551  		length := asInt(args[1])
  1552  		if ptr.IsNil() {
  1553  			if length == 0 {
  1554  				return reflect.New(reflect.SliceOf(ptr.Type().Elem())).Elem().Interface()
  1555  			}
  1556  			panic(runtimeError("unsafe.Slice: ptr is nil and len is not zero"))
  1557  		}
  1558  		typ := reflect.ArrayOf(length, ptr.Type().Elem())
  1559  		v := reflect.NewAt(typ, unsafe.Pointer(ptr.Pointer()))
  1560  		return v.Elem().Slice(0, length).Interface()
  1561  	default:
  1562  		panic("unknown built-in: " + fnName)
  1563  	}
  1564  }
  1565  
  1566  // callBuiltinDiscardsResult interprets a call to builtin fn with arguments args,
  1567  // discards its result.
  1568  func (inter *Interp) callBuiltinDiscardsResult(caller *frame, fn *ssa.Builtin, args []value, ssaArgs []ssa.Value) {
  1569  	switch fnName := fn.Name(); fnName {
  1570  	case "append":
  1571  		panic("discards result of " + fnName)
  1572  
  1573  	case "copy": // copy([]T, []T) int or copy([]byte, string) int
  1574  		reflect.Copy(reflect.ValueOf(args[0]), reflect.ValueOf(args[1]))
  1575  
  1576  	case "close": // close(chan T)
  1577  		reflect.ValueOf(args[0]).Close()
  1578  
  1579  	case "delete": // delete(map[K]value, K)
  1580  		reflect.ValueOf(args[0]).SetMapIndex(reflect.ValueOf(args[1]), reflect.Value{})
  1581  
  1582  	case "print", "println": // print(any, ...)
  1583  		ln := fn.Name() == "println"
  1584  		var buf bytes.Buffer
  1585  		for i, arg := range args {
  1586  			if i > 0 && ln {
  1587  				buf.WriteRune(' ')
  1588  			}
  1589  			if len(ssaArgs) > i {
  1590  				typ := inter.toType(ssaArgs[i].Type())
  1591  				if typ.Kind() == reflect.Interface {
  1592  					writeinterface(&buf, arg)
  1593  					continue
  1594  				}
  1595  			}
  1596  			writevalue(&buf, arg, inter.mode&EnablePrintAny != 0)
  1597  		}
  1598  		if ln {
  1599  			buf.WriteRune('\n')
  1600  		}
  1601  		inter.ctx.writeOutput(buf.Bytes())
  1602  
  1603  	case "len":
  1604  		panic("discards result of " + fnName)
  1605  
  1606  	case "cap":
  1607  		panic("discards result of " + fnName)
  1608  
  1609  	case "real":
  1610  		panic("discards result of " + fnName)
  1611  
  1612  	case "imag":
  1613  		panic("discards result of " + fnName)
  1614  
  1615  	case "complex":
  1616  		panic("discards result of " + fnName)
  1617  
  1618  	case "panic":
  1619  		// ssa.Panic handles most cases; this is only for "go
  1620  		// panic" or "defer panic".
  1621  		panic(targetPanic{args[0]})
  1622  
  1623  	case "recover":
  1624  		doRecover(caller)
  1625  
  1626  	case "ssa:wrapnilchk":
  1627  		recv := args[0]
  1628  		if reflect.ValueOf(recv).IsNil() {
  1629  			recvType := args[1]
  1630  			methodName := args[2]
  1631  			var info value
  1632  			if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") {
  1633  				info = s[5:]
  1634  			} else {
  1635  				info = recvType
  1636  			}
  1637  			panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer",
  1638  				recvType, methodName, info)))
  1639  		}
  1640  
  1641  	case "Add":
  1642  		panic("discards result of " + fnName)
  1643  
  1644  	case "Slice":
  1645  		//func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
  1646  		//(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
  1647  		panic("discards result of " + fnName)
  1648  
  1649  	default:
  1650  		panic("unknown built-in: " + fnName)
  1651  	}
  1652  }
  1653  
  1654  // callBuiltin interprets a call to builtin fn with arguments args,
  1655  // returning its result.
  1656  func (inter *Interp) callBuiltinByStack(caller *frame, fn string, ssaArgs []ssa.Value, ir register, ia []register) {
  1657  	switch fn {
  1658  	case "append":
  1659  		if len(ia) == 1 {
  1660  			caller.copyReg(ir, ia[0])
  1661  			return
  1662  		}
  1663  		arg0 := caller.reg(ia[0])
  1664  		arg1 := caller.reg(ia[1])
  1665  		if s, ok := arg1.(string); ok {
  1666  			// append([]byte, ...string) []byte
  1667  			arg1 = []byte(s)
  1668  		}
  1669  		v0 := reflect.ValueOf(arg0)
  1670  		v1 := reflect.ValueOf(arg1)
  1671  		i0 := v0.Len()
  1672  		i1 := v1.Len()
  1673  		if i0+i1 < i0 {
  1674  			panic(runtimeError("growslice: cap out of range"))
  1675  		}
  1676  		caller.setReg(ir, reflect.AppendSlice(v0, v1).Interface())
  1677  
  1678  	case "copy": // copy([]T, []T) int or copy([]byte, string) int
  1679  		arg0 := caller.reg(ia[0])
  1680  		arg1 := caller.reg(ia[1])
  1681  		caller.setReg(ir, reflect.Copy(reflect.ValueOf(arg0), reflect.ValueOf(arg1)))
  1682  
  1683  	case "close": // close(chan T)
  1684  		arg0 := caller.reg(ia[0])
  1685  		reflect.ValueOf(arg0).Close()
  1686  
  1687  	case "delete": // delete(map[K]value, K)
  1688  		arg0 := caller.reg(ia[0])
  1689  		arg1 := caller.reg(ia[1])
  1690  		reflect.ValueOf(arg0).SetMapIndex(reflect.ValueOf(arg1), reflect.Value{})
  1691  
  1692  	case "print", "println": // print(any, ...)
  1693  		ln := fn == "println"
  1694  		var buf bytes.Buffer
  1695  		for i := 0; i < len(ia); i++ {
  1696  			arg := caller.reg(ia[i])
  1697  			if i > 0 && ln {
  1698  				buf.WriteRune(' ')
  1699  			}
  1700  			if len(ssaArgs) > i {
  1701  				typ := inter.toType(ssaArgs[i].Type())
  1702  				if typ.Kind() == reflect.Interface {
  1703  					writeinterface(&buf, arg)
  1704  					continue
  1705  				}
  1706  			}
  1707  			writevalue(&buf, arg, inter.mode&EnablePrintAny != 0)
  1708  		}
  1709  		if ln {
  1710  			buf.WriteRune('\n')
  1711  		}
  1712  		inter.ctx.writeOutput(buf.Bytes())
  1713  
  1714  	case "len":
  1715  		arg0 := caller.reg(ia[0])
  1716  		caller.setReg(ir, reflect.ValueOf(arg0).Len())
  1717  
  1718  	case "cap":
  1719  		arg0 := caller.reg(ia[0])
  1720  		caller.setReg(ir, reflect.ValueOf(arg0).Cap())
  1721  
  1722  	case "real":
  1723  		arg0 := caller.reg(ia[0])
  1724  		c := reflect.ValueOf(arg0)
  1725  		switch c.Kind() {
  1726  		case reflect.Complex64:
  1727  			caller.setReg(ir, real(complex64(c.Complex())))
  1728  		case reflect.Complex128:
  1729  			caller.setReg(ir, real(c.Complex()))
  1730  		default:
  1731  			panic(fmt.Sprintf("real: illegal operand: %T", c))
  1732  		}
  1733  
  1734  	case "imag":
  1735  		arg0 := caller.reg(ia[0])
  1736  		c := reflect.ValueOf(arg0)
  1737  		switch c.Kind() {
  1738  		case reflect.Complex64:
  1739  			caller.setReg(ir, imag(complex64(c.Complex())))
  1740  		case reflect.Complex128:
  1741  			caller.setReg(ir, imag(c.Complex()))
  1742  		default:
  1743  			panic(fmt.Sprintf("imag: illegal operand: %T", c))
  1744  		}
  1745  
  1746  	case "complex":
  1747  		arg0 := caller.reg(ia[0])
  1748  		arg1 := caller.reg(ia[1])
  1749  		r := reflect.ValueOf(arg0)
  1750  		i := reflect.ValueOf(arg1)
  1751  		switch r.Kind() {
  1752  		case reflect.Float32:
  1753  			caller.setReg(ir, complex(float32(r.Float()), float32(i.Float())))
  1754  		case reflect.Float64:
  1755  			caller.setReg(ir, complex(r.Float(), i.Float()))
  1756  		default:
  1757  			panic(fmt.Sprintf("complex: illegal operand: %v", r.Kind()))
  1758  		}
  1759  
  1760  	case "panic":
  1761  		// ssa.Panic handles most cases; this is only for "go
  1762  		// panic" or "defer panic".
  1763  		arg0 := caller.reg(ia[0])
  1764  		panic(targetPanic{arg0})
  1765  
  1766  	case "recover":
  1767  		caller.setReg(ir, doRecover(caller))
  1768  
  1769  	case "ssa:wrapnilchk":
  1770  		recv := caller.reg(ia[0])
  1771  		if reflect.ValueOf(recv).IsNil() {
  1772  			recvType := caller.reg(ia[1])
  1773  			methodName := caller.reg(ia[2])
  1774  			var info value
  1775  			if s, ok := recvType.(string); ok && strings.HasPrefix(s, "main.") {
  1776  				info = s[5:]
  1777  			} else {
  1778  				info = recvType
  1779  			}
  1780  			panic(plainError(fmt.Sprintf("value method %s.%s called using nil *%s pointer",
  1781  				recvType, methodName, info)))
  1782  		}
  1783  		caller.setReg(ir, recv)
  1784  
  1785  	case "Add":
  1786  		arg0 := caller.reg(ia[0])
  1787  		arg1 := caller.reg(ia[1])
  1788  		ptr := arg0.(unsafe.Pointer)
  1789  		length := asInt(arg1)
  1790  		caller.setReg(ir, unsafe.Pointer(uintptr(ptr)+uintptr(length)))
  1791  	case "Slice":
  1792  		//func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
  1793  		//(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
  1794  		arg0 := caller.reg(ia[0])
  1795  		arg1 := caller.reg(ia[1])
  1796  		ptr := reflect.ValueOf(arg0)
  1797  		length := asInt(arg1)
  1798  		if ptr.IsNil() {
  1799  			if length == 0 {
  1800  				caller.setReg(ir, reflect.New(reflect.SliceOf(ptr.Type().Elem())).Elem().Interface())
  1801  				return
  1802  			}
  1803  			panic(runtimeError("unsafe.Slice: ptr is nil and len is not zero"))
  1804  		}
  1805  		typ := reflect.ArrayOf(length, ptr.Type().Elem())
  1806  		v := reflect.NewAt(typ, unsafe.Pointer(ptr.Pointer()))
  1807  		caller.setReg(ir, v.Elem().Slice(0, length).Interface())
  1808  	default:
  1809  		panic("unknown built-in: " + fn)
  1810  	}
  1811  }
  1812  
  1813  // widen widens a xtype typed value x to the widest type of its
  1814  // category, one of:
  1815  //   bool, int64, uint64, float64, complex128, string.
  1816  // This is inefficient but reduces the size of the cross-product of
  1817  // cases we have to consider.
  1818  //
  1819  func widen(x value) value {
  1820  	switch y := x.(type) {
  1821  	case bool, int64, uint64, float64, complex128, string, unsafe.Pointer:
  1822  		return x
  1823  	case int:
  1824  		return int64(y)
  1825  	case int8:
  1826  		return int64(y)
  1827  	case int16:
  1828  		return int64(y)
  1829  	case int32:
  1830  		return int64(y)
  1831  	case uint:
  1832  		return uint64(y)
  1833  	case uint8:
  1834  		return uint64(y)
  1835  	case uint16:
  1836  		return uint64(y)
  1837  	case uint32:
  1838  		return uint64(y)
  1839  	case uintptr:
  1840  		return uint64(y)
  1841  	case float32:
  1842  		return float64(y)
  1843  	case complex64:
  1844  		return complex128(y)
  1845  	}
  1846  	panic(fmt.Sprintf("cannot widen %T", x))
  1847  }
  1848  
  1849  //go:nocheckptr
  1850  func toUnsafePointer(v uintptr) unsafe.Pointer {
  1851  	return unsafe.Pointer(v)
  1852  }
  1853  
  1854  func toUserFuncId(v *reflect.Value) uintptr {
  1855  	return uintptr((*reflectValue)(unsafe.Pointer(v)).ptr)
  1856  }
  1857  
  1858  type reflectValue struct {
  1859  	typ  unsafe.Pointer
  1860  	ptr  unsafe.Pointer
  1861  	flag uintptr
  1862  }
  1863  
  1864  func convert(x interface{}, typ reflect.Type) interface{} {
  1865  	v := reflect.ValueOf(x)
  1866  	vk := v.Kind()
  1867  	switch typ.Kind() {
  1868  	case reflect.UnsafePointer:
  1869  		if vk == reflect.Uintptr {
  1870  			return toUnsafePointer(uintptr(v.Uint()))
  1871  		} else if vk == reflect.Ptr {
  1872  			return unsafe.Pointer(v.Pointer())
  1873  		}
  1874  	case reflect.Uintptr:
  1875  		if vk == reflect.UnsafePointer {
  1876  			return v.Pointer()
  1877  		}
  1878  	case reflect.Ptr:
  1879  		if vk == reflect.UnsafePointer {
  1880  			return reflect.NewAt(typ.Elem(), unsafe.Pointer(v.Pointer())).Interface()
  1881  		}
  1882  	case reflect.Slice:
  1883  		if v.Kind() == reflect.String {
  1884  			elem := typ.Elem()
  1885  			switch elem.Kind() {
  1886  			case reflect.Uint8:
  1887  				if elem.PkgPath() != "" {
  1888  					dst := reflect.New(typ).Elem()
  1889  					dst.SetBytes([]byte(v.String()))
  1890  					return dst.Interface()
  1891  				}
  1892  			case reflect.Int32:
  1893  				if elem.PkgPath() != "" {
  1894  					dst := reflect.New(typ).Elem()
  1895  					*(*[]rune)((*reflectValue)(unsafe.Pointer(&dst)).ptr) = []rune(v.String())
  1896  					return dst.Interface()
  1897  				}
  1898  			}
  1899  		}
  1900  	case reflect.String:
  1901  		if v.Kind() == reflect.Slice {
  1902  			elem := v.Type().Elem()
  1903  			switch elem.Kind() {
  1904  			case reflect.Uint8:
  1905  				if elem.PkgPath() != "" {
  1906  					v = reflect.ValueOf(string(v.Bytes()))
  1907  				}
  1908  			case reflect.Int32:
  1909  				if elem.PkgPath() != "" {
  1910  					v = reflect.ValueOf(*(*[]rune)(((*reflectValue)(unsafe.Pointer(&v))).ptr))
  1911  				}
  1912  			}
  1913  		}
  1914  	}
  1915  	return v.Convert(typ).Interface()
  1916  }