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.
7 // Emulated "reflect" package.
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.
20 "golang.org/x/tools/go/ssa"
23 type opaqueType struct {
28 func (t *opaqueType) String() string { return t.name }
30 // A bogus "reflect" type-checker package. Shared across interpreters.
31 var reflectTypesPackage = types.NewPackage("reflect", "reflect")
33 // rtype is the concrete type the interpreter uses to implement the
34 // reflect.Type interface.
36 // type rtype <opaque>
37 var rtypeType = makeNamedType("rtype", &opaqueType{nil, "rtype"})
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.
45 var errorType = makeNamedType("error", &opaqueType{nil, "error"})
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)
52 func makeReflectValue(t types.Type, v value) value {
53 return structure{rtype{t}, v}
56 // Given a reflect.Value, returns its rtype.
57 func rV2T(v value) rtype {
58 return v.(structure)[0].(rtype)
61 // Given a reflect.Value, returns the underlying interpreter value.
62 func rV2V(v value) value {
63 return v.(structure)[1]
66 // makeReflectType boxes up an rtype in a reflect.Type interface.
67 func makeReflectType(rt rtype) value {
68 return iface{rtypeType, rt}
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)
76 panic(fmt.Sprintf("reflect.Type.Bits(%T): non-basic type", rt))
78 return int(fr.i.sizes.Sizeof(basic)) * 8
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 {
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)
96 makeReflectType(rtype{f.Type()}),
98 0, // TODO(adonovan): offset
99 []value{}, // TODO(adonovan): indices
104 func ext۰reflect۰rtype۰In(fr *frame, args []value) value {
105 // Signature: func (t reflect.rtype, i int) int
107 return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Params().At(i).Type()})
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))
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()
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()
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()
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()
135 func ext۰reflect۰rtype۰Out(fr *frame, args []value) value {
136 // Signature: func (t reflect.rtype, i int) int
138 return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Results().At(i).Type()})
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))
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()
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
155 return makeReflectValue(types.NewPointer(t), &alloc)
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)})
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})
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)
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))
180 func reflectKind(t types.Type) reflect.Kind {
181 switch t := t.(type) {
183 return reflectKind(t.Underlying())
203 return reflect.Uint16
205 return reflect.Uint32
207 return reflect.Uint64
209 return reflect.Uintptr
211 return reflect.Float32
213 return reflect.Float64
214 case types.Complex64:
215 return reflect.Complex64
216 case types.Complex128:
217 return reflect.Complex128
219 return reflect.String
220 case types.UnsafePointer:
221 return reflect.UnsafePointer
227 case *types.Signature:
229 case *types.Interface:
230 return reflect.Interface
238 return reflect.Struct
240 panic(fmt.Sprint("unexpected type: ", t))
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))
248 func ext۰reflect۰Value۰String(fr *frame, args []value) value {
249 // Signature: func (reflect.Value) string
250 return toString(rV2V(args[0]))
253 func ext۰reflect۰Value۰Type(fr *frame, args []value) value {
254 // Signature: func (reflect.Value) reflect.Type
255 return makeReflectType(rV2T(args[0]))
258 func ext۰reflect۰Value۰Uint(fr *frame, args []value) value {
259 // Signature: func (reflect.Value) uint64
260 switch v := rV2V(args[0]).(type) {
274 panic("reflect.Value.Uint")
277 func ext۰reflect۰Value۰Len(fr *frame, args []value) value {
278 // Signature: func (reflect.Value) int
279 switch v := rV2V(args[0]).(type) {
290 case map[value]value:
293 panic(fmt.Sprintf("reflect.(Value).Len(%v)", v))
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()
301 switch m := rV2V(args[0]).(type) {
302 case map[value]value:
303 if v, ok := m[k]; ok {
304 return makeReflectValue(tValue, v)
308 if v := m.lookup(k.(hashable)); v != nil {
309 return makeReflectValue(tValue, v)
313 panic(fmt.Sprintf("(reflect.Value).MapIndex(%T, %T)", m, k))
315 return makeReflectValue(nil, nil)
318 func ext۰reflect۰Value۰MapKeys(fr *frame, args []value) value {
319 // Signature: func (reflect.Value) []Value
321 tKey := rV2T(args[0]).t.Underlying().(*types.Map).Key()
322 switch v := rV2V(args[0]).(type) {
323 case map[value]value:
325 keys = append(keys, makeReflectValue(tKey, k))
329 for _, e := range v.entries() {
330 for ; e != nil; e = e.next {
331 keys = append(keys, makeReflectValue(tKey, e.key))
336 panic(fmt.Sprintf("(reflect.Value).MapKeys(%T)", v))
341 func ext۰reflect۰Value۰NumField(fr *frame, args []value) value {
342 // Signature: func (reflect.Value) int
343 return len(rV2V(args[0]).(structure))
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()
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) {
355 return uintptr(unsafe.Pointer(v))
357 return reflect.ValueOf(v).Pointer()
359 return reflect.ValueOf(v).Pointer()
361 return reflect.ValueOf(v.entries()).Pointer()
362 case map[value]value:
363 return reflect.ValueOf(v).Pointer()
365 return uintptr(unsafe.Pointer(v))
367 return uintptr(unsafe.Pointer(v))
369 panic(fmt.Sprintf("reflect.(Value).Pointer(%T)", v))
373 func ext۰reflect۰Value۰Index(fr *frame, args []value) value {
374 // Signature: func (v reflect.Value, i int) Value
376 t := rV2T(args[0]).t.Underlying()
377 switch v := rV2V(args[0]).(type) {
379 return makeReflectValue(t.(*types.Array).Elem(), v[i])
381 return makeReflectValue(t.(*types.Slice).Elem(), v[i])
383 panic(fmt.Sprintf("reflect.(Value).Index(%T)", v))
387 func ext۰reflect۰Value۰Bool(fr *frame, args []value) value {
388 // Signature: func (reflect.Value) bool
389 return rV2V(args[0]).(bool)
392 func ext۰reflect۰Value۰CanAddr(fr *frame, args []value) value {
393 // Signature: func (v reflect.Value) bool
394 // Always false for our representation.
398 func ext۰reflect۰Value۰CanInterface(fr *frame, args []value) value {
399 // Signature: func (v reflect.Value) bool
400 // Always true for our representation.
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) {
408 return makeReflectValue(x.t, x.v)
410 return makeReflectValue(rV2T(args[0]).t.Underlying().(*types.Pointer).Elem(), *x)
412 panic(fmt.Sprintf("reflect.(Value).Elem(%T)", x))
416 func ext۰reflect۰Value۰Field(fr *frame, args []value) value {
417 // Signature: func (v reflect.Value, i int) reflect.Value
420 return makeReflectValue(rV2T(v).t.Underlying().(*types.Struct).Field(i).Type(), rV2V(v).(structure)[i])
423 func ext۰reflect۰Value۰Float(fr *frame, args []value) value {
424 // Signature: func (reflect.Value) float64
425 switch v := rV2V(args[0]).(type) {
431 panic("reflect.Value.Float")
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)
439 func ext۰reflect۰Value۰Int(fr *frame, args []value) value {
440 // Signature: func (reflect.Value) int64
441 switch x := rV2V(args[0]).(type) {
453 panic(fmt.Sprintf("reflect.(Value).Int(%T)", x))
457 func ext۰reflect۰Value۰IsNil(fr *frame, args []value) value {
458 // Signature: func (reflect.Value) bool
459 switch x := rV2V(args[0]).(type) {
464 case map[value]value:
479 panic(fmt.Sprintf("reflect.(Value).IsNil(%T)", x))
483 func ext۰reflect۰Value۰IsValid(fr *frame, args []value) value {
484 // Signature: func (reflect.Value) bool
485 return rV2V(args[0]) != nil
488 func ext۰reflect۰Value۰Set(fr *frame, args []value) value {
489 // TODO(adonovan): implement.
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)}
499 func ext۰reflect۰error۰Error(fr *frame, args []value) value {
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")
515 func initReflect(i *interpreter) {
516 i.reflectPackage = &ssa.Package{
518 Pkg: reflectTypesPackage,
519 Members: make(map[string]ssa.Member),
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
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.
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)
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
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),
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"),
566 i.errorMethods = methodSet{
567 "Error": newMethod(i.reflectPackage, errorType, "Error"),