Source file
src/reflect/value.go
Documentation: reflect
1
2
3
4
5 package reflect
6
7 import (
8 "math"
9 "runtime"
10 "unsafe"
11 )
12
13 const ptrSize = 4 << (^uintptr(0) >> 63)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 type Value struct {
37
38 typ *rtype
39
40
41
42 ptr unsafe.Pointer
43
44
45
46
47
48
49
50
51
52
53
54
55
56 flag
57
58
59
60
61
62
63 }
64
65 type flag uintptr
66
67 const (
68 flagKindWidth = 5
69 flagKindMask flag = 1<<flagKindWidth - 1
70 flagStickyRO flag = 1 << 5
71 flagEmbedRO flag = 1 << 6
72 flagIndir flag = 1 << 7
73 flagAddr flag = 1 << 8
74 flagMethod flag = 1 << 9
75 flagMethodShift = 10
76 flagRO flag = flagStickyRO | flagEmbedRO
77 )
78
79 func (f flag) kind() Kind {
80 return Kind(f & flagKindMask)
81 }
82
83 func (f flag) ro() flag {
84 if f&flagRO != 0 {
85 return flagStickyRO
86 }
87 return 0
88 }
89
90
91
92 func (v Value) pointer() unsafe.Pointer {
93 if v.typ.size != ptrSize || !v.typ.pointers() {
94 panic("can't call pointer on a non-pointer Value")
95 }
96 if v.flag&flagIndir != 0 {
97 return *(*unsafe.Pointer)(v.ptr)
98 }
99 return v.ptr
100 }
101
102
103 func packEface(v Value) interface{} {
104 t := v.typ
105 var i interface{}
106 e := (*emptyInterface)(unsafe.Pointer(&i))
107
108 switch {
109 case ifaceIndir(t):
110 if v.flag&flagIndir == 0 {
111 panic("bad indir")
112 }
113
114 ptr := v.ptr
115 if v.flag&flagAddr != 0 {
116
117
118 c := unsafe_New(t)
119 typedmemmove(t, c, ptr)
120 ptr = c
121 }
122 e.word = ptr
123 case v.flag&flagIndir != 0:
124
125
126 e.word = *(*unsafe.Pointer)(v.ptr)
127 default:
128
129 e.word = v.ptr
130 }
131
132
133
134
135 e.typ = t
136 return i
137 }
138
139
140 func unpackEface(i interface{}) Value {
141 e := (*emptyInterface)(unsafe.Pointer(&i))
142
143 t := e.typ
144 if t == nil {
145 return Value{}
146 }
147 f := flag(t.Kind())
148 if ifaceIndir(t) {
149 f |= flagIndir
150 }
151 return Value{t, e.word, f}
152 }
153
154
155
156
157 type ValueError struct {
158 Method string
159 Kind Kind
160 }
161
162 func (e *ValueError) Error() string {
163 if e.Kind == 0 {
164 return "reflect: call of " + e.Method + " on zero Value"
165 }
166 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
167 }
168
169
170
171 func methodName() string {
172 pc, _, _, _ := runtime.Caller(2)
173 f := runtime.FuncForPC(pc)
174 if f == nil {
175 return "unknown method"
176 }
177 return f.Name()
178 }
179
180
181 type emptyInterface struct {
182 typ *rtype
183 word unsafe.Pointer
184 }
185
186
187 type nonEmptyInterface struct {
188
189 itab *struct {
190 ityp *rtype
191 typ *rtype
192 hash uint32
193 _ [4]byte
194 fun [100000]unsafe.Pointer
195 }
196 word unsafe.Pointer
197 }
198
199
200
201
202
203
204
205 func (f flag) mustBe(expected Kind) {
206 if f.kind() != expected {
207 panic(&ValueError{methodName(), f.kind()})
208 }
209 }
210
211
212
213 func (f flag) mustBeExported() {
214 if f == 0 {
215 panic(&ValueError{methodName(), 0})
216 }
217 if f&flagRO != 0 {
218 panic("reflect: " + methodName() + " using value obtained using unexported field")
219 }
220 }
221
222
223
224
225 func (f flag) mustBeAssignable() {
226 if f == 0 {
227 panic(&ValueError{methodName(), Invalid})
228 }
229
230 if f&flagRO != 0 {
231 panic("reflect: " + methodName() + " using value obtained using unexported field")
232 }
233 if f&flagAddr == 0 {
234 panic("reflect: " + methodName() + " using unaddressable value")
235 }
236 }
237
238
239
240
241
242
243 func (v Value) Addr() Value {
244 if v.flag&flagAddr == 0 {
245 panic("reflect.Value.Addr of unaddressable value")
246 }
247 return Value{v.typ.ptrTo(), v.ptr, v.flag.ro() | flag(Ptr)}
248 }
249
250
251
252 func (v Value) Bool() bool {
253 v.mustBe(Bool)
254 return *(*bool)(v.ptr)
255 }
256
257
258
259 func (v Value) Bytes() []byte {
260 v.mustBe(Slice)
261 if v.typ.Elem().Kind() != Uint8 {
262 panic("reflect.Value.Bytes of non-byte slice")
263 }
264
265 return *(*[]byte)(v.ptr)
266 }
267
268
269
270 func (v Value) runes() []rune {
271 v.mustBe(Slice)
272 if v.typ.Elem().Kind() != Int32 {
273 panic("reflect.Value.Bytes of non-rune slice")
274 }
275
276 return *(*[]rune)(v.ptr)
277 }
278
279
280
281
282
283
284 func (v Value) CanAddr() bool {
285 return v.flag&flagAddr != 0
286 }
287
288
289
290
291
292
293 func (v Value) CanSet() bool {
294 return v.flag&(flagAddr|flagRO) == flagAddr
295 }
296
297
298
299
300
301
302
303
304
305 func (v Value) Call(in []Value) []Value {
306 v.mustBe(Func)
307 v.mustBeExported()
308 return v.call("Call", in)
309 }
310
311
312
313
314
315
316
317
318 func (v Value) CallSlice(in []Value) []Value {
319 v.mustBe(Func)
320 v.mustBeExported()
321 return v.call("CallSlice", in)
322 }
323
324 var callGC bool
325
326 func (v Value) call(op string, in []Value) []Value {
327
328 t := v.typ
329 var (
330 fn unsafe.Pointer
331 rcvr Value
332 rcvrtype *rtype
333 )
334 if v.flag&flagMethod != 0 {
335 rcvr = v
336 rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
337 } else if v.flag&flagIndir != 0 {
338 fn = *(*unsafe.Pointer)(v.ptr)
339 } else {
340 fn = v.ptr
341 }
342
343 if fn == nil {
344 panic("reflect.Value.Call: call of nil function")
345 }
346
347 isSlice := op == "CallSlice"
348 n := t.NumIn()
349 if isSlice {
350 if !t.IsVariadic() {
351 panic("reflect: CallSlice of non-variadic function")
352 }
353 if len(in) < n {
354 panic("reflect: CallSlice with too few input arguments")
355 }
356 if len(in) > n {
357 panic("reflect: CallSlice with too many input arguments")
358 }
359 } else {
360 if t.IsVariadic() {
361 n--
362 }
363 if len(in) < n {
364 panic("reflect: Call with too few input arguments")
365 }
366 if !t.IsVariadic() && len(in) > n {
367 panic("reflect: Call with too many input arguments")
368 }
369 }
370 for _, x := range in {
371 if x.Kind() == Invalid {
372 panic("reflect: " + op + " using zero Value argument")
373 }
374 }
375 for i := 0; i < n; i++ {
376 if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
377 panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
378 }
379 }
380 if !isSlice && t.IsVariadic() {
381
382 m := len(in) - n
383 slice := MakeSlice(t.In(n), m, m)
384 elem := t.In(n).Elem()
385 for i := 0; i < m; i++ {
386 x := in[n+i]
387 if xt := x.Type(); !xt.AssignableTo(elem) {
388 panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
389 }
390 slice.Index(i).Set(x)
391 }
392 origIn := in
393 in = make([]Value, n+1)
394 copy(in[:n], origIn)
395 in[n] = slice
396 }
397
398 nin := len(in)
399 if nin != t.NumIn() {
400 panic("reflect.Value.Call: wrong argument count")
401 }
402 nout := t.NumOut()
403
404
405 frametype, _, retOffset, _, framePool := funcLayout(t, rcvrtype)
406
407
408 var args unsafe.Pointer
409 if nout == 0 {
410 args = framePool.Get().(unsafe.Pointer)
411 } else {
412
413
414 args = unsafe_New(frametype)
415 }
416 off := uintptr(0)
417
418
419 if rcvrtype != nil {
420 storeRcvr(rcvr, args)
421 off = ptrSize
422 }
423 for i, v := range in {
424 v.mustBeExported()
425 targ := t.In(i).(*rtype)
426 a := uintptr(targ.align)
427 off = (off + a - 1) &^ (a - 1)
428 n := targ.size
429 if n == 0 {
430
431
432
433 v.assignTo("reflect.Value.Call", targ, nil)
434 continue
435 }
436 addr := add(args, off, "n > 0")
437 v = v.assignTo("reflect.Value.Call", targ, addr)
438 if v.flag&flagIndir != 0 {
439 typedmemmove(targ, addr, v.ptr)
440 } else {
441 *(*unsafe.Pointer)(addr) = v.ptr
442 }
443 off += n
444 }
445
446
447 call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
448
449
450 if callGC {
451 runtime.GC()
452 }
453
454 var ret []Value
455 if nout == 0 {
456
457
458 memclrNoHeapPointers(args, frametype.size)
459 framePool.Put(args)
460 } else {
461
462
463
464 memclrNoHeapPointers(args, retOffset)
465
466 ret = make([]Value, nout)
467 off = retOffset
468 for i := 0; i < nout; i++ {
469 tv := t.Out(i)
470 a := uintptr(tv.Align())
471 off = (off + a - 1) &^ (a - 1)
472 if tv.Size() != 0 {
473 fl := flagIndir | flag(tv.Kind())
474 ret[i] = Value{tv.common(), add(args, off, "tv.Size() != 0"), fl}
475 } else {
476
477
478 ret[i] = Zero(tv)
479 }
480 off += tv.Size()
481 }
482 }
483
484 return ret
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498
499 func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
500 ftyp := ctxt.typ
501 f := ctxt.fn
502
503
504 ptr := frame
505 off := uintptr(0)
506 in := make([]Value, 0, int(ftyp.inCount))
507 for _, typ := range ftyp.in() {
508 off += -off & uintptr(typ.align-1)
509 v := Value{typ, nil, flag(typ.Kind())}
510 if ifaceIndir(typ) {
511
512
513
514
515 v.ptr = unsafe_New(typ)
516 if typ.size > 0 {
517 typedmemmove(typ, v.ptr, add(ptr, off, "typ.size > 0"))
518 }
519 v.flag |= flagIndir
520 } else {
521 v.ptr = *(*unsafe.Pointer)(add(ptr, off, "1-ptr"))
522 }
523 in = append(in, v)
524 off += typ.size
525 }
526
527
528 out := f(in)
529 numOut := ftyp.NumOut()
530 if len(out) != numOut {
531 panic("reflect: wrong return count from function created by MakeFunc")
532 }
533
534
535 if numOut > 0 {
536 off += -off & (ptrSize - 1)
537 if runtime.GOARCH == "amd64p32" {
538 off = align(off, 8)
539 }
540 for i, typ := range ftyp.out() {
541 v := out[i]
542 if v.typ != typ {
543 panic("reflect: function created by MakeFunc using " + funcName(f) +
544 " returned wrong type: have " +
545 out[i].typ.String() + " for " + typ.String())
546 }
547 if v.flag&flagRO != 0 {
548 panic("reflect: function created by MakeFunc using " + funcName(f) +
549 " returned value obtained from unexported field")
550 }
551 off += -off & uintptr(typ.align-1)
552 if typ.size == 0 {
553 continue
554 }
555 addr := add(ptr, off, "typ.size > 0")
556 if v.flag&flagIndir != 0 {
557 typedmemmove(typ, addr, v.ptr)
558 } else {
559 *(*unsafe.Pointer)(addr) = v.ptr
560 }
561 off += typ.size
562 }
563 }
564
565
566
567
568 runtime.KeepAlive(ctxt)
569 }
570
571
572
573
574
575
576
577
578 func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) {
579 i := methodIndex
580 if v.typ.Kind() == Interface {
581 tt := (*interfaceType)(unsafe.Pointer(v.typ))
582 if uint(i) >= uint(len(tt.methods)) {
583 panic("reflect: internal error: invalid method index")
584 }
585 m := &tt.methods[i]
586 if !tt.nameOff(m.name).isExported() {
587 panic("reflect: " + op + " of unexported method")
588 }
589 iface := (*nonEmptyInterface)(v.ptr)
590 if iface.itab == nil {
591 panic("reflect: " + op + " of method on nil interface value")
592 }
593 rcvrtype = iface.itab.typ
594 fn = unsafe.Pointer(&iface.itab.fun[i])
595 t = tt.typeOff(m.typ)
596 } else {
597 rcvrtype = v.typ
598 ms := v.typ.exportedMethods()
599 if uint(i) >= uint(len(ms)) {
600 panic("reflect: internal error: invalid method index")
601 }
602 m := ms[i]
603 if !v.typ.nameOff(m.name).isExported() {
604 panic("reflect: " + op + " of unexported method")
605 }
606 ifn := v.typ.textOff(m.ifn)
607 fn = unsafe.Pointer(&ifn)
608 t = v.typ.typeOff(m.mtyp)
609 }
610 return
611 }
612
613
614
615
616
617 func storeRcvr(v Value, p unsafe.Pointer) {
618 t := v.typ
619 if t.Kind() == Interface {
620
621 iface := (*nonEmptyInterface)(v.ptr)
622 *(*unsafe.Pointer)(p) = iface.word
623 } else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
624 *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
625 } else {
626 *(*unsafe.Pointer)(p) = v.ptr
627 }
628 }
629
630
631
632 func align(x, n uintptr) uintptr {
633 return (x + n - 1) &^ (n - 1)
634 }
635
636
637
638
639
640
641
642
643
644
645
646
647 func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
648 rcvr := ctxt.rcvr
649 rcvrtype, t, fn := methodReceiver("call", rcvr, ctxt.method)
650 frametype, argSize, retOffset, _, framePool := funcLayout(t, rcvrtype)
651
652
653 args := framePool.Get().(unsafe.Pointer)
654
655
656
657 storeRcvr(rcvr, args)
658 if argSize-ptrSize > 0 {
659 typedmemmovepartial(frametype, add(args, ptrSize, "argSize > ptrSize"), frame, ptrSize, argSize-ptrSize)
660 }
661
662
663 call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
664
665
666
667
668
669
670
671 if frametype.size-retOffset > 0 {
672 callerRetOffset := retOffset - ptrSize
673 if runtime.GOARCH == "amd64p32" {
674 callerRetOffset = align(argSize-ptrSize, 8)
675 }
676 typedmemmovepartial(frametype,
677 add(frame, callerRetOffset, "frametype.size > retOffset"),
678 add(args, retOffset, "frametype.size > retOffset"),
679 retOffset,
680 frametype.size-retOffset)
681 }
682
683
684
685 memclrNoHeapPointers(args, frametype.size)
686 framePool.Put(args)
687
688
689 runtime.KeepAlive(ctxt)
690 }
691
692
693 func funcName(f func([]Value) []Value) string {
694 pc := *(*uintptr)(unsafe.Pointer(&f))
695 rf := runtime.FuncForPC(pc)
696 if rf != nil {
697 return rf.Name()
698 }
699 return "closure"
700 }
701
702
703
704 func (v Value) Cap() int {
705 k := v.kind()
706 switch k {
707 case Array:
708 return v.typ.Len()
709 case Chan:
710 return chancap(v.pointer())
711 case Slice:
712
713 return (*sliceHeader)(v.ptr).Cap
714 }
715 panic(&ValueError{"reflect.Value.Cap", v.kind()})
716 }
717
718
719
720 func (v Value) Close() {
721 v.mustBe(Chan)
722 v.mustBeExported()
723 chanclose(v.pointer())
724 }
725
726
727
728 func (v Value) Complex() complex128 {
729 k := v.kind()
730 switch k {
731 case Complex64:
732 return complex128(*(*complex64)(v.ptr))
733 case Complex128:
734 return *(*complex128)(v.ptr)
735 }
736 panic(&ValueError{"reflect.Value.Complex", v.kind()})
737 }
738
739
740
741
742
743 func (v Value) Elem() Value {
744 k := v.kind()
745 switch k {
746 case Interface:
747 var eface interface{}
748 if v.typ.NumMethod() == 0 {
749 eface = *(*interface{})(v.ptr)
750 } else {
751 eface = (interface{})(*(*interface {
752 M()
753 })(v.ptr))
754 }
755 x := unpackEface(eface)
756 if x.flag != 0 {
757 x.flag |= v.flag.ro()
758 }
759 return x
760 case Ptr:
761 ptr := v.ptr
762 if v.flag&flagIndir != 0 {
763 ptr = *(*unsafe.Pointer)(ptr)
764 }
765
766 if ptr == nil {
767 return Value{}
768 }
769 tt := (*ptrType)(unsafe.Pointer(v.typ))
770 typ := tt.elem
771 fl := v.flag&flagRO | flagIndir | flagAddr
772 fl |= flag(typ.Kind())
773 return Value{typ, ptr, fl}
774 }
775 panic(&ValueError{"reflect.Value.Elem", v.kind()})
776 }
777
778
779
780 func (v Value) Field(i int) Value {
781 if v.kind() != Struct {
782 panic(&ValueError{"reflect.Value.Field", v.kind()})
783 }
784 tt := (*structType)(unsafe.Pointer(v.typ))
785 if uint(i) >= uint(len(tt.fields)) {
786 panic("reflect: Field index out of range")
787 }
788 field := &tt.fields[i]
789 typ := field.typ
790
791
792 fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
793
794 if !field.name.isExported() {
795 if field.anon() {
796 fl |= flagEmbedRO
797 } else {
798 fl |= flagStickyRO
799 }
800 }
801
802
803
804
805
806 ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
807 return Value{typ, ptr, fl}
808 }
809
810
811
812 func (v Value) FieldByIndex(index []int) Value {
813 if len(index) == 1 {
814 return v.Field(index[0])
815 }
816 v.mustBe(Struct)
817 for i, x := range index {
818 if i > 0 {
819 if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
820 if v.IsNil() {
821 panic("reflect: indirection through nil pointer to embedded struct")
822 }
823 v = v.Elem()
824 }
825 }
826 v = v.Field(x)
827 }
828 return v
829 }
830
831
832
833
834 func (v Value) FieldByName(name string) Value {
835 v.mustBe(Struct)
836 if f, ok := v.typ.FieldByName(name); ok {
837 return v.FieldByIndex(f.Index)
838 }
839 return Value{}
840 }
841
842
843
844
845
846 func (v Value) FieldByNameFunc(match func(string) bool) Value {
847 if f, ok := v.typ.FieldByNameFunc(match); ok {
848 return v.FieldByIndex(f.Index)
849 }
850 return Value{}
851 }
852
853
854
855 func (v Value) Float() float64 {
856 k := v.kind()
857 switch k {
858 case Float32:
859 return float64(*(*float32)(v.ptr))
860 case Float64:
861 return *(*float64)(v.ptr)
862 }
863 panic(&ValueError{"reflect.Value.Float", v.kind()})
864 }
865
866 var uint8Type = TypeOf(uint8(0)).(*rtype)
867
868
869
870 func (v Value) Index(i int) Value {
871 switch v.kind() {
872 case Array:
873 tt := (*arrayType)(unsafe.Pointer(v.typ))
874 if uint(i) >= uint(tt.len) {
875 panic("reflect: array index out of range")
876 }
877 typ := tt.elem
878 offset := uintptr(i) * typ.size
879
880
881
882
883
884
885 val := add(v.ptr, offset, "same as &v[i], i < tt.len")
886 fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind())
887 return Value{typ, val, fl}
888
889 case Slice:
890
891
892 s := (*sliceHeader)(v.ptr)
893 if uint(i) >= uint(s.Len) {
894 panic("reflect: slice index out of range")
895 }
896 tt := (*sliceType)(unsafe.Pointer(v.typ))
897 typ := tt.elem
898 val := arrayAt(s.Data, i, typ.size, "i < s.Len")
899 fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
900 return Value{typ, val, fl}
901
902 case String:
903 s := (*stringHeader)(v.ptr)
904 if uint(i) >= uint(s.Len) {
905 panic("reflect: string index out of range")
906 }
907 p := arrayAt(s.Data, i, 1, "i < s.Len")
908 fl := v.flag.ro() | flag(Uint8) | flagIndir
909 return Value{uint8Type, p, fl}
910 }
911 panic(&ValueError{"reflect.Value.Index", v.kind()})
912 }
913
914
915
916 func (v Value) Int() int64 {
917 k := v.kind()
918 p := v.ptr
919 switch k {
920 case Int:
921 return int64(*(*int)(p))
922 case Int8:
923 return int64(*(*int8)(p))
924 case Int16:
925 return int64(*(*int16)(p))
926 case Int32:
927 return int64(*(*int32)(p))
928 case Int64:
929 return *(*int64)(p)
930 }
931 panic(&ValueError{"reflect.Value.Int", v.kind()})
932 }
933
934
935 func (v Value) CanInterface() bool {
936 if v.flag == 0 {
937 panic(&ValueError{"reflect.Value.CanInterface", Invalid})
938 }
939 return v.flag&flagRO == 0
940 }
941
942
943
944
945
946
947 func (v Value) Interface() (i interface{}) {
948 return valueInterface(v, true)
949 }
950
951 func valueInterface(v Value, safe bool) interface{} {
952 if v.flag == 0 {
953 panic(&ValueError{"reflect.Value.Interface", 0})
954 }
955 if safe && v.flag&flagRO != 0 {
956
957
958
959 panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
960 }
961 if v.flag&flagMethod != 0 {
962 v = makeMethodValue("Interface", v)
963 }
964
965 if v.kind() == Interface {
966
967
968
969 if v.NumMethod() == 0 {
970 return *(*interface{})(v.ptr)
971 }
972 return *(*interface {
973 M()
974 })(v.ptr)
975 }
976
977
978 return packEface(v)
979 }
980
981
982
983 func (v Value) InterfaceData() [2]uintptr {
984
985 v.mustBe(Interface)
986
987
988
989
990
991 return *(*[2]uintptr)(v.ptr)
992 }
993
994
995
996
997
998
999
1000
1001 func (v Value) IsNil() bool {
1002 k := v.kind()
1003 switch k {
1004 case Chan, Func, Map, Ptr:
1005 if v.flag&flagMethod != 0 {
1006 return false
1007 }
1008 ptr := v.ptr
1009 if v.flag&flagIndir != 0 {
1010 ptr = *(*unsafe.Pointer)(ptr)
1011 }
1012 return ptr == nil
1013 case Interface, Slice:
1014
1015
1016 return *(*unsafe.Pointer)(v.ptr) == nil
1017 }
1018 panic(&ValueError{"reflect.Value.IsNil", v.kind()})
1019 }
1020
1021
1022
1023
1024
1025
1026 func (v Value) IsValid() bool {
1027 return v.flag != 0
1028 }
1029
1030
1031
1032 func (v Value) Kind() Kind {
1033 return v.kind()
1034 }
1035
1036
1037
1038 func (v Value) Len() int {
1039 k := v.kind()
1040 switch k {
1041 case Array:
1042 tt := (*arrayType)(unsafe.Pointer(v.typ))
1043 return int(tt.len)
1044 case Chan:
1045 return chanlen(v.pointer())
1046 case Map:
1047 return maplen(v.pointer())
1048 case Slice:
1049
1050 return (*sliceHeader)(v.ptr).Len
1051 case String:
1052
1053 return (*stringHeader)(v.ptr).Len
1054 }
1055 panic(&ValueError{"reflect.Value.Len", v.kind()})
1056 }
1057
1058
1059
1060
1061
1062 func (v Value) MapIndex(key Value) Value {
1063 v.mustBe(Map)
1064 tt := (*mapType)(unsafe.Pointer(v.typ))
1065
1066
1067
1068
1069
1070
1071
1072
1073 key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
1074
1075 var k unsafe.Pointer
1076 if key.flag&flagIndir != 0 {
1077 k = key.ptr
1078 } else {
1079 k = unsafe.Pointer(&key.ptr)
1080 }
1081 e := mapaccess(v.typ, v.pointer(), k)
1082 if e == nil {
1083 return Value{}
1084 }
1085 typ := tt.elem
1086 fl := (v.flag | key.flag).ro()
1087 fl |= flag(typ.Kind())
1088 if !ifaceIndir(typ) {
1089 return Value{typ, *(*unsafe.Pointer)(e), fl}
1090 }
1091
1092
1093 c := unsafe_New(typ)
1094 typedmemmove(typ, c, e)
1095 return Value{typ, c, fl | flagIndir}
1096 }
1097
1098
1099
1100
1101
1102 func (v Value) MapKeys() []Value {
1103 v.mustBe(Map)
1104 tt := (*mapType)(unsafe.Pointer(v.typ))
1105 keyType := tt.key
1106
1107 fl := v.flag.ro() | flag(keyType.Kind())
1108
1109 m := v.pointer()
1110 mlen := int(0)
1111 if m != nil {
1112 mlen = maplen(m)
1113 }
1114 it := mapiterinit(v.typ, m)
1115 a := make([]Value, mlen)
1116 var i int
1117 for i = 0; i < len(a); i++ {
1118 key := mapiterkey(it)
1119 if key == nil {
1120
1121
1122
1123 break
1124 }
1125 if ifaceIndir(keyType) {
1126
1127
1128 c := unsafe_New(keyType)
1129 typedmemmove(keyType, c, key)
1130 a[i] = Value{keyType, c, fl | flagIndir}
1131 } else {
1132 a[i] = Value{keyType, *(*unsafe.Pointer)(key), fl}
1133 }
1134 mapiternext(it)
1135 }
1136 return a[:i]
1137 }
1138
1139
1140
1141
1142
1143 func (v Value) Method(i int) Value {
1144 if v.typ == nil {
1145 panic(&ValueError{"reflect.Value.Method", Invalid})
1146 }
1147 if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
1148 panic("reflect: Method index out of range")
1149 }
1150 if v.typ.Kind() == Interface && v.IsNil() {
1151 panic("reflect: Method on nil interface value")
1152 }
1153 fl := v.flag & (flagStickyRO | flagIndir)
1154 fl |= flag(Func)
1155 fl |= flag(i)<<flagMethodShift | flagMethod
1156 return Value{v.typ, v.ptr, fl}
1157 }
1158
1159
1160 func (v Value) NumMethod() int {
1161 if v.typ == nil {
1162 panic(&ValueError{"reflect.Value.NumMethod", Invalid})
1163 }
1164 if v.flag&flagMethod != 0 {
1165 return 0
1166 }
1167 return v.typ.NumMethod()
1168 }
1169
1170
1171
1172
1173
1174
1175 func (v Value) MethodByName(name string) Value {
1176 if v.typ == nil {
1177 panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1178 }
1179 if v.flag&flagMethod != 0 {
1180 return Value{}
1181 }
1182 m, ok := v.typ.MethodByName(name)
1183 if !ok {
1184 return Value{}
1185 }
1186 return v.Method(m.Index)
1187 }
1188
1189
1190
1191 func (v Value) NumField() int {
1192 v.mustBe(Struct)
1193 tt := (*structType)(unsafe.Pointer(v.typ))
1194 return len(tt.fields)
1195 }
1196
1197
1198
1199 func (v Value) OverflowComplex(x complex128) bool {
1200 k := v.kind()
1201 switch k {
1202 case Complex64:
1203 return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1204 case Complex128:
1205 return false
1206 }
1207 panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
1208 }
1209
1210
1211
1212 func (v Value) OverflowFloat(x float64) bool {
1213 k := v.kind()
1214 switch k {
1215 case Float32:
1216 return overflowFloat32(x)
1217 case Float64:
1218 return false
1219 }
1220 panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
1221 }
1222
1223 func overflowFloat32(x float64) bool {
1224 if x < 0 {
1225 x = -x
1226 }
1227 return math.MaxFloat32 < x && x <= math.MaxFloat64
1228 }
1229
1230
1231
1232 func (v Value) OverflowInt(x int64) bool {
1233 k := v.kind()
1234 switch k {
1235 case Int, Int8, Int16, Int32, Int64:
1236 bitSize := v.typ.size * 8
1237 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1238 return x != trunc
1239 }
1240 panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
1241 }
1242
1243
1244
1245 func (v Value) OverflowUint(x uint64) bool {
1246 k := v.kind()
1247 switch k {
1248 case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
1249 bitSize := v.typ.size * 8
1250 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1251 return x != trunc
1252 }
1253 panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
1254 }
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270 func (v Value) Pointer() uintptr {
1271
1272 k := v.kind()
1273 switch k {
1274 case Chan, Map, Ptr, UnsafePointer:
1275 return uintptr(v.pointer())
1276 case Func:
1277 if v.flag&flagMethod != 0 {
1278
1279
1280
1281
1282
1283
1284 f := methodValueCall
1285 return **(**uintptr)(unsafe.Pointer(&f))
1286 }
1287 p := v.pointer()
1288
1289
1290 if p != nil {
1291 p = *(*unsafe.Pointer)(p)
1292 }
1293 return uintptr(p)
1294
1295 case Slice:
1296 return (*SliceHeader)(v.ptr).Data
1297 }
1298 panic(&ValueError{"reflect.Value.Pointer", v.kind()})
1299 }
1300
1301
1302
1303
1304
1305
1306 func (v Value) Recv() (x Value, ok bool) {
1307 v.mustBe(Chan)
1308 v.mustBeExported()
1309 return v.recv(false)
1310 }
1311
1312
1313
1314 func (v Value) recv(nb bool) (val Value, ok bool) {
1315 tt := (*chanType)(unsafe.Pointer(v.typ))
1316 if ChanDir(tt.dir)&RecvDir == 0 {
1317 panic("reflect: recv on send-only channel")
1318 }
1319 t := tt.elem
1320 val = Value{t, nil, flag(t.Kind())}
1321 var p unsafe.Pointer
1322 if ifaceIndir(t) {
1323 p = unsafe_New(t)
1324 val.ptr = p
1325 val.flag |= flagIndir
1326 } else {
1327 p = unsafe.Pointer(&val.ptr)
1328 }
1329 selected, ok := chanrecv(v.pointer(), nb, p)
1330 if !selected {
1331 val = Value{}
1332 }
1333 return
1334 }
1335
1336
1337
1338
1339 func (v Value) Send(x Value) {
1340 v.mustBe(Chan)
1341 v.mustBeExported()
1342 v.send(x, false)
1343 }
1344
1345
1346
1347 func (v Value) send(x Value, nb bool) (selected bool) {
1348 tt := (*chanType)(unsafe.Pointer(v.typ))
1349 if ChanDir(tt.dir)&SendDir == 0 {
1350 panic("reflect: send on recv-only channel")
1351 }
1352 x.mustBeExported()
1353 x = x.assignTo("reflect.Value.Send", tt.elem, nil)
1354 var p unsafe.Pointer
1355 if x.flag&flagIndir != 0 {
1356 p = x.ptr
1357 } else {
1358 p = unsafe.Pointer(&x.ptr)
1359 }
1360 return chansend(v.pointer(), p, nb)
1361 }
1362
1363
1364
1365
1366 func (v Value) Set(x Value) {
1367 v.mustBeAssignable()
1368 x.mustBeExported()
1369 var target unsafe.Pointer
1370 if v.kind() == Interface {
1371 target = v.ptr
1372 }
1373 x = x.assignTo("reflect.Set", v.typ, target)
1374 if x.flag&flagIndir != 0 {
1375 typedmemmove(v.typ, v.ptr, x.ptr)
1376 } else {
1377 *(*unsafe.Pointer)(v.ptr) = x.ptr
1378 }
1379 }
1380
1381
1382
1383 func (v Value) SetBool(x bool) {
1384 v.mustBeAssignable()
1385 v.mustBe(Bool)
1386 *(*bool)(v.ptr) = x
1387 }
1388
1389
1390
1391 func (v Value) SetBytes(x []byte) {
1392 v.mustBeAssignable()
1393 v.mustBe(Slice)
1394 if v.typ.Elem().Kind() != Uint8 {
1395 panic("reflect.Value.SetBytes of non-byte slice")
1396 }
1397 *(*[]byte)(v.ptr) = x
1398 }
1399
1400
1401
1402 func (v Value) setRunes(x []rune) {
1403 v.mustBeAssignable()
1404 v.mustBe(Slice)
1405 if v.typ.Elem().Kind() != Int32 {
1406 panic("reflect.Value.setRunes of non-rune slice")
1407 }
1408 *(*[]rune)(v.ptr) = x
1409 }
1410
1411
1412
1413 func (v Value) SetComplex(x complex128) {
1414 v.mustBeAssignable()
1415 switch k := v.kind(); k {
1416 default:
1417 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
1418 case Complex64:
1419 *(*complex64)(v.ptr) = complex64(x)
1420 case Complex128:
1421 *(*complex128)(v.ptr) = x
1422 }
1423 }
1424
1425
1426
1427 func (v Value) SetFloat(x float64) {
1428 v.mustBeAssignable()
1429 switch k := v.kind(); k {
1430 default:
1431 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
1432 case Float32:
1433 *(*float32)(v.ptr) = float32(x)
1434 case Float64:
1435 *(*float64)(v.ptr) = x
1436 }
1437 }
1438
1439
1440
1441 func (v Value) SetInt(x int64) {
1442 v.mustBeAssignable()
1443 switch k := v.kind(); k {
1444 default:
1445 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
1446 case Int:
1447 *(*int)(v.ptr) = int(x)
1448 case Int8:
1449 *(*int8)(v.ptr) = int8(x)
1450 case Int16:
1451 *(*int16)(v.ptr) = int16(x)
1452 case Int32:
1453 *(*int32)(v.ptr) = int32(x)
1454 case Int64:
1455 *(*int64)(v.ptr) = x
1456 }
1457 }
1458
1459
1460
1461
1462 func (v Value) SetLen(n int) {
1463 v.mustBeAssignable()
1464 v.mustBe(Slice)
1465 s := (*sliceHeader)(v.ptr)
1466 if uint(n) > uint(s.Cap) {
1467 panic("reflect: slice length out of range in SetLen")
1468 }
1469 s.Len = n
1470 }
1471
1472
1473
1474
1475 func (v Value) SetCap(n int) {
1476 v.mustBeAssignable()
1477 v.mustBe(Slice)
1478 s := (*sliceHeader)(v.ptr)
1479 if n < s.Len || n > s.Cap {
1480 panic("reflect: slice capacity out of range in SetCap")
1481 }
1482 s.Cap = n
1483 }
1484
1485
1486
1487
1488
1489
1490
1491 func (v Value) SetMapIndex(key, val Value) {
1492 v.mustBe(Map)
1493 v.mustBeExported()
1494 key.mustBeExported()
1495 tt := (*mapType)(unsafe.Pointer(v.typ))
1496 key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
1497 var k unsafe.Pointer
1498 if key.flag&flagIndir != 0 {
1499 k = key.ptr
1500 } else {
1501 k = unsafe.Pointer(&key.ptr)
1502 }
1503 if val.typ == nil {
1504 mapdelete(v.typ, v.pointer(), k)
1505 return
1506 }
1507 val.mustBeExported()
1508 val = val.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
1509 var e unsafe.Pointer
1510 if val.flag&flagIndir != 0 {
1511 e = val.ptr
1512 } else {
1513 e = unsafe.Pointer(&val.ptr)
1514 }
1515 mapassign(v.typ, v.pointer(), k, e)
1516 }
1517
1518
1519
1520 func (v Value) SetUint(x uint64) {
1521 v.mustBeAssignable()
1522 switch k := v.kind(); k {
1523 default:
1524 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
1525 case Uint:
1526 *(*uint)(v.ptr) = uint(x)
1527 case Uint8:
1528 *(*uint8)(v.ptr) = uint8(x)
1529 case Uint16:
1530 *(*uint16)(v.ptr) = uint16(x)
1531 case Uint32:
1532 *(*uint32)(v.ptr) = uint32(x)
1533 case Uint64:
1534 *(*uint64)(v.ptr) = x
1535 case Uintptr:
1536 *(*uintptr)(v.ptr) = uintptr(x)
1537 }
1538 }
1539
1540
1541
1542 func (v Value) SetPointer(x unsafe.Pointer) {
1543 v.mustBeAssignable()
1544 v.mustBe(UnsafePointer)
1545 *(*unsafe.Pointer)(v.ptr) = x
1546 }
1547
1548
1549
1550 func (v Value) SetString(x string) {
1551 v.mustBeAssignable()
1552 v.mustBe(String)
1553 *(*string)(v.ptr) = x
1554 }
1555
1556
1557
1558
1559 func (v Value) Slice(i, j int) Value {
1560 var (
1561 cap int
1562 typ *sliceType
1563 base unsafe.Pointer
1564 )
1565 switch kind := v.kind(); kind {
1566 default:
1567 panic(&ValueError{"reflect.Value.Slice", v.kind()})
1568
1569 case Array:
1570 if v.flag&flagAddr == 0 {
1571 panic("reflect.Value.Slice: slice of unaddressable array")
1572 }
1573 tt := (*arrayType)(unsafe.Pointer(v.typ))
1574 cap = int(tt.len)
1575 typ = (*sliceType)(unsafe.Pointer(tt.slice))
1576 base = v.ptr
1577
1578 case Slice:
1579 typ = (*sliceType)(unsafe.Pointer(v.typ))
1580 s := (*sliceHeader)(v.ptr)
1581 base = s.Data
1582 cap = s.Cap
1583
1584 case String:
1585 s := (*stringHeader)(v.ptr)
1586 if i < 0 || j < i || j > s.Len {
1587 panic("reflect.Value.Slice: string slice index out of bounds")
1588 }
1589 var t stringHeader
1590 if i < s.Len {
1591 t = stringHeader{arrayAt(s.Data, i, 1, "i < s.Len"), j - i}
1592 }
1593 return Value{v.typ, unsafe.Pointer(&t), v.flag}
1594 }
1595
1596 if i < 0 || j < i || j > cap {
1597 panic("reflect.Value.Slice: slice index out of bounds")
1598 }
1599
1600
1601 var x []unsafe.Pointer
1602
1603
1604 s := (*sliceHeader)(unsafe.Pointer(&x))
1605 s.Len = j - i
1606 s.Cap = cap - i
1607 if cap-i > 0 {
1608 s.Data = arrayAt(base, i, typ.elem.Size(), "i < cap")
1609 } else {
1610
1611 s.Data = base
1612 }
1613
1614 fl := v.flag.ro() | flagIndir | flag(Slice)
1615 return Value{typ.common(), unsafe.Pointer(&x), fl}
1616 }
1617
1618
1619
1620
1621 func (v Value) Slice3(i, j, k int) Value {
1622 var (
1623 cap int
1624 typ *sliceType
1625 base unsafe.Pointer
1626 )
1627 switch kind := v.kind(); kind {
1628 default:
1629 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
1630
1631 case Array:
1632 if v.flag&flagAddr == 0 {
1633 panic("reflect.Value.Slice3: slice of unaddressable array")
1634 }
1635 tt := (*arrayType)(unsafe.Pointer(v.typ))
1636 cap = int(tt.len)
1637 typ = (*sliceType)(unsafe.Pointer(tt.slice))
1638 base = v.ptr
1639
1640 case Slice:
1641 typ = (*sliceType)(unsafe.Pointer(v.typ))
1642 s := (*sliceHeader)(v.ptr)
1643 base = s.Data
1644 cap = s.Cap
1645 }
1646
1647 if i < 0 || j < i || k < j || k > cap {
1648 panic("reflect.Value.Slice3: slice index out of bounds")
1649 }
1650
1651
1652
1653 var x []unsafe.Pointer
1654
1655
1656 s := (*sliceHeader)(unsafe.Pointer(&x))
1657 s.Len = j - i
1658 s.Cap = k - i
1659 if k-i > 0 {
1660 s.Data = arrayAt(base, i, typ.elem.Size(), "i < k <= cap")
1661 } else {
1662
1663 s.Data = base
1664 }
1665
1666 fl := v.flag.ro() | flagIndir | flag(Slice)
1667 return Value{typ.common(), unsafe.Pointer(&x), fl}
1668 }
1669
1670
1671
1672
1673
1674
1675
1676 func (v Value) String() string {
1677 switch k := v.kind(); k {
1678 case Invalid:
1679 return "<invalid Value>"
1680 case String:
1681 return *(*string)(v.ptr)
1682 }
1683
1684
1685 return "<" + v.Type().String() + " Value>"
1686 }
1687
1688
1689
1690
1691
1692
1693 func (v Value) TryRecv() (x Value, ok bool) {
1694 v.mustBe(Chan)
1695 v.mustBeExported()
1696 return v.recv(true)
1697 }
1698
1699
1700
1701
1702
1703 func (v Value) TrySend(x Value) bool {
1704 v.mustBe(Chan)
1705 v.mustBeExported()
1706 return v.send(x, true)
1707 }
1708
1709
1710 func (v Value) Type() Type {
1711 f := v.flag
1712 if f == 0 {
1713 panic(&ValueError{"reflect.Value.Type", Invalid})
1714 }
1715 if f&flagMethod == 0 {
1716
1717 return v.typ
1718 }
1719
1720
1721
1722 i := int(v.flag) >> flagMethodShift
1723 if v.typ.Kind() == Interface {
1724
1725 tt := (*interfaceType)(unsafe.Pointer(v.typ))
1726 if uint(i) >= uint(len(tt.methods)) {
1727 panic("reflect: internal error: invalid method index")
1728 }
1729 m := &tt.methods[i]
1730 return v.typ.typeOff(m.typ)
1731 }
1732
1733 ms := v.typ.exportedMethods()
1734 if uint(i) >= uint(len(ms)) {
1735 panic("reflect: internal error: invalid method index")
1736 }
1737 m := ms[i]
1738 return v.typ.typeOff(m.mtyp)
1739 }
1740
1741
1742
1743 func (v Value) Uint() uint64 {
1744 k := v.kind()
1745 p := v.ptr
1746 switch k {
1747 case Uint:
1748 return uint64(*(*uint)(p))
1749 case Uint8:
1750 return uint64(*(*uint8)(p))
1751 case Uint16:
1752 return uint64(*(*uint16)(p))
1753 case Uint32:
1754 return uint64(*(*uint32)(p))
1755 case Uint64:
1756 return *(*uint64)(p)
1757 case Uintptr:
1758 return uint64(*(*uintptr)(p))
1759 }
1760 panic(&ValueError{"reflect.Value.Uint", v.kind()})
1761 }
1762
1763
1764
1765
1766 func (v Value) UnsafeAddr() uintptr {
1767
1768 if v.typ == nil {
1769 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
1770 }
1771 if v.flag&flagAddr == 0 {
1772 panic("reflect.Value.UnsafeAddr of unaddressable value")
1773 }
1774 return uintptr(v.ptr)
1775 }
1776
1777
1778
1779
1780
1781
1782
1783 type StringHeader struct {
1784 Data uintptr
1785 Len int
1786 }
1787
1788
1789 type stringHeader struct {
1790 Data unsafe.Pointer
1791 Len int
1792 }
1793
1794
1795
1796
1797
1798
1799
1800 type SliceHeader struct {
1801 Data uintptr
1802 Len int
1803 Cap int
1804 }
1805
1806
1807 type sliceHeader struct {
1808 Data unsafe.Pointer
1809 Len int
1810 Cap int
1811 }
1812
1813 func typesMustMatch(what string, t1, t2 Type) {
1814 if t1 != t2 {
1815 panic(what + ": " + t1.String() + " != " + t2.String())
1816 }
1817 }
1818
1819
1820
1821
1822
1823
1824
1825
1826 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
1827 return add(p, uintptr(i)*eltSize, "i < len")
1828 }
1829
1830
1831
1832 func grow(s Value, extra int) (Value, int, int) {
1833 i0 := s.Len()
1834 i1 := i0 + extra
1835 if i1 < i0 {
1836 panic("reflect.Append: slice overflow")
1837 }
1838 m := s.Cap()
1839 if i1 <= m {
1840 return s.Slice(0, i1), i0, i1
1841 }
1842 if m == 0 {
1843 m = extra
1844 } else {
1845 for m < i1 {
1846 if i0 < 1024 {
1847 m += m
1848 } else {
1849 m += m / 4
1850 }
1851 }
1852 }
1853 t := MakeSlice(s.Type(), i1, m)
1854 Copy(t, s)
1855 return t, i0, i1
1856 }
1857
1858
1859
1860 func Append(s Value, x ...Value) Value {
1861 s.mustBe(Slice)
1862 s, i0, i1 := grow(s, len(x))
1863 for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
1864 s.Index(i).Set(x[j])
1865 }
1866 return s
1867 }
1868
1869
1870
1871 func AppendSlice(s, t Value) Value {
1872 s.mustBe(Slice)
1873 t.mustBe(Slice)
1874 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
1875 s, i0, i1 := grow(s, t.Len())
1876 Copy(s.Slice(i0, i1), t)
1877 return s
1878 }
1879
1880
1881
1882
1883
1884
1885
1886
1887 func Copy(dst, src Value) int {
1888 dk := dst.kind()
1889 if dk != Array && dk != Slice {
1890 panic(&ValueError{"reflect.Copy", dk})
1891 }
1892 if dk == Array {
1893 dst.mustBeAssignable()
1894 }
1895 dst.mustBeExported()
1896
1897 sk := src.kind()
1898 var stringCopy bool
1899 if sk != Array && sk != Slice {
1900 stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
1901 if !stringCopy {
1902 panic(&ValueError{"reflect.Copy", sk})
1903 }
1904 }
1905 src.mustBeExported()
1906
1907 de := dst.typ.Elem()
1908 if !stringCopy {
1909 se := src.typ.Elem()
1910 typesMustMatch("reflect.Copy", de, se)
1911 }
1912
1913 var ds, ss sliceHeader
1914 if dk == Array {
1915 ds.Data = dst.ptr
1916 ds.Len = dst.Len()
1917 ds.Cap = ds.Len
1918 } else {
1919 ds = *(*sliceHeader)(dst.ptr)
1920 }
1921 if sk == Array {
1922 ss.Data = src.ptr
1923 ss.Len = src.Len()
1924 ss.Cap = ss.Len
1925 } else if sk == Slice {
1926 ss = *(*sliceHeader)(src.ptr)
1927 } else {
1928 sh := *(*stringHeader)(src.ptr)
1929 ss.Data = sh.Data
1930 ss.Len = sh.Len
1931 ss.Cap = sh.Len
1932 }
1933
1934 return typedslicecopy(de.common(), ds, ss)
1935 }
1936
1937
1938
1939 type runtimeSelect struct {
1940 dir SelectDir
1941 typ *rtype
1942 ch unsafe.Pointer
1943 val unsafe.Pointer
1944 }
1945
1946
1947
1948
1949
1950
1951 func rselect([]runtimeSelect) (chosen int, recvOK bool)
1952
1953
1954 type SelectDir int
1955
1956
1957
1958 const (
1959 _ SelectDir = iota
1960 SelectSend
1961 SelectRecv
1962 SelectDefault
1963 )
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982 type SelectCase struct {
1983 Dir SelectDir
1984 Chan Value
1985 Send Value
1986 }
1987
1988
1989
1990
1991
1992
1993
1994
1995 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
1996
1997
1998
1999 runcases := make([]runtimeSelect, len(cases))
2000 haveDefault := false
2001 for i, c := range cases {
2002 rc := &runcases[i]
2003 rc.dir = c.Dir
2004 switch c.Dir {
2005 default:
2006 panic("reflect.Select: invalid Dir")
2007
2008 case SelectDefault:
2009 if haveDefault {
2010 panic("reflect.Select: multiple default cases")
2011 }
2012 haveDefault = true
2013 if c.Chan.IsValid() {
2014 panic("reflect.Select: default case has Chan value")
2015 }
2016 if c.Send.IsValid() {
2017 panic("reflect.Select: default case has Send value")
2018 }
2019
2020 case SelectSend:
2021 ch := c.Chan
2022 if !ch.IsValid() {
2023 break
2024 }
2025 ch.mustBe(Chan)
2026 ch.mustBeExported()
2027 tt := (*chanType)(unsafe.Pointer(ch.typ))
2028 if ChanDir(tt.dir)&SendDir == 0 {
2029 panic("reflect.Select: SendDir case using recv-only channel")
2030 }
2031 rc.ch = ch.pointer()
2032 rc.typ = &tt.rtype
2033 v := c.Send
2034 if !v.IsValid() {
2035 panic("reflect.Select: SendDir case missing Send value")
2036 }
2037 v.mustBeExported()
2038 v = v.assignTo("reflect.Select", tt.elem, nil)
2039 if v.flag&flagIndir != 0 {
2040 rc.val = v.ptr
2041 } else {
2042 rc.val = unsafe.Pointer(&v.ptr)
2043 }
2044
2045 case SelectRecv:
2046 if c.Send.IsValid() {
2047 panic("reflect.Select: RecvDir case has Send value")
2048 }
2049 ch := c.Chan
2050 if !ch.IsValid() {
2051 break
2052 }
2053 ch.mustBe(Chan)
2054 ch.mustBeExported()
2055 tt := (*chanType)(unsafe.Pointer(ch.typ))
2056 if ChanDir(tt.dir)&RecvDir == 0 {
2057 panic("reflect.Select: RecvDir case using send-only channel")
2058 }
2059 rc.ch = ch.pointer()
2060 rc.typ = &tt.rtype
2061 rc.val = unsafe_New(tt.elem)
2062 }
2063 }
2064
2065 chosen, recvOK = rselect(runcases)
2066 if runcases[chosen].dir == SelectRecv {
2067 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
2068 t := tt.elem
2069 p := runcases[chosen].val
2070 fl := flag(t.Kind())
2071 if ifaceIndir(t) {
2072 recv = Value{t, p, fl | flagIndir}
2073 } else {
2074 recv = Value{t, *(*unsafe.Pointer)(p), fl}
2075 }
2076 }
2077 return chosen, recv, recvOK
2078 }
2079
2080
2083
2084
2085 func unsafe_New(*rtype) unsafe.Pointer
2086 func unsafe_NewArray(*rtype, int) unsafe.Pointer
2087
2088
2089
2090 func MakeSlice(typ Type, len, cap int) Value {
2091 if typ.Kind() != Slice {
2092 panic("reflect.MakeSlice of non-slice type")
2093 }
2094 if len < 0 {
2095 panic("reflect.MakeSlice: negative len")
2096 }
2097 if cap < 0 {
2098 panic("reflect.MakeSlice: negative cap")
2099 }
2100 if len > cap {
2101 panic("reflect.MakeSlice: len > cap")
2102 }
2103
2104 s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap}
2105 return Value{typ.common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
2106 }
2107
2108
2109 func MakeChan(typ Type, buffer int) Value {
2110 if typ.Kind() != Chan {
2111 panic("reflect.MakeChan of non-chan type")
2112 }
2113 if buffer < 0 {
2114 panic("reflect.MakeChan: negative buffer size")
2115 }
2116 if typ.ChanDir() != BothDir {
2117 panic("reflect.MakeChan: unidirectional channel type")
2118 }
2119 ch := makechan(typ.(*rtype), buffer)
2120 return Value{typ.common(), ch, flag(Chan)}
2121 }
2122
2123
2124 func MakeMap(typ Type) Value {
2125 return MakeMapWithSize(typ, 0)
2126 }
2127
2128
2129
2130 func MakeMapWithSize(typ Type, n int) Value {
2131 if typ.Kind() != Map {
2132 panic("reflect.MakeMapWithSize of non-map type")
2133 }
2134 m := makemap(typ.(*rtype), n)
2135 return Value{typ.common(), m, flag(Map)}
2136 }
2137
2138
2139
2140
2141 func Indirect(v Value) Value {
2142 if v.Kind() != Ptr {
2143 return v
2144 }
2145 return v.Elem()
2146 }
2147
2148
2149
2150 func ValueOf(i interface{}) Value {
2151 if i == nil {
2152 return Value{}
2153 }
2154
2155
2156
2157
2158
2159 escapes(i)
2160
2161 return unpackEface(i)
2162 }
2163
2164
2165
2166
2167
2168
2169 func Zero(typ Type) Value {
2170 if typ == nil {
2171 panic("reflect: Zero(nil)")
2172 }
2173 t := typ.common()
2174 fl := flag(t.Kind())
2175 if ifaceIndir(t) {
2176 return Value{t, unsafe_New(typ.(*rtype)), fl | flagIndir}
2177 }
2178 return Value{t, nil, fl}
2179 }
2180
2181
2182
2183 func New(typ Type) Value {
2184 if typ == nil {
2185 panic("reflect: New(nil)")
2186 }
2187 ptr := unsafe_New(typ.(*rtype))
2188 fl := flag(Ptr)
2189 return Value{typ.common().ptrTo(), ptr, fl}
2190 }
2191
2192
2193
2194 func NewAt(typ Type, p unsafe.Pointer) Value {
2195 fl := flag(Ptr)
2196 return Value{typ.common().ptrTo(), p, fl}
2197 }
2198
2199
2200
2201
2202 func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
2203 if v.flag&flagMethod != 0 {
2204 v = makeMethodValue(context, v)
2205 }
2206
2207 switch {
2208 case directlyAssignable(dst, v.typ):
2209
2210
2211 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
2212 fl |= flag(dst.Kind())
2213 return Value{dst, v.ptr, fl}
2214
2215 case implements(dst, v.typ):
2216 if target == nil {
2217 target = unsafe_New(dst)
2218 }
2219 if v.Kind() == Interface && v.IsNil() {
2220
2221
2222
2223 return Value{dst, nil, flag(Interface)}
2224 }
2225 x := valueInterface(v, false)
2226 if dst.NumMethod() == 0 {
2227 *(*interface{})(target) = x
2228 } else {
2229 ifaceE2I(dst, x, target)
2230 }
2231 return Value{dst, target, flagIndir | flag(Interface)}
2232 }
2233
2234
2235 panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
2236 }
2237
2238
2239
2240
2241 func (v Value) Convert(t Type) Value {
2242 if v.flag&flagMethod != 0 {
2243 v = makeMethodValue("Convert", v)
2244 }
2245 op := convertOp(t.common(), v.typ)
2246 if op == nil {
2247 panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
2248 }
2249 return op(v, t)
2250 }
2251
2252
2253
2254 func convertOp(dst, src *rtype) func(Value, Type) Value {
2255 switch src.Kind() {
2256 case Int, Int8, Int16, Int32, Int64:
2257 switch dst.Kind() {
2258 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2259 return cvtInt
2260 case Float32, Float64:
2261 return cvtIntFloat
2262 case String:
2263 return cvtIntString
2264 }
2265
2266 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2267 switch dst.Kind() {
2268 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2269 return cvtUint
2270 case Float32, Float64:
2271 return cvtUintFloat
2272 case String:
2273 return cvtUintString
2274 }
2275
2276 case Float32, Float64:
2277 switch dst.Kind() {
2278 case Int, Int8, Int16, Int32, Int64:
2279 return cvtFloatInt
2280 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2281 return cvtFloatUint
2282 case Float32, Float64:
2283 return cvtFloat
2284 }
2285
2286 case Complex64, Complex128:
2287 switch dst.Kind() {
2288 case Complex64, Complex128:
2289 return cvtComplex
2290 }
2291
2292 case String:
2293 if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
2294 switch dst.Elem().Kind() {
2295 case Uint8:
2296 return cvtStringBytes
2297 case Int32:
2298 return cvtStringRunes
2299 }
2300 }
2301
2302 case Slice:
2303 if dst.Kind() == String && src.Elem().PkgPath() == "" {
2304 switch src.Elem().Kind() {
2305 case Uint8:
2306 return cvtBytesString
2307 case Int32:
2308 return cvtRunesString
2309 }
2310 }
2311 }
2312
2313
2314 if haveIdenticalUnderlyingType(dst, src, false) {
2315 return cvtDirect
2316 }
2317
2318
2319 if dst.Kind() == Ptr && dst.Name() == "" &&
2320 src.Kind() == Ptr && src.Name() == "" &&
2321 haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common(), false) {
2322 return cvtDirect
2323 }
2324
2325 if implements(dst, src) {
2326 if src.Kind() == Interface {
2327 return cvtI2I
2328 }
2329 return cvtT2I
2330 }
2331
2332 return nil
2333 }
2334
2335
2336
2337 func makeInt(f flag, bits uint64, t Type) Value {
2338 typ := t.common()
2339 ptr := unsafe_New(typ)
2340 switch typ.size {
2341 case 1:
2342 *(*uint8)(ptr) = uint8(bits)
2343 case 2:
2344 *(*uint16)(ptr) = uint16(bits)
2345 case 4:
2346 *(*uint32)(ptr) = uint32(bits)
2347 case 8:
2348 *(*uint64)(ptr) = bits
2349 }
2350 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
2351 }
2352
2353
2354
2355 func makeFloat(f flag, v float64, t Type) Value {
2356 typ := t.common()
2357 ptr := unsafe_New(typ)
2358 switch typ.size {
2359 case 4:
2360 *(*float32)(ptr) = float32(v)
2361 case 8:
2362 *(*float64)(ptr) = v
2363 }
2364 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
2365 }
2366
2367
2368
2369 func makeComplex(f flag, v complex128, t Type) Value {
2370 typ := t.common()
2371 ptr := unsafe_New(typ)
2372 switch typ.size {
2373 case 8:
2374 *(*complex64)(ptr) = complex64(v)
2375 case 16:
2376 *(*complex128)(ptr) = v
2377 }
2378 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
2379 }
2380
2381 func makeString(f flag, v string, t Type) Value {
2382 ret := New(t).Elem()
2383 ret.SetString(v)
2384 ret.flag = ret.flag&^flagAddr | f
2385 return ret
2386 }
2387
2388 func makeBytes(f flag, v []byte, t Type) Value {
2389 ret := New(t).Elem()
2390 ret.SetBytes(v)
2391 ret.flag = ret.flag&^flagAddr | f
2392 return ret
2393 }
2394
2395 func makeRunes(f flag, v []rune, t Type) Value {
2396 ret := New(t).Elem()
2397 ret.setRunes(v)
2398 ret.flag = ret.flag&^flagAddr | f
2399 return ret
2400 }
2401
2402
2403
2404
2405
2406
2407
2408 func cvtInt(v Value, t Type) Value {
2409 return makeInt(v.flag.ro(), uint64(v.Int()), t)
2410 }
2411
2412
2413 func cvtUint(v Value, t Type) Value {
2414 return makeInt(v.flag.ro(), v.Uint(), t)
2415 }
2416
2417
2418 func cvtFloatInt(v Value, t Type) Value {
2419 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
2420 }
2421
2422
2423 func cvtFloatUint(v Value, t Type) Value {
2424 return makeInt(v.flag.ro(), uint64(v.Float()), t)
2425 }
2426
2427
2428 func cvtIntFloat(v Value, t Type) Value {
2429 return makeFloat(v.flag.ro(), float64(v.Int()), t)
2430 }
2431
2432
2433 func cvtUintFloat(v Value, t Type) Value {
2434 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
2435 }
2436
2437
2438 func cvtFloat(v Value, t Type) Value {
2439 return makeFloat(v.flag.ro(), v.Float(), t)
2440 }
2441
2442
2443 func cvtComplex(v Value, t Type) Value {
2444 return makeComplex(v.flag.ro(), v.Complex(), t)
2445 }
2446
2447
2448 func cvtIntString(v Value, t Type) Value {
2449 return makeString(v.flag.ro(), string(v.Int()), t)
2450 }
2451
2452
2453 func cvtUintString(v Value, t Type) Value {
2454 return makeString(v.flag.ro(), string(v.Uint()), t)
2455 }
2456
2457
2458 func cvtBytesString(v Value, t Type) Value {
2459 return makeString(v.flag.ro(), string(v.Bytes()), t)
2460 }
2461
2462
2463 func cvtStringBytes(v Value, t Type) Value {
2464 return makeBytes(v.flag.ro(), []byte(v.String()), t)
2465 }
2466
2467
2468 func cvtRunesString(v Value, t Type) Value {
2469 return makeString(v.flag.ro(), string(v.runes()), t)
2470 }
2471
2472
2473 func cvtStringRunes(v Value, t Type) Value {
2474 return makeRunes(v.flag.ro(), []rune(v.String()), t)
2475 }
2476
2477
2478 func cvtDirect(v Value, typ Type) Value {
2479 f := v.flag
2480 t := typ.common()
2481 ptr := v.ptr
2482 if f&flagAddr != 0 {
2483
2484 c := unsafe_New(t)
2485 typedmemmove(t, c, ptr)
2486 ptr = c
2487 f &^= flagAddr
2488 }
2489 return Value{t, ptr, v.flag.ro() | f}
2490 }
2491
2492
2493 func cvtT2I(v Value, typ Type) Value {
2494 target := unsafe_New(typ.common())
2495 x := valueInterface(v, false)
2496 if typ.NumMethod() == 0 {
2497 *(*interface{})(target) = x
2498 } else {
2499 ifaceE2I(typ.(*rtype), x, target)
2500 }
2501 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
2502 }
2503
2504
2505 func cvtI2I(v Value, typ Type) Value {
2506 if v.IsNil() {
2507 ret := Zero(typ)
2508 ret.flag |= v.flag.ro()
2509 return ret
2510 }
2511 return cvtT2I(v.Elem(), typ)
2512 }
2513
2514
2515 func chancap(ch unsafe.Pointer) int
2516 func chanclose(ch unsafe.Pointer)
2517 func chanlen(ch unsafe.Pointer) int
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
2529
2530
2531 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
2532
2533 func makechan(typ *rtype, size int) (ch unsafe.Pointer)
2534 func makemap(t *rtype, cap int) (m unsafe.Pointer)
2535
2536
2537 func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
2538
2539
2540 func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
2541
2542
2543 func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
2544
2545
2546
2547
2548 func mapiterinit(t *rtype, m unsafe.Pointer) unsafe.Pointer
2549
2550
2551 func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
2552
2553
2554 func mapiternext(it unsafe.Pointer)
2555
2556
2557 func maplen(m unsafe.Pointer) int
2558
2559
2560
2561
2562
2563
2564 func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)
2565
2566 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
2567
2568
2569
2570 func typedmemmove(t *rtype, dst, src unsafe.Pointer)
2571
2572
2573
2574
2575 func typedmemmovepartial(t *rtype, dst, src unsafe.Pointer, off, size uintptr)
2576
2577
2578
2579
2580 func typedslicecopy(elemType *rtype, dst, src sliceHeader) int
2581
2582
2583 func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
2584
2585
2586
2587
2588 func escapes(x interface{}) {
2589 if dummy.b {
2590 dummy.x = x
2591 }
2592 }
2593
2594 var dummy struct {
2595 b bool
2596 x interface{}
2597 }
2598
View as plain text