@@ -12,6 +12,9 @@ import (
1212 "github.com/gopherjs/gopherjs/js"
1313)
1414
15+ //gopherjs:purge This is the header for an interface value with methods and not needed for GopherJS.
16+ type nonEmptyInterface struct {}
17+
1518// New returns a Value representing a pointer to a new zero value
1619// for the specified type. That is, the returned Value's Type is PtrTo(typ).
1720//
@@ -24,11 +27,11 @@ func New(typ Type) Value {
2427 if typ == nil {
2528 panic ("reflect: New(nil)" )
2629 }
27- t := typ .( * rtype )
28- pt := t .ptrTo ()
30+ t := toAbiType ( typ )
31+ pt := t .PtrTo ()
2932 ptr := unsafe_New (t )
3033 fl := flag (Pointer )
31- return Value {typ : pt , ptr : ptr , flag : fl }
34+ return Value {typ_ : pt , ptr : ptr , flag : fl }
3235}
3336
3437//gopherjs:replace
@@ -44,12 +47,20 @@ func unsafe_New(typ *abi.Type) unsafe.Pointer {
4447 return abi .UnsafeNew (typ )
4548}
4649
47- func makeValue (t Type , v * js.Object , fl flag ) Value {
48- rt := t .common ()
49- if t .Kind () == Array || t .Kind () == Struct || t .Kind () == Ptr {
50- return Value {rt , unsafe .Pointer (v .Unsafe ()), fl | flag (t .Kind ())}
50+ func makeValue (t * abi.Type , v * js.Object , fl flag ) Value {
51+ switch t .Kind () {
52+ case abi .Array , abi .Struct , abi .Pointer :
53+ return Value {
54+ typ_ : t ,
55+ ptr : unsafe .Pointer (v .Unsafe ()),
56+ flag : fl | flag (t .Kind ()),
57+ }
58+ }
59+ return Value {
60+ typ_ : t ,
61+ ptr : unsafe .Pointer (js .Global .Call ("$newDataPointer" , v , t .JsPtrTo ()).Unsafe ()),
62+ flag : fl | flag (t .Kind ()) | flagIndir ,
5163 }
52- return Value {rt , unsafe .Pointer (js .Global .Call ("$newDataPointer" , v , jsType (rt .ptrTo ())).Unsafe ()), fl | flag (t .Kind ()) | flagIndir }
5364}
5465
5566func MakeSlice (typ Type , len , cap int ) Value {
@@ -66,74 +77,91 @@ func MakeSlice(typ Type, len, cap int) Value {
6677 panic ("reflect.MakeSlice: len > cap" )
6778 }
6879
69- return makeValue (typ , js .Global .Call ("$makeSlice" , jsType (typ ), len , cap , js .InternalObject (func () * js.Object { return jsType (typ .Elem ()).Call ("zero" ) })), 0 )
80+ return makeValue (toAbiType ( typ ) , js .Global .Call ("$makeSlice" , jsType (typ ), len , cap , js .InternalObject (func () * js.Object { return jsType (typ .Elem ()).Call ("zero" ) })), 0 )
7081}
7182
7283func Zero (typ Type ) Value {
73- return makeValue (typ , jsType (typ ).Call ("zero" ), 0 )
84+ return makeValue (toAbiType ( typ ) , jsType (typ ).Call ("zero" ), 0 )
7485}
7586
7687func makeInt (f flag , bits uint64 , t Type ) Value {
7788 typ := t .common ()
7889 ptr := unsafe_New (typ )
7990 switch typ .Kind () {
80- case Int8 :
91+ case abi . Int8 :
8192 * (* int8 )(ptr ) = int8 (bits )
82- case Int16 :
93+ case abi . Int16 :
8394 * (* int16 )(ptr ) = int16 (bits )
84- case Int , Int32 :
95+ case abi . Int , abi . Int32 :
8596 * (* int32 )(ptr ) = int32 (bits )
86- case Int64 :
97+ case abi . Int64 :
8798 * (* int64 )(ptr ) = int64 (bits )
88- case Uint8 :
99+ case abi . Uint8 :
89100 * (* uint8 )(ptr ) = uint8 (bits )
90- case Uint16 :
101+ case abi . Uint16 :
91102 * (* uint16 )(ptr ) = uint16 (bits )
92- case Uint , Uint32 , Uintptr :
103+ case abi . Uint , abi . Uint32 , abi . Uintptr :
93104 * (* uint32 )(ptr ) = uint32 (bits )
94- case Uint64 :
105+ case abi . Uint64 :
95106 * (* uint64 )(ptr ) = uint64 (bits )
96107 }
97- return Value {typ , ptr , f | flagIndir | flag (typ .Kind ())}
108+ return Value {
109+ typ_ : typ ,
110+ ptr : ptr ,
111+ flag : f | flagIndir | flag (typ .Kind ()),
112+ }
98113}
99114
100115//gopherjs:replace
101116func methodReceiver (op string , v Value , methodIndex int ) (rcvrtype * abi.Type , t * funcType , fn unsafe.Pointer ) {
102117 i := methodIndex
103118 var prop string
104- if v .typ .Kind () == Interface {
105- tt := (* interfaceType )(unsafe .Pointer (v .typ ))
106- if i < 0 || i >= len (tt .methods ) {
119+ if tt := v .typ ().InterfaceType (); tt != nil {
120+ if i < 0 || i >= len (tt .Methods ) {
107121 panic ("reflect: internal error: invalid method index" )
108122 }
109- m := & tt .methods [i ]
110- if ! tt .nameOff (m .name ). isExported () {
123+ m := & tt .Methods [i ]
124+ if ! tt .NameOff (m .Name ). IsExported () {
111125 panic ("reflect: " + op + " of unexported method" )
112126 }
113- rcvrtype = iface . itab . typ
114- t = ( * funcType )( unsafe . Pointer ( tt .typeOff (m .typ )) )
115- prop = tt .nameOff (m .name ). name ()
127+ // TODO(grantnelson-wf): Set rcvrtype to the type the interface is holding onto.
128+ t = tt .TypeOff (m .typ ). FuncType ( )
129+ prop = tt .NameOff (m .Name ). Name ()
116130 } else {
117131 rcvrtype = v .typ ()
118- ms := v .typ . exportedMethods ()
132+ ms := v .typ (). ExportedMethods ()
119133 if uint (i ) >= uint (len (ms )) {
120134 panic ("reflect: internal error: invalid method index" )
121135 }
122136 m := ms [i ]
123- if ! v .typ . nameOff (m .name ). isExported () {
137+ if ! v .typ (). NameOff (m .Name ). IsExported () {
124138 panic ("reflect: " + op + " of unexported method" )
125139 }
126- t = ( * funcType )( unsafe . Pointer ( v .typ . typeOff (m .mtyp )) )
140+ t = v .typ (). TypeOff (m .mtyp ). FuncType ( )
127141 prop = js .Global .Call ("$methodSet" , jsType (v .typ )).Index (i ).Get ("prop" ).String ()
128142 }
129143 rcvr := v .object ()
130- if isWrapped ( v .typ ) {
144+ if v .typ (). IsWrapped ( ) {
131145 rcvr = jsType (v .typ ).New (rcvr )
132146 }
133147 fn = unsafe .Pointer (rcvr .Get (prop ).Unsafe ())
134148 return
135149}
136150
151+ //gopherjs:replace
152+ func storeRcvr (v Value , p unsafe.Pointer ) {
153+ t := v .typ ()
154+ if t .Kind () == abi .Interface {
155+ // the interface data word becomes the receiver word
156+ iface := (* nonEmptyInterface )(v .ptr )
157+ * (* unsafe .Pointer )(p ) = iface .word
158+ } else if v .flag & flagIndir != 0 && ! ifaceIndir (t ) {
159+ * (* unsafe .Pointer )(p ) = * (* unsafe .Pointer )(v .ptr )
160+ } else {
161+ * (* unsafe .Pointer )(p ) = v .ptr
162+ }
163+ }
164+
137165func MakeFunc (typ Type , fn func (args []Value ) (results []Value )) Value {
138166 if typ .Kind () != Func {
139167 panic ("reflect: call of MakeFunc with non-Func type" )
@@ -193,7 +221,7 @@ func typedmemmove(t *abi.Type, dst, src unsafe.Pointer) {
193221
194222//gopherjs:replace
195223func makechan (typ * abi.Type , size int ) (ch unsafe.Pointer ) {
196- ctyp := ( * abi .ChanType )( unsafe . Pointer ( typ ) )
224+ ctyp := typ .ChanType ( )
197225 return unsafe .Pointer (js .Global .Get ("$Chan" ).New (jsType (ctyp .Elem ), size ).Unsafe ())
198226}
199227
0 commit comments