@@ -42,7 +42,7 @@ func reflectType(typ *js.Object) *rtype {
42
42
rt := & rtype {
43
43
size : uintptr (typ .Get ("size" ).Int ()),
44
44
kind : uint8 (typ .Get ("kind" ).Int ()),
45
- str : newNameOff (newName (internalStr (typ .Get ("string" )), "" , "" , typ .Get ("exported" ).Bool ())),
45
+ str : newNameOff (newName (internalStr (typ .Get ("string" )), "" , typ .Get ("exported" ).Bool ())),
46
46
}
47
47
js .InternalObject (rt ).Set ("jsType" , typ )
48
48
typ .Set ("reflectType" , js .InternalObject (rt ))
@@ -57,12 +57,12 @@ func reflectType(typ *js.Object) *rtype {
57
57
for i := range reflectMethods {
58
58
m := methodSet .Index (i )
59
59
reflectMethods [i ] = method {
60
- name : newNameOff (newName (internalStr (m .Get ("name" )), "" , "" , internalStr (m .Get ("pkg" )) == "" )),
60
+ name : newNameOff (newName (internalStr (m .Get ("name" )), "" , internalStr (m .Get ("pkg" )) == "" )),
61
61
mtyp : newTypeOff (reflectType (m .Get ("typ" ))),
62
62
}
63
63
}
64
64
ut := & uncommonType {
65
- pkgPath : newNameOff (newName (internalStr (typ .Get ("pkg" )), "" , "" , false )),
65
+ pkgPath : newNameOff (newName (internalStr (typ .Get ("pkg" )), "" , false )),
66
66
mcount : uint16 (methodSet .Length ()),
67
67
_methods : reflectMethods ,
68
68
}
@@ -116,13 +116,13 @@ func reflectType(typ *js.Object) *rtype {
116
116
for i := range imethods {
117
117
m := methods .Index (i )
118
118
imethods [i ] = imethod {
119
- name : newNameOff (newName (internalStr (m .Get ("name" )), "" , "" , internalStr (m .Get ("pkg" )) == "" )),
119
+ name : newNameOff (newName (internalStr (m .Get ("name" )), "" , internalStr (m .Get ("pkg" )) == "" )),
120
120
typ : newTypeOff (reflectType (m .Get ("typ" ))),
121
121
}
122
122
}
123
123
setKindType (rt , & interfaceType {
124
124
rtype : * rt ,
125
- pkgPath : newName (internalStr (typ .Get ("pkg" )), "" , "" , false ),
125
+ pkgPath : newName (internalStr (typ .Get ("pkg" )), "" , false ),
126
126
methods : imethods ,
127
127
})
128
128
case Map :
@@ -148,14 +148,14 @@ func reflectType(typ *js.Object) *rtype {
148
148
offsetAnon |= 1
149
149
}
150
150
reflectFields [i ] = structField {
151
- name : newName (internalStr (f .Get ("name" )), internalStr (f .Get ("tag" )), "" , f .Get ("exported" ).Bool ()),
151
+ name : newName (internalStr (f .Get ("name" )), internalStr (f .Get ("tag" )), f .Get ("exported" ).Bool ()),
152
152
typ : reflectType (f .Get ("typ" )),
153
153
offsetAnon : offsetAnon ,
154
154
}
155
155
}
156
156
setKindType (rt , & structType {
157
157
rtype : * rt ,
158
- pkgPath : newName (internalStr (typ .Get ("pkgPath" )), "" , "" , false ),
158
+ pkgPath : newName (internalStr (typ .Get ("pkgPath" )), "" , false ),
159
159
fields : reflectFields ,
160
160
})
161
161
}
@@ -213,34 +213,21 @@ type name struct {
213
213
type nameData struct {
214
214
name string
215
215
tag string
216
- pkgPath string
217
216
exported bool
218
217
}
219
218
220
219
var nameMap = make (map [* byte ]* nameData )
221
220
222
- func (n name ) name () (s string ) {
223
- return nameMap [n .bytes ].name
224
- }
225
-
226
- func (n name ) tag () (s string ) {
227
- return nameMap [n .bytes ].tag
228
- }
221
+ func (n name ) name () (s string ) { return nameMap [n .bytes ].name }
222
+ func (n name ) tag () (s string ) { return nameMap [n .bytes ].tag }
223
+ func (n name ) pkgPath () string { return "" }
224
+ func (n name ) isExported () bool { return nameMap [n .bytes ].exported }
229
225
230
- func (n name ) pkgPath () string {
231
- return nameMap [n .bytes ].pkgPath
232
- }
233
-
234
- func (n name ) isExported () bool {
235
- return nameMap [n .bytes ].exported
236
- }
237
-
238
- func newName (n , tag , pkgPath string , exported bool ) name {
226
+ func newName (n , tag string , exported bool ) name {
239
227
b := new (byte )
240
228
nameMap [b ] = & nameData {
241
229
name : n ,
242
230
tag : tag ,
243
- pkgPath : pkgPath ,
244
231
exported : exported ,
245
232
}
246
233
return name {
@@ -491,7 +478,7 @@ func loadScalar(p unsafe.Pointer, n uintptr) uintptr {
491
478
return js .InternalObject (p ).Call ("$get" ).Unsafe ()
492
479
}
493
480
494
- func makechan (typ * rtype , size uint64 ) (ch unsafe.Pointer ) {
481
+ func makechan (typ * rtype , size int ) (ch unsafe.Pointer ) {
495
482
ctyp := (* chanType )(unsafe .Pointer (typ ))
496
483
return unsafe .Pointer (js .Global .Get ("$Chan" ).New (jsType (ctyp .elem ), size ).Unsafe ())
497
484
}
@@ -597,7 +584,7 @@ func cvtDirect(v Value, typ Type) Value {
597
584
default :
598
585
panic (& ValueError {"reflect.Convert" , k })
599
586
}
600
- return Value {typ .common (), unsafe .Pointer (val .Unsafe ()), v .flag & ( flagRO | flagIndir ) | flag (typ .Kind ())}
587
+ return Value {typ .common (), unsafe .Pointer (val .Unsafe ()), v .flag . ro () | v . flag & flagIndir | flag (typ .Kind ())}
601
588
}
602
589
603
590
func Copy (dst , src Value ) int {
@@ -611,12 +598,18 @@ func Copy(dst, src Value) int {
611
598
dst .mustBeExported ()
612
599
613
600
sk := src .kind ()
601
+ var stringCopy bool
614
602
if sk != Array && sk != Slice {
615
- panic (& ValueError {"reflect.Copy" , sk })
603
+ stringCopy = sk == String && dst .typ .Elem ().Kind () == Uint8
604
+ if ! stringCopy {
605
+ panic (& ValueError {"reflect.Copy" , sk })
606
+ }
616
607
}
617
608
src .mustBeExported ()
618
609
619
- typesMustMatch ("reflect.Copy" , dst .typ .Elem (), src .typ .Elem ())
610
+ if ! stringCopy {
611
+ typesMustMatch ("reflect.Copy" , dst .typ .Elem (), src .typ .Elem ())
612
+ }
620
613
621
614
dstVal := dst .object ()
622
615
if dk == Array {
@@ -628,6 +621,9 @@ func Copy(dst, src Value) int {
628
621
srcVal = jsType (SliceOf (src .typ .Elem ())).New (srcVal )
629
622
}
630
623
624
+ if stringCopy {
625
+ return js .Global .Call ("$copyString" , dstVal , srcVal ).Int ()
626
+ }
631
627
return js .Global .Call ("$copySlice" , dstVal , srcVal ).Int ()
632
628
}
633
629
@@ -645,11 +641,11 @@ func methodReceiver(op string, v Value, i int) (_, t *rtype, fn unsafe.Pointer)
645
641
t = tt .typeOff (m .typ )
646
642
prop = tt .nameOff (m .name ).name ()
647
643
} else {
648
- ut := v .typ .uncommon ()
649
- if ut == nil || uint (i ) >= uint (ut . mcount ) {
644
+ ms := v .typ .exportedMethods ()
645
+ if uint (i ) >= uint (len ( ms ) ) {
650
646
panic ("reflect: internal error: invalid method index" )
651
647
}
652
- m := ut . methods () [i ]
648
+ m := ms [i ]
653
649
if ! v .typ .nameOff (m .name ).isExported () {
654
650
panic ("reflect: " + op + " of unexported method" )
655
651
}
@@ -702,7 +698,7 @@ func makeMethodValue(op string, v Value) Value {
702
698
fv := js .MakeFunc (func (this * js.Object , arguments []* js.Object ) interface {} {
703
699
return js .InternalObject (fn ).Call ("apply" , rcvr , arguments )
704
700
})
705
- return Value {v .Type ().common (), unsafe .Pointer (fv .Unsafe ()), v .flag & flagRO | flag (Func )}
701
+ return Value {v .Type ().common (), unsafe .Pointer (fv .Unsafe ()), v .flag . ro () | flag (Func )}
706
702
}
707
703
708
704
func (t * rtype ) pointers () bool {
@@ -796,6 +792,39 @@ func (v Value) object() *js.Object {
796
792
return js .InternalObject (v .ptr )
797
793
}
798
794
795
+ func (v Value ) assignTo (context string , dst * rtype , target unsafe.Pointer ) Value {
796
+ if v .flag & flagMethod != 0 {
797
+ v = makeMethodValue (context , v )
798
+ }
799
+
800
+ switch {
801
+ case directlyAssignable (dst , v .typ ):
802
+ // Overwrite type so that they match.
803
+ // Same memory layout, so no harm done.
804
+ fl := v .flag & (flagAddr | flagIndir ) | v .flag .ro ()
805
+ fl |= flag (dst .Kind ())
806
+ return Value {dst , v .ptr , fl }
807
+
808
+ case implements (dst , v .typ ):
809
+ if target == nil {
810
+ target = unsafe_New (dst )
811
+ }
812
+ // GopherJS: Skip the v.Kind() == Interface && v.IsNil() if statement
813
+ // from upstream. ifaceE2I below does not panic, and it needs
814
+ // to run, given its custom implementation.
815
+ x := valueInterface (v , false )
816
+ if dst .NumMethod () == 0 {
817
+ * (* interface {})(target ) = x
818
+ } else {
819
+ ifaceE2I (dst , x , target )
820
+ }
821
+ return Value {dst , target , flagIndir | flag (Interface )}
822
+ }
823
+
824
+ // Failed.
825
+ panic (context + ": value of type " + v .typ .String () + " is not assignable to type " + dst .String ())
826
+ }
827
+
799
828
var callHelper = js .Global .Get ("$call" ).Interface ().(func (... interface {}) * js.Object )
800
829
801
830
func (v Value ) call (op string , in []Value ) []Value {
@@ -932,7 +961,7 @@ func (v Value) Elem() Value {
932
961
return Value {}
933
962
}
934
963
typ := reflectType (val .Get ("constructor" ))
935
- return makeValue (typ , val .Get ("$val" ), v .flag & flagRO )
964
+ return makeValue (typ , val .Get ("$val" ), v .flag . ro () )
936
965
937
966
case Ptr :
938
967
if v .IsNil () {
@@ -1053,8 +1082,7 @@ func (v Value) Index(i int) Value {
1053
1082
panic ("reflect: array index out of range" )
1054
1083
}
1055
1084
typ := tt .elem
1056
- fl := v .flag & (flagRO | flagIndir | flagAddr )
1057
- fl |= flag (typ .Kind ())
1085
+ fl := v .flag & (flagIndir | flagAddr ) | v .flag .ro () | flag (typ .Kind ())
1058
1086
1059
1087
a := js .InternalObject (v .ptr )
1060
1088
if fl & flagIndir != 0 && typ .Kind () != Array && typ .Kind () != Struct {
@@ -1072,8 +1100,7 @@ func (v Value) Index(i int) Value {
1072
1100
}
1073
1101
tt := (* sliceType )(unsafe .Pointer (v .typ ))
1074
1102
typ := tt .elem
1075
- fl := flagAddr | flagIndir | v .flag & flagRO
1076
- fl |= flag (typ .Kind ())
1103
+ fl := flagAddr | flagIndir | v .flag .ro () | flag (typ .Kind ())
1077
1104
1078
1105
i += s .Get ("$offset" ).Int ()
1079
1106
a := s .Get ("$array" )
@@ -1090,9 +1117,9 @@ func (v Value) Index(i int) Value {
1090
1117
if i < 0 || i >= len (str ) {
1091
1118
panic ("reflect: string index out of range" )
1092
1119
}
1093
- fl := v .flag & flagRO | flag (Uint8 )
1120
+ fl := v .flag . ro () | flag (Uint8 ) | flagIndir
1094
1121
c := str [i ]
1095
- return Value {uint8Type , unsafe .Pointer (& c ), fl | flagIndir }
1122
+ return Value {uint8Type , unsafe .Pointer (& c ), fl }
1096
1123
1097
1124
default :
1098
1125
panic (& ValueError {"reflect.Value.Index" , k })
@@ -1258,7 +1285,7 @@ func (v Value) Slice(i, j int) Value {
1258
1285
panic ("reflect.Value.Slice: slice index out of bounds" )
1259
1286
}
1260
1287
1261
- return makeValue (typ , js .Global .Call ("$subslice" , s , i , j ), v .flag & flagRO )
1288
+ return makeValue (typ , js .Global .Call ("$subslice" , s , i , j ), v .flag . ro () )
1262
1289
}
1263
1290
1264
1291
func (v Value ) Slice3 (i , j , k int ) Value {
@@ -1290,7 +1317,7 @@ func (v Value) Slice3(i, j, k int) Value {
1290
1317
panic ("reflect.Value.Slice3: slice index out of bounds" )
1291
1318
}
1292
1319
1293
- return makeValue (typ , js .Global .Call ("$subslice" , s , i , j , k ), v .flag & flagRO )
1320
+ return makeValue (typ , js .Global .Call ("$subslice" , s , i , j , k ), v .flag . ro () )
1294
1321
}
1295
1322
1296
1323
func (v Value ) Close () {
0 commit comments