Skip to content

Commit beff8ba

Browse files
authored
Merge pull request #1160 from visualfc/reflect
compiler/natives/src/reflect: compatible go reflect
2 parents 9b96dbe + 71d902a commit beff8ba

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

compiler/natives/src/reflect/reflect.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func reflectType(typ *js.Object) *rtype {
6363
rt := &rtype{
6464
size: uintptr(typ.Get("size").Int()),
6565
kind: uint8(typ.Get("kind").Int()),
66-
str: newNameOff(newName(internalStr(typ.Get("string")), "", typ.Get("exported").Bool())),
66+
str: resolveReflectName(newName(internalStr(typ.Get("string")), "", typ.Get("exported").Bool())),
6767
}
6868
js.InternalObject(rt).Set("jsType", typ)
6969
typ.Set("reflectType", js.InternalObject(rt))
@@ -82,7 +82,7 @@ func reflectType(typ *js.Object) *rtype {
8282
continue
8383
}
8484
reflectMethods = append(reflectMethods, method{
85-
name: newNameOff(newMethodName(m)),
85+
name: resolveReflectName(newMethodName(m)),
8686
mtyp: newTypeOff(reflectType(m.Get("typ"))),
8787
})
8888
}
@@ -94,18 +94,18 @@ func reflectType(typ *js.Object) *rtype {
9494
continue
9595
}
9696
reflectMethods = append(reflectMethods, method{
97-
name: newNameOff(newMethodName(m)),
97+
name: resolveReflectName(newMethodName(m)),
9898
mtyp: newTypeOff(reflectType(m.Get("typ"))),
9999
})
100100
}
101101
ut := &uncommonType{
102-
pkgPath: newNameOff(newName(internalStr(typ.Get("pkg")), "", false)),
102+
pkgPath: resolveReflectName(newName(internalStr(typ.Get("pkg")), "", false)),
103103
mcount: uint16(methodSet.Length()),
104104
xcount: xcount,
105105
_methods: reflectMethods,
106106
}
107-
uncommonTypeMap[rt] = ut
108107
js.InternalObject(ut).Set("jsType", typ)
108+
js.InternalObject(rt).Set("uncommonType", js.InternalObject(ut))
109109
}
110110

111111
switch rt.Kind() {
@@ -154,7 +154,7 @@ func reflectType(typ *js.Object) *rtype {
154154
for i := range imethods {
155155
m := methods.Index(i)
156156
imethods[i] = imethod{
157-
name: newNameOff(newMethodName(m)),
157+
name: resolveReflectName(newMethodName(m)),
158158
typ: newTypeOff(reflectType(m.Get("typ"))),
159159
}
160160
}
@@ -224,10 +224,12 @@ func (t *uncommonType) exportedMethods() []method {
224224
return t._methods[:t.xcount:t.xcount]
225225
}
226226

227-
var uncommonTypeMap = make(map[*rtype]*uncommonType)
228-
229227
func (t *rtype) uncommon() *uncommonType {
230-
return uncommonTypeMap[t]
228+
obj := js.InternalObject(t).Get("uncommonType")
229+
if obj == js.Undefined {
230+
return nil
231+
}
232+
return (*uncommonType)(unsafe.Pointer(obj.Unsafe()))
231233
}
232234

233235
type funcType struct {
@@ -298,7 +300,7 @@ func (t *rtype) nameOff(off nameOff) name {
298300
return nameOffList[int(off)]
299301
}
300302

301-
func newNameOff(n name) nameOff {
303+
func resolveReflectName(n name) nameOff {
302304
i := len(nameOffList)
303305
nameOffList = append(nameOffList, n)
304306
return nameOff(i)

tests/linkname_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package tests
33
import (
44
"testing"
55

6+
_ "reflect"
7+
_ "unsafe"
8+
69
"github.com/google/go-cmp/cmp"
710
"github.com/gopherjs/gopherjs/tests/testdata/linkname/method"
811
"github.com/gopherjs/gopherjs/tests/testdata/linkname/one"
@@ -34,3 +37,28 @@ func TestLinknameMethods(t *testing.T) {
3437
}()
3538
method.TestLinkname(t)
3639
}
40+
41+
type name struct{ bytes *byte }
42+
type nameOff int32
43+
type rtype struct{}
44+
45+
//go:linkname rtype_nameOff reflect.(*rtype).nameOff
46+
func rtype_nameOff(r *rtype, off nameOff) name
47+
48+
//go:linkname newName reflect.newName
49+
func newName(n, tag string, exported bool) name
50+
51+
//go:linkname name_name reflect.name.name
52+
func name_name(name) string
53+
54+
//go:linkname resolveReflectName reflect.resolveReflectName
55+
func resolveReflectName(n name) nameOff
56+
57+
func TestLinknameReflectName(t *testing.T) {
58+
info := "myinfo"
59+
off := resolveReflectName(newName(info, "", false))
60+
n := rtype_nameOff(nil, off)
61+
if s := name_name(n); s != info {
62+
t.Fatalf("to reflect.name got %q: want %q", s, info)
63+
}
64+
}

0 commit comments

Comments
 (0)