Skip to content

Commit a8f4b60

Browse files
cleaning up some changes
1 parent 59e6e1e commit a8f4b60

File tree

8 files changed

+445
-434
lines changed

8 files changed

+445
-434
lines changed

compiler/natives/src/internal/abi/type.go

Lines changed: 211 additions & 232 deletions
Large diffs are not rendered by default.

compiler/natives/src/internal/abi/utils.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ func GetJsTag(tag string) string {
8888
return ""
8989
}
9090

91+
// NewMethodName creates name instance for a method.
92+
//
93+
// Input object is expected to be an entry of the "methods" list of the
94+
// corresponding JS type.
95+
//
96+
//gopherjs:new
97+
func NewMethodName(m *js.Object) Name {
98+
return Name{
99+
name: internalStr(m.Get("name")),
100+
tag: "",
101+
pkgPath: internalStr(m.Get("pkg")),
102+
exported: internalStr(m.Get("pkg")) == "",
103+
}
104+
}
105+
91106
//gopherjs:new
92107
func UnsafeNew(typ *Type) unsafe.Pointer {
93108
switch typ.Kind() {

compiler/natives/src/internal/reflectlite/export_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22

33
package reflectlite
44

5+
import "internal/abi"
6+
7+
// Field returns the i'th field of the struct v.
8+
// It panics if v's Kind is not Struct or i is out of range.
9+
//
510
//gopherjs:replace
6-
func Field(v Value, i int) Value { return v.Field(i) }
11+
func Field(v Value, i int) Value {
12+
if v.kind() != abi.Struct {
13+
panic(&ValueError{"reflect.Value.Field", v.kind()})
14+
}
15+
return v.Field(i)
16+
}
717

818
//gopherjs:purge Used in FirstMethodNameBytes
919
type EmbedWithUnexpMeth struct{}
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//go:build js
2+
3+
package reflectlite
4+
5+
import (
6+
"unsafe"
7+
8+
"internal/abi"
9+
10+
"github.com/gopherjs/gopherjs/js"
11+
)
12+
13+
func init() {
14+
// avoid dead code elimination
15+
used := func(i any) {}
16+
used(rtype{})
17+
used(uncommonType{})
18+
used(arrayType{})
19+
used(chanType{})
20+
used(funcType{})
21+
used(interfaceType{})
22+
used(mapType{})
23+
used(ptrType{})
24+
used(sliceType{})
25+
used(structType{})
26+
}
27+
28+
//gopherjs:new
29+
func jsType(t Type) *js.Object {
30+
return toAbiType(t).JsType()
31+
}
32+
33+
//gopherjs:new
34+
func toAbiType(t Type) *abi.Type {
35+
return t.(rtype).common()
36+
}
37+
38+
//gopherjs:new
39+
func jsPtrTo(t Type) *js.Object {
40+
return toAbiType(t).JsPtrTo()
41+
}
42+
43+
//gopherjs:purge The name type is mostly unused, replaced by abi.Name, except in pkgPath which we don't implement.
44+
type name struct{}
45+
46+
//gopherjs:replace
47+
func pkgPath(n abi.Name) string { return "" }
48+
49+
//gopherjs:purge Unused function because of nameOffList in internal/abi overrides
50+
func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
51+
52+
//gopherjs:purge Unused function because of typeOffList in internal/abi overrides
53+
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
54+
55+
//gopherjs:replace
56+
func (t rtype) nameOff(off nameOff) abi.Name {
57+
return t.NameOff(off)
58+
}
59+
60+
//gopherjs:replace
61+
func (t rtype) typeOff(off typeOff) *abi.Type {
62+
return t.TypeOff(off)
63+
}
64+
65+
//gopherjs:new
66+
func makeValue(t *abi.Type, v *js.Object, fl flag) Value {
67+
switch t.Kind() {
68+
case abi.Array, abi.Struct, abi.Pointer:
69+
return Value{
70+
typ: t,
71+
ptr: unsafe.Pointer(v.Unsafe()),
72+
flag: fl | flag(t.Kind()),
73+
}
74+
}
75+
return Value{
76+
typ: t,
77+
ptr: unsafe.Pointer(js.Global.Call("$newDataPointer", v, t.JsPtrTo()).Unsafe()),
78+
flag: fl | flag(t.Kind()) | flagIndir,
79+
}
80+
}
81+
82+
//gopherjs:replace
83+
func TypeOf(i any) Type {
84+
if i == nil {
85+
return nil
86+
}
87+
return toRType(abi.ReflectType(js.InternalObject(i).Get("constructor")))
88+
}
89+
90+
//gopherjs:replace
91+
func ValueOf(i any) Value {
92+
if i == nil {
93+
return Value{}
94+
}
95+
return makeValue(abi.ReflectType(js.InternalObject(i).Get("constructor")), js.InternalObject(i).Get("$val"), 0)
96+
}
97+
98+
//gopherjs:replace
99+
func unsafe_New(typ *abi.Type) unsafe.Pointer {
100+
return abi.UnsafeNew(typ)
101+
}
102+
103+
//gopherjs:replace
104+
func typedmemmove(t *abi.Type, dst, src unsafe.Pointer) {
105+
abi.TypedMemMove(t, dst, src)
106+
}
107+
108+
//gopherjs:new This is a simplified copy of the version in reflect.
109+
func methodReceiver(op string, v Value, i int) (fn unsafe.Pointer) {
110+
var prop string
111+
if v.typ.Kind() == abi.Interface {
112+
tt := v.typ.InterfaceType()
113+
if i < 0 || i >= len(tt.Methods) {
114+
panic("reflect: internal error: invalid method index")
115+
}
116+
m := &tt.Methods[i]
117+
if !tt.NameOff(m.Name).IsExported() {
118+
panic("reflect: " + op + " of unexported method")
119+
}
120+
prop = tt.NameOff(m.Name).Name()
121+
} else {
122+
ms := v.typ.ExportedMethods()
123+
if uint(i) >= uint(len(ms)) {
124+
panic("reflect: internal error: invalid method index")
125+
}
126+
m := ms[i]
127+
if !v.typ.NameOff(m.Name).IsExported() {
128+
panic("reflect: " + op + " of unexported method")
129+
}
130+
prop = js.Global.Call("$methodSet", v.typ.JsType()).Index(i).Get("prop").String()
131+
}
132+
rcvr := v.object()
133+
if v.typ.IsWrapped() {
134+
rcvr = v.typ.JsType().New(rcvr)
135+
}
136+
fn = unsafe.Pointer(rcvr.Get(prop).Unsafe())
137+
return
138+
}
139+
140+
//gopherjs:replace
141+
func valueInterface(v Value) any {
142+
if v.flag == 0 {
143+
panic(&ValueError{Method: "reflect.Value.Interface", Kind: 0})
144+
}
145+
146+
if v.flag&flagMethod != 0 {
147+
v = makeMethodValue("Interface", v)
148+
}
149+
150+
if v.typ.IsWrapped() {
151+
if v.flag&flagIndir != 0 && v.Kind() == abi.Struct {
152+
cv := v.typ.JsType().Call("zero")
153+
abi.CopyStruct(cv, v.object(), v.typ)
154+
return any(unsafe.Pointer(v.typ.JsType().New(cv).Unsafe()))
155+
}
156+
return any(unsafe.Pointer(v.typ.JsType().New(v.object()).Unsafe()))
157+
}
158+
return any(unsafe.Pointer(v.object().Unsafe()))
159+
}
160+
161+
//gopherjs:replace
162+
func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer) {
163+
abi.IfaceE2I(t, src, dst)
164+
}
165+
166+
//gopherjs:replace
167+
func methodName() string {
168+
// TODO(grantnelson-wf): methodName returns the name of the calling method,
169+
// assumed to be two stack frames above.
170+
return "?FIXME?"
171+
}
172+
173+
//gopherjs:new This is new to reflectlite but there are commented out references in the native code and a copy in reflect.
174+
func makeMethodValue(op string, v Value) Value {
175+
if v.flag&flagMethod == 0 {
176+
panic("reflect: internal error: invalid use of makePartialFunc")
177+
}
178+
179+
fn := methodReceiver(op, v, int(v.flag)>>flagMethodShift)
180+
rcvr := v.object()
181+
if v.typ.IsWrapped() {
182+
rcvr = v.typ.JsType().New(rcvr)
183+
}
184+
fv := js.MakeFunc(func(this *js.Object, arguments []*js.Object) any {
185+
return js.InternalObject(fn).Call("apply", rcvr, arguments)
186+
})
187+
return Value{
188+
typ: v.Type().common(),
189+
ptr: unsafe.Pointer(fv.Unsafe()),
190+
flag: v.flag.ro() | flag(abi.Func),
191+
}
192+
}

compiler/natives/src/internal/reflectlite/type.go

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,80 +3,16 @@
33
package reflectlite
44

55
import (
6-
"unsafe"
7-
86
"internal/abi"
9-
10-
"github.com/gopherjs/gopherjs/js"
117
)
128

13-
func init() {
14-
// avoid dead code elimination
15-
used := func(i any) {}
16-
used(rtype{})
17-
used(uncommonType{})
18-
used(arrayType{})
19-
used(chanType{})
20-
used(funcType{})
21-
used(interfaceType{})
22-
used(mapType{})
23-
used(ptrType{})
24-
used(sliceType{})
25-
used(structType{})
26-
}
27-
28-
//gopherjs:new
29-
func toAbiType(t Type) *abi.Type {
30-
return t.(rtype).common()
31-
}
32-
33-
//gopherjs:new
34-
func jsType(t Type) *js.Object {
35-
return toAbiType(t).JsType()
36-
}
37-
38-
//gopherjs:new
39-
func jsPtrTo(t Type) *js.Object {
40-
return toAbiType(t).JsPtrTo()
41-
}
42-
439
// GOPHERJS: For some reason the original code left mapType and aliased the rest
4410
// to the ABI version. mapType is not used so this is an alias to override the
4511
// left over refactor cruft.
4612
//
4713
//gopherjs:replace
4814
type mapType = abi.MapType
4915

50-
//gopherjs:purge The name type is mostly unused, replaced by abi.Name, except in pkgPath which we don't implement.
51-
type name struct{}
52-
53-
//gopherjs:replace
54-
func pkgPath(n abi.Name) string { return "" }
55-
56-
//gopherjs:purge Unused function because of nameOffList in internal/abi overrides
57-
func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
58-
59-
//gopherjs:purge Unused function because of typeOffList in internal/abi overrides
60-
func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
61-
62-
//gopherjs:replace
63-
func (t rtype) nameOff(off nameOff) abi.Name {
64-
return t.NameOff(off)
65-
}
66-
67-
//gopherjs:replace
68-
func (t rtype) typeOff(off typeOff) *abi.Type {
69-
return t.TypeOff(off)
70-
}
71-
72-
//gopherjs:replace
73-
func TypeOf(i any) Type {
74-
if i == nil {
75-
return nil
76-
}
77-
return toRType(abi.ReflectType(js.InternalObject(i).Get("constructor")))
78-
}
79-
8016
//gopherjs:replace
8117
func (t rtype) Comparable() bool {
8218
switch t.Kind() {

0 commit comments

Comments
 (0)