From ac303766f5f240c1796eeea3dc9bf34f1261aa35 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Fri, 5 Jun 2015 18:37:20 -0400 Subject: [PATCH] go/ssa/interp: don't run encoding/pem tests in interpreter since they use quick.Check, which requires the unimplemented (reflect.Value).SetString. Also: - Add reflect.Type.{In,NumIn} methods, whose absence was only the proximate cause of the failed test. - Delete bodies of reflect.Value methods so that it's obvious a function that should be intrinsic is missing. Change-Id: Ib64b8f4953a913f4ead90e376bda70419adb87cb Reviewed-on: https://go-review.googlesource.com/10796 Reviewed-by: Robert Griesemer --- go/ssa/interp/external.go | 3 +++ go/ssa/interp/interp_test.go | 4 ++-- go/ssa/interp/reflect.go | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/go/ssa/interp/external.go b/go/ssa/interp/external.go index 627aa5a8..eb0757fb 100644 --- a/go/ssa/interp/external.go +++ b/go/ssa/interp/external.go @@ -59,8 +59,10 @@ func init() { "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits, "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem, "(reflect.rtype).Field": ext۰reflect۰rtype۰Field, + "(reflect.rtype).In": ext۰reflect۰rtype۰In, "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind, "(reflect.rtype).NumField": ext۰reflect۰rtype۰NumField, + "(reflect.rtype).NumIn": ext۰reflect۰rtype۰NumIn, "(reflect.rtype).NumMethod": ext۰reflect۰rtype۰NumMethod, "(reflect.rtype).NumOut": ext۰reflect۰rtype۰NumOut, "(reflect.rtype).Out": ext۰reflect۰rtype۰Out, @@ -84,6 +86,7 @@ func init() { "reflect.SliceOf": ext۰reflect۰SliceOf, "reflect.TypeOf": ext۰reflect۰TypeOf, "reflect.ValueOf": ext۰reflect۰ValueOf, + "reflect.Zero": ext۰reflect۰Zero, "reflect.init": ext۰reflect۰Init, "reflect.valueInterface": ext۰reflect۰valueInterface, "runtime.Breakpoint": ext۰runtime۰Breakpoint, diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go index 17fe7848..48fcae15 100644 --- a/go/ssa/interp/interp_test.go +++ b/go/ssa/interp/interp_test.go @@ -157,8 +157,8 @@ var gorootSrcTests = []string{ "encoding/ascii85", "encoding/csv", "encoding/hex", - "encoding/pem", - // "testing", // TODO(adonovan): implement runtime.Goexit correctly + // "encoding/pem", // TODO(adonovan): implement (reflect.Value).SetString + // "testing", // TODO(adonovan): implement runtime.Goexit correctly "text/scanner", "unicode", diff --git a/go/ssa/interp/reflect.go b/go/ssa/interp/reflect.go index 083173a7..f5bf3d03 100644 --- a/go/ssa/interp/reflect.go +++ b/go/ssa/interp/reflect.go @@ -106,6 +106,12 @@ func ext۰reflect۰rtype۰Field(fr *frame, args []value) value { } } +func ext۰reflect۰rtype۰In(fr *frame, args []value) value { + // Signature: func (t reflect.rtype, i int) int + i := args[1].(int) + return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Params().At(i).Type()}) +} + func ext۰reflect۰rtype۰Kind(fr *frame, args []value) value { // Signature: func (t reflect.rtype) uint return uint(reflectKind(args[0].(rtype).t)) @@ -116,6 +122,11 @@ func ext۰reflect۰rtype۰NumField(fr *frame, args []value) value { return args[0].(rtype).t.Underlying().(*types.Struct).NumFields() } +func ext۰reflect۰rtype۰NumIn(fr *frame, args []value) value { + // Signature: func (t reflect.rtype) int + return args[0].(rtype).t.(*types.Signature).Params().Len() +} + func ext۰reflect۰rtype۰NumMethod(fr *frame, args []value) value { // Signature: func (t reflect.rtype) int return fr.i.prog.MethodSets.MethodSet(args[0].(rtype).t).Len() @@ -165,6 +176,12 @@ func ext۰reflect۰ValueOf(fr *frame, args []value) value { return makeReflectValue(itf.t, itf.v) } +func ext۰reflect۰Zero(fr *frame, args []value) value { + // Signature: func (t reflect.Type) reflect.Value + t := args[0].(iface).v.(rtype).t + return makeReflectValue(t, zero(t)) +} + func reflectKind(t types.Type) reflect.Kind { switch t := t.(type) { case *types.Named: @@ -523,6 +540,13 @@ func initReflect(i *interpreter) { // information leaks into other packages. if r := i.prog.ImportedPackage("reflect"); r != nil { rV := r.Object.Scope().Lookup("Value").Type().(*types.Named) + + // delete bodies of the old methods + mset := i.prog.MethodSets.MethodSet(rV) + for j := 0; j < mset.Len(); j++ { + i.prog.Method(mset.At(j)).Blocks = nil + } + tEface := types.NewInterface(nil, nil).Complete() rV.SetUnderlying(types.NewStruct([]*types.Var{ types.NewField(token.NoPos, r.Object, "t", tEface, false), // a lie @@ -534,8 +558,10 @@ func initReflect(i *interpreter) { "Bits": newMethod(i.reflectPackage, rtypeType, "Bits"), "Elem": newMethod(i.reflectPackage, rtypeType, "Elem"), "Field": newMethod(i.reflectPackage, rtypeType, "Field"), + "In": newMethod(i.reflectPackage, rtypeType, "In"), "Kind": newMethod(i.reflectPackage, rtypeType, "Kind"), "NumField": newMethod(i.reflectPackage, rtypeType, "NumField"), + "NumIn": newMethod(i.reflectPackage, rtypeType, "NumIn"), "NumMethod": newMethod(i.reflectPackage, rtypeType, "NumMethod"), "NumOut": newMethod(i.reflectPackage, rtypeType, "NumOut"), "Out": newMethod(i.reflectPackage, rtypeType, "Out"),