github.com/jd-ly/tools@v0.5.7/go/ssa/interp/reflect.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package interp
     6  
     7  // Emulated "reflect" package.
     8  //
     9  // We completely replace the built-in "reflect" package.
    10  // The only thing clients can depend upon are that reflect.Type is an
    11  // interface and reflect.Value is an (opaque) struct.
    12  
    13  import (
    14  	"fmt"
    15  	"go/token"
    16  	"go/types"
    17  	"reflect"
    18  	"unsafe"
    19  
    20  	"github.com/jd-ly/tools/go/ssa"
    21  )
    22  
    23  type opaqueType struct {
    24  	types.Type
    25  	name string
    26  }
    27  
    28  func (t *opaqueType) String() string { return t.name }
    29  
    30  // A bogus "reflect" type-checker package.  Shared across interpreters.
    31  var reflectTypesPackage = types.NewPackage("reflect", "reflect")
    32  
    33  // rtype is the concrete type the interpreter uses to implement the
    34  // reflect.Type interface.
    35  //
    36  // type rtype <opaque>
    37  var rtypeType = makeNamedType("rtype", &opaqueType{nil, "rtype"})
    38  
    39  // error is an (interpreted) named type whose underlying type is string.
    40  // The interpreter uses it for all implementations of the built-in error
    41  // interface that it creates.
    42  // We put it in the "reflect" package for expedience.
    43  //
    44  // type error string
    45  var errorType = makeNamedType("error", &opaqueType{nil, "error"})
    46  
    47  func makeNamedType(name string, underlying types.Type) *types.Named {
    48  	obj := types.NewTypeName(token.NoPos, reflectTypesPackage, name, nil)
    49  	return types.NewNamed(obj, underlying, nil)
    50  }
    51  
    52  func makeReflectValue(t types.Type, v value) value {
    53  	return structure{rtype{t}, v}
    54  }
    55  
    56  // Given a reflect.Value, returns its rtype.
    57  func rV2T(v value) rtype {
    58  	return v.(structure)[0].(rtype)
    59  }
    60  
    61  // Given a reflect.Value, returns the underlying interpreter value.
    62  func rV2V(v value) value {
    63  	return v.(structure)[1]
    64  }
    65  
    66  // makeReflectType boxes up an rtype in a reflect.Type interface.
    67  func makeReflectType(rt rtype) value {
    68  	return iface{rtypeType, rt}
    69  }
    70  
    71  func ext۰reflect۰rtype۰Bits(fr *frame, args []value) value {
    72  	// Signature: func (t reflect.rtype) int
    73  	rt := args[0].(rtype).t
    74  	basic, ok := rt.Underlying().(*types.Basic)
    75  	if !ok {
    76  		panic(fmt.Sprintf("reflect.Type.Bits(%T): non-basic type", rt))
    77  	}
    78  	return int(fr.i.sizes.Sizeof(basic)) * 8
    79  }
    80  
    81  func ext۰reflect۰rtype۰Elem(fr *frame, args []value) value {
    82  	// Signature: func (t reflect.rtype) reflect.Type
    83  	return makeReflectType(rtype{args[0].(rtype).t.Underlying().(interface {
    84  		Elem() types.Type
    85  	}).Elem()})
    86  }
    87  
    88  func ext۰reflect۰rtype۰Field(fr *frame, args []value) value {
    89  	// Signature: func (t reflect.rtype, i int) reflect.StructField
    90  	st := args[0].(rtype).t.Underlying().(*types.Struct)
    91  	i := args[1].(int)
    92  	f := st.Field(i)
    93  	return structure{
    94  		f.Name(),
    95  		f.Pkg().Path(),
    96  		makeReflectType(rtype{f.Type()}),
    97  		st.Tag(i),
    98  		0,         // TODO(adonovan): offset
    99  		[]value{}, // TODO(adonovan): indices
   100  		f.Anonymous(),
   101  	}
   102  }
   103  
   104  func ext۰reflect۰rtype۰In(fr *frame, args []value) value {
   105  	// Signature: func (t reflect.rtype, i int) int
   106  	i := args[1].(int)
   107  	return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Params().At(i).Type()})
   108  }
   109  
   110  func ext۰reflect۰rtype۰Kind(fr *frame, args []value) value {
   111  	// Signature: func (t reflect.rtype) uint
   112  	return uint(reflectKind(args[0].(rtype).t))
   113  }
   114  
   115  func ext۰reflect۰rtype۰NumField(fr *frame, args []value) value {
   116  	// Signature: func (t reflect.rtype) int
   117  	return args[0].(rtype).t.Underlying().(*types.Struct).NumFields()
   118  }
   119  
   120  func ext۰reflect۰rtype۰NumIn(fr *frame, args []value) value {
   121  	// Signature: func (t reflect.rtype) int
   122  	return args[0].(rtype).t.(*types.Signature).Params().Len()
   123  }
   124  
   125  func ext۰reflect۰rtype۰NumMethod(fr *frame, args []value) value {
   126  	// Signature: func (t reflect.rtype) int
   127  	return fr.i.prog.MethodSets.MethodSet(args[0].(rtype).t).Len()
   128  }
   129  
   130  func ext۰reflect۰rtype۰NumOut(fr *frame, args []value) value {
   131  	// Signature: func (t reflect.rtype) int
   132  	return args[0].(rtype).t.(*types.Signature).Results().Len()
   133  }
   134  
   135  func ext۰reflect۰rtype۰Out(fr *frame, args []value) value {
   136  	// Signature: func (t reflect.rtype, i int) int
   137  	i := args[1].(int)
   138  	return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Results().At(i).Type()})
   139  }
   140  
   141  func ext۰reflect۰rtype۰Size(fr *frame, args []value) value {
   142  	// Signature: func (t reflect.rtype) uintptr
   143  	return uintptr(fr.i.sizes.Sizeof(args[0].(rtype).t))
   144  }
   145  
   146  func ext۰reflect۰rtype۰String(fr *frame, args []value) value {
   147  	// Signature: func (t reflect.rtype) string
   148  	return args[0].(rtype).t.String()
   149  }
   150  
   151  func ext۰reflect۰New(fr *frame, args []value) value {
   152  	// Signature: func (t reflect.Type) reflect.Value
   153  	t := args[0].(iface).v.(rtype).t
   154  	alloc := zero(t)
   155  	return makeReflectValue(types.NewPointer(t), &alloc)
   156  }
   157  
   158  func ext۰reflect۰SliceOf(fr *frame, args []value) value {
   159  	// Signature: func (t reflect.rtype) Type
   160  	return makeReflectType(rtype{types.NewSlice(args[0].(iface).v.(rtype).t)})
   161  }
   162  
   163  func ext۰reflect۰TypeOf(fr *frame, args []value) value {
   164  	// Signature: func (t reflect.rtype) Type
   165  	return makeReflectType(rtype{args[0].(iface).t})
   166  }
   167  
   168  func ext۰reflect۰ValueOf(fr *frame, args []value) value {
   169  	// Signature: func (interface{}) reflect.Value
   170  	itf := args[0].(iface)
   171  	return makeReflectValue(itf.t, itf.v)
   172  }
   173  
   174  func ext۰reflect۰Zero(fr *frame, args []value) value {
   175  	// Signature: func (t reflect.Type) reflect.Value
   176  	t := args[0].(iface).v.(rtype).t
   177  	return makeReflectValue(t, zero(t))
   178  }
   179  
   180  func reflectKind(t types.Type) reflect.Kind {
   181  	switch t := t.(type) {
   182  	case *types.Named:
   183  		return reflectKind(t.Underlying())
   184  	case *types.Basic:
   185  		switch t.Kind() {
   186  		case types.Bool:
   187  			return reflect.Bool
   188  		case types.Int:
   189  			return reflect.Int
   190  		case types.Int8:
   191  			return reflect.Int8
   192  		case types.Int16:
   193  			return reflect.Int16
   194  		case types.Int32:
   195  			return reflect.Int32
   196  		case types.Int64:
   197  			return reflect.Int64
   198  		case types.Uint:
   199  			return reflect.Uint
   200  		case types.Uint8:
   201  			return reflect.Uint8
   202  		case types.Uint16:
   203  			return reflect.Uint16
   204  		case types.Uint32:
   205  			return reflect.Uint32
   206  		case types.Uint64:
   207  			return reflect.Uint64
   208  		case types.Uintptr:
   209  			return reflect.Uintptr
   210  		case types.Float32:
   211  			return reflect.Float32
   212  		case types.Float64:
   213  			return reflect.Float64
   214  		case types.Complex64:
   215  			return reflect.Complex64
   216  		case types.Complex128:
   217  			return reflect.Complex128
   218  		case types.String:
   219  			return reflect.String
   220  		case types.UnsafePointer:
   221  			return reflect.UnsafePointer
   222  		}
   223  	case *types.Array:
   224  		return reflect.Array
   225  	case *types.Chan:
   226  		return reflect.Chan
   227  	case *types.Signature:
   228  		return reflect.Func
   229  	case *types.Interface:
   230  		return reflect.Interface
   231  	case *types.Map:
   232  		return reflect.Map
   233  	case *types.Pointer:
   234  		return reflect.Ptr
   235  	case *types.Slice:
   236  		return reflect.Slice
   237  	case *types.Struct:
   238  		return reflect.Struct
   239  	}
   240  	panic(fmt.Sprint("unexpected type: ", t))
   241  }
   242  
   243  func ext۰reflect۰Value۰Kind(fr *frame, args []value) value {
   244  	// Signature: func (reflect.Value) uint
   245  	return uint(reflectKind(rV2T(args[0]).t))
   246  }
   247  
   248  func ext۰reflect۰Value۰String(fr *frame, args []value) value {
   249  	// Signature: func (reflect.Value) string
   250  	return toString(rV2V(args[0]))
   251  }
   252  
   253  func ext۰reflect۰Value۰Type(fr *frame, args []value) value {
   254  	// Signature: func (reflect.Value) reflect.Type
   255  	return makeReflectType(rV2T(args[0]))
   256  }
   257  
   258  func ext۰reflect۰Value۰Uint(fr *frame, args []value) value {
   259  	// Signature: func (reflect.Value) uint64
   260  	switch v := rV2V(args[0]).(type) {
   261  	case uint:
   262  		return uint64(v)
   263  	case uint8:
   264  		return uint64(v)
   265  	case uint16:
   266  		return uint64(v)
   267  	case uint32:
   268  		return uint64(v)
   269  	case uint64:
   270  		return uint64(v)
   271  	case uintptr:
   272  		return uint64(v)
   273  	}
   274  	panic("reflect.Value.Uint")
   275  }
   276  
   277  func ext۰reflect۰Value۰Len(fr *frame, args []value) value {
   278  	// Signature: func (reflect.Value) int
   279  	switch v := rV2V(args[0]).(type) {
   280  	case string:
   281  		return len(v)
   282  	case array:
   283  		return len(v)
   284  	case chan value:
   285  		return cap(v)
   286  	case []value:
   287  		return len(v)
   288  	case *hashmap:
   289  		return v.len()
   290  	case map[value]value:
   291  		return len(v)
   292  	default:
   293  		panic(fmt.Sprintf("reflect.(Value).Len(%v)", v))
   294  	}
   295  }
   296  
   297  func ext۰reflect۰Value۰MapIndex(fr *frame, args []value) value {
   298  	// Signature: func (reflect.Value) Value
   299  	tValue := rV2T(args[0]).t.Underlying().(*types.Map).Key()
   300  	k := rV2V(args[1])
   301  	switch m := rV2V(args[0]).(type) {
   302  	case map[value]value:
   303  		if v, ok := m[k]; ok {
   304  			return makeReflectValue(tValue, v)
   305  		}
   306  
   307  	case *hashmap:
   308  		if v := m.lookup(k.(hashable)); v != nil {
   309  			return makeReflectValue(tValue, v)
   310  		}
   311  
   312  	default:
   313  		panic(fmt.Sprintf("(reflect.Value).MapIndex(%T, %T)", m, k))
   314  	}
   315  	return makeReflectValue(nil, nil)
   316  }
   317  
   318  func ext۰reflect۰Value۰MapKeys(fr *frame, args []value) value {
   319  	// Signature: func (reflect.Value) []Value
   320  	var keys []value
   321  	tKey := rV2T(args[0]).t.Underlying().(*types.Map).Key()
   322  	switch v := rV2V(args[0]).(type) {
   323  	case map[value]value:
   324  		for k := range v {
   325  			keys = append(keys, makeReflectValue(tKey, k))
   326  		}
   327  
   328  	case *hashmap:
   329  		for _, e := range v.entries() {
   330  			for ; e != nil; e = e.next {
   331  				keys = append(keys, makeReflectValue(tKey, e.key))
   332  			}
   333  		}
   334  
   335  	default:
   336  		panic(fmt.Sprintf("(reflect.Value).MapKeys(%T)", v))
   337  	}
   338  	return keys
   339  }
   340  
   341  func ext۰reflect۰Value۰NumField(fr *frame, args []value) value {
   342  	// Signature: func (reflect.Value) int
   343  	return len(rV2V(args[0]).(structure))
   344  }
   345  
   346  func ext۰reflect۰Value۰NumMethod(fr *frame, args []value) value {
   347  	// Signature: func (reflect.Value) int
   348  	return fr.i.prog.MethodSets.MethodSet(rV2T(args[0]).t).Len()
   349  }
   350  
   351  func ext۰reflect۰Value۰Pointer(fr *frame, args []value) value {
   352  	// Signature: func (v reflect.Value) uintptr
   353  	switch v := rV2V(args[0]).(type) {
   354  	case *value:
   355  		return uintptr(unsafe.Pointer(v))
   356  	case chan value:
   357  		return reflect.ValueOf(v).Pointer()
   358  	case []value:
   359  		return reflect.ValueOf(v).Pointer()
   360  	case *hashmap:
   361  		return reflect.ValueOf(v.entries()).Pointer()
   362  	case map[value]value:
   363  		return reflect.ValueOf(v).Pointer()
   364  	case *ssa.Function:
   365  		return uintptr(unsafe.Pointer(v))
   366  	case *closure:
   367  		return uintptr(unsafe.Pointer(v))
   368  	default:
   369  		panic(fmt.Sprintf("reflect.(Value).Pointer(%T)", v))
   370  	}
   371  }
   372  
   373  func ext۰reflect۰Value۰Index(fr *frame, args []value) value {
   374  	// Signature: func (v reflect.Value, i int) Value
   375  	i := args[1].(int)
   376  	t := rV2T(args[0]).t.Underlying()
   377  	switch v := rV2V(args[0]).(type) {
   378  	case array:
   379  		return makeReflectValue(t.(*types.Array).Elem(), v[i])
   380  	case []value:
   381  		return makeReflectValue(t.(*types.Slice).Elem(), v[i])
   382  	default:
   383  		panic(fmt.Sprintf("reflect.(Value).Index(%T)", v))
   384  	}
   385  }
   386  
   387  func ext۰reflect۰Value۰Bool(fr *frame, args []value) value {
   388  	// Signature: func (reflect.Value) bool
   389  	return rV2V(args[0]).(bool)
   390  }
   391  
   392  func ext۰reflect۰Value۰CanAddr(fr *frame, args []value) value {
   393  	// Signature: func (v reflect.Value) bool
   394  	// Always false for our representation.
   395  	return false
   396  }
   397  
   398  func ext۰reflect۰Value۰CanInterface(fr *frame, args []value) value {
   399  	// Signature: func (v reflect.Value) bool
   400  	// Always true for our representation.
   401  	return true
   402  }
   403  
   404  func ext۰reflect۰Value۰Elem(fr *frame, args []value) value {
   405  	// Signature: func (v reflect.Value) reflect.Value
   406  	switch x := rV2V(args[0]).(type) {
   407  	case iface:
   408  		return makeReflectValue(x.t, x.v)
   409  	case *value:
   410  		return makeReflectValue(rV2T(args[0]).t.Underlying().(*types.Pointer).Elem(), *x)
   411  	default:
   412  		panic(fmt.Sprintf("reflect.(Value).Elem(%T)", x))
   413  	}
   414  }
   415  
   416  func ext۰reflect۰Value۰Field(fr *frame, args []value) value {
   417  	// Signature: func (v reflect.Value, i int) reflect.Value
   418  	v := args[0]
   419  	i := args[1].(int)
   420  	return makeReflectValue(rV2T(v).t.Underlying().(*types.Struct).Field(i).Type(), rV2V(v).(structure)[i])
   421  }
   422  
   423  func ext۰reflect۰Value۰Float(fr *frame, args []value) value {
   424  	// Signature: func (reflect.Value) float64
   425  	switch v := rV2V(args[0]).(type) {
   426  	case float32:
   427  		return float64(v)
   428  	case float64:
   429  		return float64(v)
   430  	}
   431  	panic("reflect.Value.Float")
   432  }
   433  
   434  func ext۰reflect۰Value۰Interface(fr *frame, args []value) value {
   435  	// Signature: func (v reflect.Value) interface{}
   436  	return ext۰reflect۰valueInterface(fr, args)
   437  }
   438  
   439  func ext۰reflect۰Value۰Int(fr *frame, args []value) value {
   440  	// Signature: func (reflect.Value) int64
   441  	switch x := rV2V(args[0]).(type) {
   442  	case int:
   443  		return int64(x)
   444  	case int8:
   445  		return int64(x)
   446  	case int16:
   447  		return int64(x)
   448  	case int32:
   449  		return int64(x)
   450  	case int64:
   451  		return x
   452  	default:
   453  		panic(fmt.Sprintf("reflect.(Value).Int(%T)", x))
   454  	}
   455  }
   456  
   457  func ext۰reflect۰Value۰IsNil(fr *frame, args []value) value {
   458  	// Signature: func (reflect.Value) bool
   459  	switch x := rV2V(args[0]).(type) {
   460  	case *value:
   461  		return x == nil
   462  	case chan value:
   463  		return x == nil
   464  	case map[value]value:
   465  		return x == nil
   466  	case *hashmap:
   467  		return x == nil
   468  	case iface:
   469  		return x.t == nil
   470  	case []value:
   471  		return x == nil
   472  	case *ssa.Function:
   473  		return x == nil
   474  	case *ssa.Builtin:
   475  		return x == nil
   476  	case *closure:
   477  		return x == nil
   478  	default:
   479  		panic(fmt.Sprintf("reflect.(Value).IsNil(%T)", x))
   480  	}
   481  }
   482  
   483  func ext۰reflect۰Value۰IsValid(fr *frame, args []value) value {
   484  	// Signature: func (reflect.Value) bool
   485  	return rV2V(args[0]) != nil
   486  }
   487  
   488  func ext۰reflect۰Value۰Set(fr *frame, args []value) value {
   489  	// TODO(adonovan): implement.
   490  	return nil
   491  }
   492  
   493  func ext۰reflect۰valueInterface(fr *frame, args []value) value {
   494  	// Signature: func (v reflect.Value, safe bool) interface{}
   495  	v := args[0].(structure)
   496  	return iface{rV2T(v).t, rV2V(v)}
   497  }
   498  
   499  func ext۰reflect۰error۰Error(fr *frame, args []value) value {
   500  	return args[0]
   501  }
   502  
   503  // newMethod creates a new method of the specified name, package and receiver type.
   504  func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function {
   505  	// TODO(adonovan): fix: hack: currently the only part of Signature
   506  	// that is needed is the "pointerness" of Recv.Type, and for
   507  	// now, we'll set it to always be false since we're only
   508  	// concerned with rtype.  Encapsulate this better.
   509  	sig := types.NewSignature(types.NewVar(token.NoPos, nil, "recv", recvType), nil, nil, false)
   510  	fn := pkg.Prog.NewFunction(name, sig, "fake reflect method")
   511  	fn.Pkg = pkg
   512  	return fn
   513  }
   514  
   515  func initReflect(i *interpreter) {
   516  	i.reflectPackage = &ssa.Package{
   517  		Prog:    i.prog,
   518  		Pkg:     reflectTypesPackage,
   519  		Members: make(map[string]ssa.Member),
   520  	}
   521  
   522  	// Clobber the type-checker's notion of reflect.Value's
   523  	// underlying type so that it more closely matches the fake one
   524  	// (at least in the number of fields---we lie about the type of
   525  	// the rtype field).
   526  	//
   527  	// We must ensure that calls to (ssa.Value).Type() return the
   528  	// fake type so that correct "shape" is used when allocating
   529  	// variables, making zero values, loading, and storing.
   530  	//
   531  	// TODO(adonovan): obviously this is a hack.  We need a cleaner
   532  	// way to fake the reflect package (almost---DeepEqual is fine).
   533  	// One approach would be not to even load its source code, but
   534  	// provide fake source files.  This would guarantee that no bad
   535  	// information leaks into other packages.
   536  	if r := i.prog.ImportedPackage("reflect"); r != nil {
   537  		rV := r.Pkg.Scope().Lookup("Value").Type().(*types.Named)
   538  
   539  		// delete bodies of the old methods
   540  		mset := i.prog.MethodSets.MethodSet(rV)
   541  		for j := 0; j < mset.Len(); j++ {
   542  			i.prog.MethodValue(mset.At(j)).Blocks = nil
   543  		}
   544  
   545  		tEface := types.NewInterface(nil, nil).Complete()
   546  		rV.SetUnderlying(types.NewStruct([]*types.Var{
   547  			types.NewField(token.NoPos, r.Pkg, "t", tEface, false), // a lie
   548  			types.NewField(token.NoPos, r.Pkg, "v", tEface, false),
   549  		}, nil))
   550  	}
   551  
   552  	i.rtypeMethods = methodSet{
   553  		"Bits":      newMethod(i.reflectPackage, rtypeType, "Bits"),
   554  		"Elem":      newMethod(i.reflectPackage, rtypeType, "Elem"),
   555  		"Field":     newMethod(i.reflectPackage, rtypeType, "Field"),
   556  		"In":        newMethod(i.reflectPackage, rtypeType, "In"),
   557  		"Kind":      newMethod(i.reflectPackage, rtypeType, "Kind"),
   558  		"NumField":  newMethod(i.reflectPackage, rtypeType, "NumField"),
   559  		"NumIn":     newMethod(i.reflectPackage, rtypeType, "NumIn"),
   560  		"NumMethod": newMethod(i.reflectPackage, rtypeType, "NumMethod"),
   561  		"NumOut":    newMethod(i.reflectPackage, rtypeType, "NumOut"),
   562  		"Out":       newMethod(i.reflectPackage, rtypeType, "Out"),
   563  		"Size":      newMethod(i.reflectPackage, rtypeType, "Size"),
   564  		"String":    newMethod(i.reflectPackage, rtypeType, "String"),
   565  	}
   566  	i.errorMethods = methodSet{
   567  		"Error": newMethod(i.reflectPackage, errorType, "Error"),
   568  	}
   569  }