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