...

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

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

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

View as plain text