From c873595a1358896ff2c0e56d92b3aacb43ffddfb Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 7 Oct 2022 15:53:28 +0800 Subject: [PATCH 1/2] compiler/natives/src/reflect: rename resolveReflectName and can be set uncommonType for compatible go reflect --- compiler/natives/src/reflect/reflect.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/natives/src/reflect/reflect.go b/compiler/natives/src/reflect/reflect.go index 957b948f8..d2fdfc05e 100644 --- a/compiler/natives/src/reflect/reflect.go +++ b/compiler/natives/src/reflect/reflect.go @@ -63,7 +63,7 @@ func reflectType(typ *js.Object) *rtype { rt := &rtype{ size: uintptr(typ.Get("size").Int()), kind: uint8(typ.Get("kind").Int()), - str: newNameOff(newName(internalStr(typ.Get("string")), "", typ.Get("exported").Bool())), + str: resolveReflectName(newName(internalStr(typ.Get("string")), "", typ.Get("exported").Bool())), } js.InternalObject(rt).Set("jsType", typ) typ.Set("reflectType", js.InternalObject(rt)) @@ -82,7 +82,7 @@ func reflectType(typ *js.Object) *rtype { continue } reflectMethods = append(reflectMethods, method{ - name: newNameOff(newMethodName(m)), + name: resolveReflectName(newMethodName(m)), mtyp: newTypeOff(reflectType(m.Get("typ"))), }) } @@ -94,18 +94,18 @@ func reflectType(typ *js.Object) *rtype { continue } reflectMethods = append(reflectMethods, method{ - name: newNameOff(newMethodName(m)), + name: resolveReflectName(newMethodName(m)), mtyp: newTypeOff(reflectType(m.Get("typ"))), }) } ut := &uncommonType{ - pkgPath: newNameOff(newName(internalStr(typ.Get("pkg")), "", false)), + pkgPath: resolveReflectName(newName(internalStr(typ.Get("pkg")), "", false)), mcount: uint16(methodSet.Length()), xcount: xcount, _methods: reflectMethods, } - uncommonTypeMap[rt] = ut js.InternalObject(ut).Set("jsType", typ) + js.InternalObject(rt).Set("uncommonType", js.InternalObject(ut)) } switch rt.Kind() { @@ -154,7 +154,7 @@ func reflectType(typ *js.Object) *rtype { for i := range imethods { m := methods.Index(i) imethods[i] = imethod{ - name: newNameOff(newMethodName(m)), + name: resolveReflectName(newMethodName(m)), typ: newTypeOff(reflectType(m.Get("typ"))), } } @@ -224,10 +224,12 @@ func (t *uncommonType) exportedMethods() []method { return t._methods[:t.xcount:t.xcount] } -var uncommonTypeMap = make(map[*rtype]*uncommonType) - func (t *rtype) uncommon() *uncommonType { - return uncommonTypeMap[t] + obj := js.InternalObject(t).Get("uncommonType") + if obj == js.Undefined { + return nil + } + return (*uncommonType)(unsafe.Pointer(obj.Unsafe())) } type funcType struct { @@ -298,7 +300,7 @@ func (t *rtype) nameOff(off nameOff) name { return nameOffList[int(off)] } -func newNameOff(n name) nameOff { +func resolveReflectName(n name) nameOff { i := len(nameOffList) nameOffList = append(nameOffList, n) return nameOff(i) From 71d902ae194df884819a3621b3b7bc8d6fd48d26 Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 12 Oct 2022 08:13:34 +0800 Subject: [PATCH 2/2] tests: add TestLinknameReflectName --- tests/linkname_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/linkname_test.go b/tests/linkname_test.go index c1646d0a5..9fb34ad03 100644 --- a/tests/linkname_test.go +++ b/tests/linkname_test.go @@ -3,6 +3,9 @@ package tests import ( "testing" + _ "reflect" + _ "unsafe" + "github.com/google/go-cmp/cmp" "github.com/gopherjs/gopherjs/tests/testdata/linkname/method" "github.com/gopherjs/gopherjs/tests/testdata/linkname/one" @@ -34,3 +37,28 @@ func TestLinknameMethods(t *testing.T) { }() method.TestLinkname(t) } + +type name struct{ bytes *byte } +type nameOff int32 +type rtype struct{} + +//go:linkname rtype_nameOff reflect.(*rtype).nameOff +func rtype_nameOff(r *rtype, off nameOff) name + +//go:linkname newName reflect.newName +func newName(n, tag string, exported bool) name + +//go:linkname name_name reflect.name.name +func name_name(name) string + +//go:linkname resolveReflectName reflect.resolveReflectName +func resolveReflectName(n name) nameOff + +func TestLinknameReflectName(t *testing.T) { + info := "myinfo" + off := resolveReflectName(newName(info, "", false)) + n := rtype_nameOff(nil, off) + if s := name_name(n); s != info { + t.Fatalf("to reflect.name got %q: want %q", s, info) + } +}