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