...

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  )
    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  		var v value
   411  		if x != nil {
   412  			v = *x
   413  		}
   414  		return makeReflectValue(rV2T(args[0]).t.Underlying().(*types.Pointer).Elem(), v)
   415  	default:
   416  		panic(fmt.Sprintf("reflect.(Value).Elem(%T)", x))
   417  	}
   418  }
   419  
   420  func ext۰reflect۰Value۰Field(fr *frame, args []value) value {
   421  	// Signature: func (v reflect.Value, i int) reflect.Value
   422  	v := args[0]
   423  	i := args[1].(int)
   424  	return makeReflectValue(rV2T(v).t.Underlying().(*types.Struct).Field(i).Type(), rV2V(v).(structure)[i])
   425  }
   426  
   427  func ext۰reflect۰Value۰Float(fr *frame, args []value) value {
   428  	// Signature: func (reflect.Value) float64
   429  	switch v := rV2V(args[0]).(type) {
   430  	case float32:
   431  		return float64(v)
   432  	case float64:
   433  		return float64(v)
   434  	}
   435  	panic("reflect.Value.Float")
   436  }
   437  
   438  func ext۰reflect۰Value۰Interface(fr *frame, args []value) value {
   439  	// Signature: func (v reflect.Value) interface{}
   440  	return ext۰reflect۰valueInterface(fr, args)
   441  }
   442  
   443  func ext۰reflect۰Value۰Int(fr *frame, args []value) value {
   444  	// Signature: func (reflect.Value) int64
   445  	switch x := rV2V(args[0]).(type) {
   446  	case int:
   447  		return int64(x)
   448  	case int8:
   449  		return int64(x)
   450  	case int16:
   451  		return int64(x)
   452  	case int32:
   453  		return int64(x)
   454  	case int64:
   455  		return x
   456  	default:
   457  		panic(fmt.Sprintf("reflect.(Value).Int(%T)", x))
   458  	}
   459  }
   460  
   461  func ext۰reflect۰Value۰IsNil(fr *frame, args []value) value {
   462  	// Signature: func (reflect.Value) bool
   463  	switch x := rV2V(args[0]).(type) {
   464  	case *value:
   465  		return x == nil
   466  	case chan value:
   467  		return x == nil
   468  	case map[value]value:
   469  		return x == nil
   470  	case *hashmap:
   471  		return x == nil
   472  	case iface:
   473  		return x.t == nil
   474  	case []value:
   475  		return x == nil
   476  	case *ssa.Function:
   477  		return x == nil
   478  	case *ssa.Builtin:
   479  		return x == nil
   480  	case *closure:
   481  		return x == nil
   482  	default:
   483  		panic(fmt.Sprintf("reflect.(Value).IsNil(%T)", x))
   484  	}
   485  }
   486  
   487  func ext۰reflect۰Value۰IsValid(fr *frame, args []value) value {
   488  	// Signature: func (reflect.Value) bool
   489  	return rV2V(args[0]) != nil
   490  }
   491  
   492  func ext۰reflect۰Value۰Set(fr *frame, args []value) value {
   493  	// TODO(adonovan): implement.
   494  	return nil
   495  }
   496  
   497  func ext۰reflect۰valueInterface(fr *frame, args []value) value {
   498  	// Signature: func (v reflect.Value, safe bool) interface{}
   499  	v := args[0].(structure)
   500  	return iface{rV2T(v).t, rV2V(v)}
   501  }
   502  
   503  func ext۰reflect۰error۰Error(fr *frame, args []value) value {
   504  	return args[0]
   505  }
   506  
   507  // newMethod creates a new method of the specified name, package and receiver type.
   508  func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function {
   509  	// TODO(adonovan): fix: hack: currently the only part of Signature
   510  	// that is needed is the "pointerness" of Recv.Type, and for
   511  	// now, we'll set it to always be false since we're only
   512  	// concerned with rtype.  Encapsulate this better.
   513  	sig := types.NewSignature(types.NewVar(token.NoPos, nil, "recv", recvType), nil, nil, false)
   514  	fn := pkg.Prog.NewFunction(name, sig, "fake reflect method")
   515  	fn.Pkg = pkg
   516  	return fn
   517  }
   518  
   519  func initReflect(i *interpreter) {
   520  	i.reflectPackage = &ssa.Package{
   521  		Prog:    i.prog,
   522  		Pkg:     reflectTypesPackage,
   523  		Members: make(map[string]ssa.Member),
   524  	}
   525  
   526  	// Clobber the type-checker's notion of reflect.Value's
   527  	// underlying type so that it more closely matches the fake one
   528  	// (at least in the number of fields---we lie about the type of
   529  	// the rtype field).
   530  	//
   531  	// We must ensure that calls to (ssa.Value).Type() return the
   532  	// fake type so that correct "shape" is used when allocating
   533  	// variables, making zero values, loading, and storing.
   534  	//
   535  	// TODO(adonovan): obviously this is a hack.  We need a cleaner
   536  	// way to fake the reflect package (almost---DeepEqual is fine).
   537  	// One approach would be not to even load its source code, but
   538  	// provide fake source files.  This would guarantee that no bad
   539  	// information leaks into other packages.
   540  	if r := i.prog.ImportedPackage("reflect"); r != nil {
   541  		rV := r.Pkg.Scope().Lookup("Value").Type().(*types.Named)
   542  
   543  		// delete bodies of the old methods
   544  		mset := i.prog.MethodSets.MethodSet(rV)
   545  		for j := 0; j < mset.Len(); j++ {
   546  			i.prog.MethodValue(mset.At(j)).Blocks = nil
   547  		}
   548  
   549  		tEface := types.NewInterface(nil, nil).Complete()
   550  		rV.SetUnderlying(types.NewStruct([]*types.Var{
   551  			types.NewField(token.NoPos, r.Pkg, "t", tEface, false), // a lie
   552  			types.NewField(token.NoPos, r.Pkg, "v", tEface, false),
   553  		}, nil))
   554  	}
   555  
   556  	i.rtypeMethods = methodSet{
   557  		"Bits":      newMethod(i.reflectPackage, rtypeType, "Bits"),
   558  		"Elem":      newMethod(i.reflectPackage, rtypeType, "Elem"),
   559  		"Field":     newMethod(i.reflectPackage, rtypeType, "Field"),
   560  		"In":        newMethod(i.reflectPackage, rtypeType, "In"),
   561  		"Kind":      newMethod(i.reflectPackage, rtypeType, "Kind"),
   562  		"NumField":  newMethod(i.reflectPackage, rtypeType, "NumField"),
   563  		"NumIn":     newMethod(i.reflectPackage, rtypeType, "NumIn"),
   564  		"NumMethod": newMethod(i.reflectPackage, rtypeType, "NumMethod"),
   565  		"NumOut":    newMethod(i.reflectPackage, rtypeType, "NumOut"),
   566  		"Out":       newMethod(i.reflectPackage, rtypeType, "Out"),
   567  		"Size":      newMethod(i.reflectPackage, rtypeType, "Size"),
   568  		"String":    newMethod(i.reflectPackage, rtypeType, "String"),
   569  	}
   570  	i.errorMethods = methodSet{
   571  		"Error": newMethod(i.reflectPackage, errorType, "Error"),
   572  	}
   573  }
   574  

View as plain text