Source file
src/reflect/value.go
Documentation: reflect
1
2
3
4
5 package reflect
6
7 import (
8 "errors"
9 "internal/abi"
10 "internal/goarch"
11 "internal/itoa"
12 "internal/unsafeheader"
13 "math"
14 "runtime"
15 "unsafe"
16 )
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 type Value struct {
40
41 typ *rtype
42
43
44
45 ptr unsafe.Pointer
46
47
48
49
50
51
52
53
54
55
56
57
58
59 flag
60
61
62
63
64
65
66 }
67
68 type flag uintptr
69
70 const (
71 flagKindWidth = 5
72 flagKindMask flag = 1<<flagKindWidth - 1
73 flagStickyRO flag = 1 << 5
74 flagEmbedRO flag = 1 << 6
75 flagIndir flag = 1 << 7
76 flagAddr flag = 1 << 8
77 flagMethod flag = 1 << 9
78 flagMethodShift = 10
79 flagRO flag = flagStickyRO | flagEmbedRO
80 )
81
82 func (f flag) kind() Kind {
83 return Kind(f & flagKindMask)
84 }
85
86 func (f flag) ro() flag {
87 if f&flagRO != 0 {
88 return flagStickyRO
89 }
90 return 0
91 }
92
93
94
95
96 func (v Value) pointer() unsafe.Pointer {
97 if v.typ.size != goarch.PtrSize || !v.typ.pointers() {
98 panic("can't call pointer on a non-pointer Value")
99 }
100 if v.flag&flagIndir != 0 {
101 return *(*unsafe.Pointer)(v.ptr)
102 }
103 return v.ptr
104 }
105
106
107 func packEface(v Value) any {
108 t := v.typ
109 var i any
110 e := (*emptyInterface)(unsafe.Pointer(&i))
111
112 switch {
113 case ifaceIndir(t):
114 if v.flag&flagIndir == 0 {
115 panic("bad indir")
116 }
117
118 ptr := v.ptr
119 if v.flag&flagAddr != 0 {
120
121
122 c := unsafe_New(t)
123 typedmemmove(t, c, ptr)
124 ptr = c
125 }
126 e.word = ptr
127 case v.flag&flagIndir != 0:
128
129
130 e.word = *(*unsafe.Pointer)(v.ptr)
131 default:
132
133 e.word = v.ptr
134 }
135
136
137
138
139 e.typ = t
140 return i
141 }
142
143
144 func unpackEface(i any) Value {
145 e := (*emptyInterface)(unsafe.Pointer(&i))
146
147 t := e.typ
148 if t == nil {
149 return Value{}
150 }
151 f := flag(t.Kind())
152 if ifaceIndir(t) {
153 f |= flagIndir
154 }
155 return Value{t, e.word, f}
156 }
157
158
159
160
161 type ValueError struct {
162 Method string
163 Kind Kind
164 }
165
166 func (e *ValueError) Error() string {
167 if e.Kind == 0 {
168 return "reflect: call of " + e.Method + " on zero Value"
169 }
170 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
171 }
172
173
174 func valueMethodName() string {
175 var pc [5]uintptr
176 n := runtime.Callers(1, pc[:])
177 frames := runtime.CallersFrames(pc[:n])
178 var frame runtime.Frame
179 for more := true; more; {
180 const prefix = "reflect.Value."
181 frame, more = frames.Next()
182 name := frame.Function
183 if len(name) > len(prefix) && name[:len(prefix)] == prefix {
184 methodName := name[len(prefix):]
185 if len(methodName) > 0 && 'A' <= methodName[0] && methodName[0] <= 'Z' {
186 return name
187 }
188 }
189 }
190 return "unknown method"
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{valueMethodName(), 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{valueMethodName(), Invalid})
236 }
237 if f&flagRO != 0 {
238 panic("reflect: " + valueMethodName() + " 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{valueMethodName(), Invalid})
254 }
255
256 if f&flagRO != 0 {
257 panic("reflect: " + valueMethodName() + " using value obtained using unexported field")
258 }
259 if f&flagAddr == 0 {
260 panic("reflect: " + valueMethodName() + " 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(Pointer)}
277 }
278
279
280
281 func (v Value) Bool() bool {
282
283 if v.kind() != Bool {
284 v.panicNotBool()
285 }
286 return *(*bool)(v.ptr)
287 }
288
289 func (v Value) panicNotBool() {
290 v.mustBe(Bool)
291 }
292
293 var bytesType = TypeOf(([]byte)(nil)).(*rtype)
294
295
296
297
298 func (v Value) Bytes() []byte {
299
300 if v.typ == bytesType {
301 return *(*[]byte)(v.ptr)
302 }
303 return v.bytesSlow()
304 }
305
306 func (v Value) bytesSlow() []byte {
307 switch v.kind() {
308 case Slice:
309 if v.typ.Elem().Kind() != Uint8 {
310 panic("reflect.Value.Bytes of non-byte slice")
311 }
312
313 return *(*[]byte)(v.ptr)
314 case Array:
315 if v.typ.Elem().Kind() != Uint8 {
316 panic("reflect.Value.Bytes of non-byte array")
317 }
318 if !v.CanAddr() {
319 panic("reflect.Value.Bytes of unaddressable byte array")
320 }
321 p := (*byte)(v.ptr)
322 n := int((*arrayType)(unsafe.Pointer(v.typ)).len)
323 return unsafe.Slice(p, n)
324 }
325 panic(&ValueError{"reflect.Value.Bytes", v.kind()})
326 }
327
328
329
330 func (v Value) runes() []rune {
331 v.mustBe(Slice)
332 if v.typ.Elem().Kind() != Int32 {
333 panic("reflect.Value.Bytes of non-rune slice")
334 }
335
336 return *(*[]rune)(v.ptr)
337 }
338
339
340
341
342
343
344 func (v Value) CanAddr() bool {
345 return v.flag&flagAddr != 0
346 }
347
348
349
350
351
352
353 func (v Value) CanSet() bool {
354 return v.flag&(flagAddr|flagRO) == flagAddr
355 }
356
357
358
359
360
361
362
363
364
365 func (v Value) Call(in []Value) []Value {
366 v.mustBe(Func)
367 v.mustBeExported()
368 return v.call("Call", in)
369 }
370
371
372
373
374
375
376
377
378 func (v Value) CallSlice(in []Value) []Value {
379 v.mustBe(Func)
380 v.mustBeExported()
381 return v.call("CallSlice", in)
382 }
383
384 var callGC bool
385
386 const debugReflectCall = false
387
388 func (v Value) call(op string, in []Value) []Value {
389
390 t := (*funcType)(unsafe.Pointer(v.typ))
391 var (
392 fn unsafe.Pointer
393 rcvr Value
394 rcvrtype *rtype
395 )
396 if v.flag&flagMethod != 0 {
397 rcvr = v
398 rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
399 } else if v.flag&flagIndir != 0 {
400 fn = *(*unsafe.Pointer)(v.ptr)
401 } else {
402 fn = v.ptr
403 }
404
405 if fn == nil {
406 panic("reflect.Value.Call: call of nil function")
407 }
408
409 isSlice := op == "CallSlice"
410 n := t.NumIn()
411 isVariadic := t.IsVariadic()
412 if isSlice {
413 if !isVariadic {
414 panic("reflect: CallSlice of non-variadic function")
415 }
416 if len(in) < n {
417 panic("reflect: CallSlice with too few input arguments")
418 }
419 if len(in) > n {
420 panic("reflect: CallSlice with too many input arguments")
421 }
422 } else {
423 if isVariadic {
424 n--
425 }
426 if len(in) < n {
427 panic("reflect: Call with too few input arguments")
428 }
429 if !isVariadic && len(in) > n {
430 panic("reflect: Call with too many input arguments")
431 }
432 }
433 for _, x := range in {
434 if x.Kind() == Invalid {
435 panic("reflect: " + op + " using zero Value argument")
436 }
437 }
438 for i := 0; i < n; i++ {
439 if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
440 panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
441 }
442 }
443 if !isSlice && isVariadic {
444
445 m := len(in) - n
446 slice := MakeSlice(t.In(n), m, m)
447 elem := t.In(n).Elem()
448 for i := 0; i < m; i++ {
449 x := in[n+i]
450 if xt := x.Type(); !xt.AssignableTo(elem) {
451 panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
452 }
453 slice.Index(i).Set(x)
454 }
455 origIn := in
456 in = make([]Value, n+1)
457 copy(in[:n], origIn)
458 in[n] = slice
459 }
460
461 nin := len(in)
462 if nin != t.NumIn() {
463 panic("reflect.Value.Call: wrong argument count")
464 }
465 nout := t.NumOut()
466
467
468 var regArgs abi.RegArgs
469
470
471 frametype, framePool, abid := funcLayout(t, rcvrtype)
472
473
474 var stackArgs unsafe.Pointer
475 if frametype.size != 0 {
476 if nout == 0 {
477 stackArgs = framePool.Get().(unsafe.Pointer)
478 } else {
479
480
481 stackArgs = unsafe_New(frametype)
482 }
483 }
484 frameSize := frametype.size
485
486 if debugReflectCall {
487 println("reflect.call", t.String())
488 abid.dump()
489 }
490
491
492
493
494 inStart := 0
495 if rcvrtype != nil {
496
497
498
499 switch st := abid.call.steps[0]; st.kind {
500 case abiStepStack:
501 storeRcvr(rcvr, stackArgs)
502 case abiStepPointer:
503 storeRcvr(rcvr, unsafe.Pointer(®Args.Ptrs[st.ireg]))
504 fallthrough
505 case abiStepIntReg:
506 storeRcvr(rcvr, unsafe.Pointer(®Args.Ints[st.ireg]))
507 case abiStepFloatReg:
508 storeRcvr(rcvr, unsafe.Pointer(®Args.Floats[st.freg]))
509 default:
510 panic("unknown ABI parameter kind")
511 }
512 inStart = 1
513 }
514
515
516 for i, v := range in {
517 v.mustBeExported()
518 targ := t.In(i).(*rtype)
519
520
521
522 v = v.assignTo("reflect.Value.Call", targ, nil)
523 stepsLoop:
524 for _, st := range abid.call.stepsForValue(i + inStart) {
525 switch st.kind {
526 case abiStepStack:
527
528 addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
529 if v.flag&flagIndir != 0 {
530 typedmemmove(targ, addr, v.ptr)
531 } else {
532 *(*unsafe.Pointer)(addr) = v.ptr
533 }
534
535 break stepsLoop
536 case abiStepIntReg, abiStepPointer:
537
538 if v.flag&flagIndir != 0 {
539 offset := add(v.ptr, st.offset, "precomputed value offset")
540 if st.kind == abiStepPointer {
541
542
543
544 regArgs.Ptrs[st.ireg] = *(*unsafe.Pointer)(offset)
545 }
546 intToReg(®Args, st.ireg, st.size, offset)
547 } else {
548 if st.kind == abiStepPointer {
549
550 regArgs.Ptrs[st.ireg] = v.ptr
551 }
552 regArgs.Ints[st.ireg] = uintptr(v.ptr)
553 }
554 case abiStepFloatReg:
555
556 if v.flag&flagIndir == 0 {
557 panic("attempted to copy pointer to FP register")
558 }
559 offset := add(v.ptr, st.offset, "precomputed value offset")
560 floatToReg(®Args, st.freg, st.size, offset)
561 default:
562 panic("unknown ABI part kind")
563 }
564 }
565 }
566
567
568 frameSize = align(frameSize, goarch.PtrSize)
569 frameSize += abid.spill
570
571
572 regArgs.ReturnIsPtr = abid.outRegPtrs
573
574 if debugReflectCall {
575 regArgs.Dump()
576 }
577
578
579 if callGC {
580 runtime.GC()
581 }
582
583
584 call(frametype, fn, stackArgs, uint32(frametype.size), uint32(abid.retOffset), uint32(frameSize), ®Args)
585
586
587 if callGC {
588 runtime.GC()
589 }
590
591 var ret []Value
592 if nout == 0 {
593 if stackArgs != nil {
594 typedmemclr(frametype, stackArgs)
595 framePool.Put(stackArgs)
596 }
597 } else {
598 if stackArgs != nil {
599
600
601
602 typedmemclrpartial(frametype, stackArgs, 0, abid.retOffset)
603 }
604
605
606 ret = make([]Value, nout)
607 for i := 0; i < nout; i++ {
608 tv := t.Out(i)
609 if tv.Size() == 0 {
610
611
612 ret[i] = Zero(tv)
613 continue
614 }
615 steps := abid.ret.stepsForValue(i)
616 if st := steps[0]; st.kind == abiStepStack {
617
618
619
620 fl := flagIndir | flag(tv.Kind())
621 ret[i] = Value{tv.common(), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
622
623
624
625
626 continue
627 }
628
629
630 if !ifaceIndir(tv.common()) {
631
632
633 if steps[0].kind != abiStepPointer {
634 print("kind=", steps[0].kind, ", type=", tv.String(), "\n")
635 panic("mismatch between ABI description and types")
636 }
637 ret[i] = Value{tv.common(), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
638 continue
639 }
640
641
642
643
644
645
646
647
648
649
650 s := unsafe_New(tv.common())
651 for _, st := range steps {
652 switch st.kind {
653 case abiStepIntReg:
654 offset := add(s, st.offset, "precomputed value offset")
655 intFromReg(®Args, st.ireg, st.size, offset)
656 case abiStepPointer:
657 s := add(s, st.offset, "precomputed value offset")
658 *((*unsafe.Pointer)(s)) = regArgs.Ptrs[st.ireg]
659 case abiStepFloatReg:
660 offset := add(s, st.offset, "precomputed value offset")
661 floatFromReg(®Args, st.freg, st.size, offset)
662 case abiStepStack:
663 panic("register-based return value has stack component")
664 default:
665 panic("unknown ABI part kind")
666 }
667 }
668 ret[i] = Value{tv.common(), s, flagIndir | flag(tv.Kind())}
669 }
670 }
671
672 return ret
673 }
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695 func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
696 if callGC {
697
698
699
700
701
702 runtime.GC()
703 }
704 ftyp := ctxt.ftyp
705 f := ctxt.fn
706
707 _, _, abid := funcLayout(ftyp, nil)
708
709
710 ptr := frame
711 in := make([]Value, 0, int(ftyp.inCount))
712 for i, typ := range ftyp.in() {
713 if typ.Size() == 0 {
714 in = append(in, Zero(typ))
715 continue
716 }
717 v := Value{typ, nil, flag(typ.Kind())}
718 steps := abid.call.stepsForValue(i)
719 if st := steps[0]; st.kind == abiStepStack {
720 if ifaceIndir(typ) {
721
722
723
724
725 v.ptr = unsafe_New(typ)
726 if typ.size > 0 {
727 typedmemmove(typ, v.ptr, add(ptr, st.stkOff, "typ.size > 0"))
728 }
729 v.flag |= flagIndir
730 } else {
731 v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
732 }
733 } else {
734 if ifaceIndir(typ) {
735
736
737 v.flag |= flagIndir
738 v.ptr = unsafe_New(typ)
739 for _, st := range steps {
740 switch st.kind {
741 case abiStepIntReg:
742 offset := add(v.ptr, st.offset, "precomputed value offset")
743 intFromReg(regs, st.ireg, st.size, offset)
744 case abiStepPointer:
745 s := add(v.ptr, st.offset, "precomputed value offset")
746 *((*unsafe.Pointer)(s)) = regs.Ptrs[st.ireg]
747 case abiStepFloatReg:
748 offset := add(v.ptr, st.offset, "precomputed value offset")
749 floatFromReg(regs, st.freg, st.size, offset)
750 case abiStepStack:
751 panic("register-based return value has stack component")
752 default:
753 panic("unknown ABI part kind")
754 }
755 }
756 } else {
757
758
759 if steps[0].kind != abiStepPointer {
760 print("kind=", steps[0].kind, ", type=", typ.String(), "\n")
761 panic("mismatch between ABI description and types")
762 }
763 v.ptr = regs.Ptrs[steps[0].ireg]
764 }
765 }
766 in = append(in, v)
767 }
768
769
770 out := f(in)
771 numOut := ftyp.NumOut()
772 if len(out) != numOut {
773 panic("reflect: wrong return count from function created by MakeFunc")
774 }
775
776
777 if numOut > 0 {
778 for i, typ := range ftyp.out() {
779 v := out[i]
780 if v.typ == nil {
781 panic("reflect: function created by MakeFunc using " + funcName(f) +
782 " returned zero Value")
783 }
784 if v.flag&flagRO != 0 {
785 panic("reflect: function created by MakeFunc using " + funcName(f) +
786 " returned value obtained from unexported field")
787 }
788 if typ.size == 0 {
789 continue
790 }
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806 v = v.assignTo("reflect.MakeFunc", typ, nil)
807 stepsLoop:
808 for _, st := range abid.ret.stepsForValue(i) {
809 switch st.kind {
810 case abiStepStack:
811
812 addr := add(ptr, st.stkOff, "precomputed stack arg offset")
813
814
815
816
817 if v.flag&flagIndir != 0 {
818 memmove(addr, v.ptr, st.size)
819 } else {
820
821 *(*uintptr)(addr) = uintptr(v.ptr)
822 }
823
824 break stepsLoop
825 case abiStepIntReg, abiStepPointer:
826
827 if v.flag&flagIndir != 0 {
828 offset := add(v.ptr, st.offset, "precomputed value offset")
829 intToReg(regs, st.ireg, st.size, offset)
830 } else {
831
832
833
834
835
836 regs.Ints[st.ireg] = uintptr(v.ptr)
837 }
838 case abiStepFloatReg:
839
840 if v.flag&flagIndir == 0 {
841 panic("attempted to copy pointer to FP register")
842 }
843 offset := add(v.ptr, st.offset, "precomputed value offset")
844 floatToReg(regs, st.freg, st.size, offset)
845 default:
846 panic("unknown ABI part kind")
847 }
848 }
849 }
850 }
851
852
853
854 *retValid = true
855
856
857
858
859
860 runtime.KeepAlive(out)
861
862
863
864
865 runtime.KeepAlive(ctxt)
866 }
867
868
869
870
871
872
873
874
875 func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *rtype, t *funcType, fn unsafe.Pointer) {
876 i := methodIndex
877 if v.typ.Kind() == Interface {
878 tt := (*interfaceType)(unsafe.Pointer(v.typ))
879 if uint(i) >= uint(len(tt.methods)) {
880 panic("reflect: internal error: invalid method index")
881 }
882 m := &tt.methods[i]
883 if !tt.nameOff(m.name).isExported() {
884 panic("reflect: " + op + " of unexported method")
885 }
886 iface := (*nonEmptyInterface)(v.ptr)
887 if iface.itab == nil {
888 panic("reflect: " + op + " of method on nil interface value")
889 }
890 rcvrtype = iface.itab.typ
891 fn = unsafe.Pointer(&iface.itab.fun[i])
892 t = (*funcType)(unsafe.Pointer(tt.typeOff(m.typ)))
893 } else {
894 rcvrtype = v.typ
895 ms := v.typ.exportedMethods()
896 if uint(i) >= uint(len(ms)) {
897 panic("reflect: internal error: invalid method index")
898 }
899 m := ms[i]
900 if !v.typ.nameOff(m.name).isExported() {
901 panic("reflect: " + op + " of unexported method")
902 }
903 ifn := v.typ.textOff(m.ifn)
904 fn = unsafe.Pointer(&ifn)
905 t = (*funcType)(unsafe.Pointer(v.typ.typeOff(m.mtyp)))
906 }
907 return
908 }
909
910
911
912
913
914 func storeRcvr(v Value, p unsafe.Pointer) {
915 t := v.typ
916 if t.Kind() == Interface {
917
918 iface := (*nonEmptyInterface)(v.ptr)
919 *(*unsafe.Pointer)(p) = iface.word
920 } else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
921 *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
922 } else {
923 *(*unsafe.Pointer)(p) = v.ptr
924 }
925 }
926
927
928
929 func align(x, n uintptr) uintptr {
930 return (x + n - 1) &^ (n - 1)
931 }
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952 func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
953 rcvr := ctxt.rcvr
954 rcvrType, valueFuncType, methodFn := methodReceiver("call", rcvr, ctxt.method)
955
956
957
958
959
960
961
962
963
964 _, _, valueABI := funcLayout(valueFuncType, nil)
965 valueFrame, valueRegs := frame, regs
966 methodFrameType, methodFramePool, methodABI := funcLayout(valueFuncType, rcvrType)
967
968
969
970 methodFrame := methodFramePool.Get().(unsafe.Pointer)
971 var methodRegs abi.RegArgs
972
973
974 switch st := methodABI.call.steps[0]; st.kind {
975 case abiStepStack:
976
977
978 storeRcvr(rcvr, methodFrame)
979 case abiStepPointer:
980
981 storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ptrs[st.ireg]))
982 fallthrough
983 case abiStepIntReg:
984 storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints[st.ireg]))
985 case abiStepFloatReg:
986 storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Floats[st.freg]))
987 default:
988 panic("unknown ABI parameter kind")
989 }
990
991
992 for i, t := range valueFuncType.in() {
993 valueSteps := valueABI.call.stepsForValue(i)
994 methodSteps := methodABI.call.stepsForValue(i + 1)
995
996
997 if len(valueSteps) == 0 {
998 if len(methodSteps) != 0 {
999 panic("method ABI and value ABI do not align")
1000 }
1001 continue
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 if vStep := valueSteps[0]; vStep.kind == abiStepStack {
1015 mStep := methodSteps[0]
1016
1017 if mStep.kind == abiStepStack {
1018 if vStep.size != mStep.size {
1019 panic("method ABI and value ABI do not align")
1020 }
1021 typedmemmove(t,
1022 add(methodFrame, mStep.stkOff, "precomputed stack offset"),
1023 add(valueFrame, vStep.stkOff, "precomputed stack offset"))
1024 continue
1025 }
1026
1027 for _, mStep := range methodSteps {
1028 from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
1029 switch mStep.kind {
1030 case abiStepPointer:
1031
1032 methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
1033 fallthrough
1034 case abiStepIntReg:
1035 intToReg(&methodRegs, mStep.ireg, mStep.size, from)
1036 case abiStepFloatReg:
1037 floatToReg(&methodRegs, mStep.freg, mStep.size, from)
1038 default:
1039 panic("unexpected method step")
1040 }
1041 }
1042 continue
1043 }
1044
1045 if mStep := methodSteps[0]; mStep.kind == abiStepStack {
1046 for _, vStep := range valueSteps {
1047 to := add(methodFrame, mStep.stkOff+vStep.offset, "precomputed stack offset")
1048 switch vStep.kind {
1049 case abiStepPointer:
1050
1051 *(*unsafe.Pointer)(to) = valueRegs.Ptrs[vStep.ireg]
1052 case abiStepIntReg:
1053 intFromReg(valueRegs, vStep.ireg, vStep.size, to)
1054 case abiStepFloatReg:
1055 floatFromReg(valueRegs, vStep.freg, vStep.size, to)
1056 default:
1057 panic("unexpected value step")
1058 }
1059 }
1060 continue
1061 }
1062
1063 if len(valueSteps) != len(methodSteps) {
1064
1065
1066
1067 panic("method ABI and value ABI don't align")
1068 }
1069 for i, vStep := range valueSteps {
1070 mStep := methodSteps[i]
1071 if mStep.kind != vStep.kind {
1072 panic("method ABI and value ABI don't align")
1073 }
1074 switch vStep.kind {
1075 case abiStepPointer:
1076
1077 methodRegs.Ptrs[mStep.ireg] = valueRegs.Ptrs[vStep.ireg]
1078 fallthrough
1079 case abiStepIntReg:
1080 methodRegs.Ints[mStep.ireg] = valueRegs.Ints[vStep.ireg]
1081 case abiStepFloatReg:
1082 methodRegs.Floats[mStep.freg] = valueRegs.Floats[vStep.freg]
1083 default:
1084 panic("unexpected value step")
1085 }
1086 }
1087 }
1088
1089 methodFrameSize := methodFrameType.size
1090
1091
1092 methodFrameSize = align(methodFrameSize, goarch.PtrSize)
1093 methodFrameSize += methodABI.spill
1094
1095
1096 methodRegs.ReturnIsPtr = methodABI.outRegPtrs
1097
1098
1099
1100
1101 call(methodFrameType, methodFn, methodFrame, uint32(methodFrameType.size), uint32(methodABI.retOffset), uint32(methodFrameSize), &methodRegs)
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112 if valueRegs != nil {
1113 *valueRegs = methodRegs
1114 }
1115 if retSize := methodFrameType.size - methodABI.retOffset; retSize > 0 {
1116 valueRet := add(valueFrame, valueABI.retOffset, "valueFrame's size > retOffset")
1117 methodRet := add(methodFrame, methodABI.retOffset, "methodFrame's size > retOffset")
1118
1119 memmove(valueRet, methodRet, retSize)
1120 }
1121
1122
1123
1124 *retValid = true
1125
1126
1127
1128
1129 typedmemclr(methodFrameType, methodFrame)
1130 methodFramePool.Put(methodFrame)
1131
1132
1133 runtime.KeepAlive(ctxt)
1134
1135
1136
1137
1138 runtime.KeepAlive(valueRegs)
1139 }
1140
1141
1142 func funcName(f func([]Value) []Value) string {
1143 pc := *(*uintptr)(unsafe.Pointer(&f))
1144 rf := runtime.FuncForPC(pc)
1145 if rf != nil {
1146 return rf.Name()
1147 }
1148 return "closure"
1149 }
1150
1151
1152
1153 func (v Value) Cap() int {
1154
1155 if v.kind() == Slice {
1156 return (*unsafeheader.Slice)(v.ptr).Cap
1157 }
1158 return v.capNonSlice()
1159 }
1160
1161 func (v Value) capNonSlice() int {
1162 k := v.kind()
1163 switch k {
1164 case Array:
1165 return v.typ.Len()
1166 case Chan:
1167 return chancap(v.pointer())
1168 case Ptr:
1169 if v.typ.Elem().Kind() == Array {
1170 return v.typ.Elem().Len()
1171 }
1172 panic("reflect: call of reflect.Value.Cap on ptr to non-array Value")
1173 }
1174 panic(&ValueError{"reflect.Value.Cap", v.kind()})
1175 }
1176
1177
1178
1179 func (v Value) Close() {
1180 v.mustBe(Chan)
1181 v.mustBeExported()
1182 chanclose(v.pointer())
1183 }
1184
1185
1186 func (v Value) CanComplex() bool {
1187 switch v.kind() {
1188 case Complex64, Complex128:
1189 return true
1190 default:
1191 return false
1192 }
1193 }
1194
1195
1196
1197 func (v Value) Complex() complex128 {
1198 k := v.kind()
1199 switch k {
1200 case Complex64:
1201 return complex128(*(*complex64)(v.ptr))
1202 case Complex128:
1203 return *(*complex128)(v.ptr)
1204 }
1205 panic(&ValueError{"reflect.Value.Complex", v.kind()})
1206 }
1207
1208
1209
1210
1211
1212 func (v Value) Elem() Value {
1213 k := v.kind()
1214 switch k {
1215 case Interface:
1216 var eface any
1217 if v.typ.NumMethod() == 0 {
1218 eface = *(*any)(v.ptr)
1219 } else {
1220 eface = (any)(*(*interface {
1221 M()
1222 })(v.ptr))
1223 }
1224 x := unpackEface(eface)
1225 if x.flag != 0 {
1226 x.flag |= v.flag.ro()
1227 }
1228 return x
1229 case Pointer:
1230 ptr := v.ptr
1231 if v.flag&flagIndir != 0 {
1232 if ifaceIndir(v.typ) {
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 if !verifyNotInHeapPtr(*(*uintptr)(ptr)) {
1244 panic("reflect: reflect.Value.Elem on an invalid notinheap pointer")
1245 }
1246 }
1247 ptr = *(*unsafe.Pointer)(ptr)
1248 }
1249
1250 if ptr == nil {
1251 return Value{}
1252 }
1253 tt := (*ptrType)(unsafe.Pointer(v.typ))
1254 typ := tt.elem
1255 fl := v.flag&flagRO | flagIndir | flagAddr
1256 fl |= flag(typ.Kind())
1257 return Value{typ, ptr, fl}
1258 }
1259 panic(&ValueError{"reflect.Value.Elem", v.kind()})
1260 }
1261
1262
1263
1264 func (v Value) Field(i int) Value {
1265 if v.kind() != Struct {
1266 panic(&ValueError{"reflect.Value.Field", v.kind()})
1267 }
1268 tt := (*structType)(unsafe.Pointer(v.typ))
1269 if uint(i) >= uint(len(tt.fields)) {
1270 panic("reflect: Field index out of range")
1271 }
1272 field := &tt.fields[i]
1273 typ := field.typ
1274
1275
1276 fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
1277
1278 if !field.name.isExported() {
1279 if field.embedded() {
1280 fl |= flagEmbedRO
1281 } else {
1282 fl |= flagStickyRO
1283 }
1284 }
1285
1286
1287
1288
1289
1290 ptr := add(v.ptr, field.offset, "same as non-reflect &v.field")
1291 return Value{typ, ptr, fl}
1292 }
1293
1294
1295
1296
1297 func (v Value) FieldByIndex(index []int) Value {
1298 if len(index) == 1 {
1299 return v.Field(index[0])
1300 }
1301 v.mustBe(Struct)
1302 for i, x := range index {
1303 if i > 0 {
1304 if v.Kind() == Pointer && v.typ.Elem().Kind() == Struct {
1305 if v.IsNil() {
1306 panic("reflect: indirection through nil pointer to embedded struct")
1307 }
1308 v = v.Elem()
1309 }
1310 }
1311 v = v.Field(x)
1312 }
1313 return v
1314 }
1315
1316
1317
1318
1319
1320 func (v Value) FieldByIndexErr(index []int) (Value, error) {
1321 if len(index) == 1 {
1322 return v.Field(index[0]), nil
1323 }
1324 v.mustBe(Struct)
1325 for i, x := range index {
1326 if i > 0 {
1327 if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
1328 if v.IsNil() {
1329 return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + v.typ.Elem().Name())
1330 }
1331 v = v.Elem()
1332 }
1333 }
1334 v = v.Field(x)
1335 }
1336 return v, nil
1337 }
1338
1339
1340
1341
1342 func (v Value) FieldByName(name string) Value {
1343 v.mustBe(Struct)
1344 if f, ok := v.typ.FieldByName(name); ok {
1345 return v.FieldByIndex(f.Index)
1346 }
1347 return Value{}
1348 }
1349
1350
1351
1352
1353
1354 func (v Value) FieldByNameFunc(match func(string) bool) Value {
1355 if f, ok := v.typ.FieldByNameFunc(match); ok {
1356 return v.FieldByIndex(f.Index)
1357 }
1358 return Value{}
1359 }
1360
1361
1362 func (v Value) CanFloat() bool {
1363 switch v.kind() {
1364 case Float32, Float64:
1365 return true
1366 default:
1367 return false
1368 }
1369 }
1370
1371
1372
1373 func (v Value) Float() float64 {
1374 k := v.kind()
1375 switch k {
1376 case Float32:
1377 return float64(*(*float32)(v.ptr))
1378 case Float64:
1379 return *(*float64)(v.ptr)
1380 }
1381 panic(&ValueError{"reflect.Value.Float", v.kind()})
1382 }
1383
1384 var uint8Type = TypeOf(uint8(0)).(*rtype)
1385
1386
1387
1388 func (v Value) Index(i int) Value {
1389 switch v.kind() {
1390 case Array:
1391 tt := (*arrayType)(unsafe.Pointer(v.typ))
1392 if uint(i) >= uint(tt.len) {
1393 panic("reflect: array index out of range")
1394 }
1395 typ := tt.elem
1396 offset := uintptr(i) * typ.size
1397
1398
1399
1400
1401
1402
1403 val := add(v.ptr, offset, "same as &v[i], i < tt.len")
1404 fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind())
1405 return Value{typ, val, fl}
1406
1407 case Slice:
1408
1409
1410 s := (*unsafeheader.Slice)(v.ptr)
1411 if uint(i) >= uint(s.Len) {
1412 panic("reflect: slice index out of range")
1413 }
1414 tt := (*sliceType)(unsafe.Pointer(v.typ))
1415 typ := tt.elem
1416 val := arrayAt(s.Data, i, typ.size, "i < s.Len")
1417 fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
1418 return Value{typ, val, fl}
1419
1420 case String:
1421 s := (*unsafeheader.String)(v.ptr)
1422 if uint(i) >= uint(s.Len) {
1423 panic("reflect: string index out of range")
1424 }
1425 p := arrayAt(s.Data, i, 1, "i < s.Len")
1426 fl := v.flag.ro() | flag(Uint8) | flagIndir
1427 return Value{uint8Type, p, fl}
1428 }
1429 panic(&ValueError{"reflect.Value.Index", v.kind()})
1430 }
1431
1432
1433 func (v Value) CanInt() bool {
1434 switch v.kind() {
1435 case Int, Int8, Int16, Int32, Int64:
1436 return true
1437 default:
1438 return false
1439 }
1440 }
1441
1442
1443
1444 func (v Value) Int() int64 {
1445 k := v.kind()
1446 p := v.ptr
1447 switch k {
1448 case Int:
1449 return int64(*(*int)(p))
1450 case Int8:
1451 return int64(*(*int8)(p))
1452 case Int16:
1453 return int64(*(*int16)(p))
1454 case Int32:
1455 return int64(*(*int32)(p))
1456 case Int64:
1457 return *(*int64)(p)
1458 }
1459 panic(&ValueError{"reflect.Value.Int", v.kind()})
1460 }
1461
1462
1463 func (v Value) CanInterface() bool {
1464 if v.flag == 0 {
1465 panic(&ValueError{"reflect.Value.CanInterface", Invalid})
1466 }
1467 return v.flag&flagRO == 0
1468 }
1469
1470
1471
1472
1473
1474
1475
1476
1477 func (v Value) Interface() (i any) {
1478 return valueInterface(v, true)
1479 }
1480
1481 func valueInterface(v Value, safe bool) any {
1482 if v.flag == 0 {
1483 panic(&ValueError{"reflect.Value.Interface", Invalid})
1484 }
1485 if safe && v.flag&flagRO != 0 {
1486
1487
1488
1489 panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
1490 }
1491 if v.flag&flagMethod != 0 {
1492 v = makeMethodValue("Interface", v)
1493 }
1494
1495 if v.kind() == Interface {
1496
1497
1498
1499 if v.NumMethod() == 0 {
1500 return *(*any)(v.ptr)
1501 }
1502 return *(*interface {
1503 M()
1504 })(v.ptr)
1505 }
1506
1507
1508 return packEface(v)
1509 }
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520 func (v Value) InterfaceData() [2]uintptr {
1521 v.mustBe(Interface)
1522
1523
1524
1525
1526
1527 return *(*[2]uintptr)(v.ptr)
1528 }
1529
1530
1531
1532
1533
1534
1535
1536
1537 func (v Value) IsNil() bool {
1538 k := v.kind()
1539 switch k {
1540 case Chan, Func, Map, Pointer, UnsafePointer:
1541 if v.flag&flagMethod != 0 {
1542 return false
1543 }
1544 ptr := v.ptr
1545 if v.flag&flagIndir != 0 {
1546 ptr = *(*unsafe.Pointer)(ptr)
1547 }
1548 return ptr == nil
1549 case Interface, Slice:
1550
1551
1552 return *(*unsafe.Pointer)(v.ptr) == nil
1553 }
1554 panic(&ValueError{"reflect.Value.IsNil", v.kind()})
1555 }
1556
1557
1558
1559
1560
1561
1562 func (v Value) IsValid() bool {
1563 return v.flag != 0
1564 }
1565
1566
1567
1568 func (v Value) IsZero() bool {
1569 switch v.kind() {
1570 case Bool:
1571 return !v.Bool()
1572 case Int, Int8, Int16, Int32, Int64:
1573 return v.Int() == 0
1574 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
1575 return v.Uint() == 0
1576 case Float32, Float64:
1577 return math.Float64bits(v.Float()) == 0
1578 case Complex64, Complex128:
1579 c := v.Complex()
1580 return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
1581 case Array:
1582 for i := 0; i < v.Len(); i++ {
1583 if !v.Index(i).IsZero() {
1584 return false
1585 }
1586 }
1587 return true
1588 case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
1589 return v.IsNil()
1590 case String:
1591 return v.Len() == 0
1592 case Struct:
1593 for i := 0; i < v.NumField(); i++ {
1594 if !v.Field(i).IsZero() {
1595 return false
1596 }
1597 }
1598 return true
1599 default:
1600
1601
1602 panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
1603 }
1604 }
1605
1606
1607
1608 func (v Value) Kind() Kind {
1609 return v.kind()
1610 }
1611
1612
1613
1614 func (v Value) Len() int {
1615
1616 if v.kind() == Slice {
1617 return (*unsafeheader.Slice)(v.ptr).Len
1618 }
1619 return v.lenNonSlice()
1620 }
1621
1622 func (v Value) lenNonSlice() int {
1623 switch k := v.kind(); k {
1624 case Array:
1625 tt := (*arrayType)(unsafe.Pointer(v.typ))
1626 return int(tt.len)
1627 case Chan:
1628 return chanlen(v.pointer())
1629 case Map:
1630 return maplen(v.pointer())
1631 case String:
1632
1633 return (*unsafeheader.String)(v.ptr).Len
1634 case Ptr:
1635 if v.typ.Elem().Kind() == Array {
1636 return v.typ.Elem().Len()
1637 }
1638 panic("reflect: call of reflect.Value.Len on ptr to non-array Value")
1639 }
1640 panic(&ValueError{"reflect.Value.Len", v.kind()})
1641 }
1642
1643 var stringType = TypeOf("").(*rtype)
1644
1645
1646
1647
1648
1649 func (v Value) MapIndex(key Value) Value {
1650 v.mustBe(Map)
1651 tt := (*mapType)(unsafe.Pointer(v.typ))
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661 var e unsafe.Pointer
1662 if (tt.key == stringType || key.kind() == String) && tt.key == key.typ && tt.elem.size <= maxValSize {
1663 k := *(*string)(key.ptr)
1664 e = mapaccess_faststr(v.typ, v.pointer(), k)
1665 } else {
1666 key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
1667 var k unsafe.Pointer
1668 if key.flag&flagIndir != 0 {
1669 k = key.ptr
1670 } else {
1671 k = unsafe.Pointer(&key.ptr)
1672 }
1673 e = mapaccess(v.typ, v.pointer(), k)
1674 }
1675 if e == nil {
1676 return Value{}
1677 }
1678 typ := tt.elem
1679 fl := (v.flag | key.flag).ro()
1680 fl |= flag(typ.Kind())
1681 return copyVal(typ, fl, e)
1682 }
1683
1684
1685
1686
1687
1688 func (v Value) MapKeys() []Value {
1689 v.mustBe(Map)
1690 tt := (*mapType)(unsafe.Pointer(v.typ))
1691 keyType := tt.key
1692
1693 fl := v.flag.ro() | flag(keyType.Kind())
1694
1695 m := v.pointer()
1696 mlen := int(0)
1697 if m != nil {
1698 mlen = maplen(m)
1699 }
1700 var it hiter
1701 mapiterinit(v.typ, m, &it)
1702 a := make([]Value, mlen)
1703 var i int
1704 for i = 0; i < len(a); i++ {
1705 key := mapiterkey(&it)
1706 if key == nil {
1707
1708
1709
1710 break
1711 }
1712 a[i] = copyVal(keyType, fl, key)
1713 mapiternext(&it)
1714 }
1715 return a[:i]
1716 }
1717
1718
1719
1720
1721
1722 type hiter struct {
1723 key unsafe.Pointer
1724 elem unsafe.Pointer
1725 t unsafe.Pointer
1726 h unsafe.Pointer
1727 buckets unsafe.Pointer
1728 bptr unsafe.Pointer
1729 overflow *[]unsafe.Pointer
1730 oldoverflow *[]unsafe.Pointer
1731 startBucket uintptr
1732 offset uint8
1733 wrapped bool
1734 B uint8
1735 i uint8
1736 bucket uintptr
1737 checkBucket uintptr
1738 }
1739
1740 func (h *hiter) initialized() bool {
1741 return h.t != nil
1742 }
1743
1744
1745
1746 type MapIter struct {
1747 m Value
1748 hiter hiter
1749 }
1750
1751
1752 func (iter *MapIter) Key() Value {
1753 if !iter.hiter.initialized() {
1754 panic("MapIter.Key called before Next")
1755 }
1756 iterkey := mapiterkey(&iter.hiter)
1757 if iterkey == nil {
1758 panic("MapIter.Key called on exhausted iterator")
1759 }
1760
1761 t := (*mapType)(unsafe.Pointer(iter.m.typ))
1762 ktype := t.key
1763 return copyVal(ktype, iter.m.flag.ro()|flag(ktype.Kind()), iterkey)
1764 }
1765
1766
1767
1768
1769 func (v Value) SetIterKey(iter *MapIter) {
1770 if !iter.hiter.initialized() {
1771 panic("reflect: Value.SetIterKey called before Next")
1772 }
1773 iterkey := mapiterkey(&iter.hiter)
1774 if iterkey == nil {
1775 panic("reflect: Value.SetIterKey called on exhausted iterator")
1776 }
1777
1778 v.mustBeAssignable()
1779 var target unsafe.Pointer
1780 if v.kind() == Interface {
1781 target = v.ptr
1782 }
1783
1784 t := (*mapType)(unsafe.Pointer(iter.m.typ))
1785 ktype := t.key
1786
1787 key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
1788 key = key.assignTo("reflect.MapIter.SetKey", v.typ, target)
1789 typedmemmove(v.typ, v.ptr, key.ptr)
1790 }
1791
1792
1793 func (iter *MapIter) Value() Value {
1794 if !iter.hiter.initialized() {
1795 panic("MapIter.Value called before Next")
1796 }
1797 iterelem := mapiterelem(&iter.hiter)
1798 if iterelem == nil {
1799 panic("MapIter.Value called on exhausted iterator")
1800 }
1801
1802 t := (*mapType)(unsafe.Pointer(iter.m.typ))
1803 vtype := t.elem
1804 return copyVal(vtype, iter.m.flag.ro()|flag(vtype.Kind()), iterelem)
1805 }
1806
1807
1808
1809
1810 func (v Value) SetIterValue(iter *MapIter) {
1811 if !iter.hiter.initialized() {
1812 panic("reflect: Value.SetIterValue called before Next")
1813 }
1814 iterelem := mapiterelem(&iter.hiter)
1815 if iterelem == nil {
1816 panic("reflect: Value.SetIterValue called on exhausted iterator")
1817 }
1818
1819 v.mustBeAssignable()
1820 var target unsafe.Pointer
1821 if v.kind() == Interface {
1822 target = v.ptr
1823 }
1824
1825 t := (*mapType)(unsafe.Pointer(iter.m.typ))
1826 vtype := t.elem
1827
1828 elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
1829 elem = elem.assignTo("reflect.MapIter.SetValue", v.typ, target)
1830 typedmemmove(v.typ, v.ptr, elem.ptr)
1831 }
1832
1833
1834
1835
1836 func (iter *MapIter) Next() bool {
1837 if !iter.m.IsValid() {
1838 panic("MapIter.Next called on an iterator that does not have an associated map Value")
1839 }
1840 if !iter.hiter.initialized() {
1841 mapiterinit(iter.m.typ, iter.m.pointer(), &iter.hiter)
1842 } else {
1843 if mapiterkey(&iter.hiter) == nil {
1844 panic("MapIter.Next called on exhausted iterator")
1845 }
1846 mapiternext(&iter.hiter)
1847 }
1848 return mapiterkey(&iter.hiter) != nil
1849 }
1850
1851
1852
1853
1854
1855 func (iter *MapIter) Reset(v Value) {
1856 if v.IsValid() {
1857 v.mustBe(Map)
1858 }
1859 iter.m = v
1860 iter.hiter = hiter{}
1861 }
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878 func (v Value) MapRange() *MapIter {
1879
1880
1881
1882
1883 if v.kind() != Map {
1884 v.panicNotMap()
1885 }
1886 return &MapIter{m: v}
1887 }
1888
1889 func (f flag) panicNotMap() {
1890 f.mustBe(Map)
1891 }
1892
1893
1894
1895 func copyVal(typ *rtype, fl flag, ptr unsafe.Pointer) Value {
1896 if ifaceIndir(typ) {
1897
1898
1899 c := unsafe_New(typ)
1900 typedmemmove(typ, c, ptr)
1901 return Value{typ, c, fl | flagIndir}
1902 }
1903 return Value{typ, *(*unsafe.Pointer)(ptr), fl}
1904 }
1905
1906
1907
1908
1909
1910 func (v Value) Method(i int) Value {
1911 if v.typ == nil {
1912 panic(&ValueError{"reflect.Value.Method", Invalid})
1913 }
1914 if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
1915 panic("reflect: Method index out of range")
1916 }
1917 if v.typ.Kind() == Interface && v.IsNil() {
1918 panic("reflect: Method on nil interface value")
1919 }
1920 fl := v.flag.ro() | (v.flag & flagIndir)
1921 fl |= flag(Func)
1922 fl |= flag(i)<<flagMethodShift | flagMethod
1923 return Value{v.typ, v.ptr, fl}
1924 }
1925
1926
1927
1928
1929
1930
1931 func (v Value) NumMethod() int {
1932 if v.typ == nil {
1933 panic(&ValueError{"reflect.Value.NumMethod", Invalid})
1934 }
1935 if v.flag&flagMethod != 0 {
1936 return 0
1937 }
1938 return v.typ.NumMethod()
1939 }
1940
1941
1942
1943
1944
1945
1946 func (v Value) MethodByName(name string) Value {
1947 if v.typ == nil {
1948 panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1949 }
1950 if v.flag&flagMethod != 0 {
1951 return Value{}
1952 }
1953 m, ok := v.typ.MethodByName(name)
1954 if !ok {
1955 return Value{}
1956 }
1957 return v.Method(m.Index)
1958 }
1959
1960
1961
1962 func (v Value) NumField() int {
1963 v.mustBe(Struct)
1964 tt := (*structType)(unsafe.Pointer(v.typ))
1965 return len(tt.fields)
1966 }
1967
1968
1969
1970 func (v Value) OverflowComplex(x complex128) bool {
1971 k := v.kind()
1972 switch k {
1973 case Complex64:
1974 return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1975 case Complex128:
1976 return false
1977 }
1978 panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
1979 }
1980
1981
1982
1983 func (v Value) OverflowFloat(x float64) bool {
1984 k := v.kind()
1985 switch k {
1986 case Float32:
1987 return overflowFloat32(x)
1988 case Float64:
1989 return false
1990 }
1991 panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
1992 }
1993
1994 func overflowFloat32(x float64) bool {
1995 if x < 0 {
1996 x = -x
1997 }
1998 return math.MaxFloat32 < x && x <= math.MaxFloat64
1999 }
2000
2001
2002
2003 func (v Value) OverflowInt(x int64) bool {
2004 k := v.kind()
2005 switch k {
2006 case Int, Int8, Int16, Int32, Int64:
2007 bitSize := v.typ.size * 8
2008 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
2009 return x != trunc
2010 }
2011 panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
2012 }
2013
2014
2015
2016 func (v Value) OverflowUint(x uint64) bool {
2017 k := v.kind()
2018 switch k {
2019 case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
2020 bitSize := v.typ.size * 8
2021 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
2022 return x != trunc
2023 }
2024 panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
2025 }
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048 func (v Value) Pointer() uintptr {
2049 k := v.kind()
2050 switch k {
2051 case Pointer:
2052 if v.typ.ptrdata == 0 {
2053 val := *(*uintptr)(v.ptr)
2054
2055
2056 if !verifyNotInHeapPtr(val) {
2057 panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
2058 }
2059 return val
2060 }
2061 fallthrough
2062 case Chan, Map, UnsafePointer:
2063 return uintptr(v.pointer())
2064 case Func:
2065 if v.flag&flagMethod != 0 {
2066
2067
2068
2069
2070
2071
2072 return methodValueCallCodePtr()
2073 }
2074 p := v.pointer()
2075
2076
2077 if p != nil {
2078 p = *(*unsafe.Pointer)(p)
2079 }
2080 return uintptr(p)
2081
2082 case Slice:
2083 return (*SliceHeader)(v.ptr).Data
2084 }
2085 panic(&ValueError{"reflect.Value.Pointer", v.kind()})
2086 }
2087
2088
2089
2090
2091
2092
2093 func (v Value) Recv() (x Value, ok bool) {
2094 v.mustBe(Chan)
2095 v.mustBeExported()
2096 return v.recv(false)
2097 }
2098
2099
2100
2101 func (v Value) recv(nb bool) (val Value, ok bool) {
2102 tt := (*chanType)(unsafe.Pointer(v.typ))
2103 if ChanDir(tt.dir)&RecvDir == 0 {
2104 panic("reflect: recv on send-only channel")
2105 }
2106 t := tt.elem
2107 val = Value{t, nil, flag(t.Kind())}
2108 var p unsafe.Pointer
2109 if ifaceIndir(t) {
2110 p = unsafe_New(t)
2111 val.ptr = p
2112 val.flag |= flagIndir
2113 } else {
2114 p = unsafe.Pointer(&val.ptr)
2115 }
2116 selected, ok := chanrecv(v.pointer(), nb, p)
2117 if !selected {
2118 val = Value{}
2119 }
2120 return
2121 }
2122
2123
2124
2125
2126 func (v Value) Send(x Value) {
2127 v.mustBe(Chan)
2128 v.mustBeExported()
2129 v.send(x, false)
2130 }
2131
2132
2133
2134 func (v Value) send(x Value, nb bool) (selected bool) {
2135 tt := (*chanType)(unsafe.Pointer(v.typ))
2136 if ChanDir(tt.dir)&SendDir == 0 {
2137 panic("reflect: send on recv-only channel")
2138 }
2139 x.mustBeExported()
2140 x = x.assignTo("reflect.Value.Send", tt.elem, nil)
2141 var p unsafe.Pointer
2142 if x.flag&flagIndir != 0 {
2143 p = x.ptr
2144 } else {
2145 p = unsafe.Pointer(&x.ptr)
2146 }
2147 return chansend(v.pointer(), p, nb)
2148 }
2149
2150
2151
2152
2153 func (v Value) Set(x Value) {
2154 v.mustBeAssignable()
2155 x.mustBeExported()
2156 var target unsafe.Pointer
2157 if v.kind() == Interface {
2158 target = v.ptr
2159 }
2160 x = x.assignTo("reflect.Set", v.typ, target)
2161 if x.flag&flagIndir != 0 {
2162 if x.ptr == unsafe.Pointer(&zeroVal[0]) {
2163 typedmemclr(v.typ, v.ptr)
2164 } else {
2165 typedmemmove(v.typ, v.ptr, x.ptr)
2166 }
2167 } else {
2168 *(*unsafe.Pointer)(v.ptr) = x.ptr
2169 }
2170 }
2171
2172
2173
2174 func (v Value) SetBool(x bool) {
2175 v.mustBeAssignable()
2176 v.mustBe(Bool)
2177 *(*bool)(v.ptr) = x
2178 }
2179
2180
2181
2182 func (v Value) SetBytes(x []byte) {
2183 v.mustBeAssignable()
2184 v.mustBe(Slice)
2185 if v.typ.Elem().Kind() != Uint8 {
2186 panic("reflect.Value.SetBytes of non-byte slice")
2187 }
2188 *(*[]byte)(v.ptr) = x
2189 }
2190
2191
2192
2193 func (v Value) setRunes(x []rune) {
2194 v.mustBeAssignable()
2195 v.mustBe(Slice)
2196 if v.typ.Elem().Kind() != Int32 {
2197 panic("reflect.Value.setRunes of non-rune slice")
2198 }
2199 *(*[]rune)(v.ptr) = x
2200 }
2201
2202
2203
2204 func (v Value) SetComplex(x complex128) {
2205 v.mustBeAssignable()
2206 switch k := v.kind(); k {
2207 default:
2208 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
2209 case Complex64:
2210 *(*complex64)(v.ptr) = complex64(x)
2211 case Complex128:
2212 *(*complex128)(v.ptr) = x
2213 }
2214 }
2215
2216
2217
2218 func (v Value) SetFloat(x float64) {
2219 v.mustBeAssignable()
2220 switch k := v.kind(); k {
2221 default:
2222 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
2223 case Float32:
2224 *(*float32)(v.ptr) = float32(x)
2225 case Float64:
2226 *(*float64)(v.ptr) = x
2227 }
2228 }
2229
2230
2231
2232 func (v Value) SetInt(x int64) {
2233 v.mustBeAssignable()
2234 switch k := v.kind(); k {
2235 default:
2236 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
2237 case Int:
2238 *(*int)(v.ptr) = int(x)
2239 case Int8:
2240 *(*int8)(v.ptr) = int8(x)
2241 case Int16:
2242 *(*int16)(v.ptr) = int16(x)
2243 case Int32:
2244 *(*int32)(v.ptr) = int32(x)
2245 case Int64:
2246 *(*int64)(v.ptr) = x
2247 }
2248 }
2249
2250
2251
2252
2253 func (v Value) SetLen(n int) {
2254 v.mustBeAssignable()
2255 v.mustBe(Slice)
2256 s := (*unsafeheader.Slice)(v.ptr)
2257 if uint(n) > uint(s.Cap) {
2258 panic("reflect: slice length out of range in SetLen")
2259 }
2260 s.Len = n
2261 }
2262
2263
2264
2265
2266 func (v Value) SetCap(n int) {
2267 v.mustBeAssignable()
2268 v.mustBe(Slice)
2269 s := (*unsafeheader.Slice)(v.ptr)
2270 if n < s.Len || n > s.Cap {
2271 panic("reflect: slice capacity out of range in SetCap")
2272 }
2273 s.Cap = n
2274 }
2275
2276
2277
2278
2279
2280
2281
2282 func (v Value) SetMapIndex(key, elem Value) {
2283 v.mustBe(Map)
2284 v.mustBeExported()
2285 key.mustBeExported()
2286 tt := (*mapType)(unsafe.Pointer(v.typ))
2287
2288 if (tt.key == stringType || key.kind() == String) && tt.key == key.typ && tt.elem.size <= maxValSize {
2289 k := *(*string)(key.ptr)
2290 if elem.typ == nil {
2291 mapdelete_faststr(v.typ, v.pointer(), k)
2292 return
2293 }
2294 elem.mustBeExported()
2295 elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
2296 var e unsafe.Pointer
2297 if elem.flag&flagIndir != 0 {
2298 e = elem.ptr
2299 } else {
2300 e = unsafe.Pointer(&elem.ptr)
2301 }
2302 mapassign_faststr(v.typ, v.pointer(), k, e)
2303 return
2304 }
2305
2306 key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
2307 var k unsafe.Pointer
2308 if key.flag&flagIndir != 0 {
2309 k = key.ptr
2310 } else {
2311 k = unsafe.Pointer(&key.ptr)
2312 }
2313 if elem.typ == nil {
2314 mapdelete(v.typ, v.pointer(), k)
2315 return
2316 }
2317 elem.mustBeExported()
2318 elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
2319 var e unsafe.Pointer
2320 if elem.flag&flagIndir != 0 {
2321 e = elem.ptr
2322 } else {
2323 e = unsafe.Pointer(&elem.ptr)
2324 }
2325 mapassign(v.typ, v.pointer(), k, e)
2326 }
2327
2328
2329
2330 func (v Value) SetUint(x uint64) {
2331 v.mustBeAssignable()
2332 switch k := v.kind(); k {
2333 default:
2334 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
2335 case Uint:
2336 *(*uint)(v.ptr) = uint(x)
2337 case Uint8:
2338 *(*uint8)(v.ptr) = uint8(x)
2339 case Uint16:
2340 *(*uint16)(v.ptr) = uint16(x)
2341 case Uint32:
2342 *(*uint32)(v.ptr) = uint32(x)
2343 case Uint64:
2344 *(*uint64)(v.ptr) = x
2345 case Uintptr:
2346 *(*uintptr)(v.ptr) = uintptr(x)
2347 }
2348 }
2349
2350
2351
2352 func (v Value) SetPointer(x unsafe.Pointer) {
2353 v.mustBeAssignable()
2354 v.mustBe(UnsafePointer)
2355 *(*unsafe.Pointer)(v.ptr) = x
2356 }
2357
2358
2359
2360 func (v Value) SetString(x string) {
2361 v.mustBeAssignable()
2362 v.mustBe(String)
2363 *(*string)(v.ptr) = x
2364 }
2365
2366
2367
2368
2369 func (v Value) Slice(i, j int) Value {
2370 var (
2371 cap int
2372 typ *sliceType
2373 base unsafe.Pointer
2374 )
2375 switch kind := v.kind(); kind {
2376 default:
2377 panic(&ValueError{"reflect.Value.Slice", v.kind()})
2378
2379 case Array:
2380 if v.flag&flagAddr == 0 {
2381 panic("reflect.Value.Slice: slice of unaddressable array")
2382 }
2383 tt := (*arrayType)(unsafe.Pointer(v.typ))
2384 cap = int(tt.len)
2385 typ = (*sliceType)(unsafe.Pointer(tt.slice))
2386 base = v.ptr
2387
2388 case Slice:
2389 typ = (*sliceType)(unsafe.Pointer(v.typ))
2390 s := (*unsafeheader.Slice)(v.ptr)
2391 base = s.Data
2392 cap = s.Cap
2393
2394 case String:
2395 s := (*unsafeheader.String)(v.ptr)
2396 if i < 0 || j < i || j > s.Len {
2397 panic("reflect.Value.Slice: string slice index out of bounds")
2398 }
2399 var t unsafeheader.String
2400 if i < s.Len {
2401 t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
2402 }
2403 return Value{v.typ, unsafe.Pointer(&t), v.flag}
2404 }
2405
2406 if i < 0 || j < i || j > cap {
2407 panic("reflect.Value.Slice: slice index out of bounds")
2408 }
2409
2410
2411 var x []unsafe.Pointer
2412
2413
2414 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2415 s.Len = j - i
2416 s.Cap = cap - i
2417 if cap-i > 0 {
2418 s.Data = arrayAt(base, i, typ.elem.Size(), "i < cap")
2419 } else {
2420
2421 s.Data = base
2422 }
2423
2424 fl := v.flag.ro() | flagIndir | flag(Slice)
2425 return Value{typ.common(), unsafe.Pointer(&x), fl}
2426 }
2427
2428
2429
2430
2431 func (v Value) Slice3(i, j, k int) Value {
2432 var (
2433 cap int
2434 typ *sliceType
2435 base unsafe.Pointer
2436 )
2437 switch kind := v.kind(); kind {
2438 default:
2439 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
2440
2441 case Array:
2442 if v.flag&flagAddr == 0 {
2443 panic("reflect.Value.Slice3: slice of unaddressable array")
2444 }
2445 tt := (*arrayType)(unsafe.Pointer(v.typ))
2446 cap = int(tt.len)
2447 typ = (*sliceType)(unsafe.Pointer(tt.slice))
2448 base = v.ptr
2449
2450 case Slice:
2451 typ = (*sliceType)(unsafe.Pointer(v.typ))
2452 s := (*unsafeheader.Slice)(v.ptr)
2453 base = s.Data
2454 cap = s.Cap
2455 }
2456
2457 if i < 0 || j < i || k < j || k > cap {
2458 panic("reflect.Value.Slice3: slice index out of bounds")
2459 }
2460
2461
2462
2463 var x []unsafe.Pointer
2464
2465
2466 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2467 s.Len = j - i
2468 s.Cap = k - i
2469 if k-i > 0 {
2470 s.Data = arrayAt(base, i, typ.elem.Size(), "i < k <= cap")
2471 } else {
2472
2473 s.Data = base
2474 }
2475
2476 fl := v.flag.ro() | flagIndir | flag(Slice)
2477 return Value{typ.common(), unsafe.Pointer(&x), fl}
2478 }
2479
2480
2481
2482
2483
2484
2485
2486 func (v Value) String() string {
2487
2488 if v.kind() == String {
2489 return *(*string)(v.ptr)
2490 }
2491 return v.stringNonString()
2492 }
2493
2494 func (v Value) stringNonString() string {
2495 if v.kind() == Invalid {
2496 return "<invalid Value>"
2497 }
2498
2499
2500 return "<" + v.Type().String() + " Value>"
2501 }
2502
2503
2504
2505
2506
2507
2508 func (v Value) TryRecv() (x Value, ok bool) {
2509 v.mustBe(Chan)
2510 v.mustBeExported()
2511 return v.recv(true)
2512 }
2513
2514
2515
2516
2517
2518 func (v Value) TrySend(x Value) bool {
2519 v.mustBe(Chan)
2520 v.mustBeExported()
2521 return v.send(x, true)
2522 }
2523
2524
2525 func (v Value) Type() Type {
2526 if v.flag != 0 && v.flag&flagMethod == 0 {
2527 return v.typ
2528 }
2529 return v.typeSlow()
2530 }
2531
2532 func (v Value) typeSlow() Type {
2533 if v.flag == 0 {
2534 panic(&ValueError{"reflect.Value.Type", Invalid})
2535 }
2536 if v.flag&flagMethod == 0 {
2537 return v.typ
2538 }
2539
2540
2541
2542 i := int(v.flag) >> flagMethodShift
2543 if v.typ.Kind() == Interface {
2544
2545 tt := (*interfaceType)(unsafe.Pointer(v.typ))
2546 if uint(i) >= uint(len(tt.methods)) {
2547 panic("reflect: internal error: invalid method index")
2548 }
2549 m := &tt.methods[i]
2550 return v.typ.typeOff(m.typ)
2551 }
2552
2553 ms := v.typ.exportedMethods()
2554 if uint(i) >= uint(len(ms)) {
2555 panic("reflect: internal error: invalid method index")
2556 }
2557 m := ms[i]
2558 return v.typ.typeOff(m.mtyp)
2559 }
2560
2561
2562 func (v Value) CanUint() bool {
2563 switch v.kind() {
2564 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2565 return true
2566 default:
2567 return false
2568 }
2569 }
2570
2571
2572
2573 func (v Value) Uint() uint64 {
2574 k := v.kind()
2575 p := v.ptr
2576 switch k {
2577 case Uint:
2578 return uint64(*(*uint)(p))
2579 case Uint8:
2580 return uint64(*(*uint8)(p))
2581 case Uint16:
2582 return uint64(*(*uint16)(p))
2583 case Uint32:
2584 return uint64(*(*uint32)(p))
2585 case Uint64:
2586 return *(*uint64)(p)
2587 case Uintptr:
2588 return uint64(*(*uintptr)(p))
2589 }
2590 panic(&ValueError{"reflect.Value.Uint", v.kind()})
2591 }
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603 func (v Value) UnsafeAddr() uintptr {
2604 if v.typ == nil {
2605 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
2606 }
2607 if v.flag&flagAddr == 0 {
2608 panic("reflect.Value.UnsafeAddr of unaddressable value")
2609 }
2610 return uintptr(v.ptr)
2611 }
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624 func (v Value) UnsafePointer() unsafe.Pointer {
2625 k := v.kind()
2626 switch k {
2627 case Pointer:
2628 if v.typ.ptrdata == 0 {
2629
2630
2631 if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
2632 panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
2633 }
2634 return *(*unsafe.Pointer)(v.ptr)
2635 }
2636 fallthrough
2637 case Chan, Map, UnsafePointer:
2638 return v.pointer()
2639 case Func:
2640 if v.flag&flagMethod != 0 {
2641
2642
2643
2644
2645
2646
2647 code := methodValueCallCodePtr()
2648 return *(*unsafe.Pointer)(unsafe.Pointer(&code))
2649 }
2650 p := v.pointer()
2651
2652
2653 if p != nil {
2654 p = *(*unsafe.Pointer)(p)
2655 }
2656 return p
2657
2658 case Slice:
2659 return (*unsafeheader.Slice)(v.ptr).Data
2660 }
2661 panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
2662 }
2663
2664
2665
2666
2667
2668
2669
2670 type StringHeader struct {
2671 Data uintptr
2672 Len int
2673 }
2674
2675
2676
2677
2678
2679
2680
2681 type SliceHeader struct {
2682 Data uintptr
2683 Len int
2684 Cap int
2685 }
2686
2687 func typesMustMatch(what string, t1, t2 Type) {
2688 if t1 != t2 {
2689 panic(what + ": " + t1.String() + " != " + t2.String())
2690 }
2691 }
2692
2693
2694
2695
2696
2697
2698
2699
2700 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
2701 return add(p, uintptr(i)*eltSize, "i < len")
2702 }
2703
2704
2705
2706 func grow(s Value, extra int) (Value, int, int) {
2707 i0 := s.Len()
2708 i1 := i0 + extra
2709 if i1 < i0 {
2710 panic("reflect.Append: slice overflow")
2711 }
2712 m := s.Cap()
2713 if i1 <= m {
2714 return s.Slice(0, i1), i0, i1
2715 }
2716 if m == 0 {
2717 m = extra
2718 } else {
2719 const threshold = 256
2720 for m < i1 {
2721 if i0 < threshold {
2722 m += m
2723 } else {
2724 m += (m + 3*threshold) / 4
2725 }
2726 }
2727 }
2728 t := MakeSlice(s.Type(), i1, m)
2729 Copy(t, s)
2730 return t, i0, i1
2731 }
2732
2733
2734
2735 func Append(s Value, x ...Value) Value {
2736 s.mustBe(Slice)
2737 s, i0, i1 := grow(s, len(x))
2738 for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
2739 s.Index(i).Set(x[j])
2740 }
2741 return s
2742 }
2743
2744
2745
2746 func AppendSlice(s, t Value) Value {
2747 s.mustBe(Slice)
2748 t.mustBe(Slice)
2749 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
2750 s, i0, i1 := grow(s, t.Len())
2751 Copy(s.Slice(i0, i1), t)
2752 return s
2753 }
2754
2755
2756
2757
2758
2759
2760
2761
2762 func Copy(dst, src Value) int {
2763 dk := dst.kind()
2764 if dk != Array && dk != Slice {
2765 panic(&ValueError{"reflect.Copy", dk})
2766 }
2767 if dk == Array {
2768 dst.mustBeAssignable()
2769 }
2770 dst.mustBeExported()
2771
2772 sk := src.kind()
2773 var stringCopy bool
2774 if sk != Array && sk != Slice {
2775 stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
2776 if !stringCopy {
2777 panic(&ValueError{"reflect.Copy", sk})
2778 }
2779 }
2780 src.mustBeExported()
2781
2782 de := dst.typ.Elem()
2783 if !stringCopy {
2784 se := src.typ.Elem()
2785 typesMustMatch("reflect.Copy", de, se)
2786 }
2787
2788 var ds, ss unsafeheader.Slice
2789 if dk == Array {
2790 ds.Data = dst.ptr
2791 ds.Len = dst.Len()
2792 ds.Cap = ds.Len
2793 } else {
2794 ds = *(*unsafeheader.Slice)(dst.ptr)
2795 }
2796 if sk == Array {
2797 ss.Data = src.ptr
2798 ss.Len = src.Len()
2799 ss.Cap = ss.Len
2800 } else if sk == Slice {
2801 ss = *(*unsafeheader.Slice)(src.ptr)
2802 } else {
2803 sh := *(*unsafeheader.String)(src.ptr)
2804 ss.Data = sh.Data
2805 ss.Len = sh.Len
2806 ss.Cap = sh.Len
2807 }
2808
2809 return typedslicecopy(de.common(), ds, ss)
2810 }
2811
2812
2813
2814 type runtimeSelect struct {
2815 dir SelectDir
2816 typ *rtype
2817 ch unsafe.Pointer
2818 val unsafe.Pointer
2819 }
2820
2821
2822
2823
2824
2825
2826
2827 func rselect([]runtimeSelect) (chosen int, recvOK bool)
2828
2829
2830 type SelectDir int
2831
2832
2833
2834 const (
2835 _ SelectDir = iota
2836 SelectSend
2837 SelectRecv
2838 SelectDefault
2839 )
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857 type SelectCase struct {
2858 Dir SelectDir
2859 Chan Value
2860 Send Value
2861 }
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
2872 if len(cases) > 65536 {
2873 panic("reflect.Select: too many cases (max 65536)")
2874 }
2875
2876
2877
2878 var runcases []runtimeSelect
2879 if len(cases) > 4 {
2880
2881 runcases = make([]runtimeSelect, len(cases))
2882 } else {
2883
2884 runcases = make([]runtimeSelect, len(cases), 4)
2885 }
2886
2887 haveDefault := false
2888 for i, c := range cases {
2889 rc := &runcases[i]
2890 rc.dir = c.Dir
2891 switch c.Dir {
2892 default:
2893 panic("reflect.Select: invalid Dir")
2894
2895 case SelectDefault:
2896 if haveDefault {
2897 panic("reflect.Select: multiple default cases")
2898 }
2899 haveDefault = true
2900 if c.Chan.IsValid() {
2901 panic("reflect.Select: default case has Chan value")
2902 }
2903 if c.Send.IsValid() {
2904 panic("reflect.Select: default case has Send value")
2905 }
2906
2907 case SelectSend:
2908 ch := c.Chan
2909 if !ch.IsValid() {
2910 break
2911 }
2912 ch.mustBe(Chan)
2913 ch.mustBeExported()
2914 tt := (*chanType)(unsafe.Pointer(ch.typ))
2915 if ChanDir(tt.dir)&SendDir == 0 {
2916 panic("reflect.Select: SendDir case using recv-only channel")
2917 }
2918 rc.ch = ch.pointer()
2919 rc.typ = &tt.rtype
2920 v := c.Send
2921 if !v.IsValid() {
2922 panic("reflect.Select: SendDir case missing Send value")
2923 }
2924 v.mustBeExported()
2925 v = v.assignTo("reflect.Select", tt.elem, nil)
2926 if v.flag&flagIndir != 0 {
2927 rc.val = v.ptr
2928 } else {
2929 rc.val = unsafe.Pointer(&v.ptr)
2930 }
2931
2932 case SelectRecv:
2933 if c.Send.IsValid() {
2934 panic("reflect.Select: RecvDir case has Send value")
2935 }
2936 ch := c.Chan
2937 if !ch.IsValid() {
2938 break
2939 }
2940 ch.mustBe(Chan)
2941 ch.mustBeExported()
2942 tt := (*chanType)(unsafe.Pointer(ch.typ))
2943 if ChanDir(tt.dir)&RecvDir == 0 {
2944 panic("reflect.Select: RecvDir case using send-only channel")
2945 }
2946 rc.ch = ch.pointer()
2947 rc.typ = &tt.rtype
2948 rc.val = unsafe_New(tt.elem)
2949 }
2950 }
2951
2952 chosen, recvOK = rselect(runcases)
2953 if runcases[chosen].dir == SelectRecv {
2954 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
2955 t := tt.elem
2956 p := runcases[chosen].val
2957 fl := flag(t.Kind())
2958 if ifaceIndir(t) {
2959 recv = Value{t, p, fl | flagIndir}
2960 } else {
2961 recv = Value{t, *(*unsafe.Pointer)(p), fl}
2962 }
2963 }
2964 return chosen, recv, recvOK
2965 }
2966
2967
2970
2971
2972 func unsafe_New(*rtype) unsafe.Pointer
2973 func unsafe_NewArray(*rtype, int) unsafe.Pointer
2974
2975
2976
2977 func MakeSlice(typ Type, len, cap int) Value {
2978 if typ.Kind() != Slice {
2979 panic("reflect.MakeSlice of non-slice type")
2980 }
2981 if len < 0 {
2982 panic("reflect.MakeSlice: negative len")
2983 }
2984 if cap < 0 {
2985 panic("reflect.MakeSlice: negative cap")
2986 }
2987 if len > cap {
2988 panic("reflect.MakeSlice: len > cap")
2989 }
2990
2991 s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().(*rtype), cap), Len: len, Cap: cap}
2992 return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)}
2993 }
2994
2995
2996 func MakeChan(typ Type, buffer int) Value {
2997 if typ.Kind() != Chan {
2998 panic("reflect.MakeChan of non-chan type")
2999 }
3000 if buffer < 0 {
3001 panic("reflect.MakeChan: negative buffer size")
3002 }
3003 if typ.ChanDir() != BothDir {
3004 panic("reflect.MakeChan: unidirectional channel type")
3005 }
3006 t := typ.(*rtype)
3007 ch := makechan(t, buffer)
3008 return Value{t, ch, flag(Chan)}
3009 }
3010
3011
3012 func MakeMap(typ Type) Value {
3013 return MakeMapWithSize(typ, 0)
3014 }
3015
3016
3017
3018 func MakeMapWithSize(typ Type, n int) Value {
3019 if typ.Kind() != Map {
3020 panic("reflect.MakeMapWithSize of non-map type")
3021 }
3022 t := typ.(*rtype)
3023 m := makemap(t, n)
3024 return Value{t, m, flag(Map)}
3025 }
3026
3027
3028
3029
3030 func Indirect(v Value) Value {
3031 if v.Kind() != Pointer {
3032 return v
3033 }
3034 return v.Elem()
3035 }
3036
3037
3038
3039 func ValueOf(i any) Value {
3040 if i == nil {
3041 return Value{}
3042 }
3043
3044
3045
3046
3047
3048 escapes(i)
3049
3050 return unpackEface(i)
3051 }
3052
3053
3054
3055
3056
3057
3058 func Zero(typ Type) Value {
3059 if typ == nil {
3060 panic("reflect: Zero(nil)")
3061 }
3062 t := typ.(*rtype)
3063 fl := flag(t.Kind())
3064 if ifaceIndir(t) {
3065 var p unsafe.Pointer
3066 if t.size <= maxZero {
3067 p = unsafe.Pointer(&zeroVal[0])
3068 } else {
3069 p = unsafe_New(t)
3070 }
3071 return Value{t, p, fl | flagIndir}
3072 }
3073 return Value{t, nil, fl}
3074 }
3075
3076
3077 const maxZero = 1024
3078
3079
3080 var zeroVal [maxZero]byte
3081
3082
3083
3084 func New(typ Type) Value {
3085 if typ == nil {
3086 panic("reflect: New(nil)")
3087 }
3088 t := typ.(*rtype)
3089 pt := t.ptrTo()
3090 if ifaceIndir(pt) {
3091
3092 panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
3093 }
3094 ptr := unsafe_New(t)
3095 fl := flag(Pointer)
3096 return Value{pt, ptr, fl}
3097 }
3098
3099
3100
3101 func NewAt(typ Type, p unsafe.Pointer) Value {
3102 fl := flag(Pointer)
3103 t := typ.(*rtype)
3104 return Value{t.ptrTo(), p, fl}
3105 }
3106
3107
3108
3109
3110
3111
3112 func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
3113 if v.flag&flagMethod != 0 {
3114 v = makeMethodValue(context, v)
3115 }
3116
3117 switch {
3118 case directlyAssignable(dst, v.typ):
3119
3120
3121 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
3122 fl |= flag(dst.Kind())
3123 return Value{dst, v.ptr, fl}
3124
3125 case implements(dst, v.typ):
3126 if v.Kind() == Interface && v.IsNil() {
3127
3128
3129
3130 return Value{dst, nil, flag(Interface)}
3131 }
3132 x := valueInterface(v, false)
3133 if target == nil {
3134 target = unsafe_New(dst)
3135 }
3136 if dst.NumMethod() == 0 {
3137 *(*any)(target) = x
3138 } else {
3139 ifaceE2I(dst, x, target)
3140 }
3141 return Value{dst, target, flagIndir | flag(Interface)}
3142 }
3143
3144
3145 panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
3146 }
3147
3148
3149
3150
3151 func (v Value) Convert(t Type) Value {
3152 if v.flag&flagMethod != 0 {
3153 v = makeMethodValue("Convert", v)
3154 }
3155 op := convertOp(t.common(), v.typ)
3156 if op == nil {
3157 panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
3158 }
3159 return op(v, t)
3160 }
3161
3162
3163
3164 func (v Value) CanConvert(t Type) bool {
3165 vt := v.Type()
3166 if !vt.ConvertibleTo(t) {
3167 return false
3168 }
3169
3170
3171
3172 if vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array {
3173 n := t.Elem().Len()
3174 if n > v.Len() {
3175 return false
3176 }
3177 }
3178 return true
3179 }
3180
3181
3182
3183 func convertOp(dst, src *rtype) func(Value, Type) Value {
3184 switch src.Kind() {
3185 case Int, Int8, Int16, Int32, Int64:
3186 switch dst.Kind() {
3187 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3188 return cvtInt
3189 case Float32, Float64:
3190 return cvtIntFloat
3191 case String:
3192 return cvtIntString
3193 }
3194
3195 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3196 switch dst.Kind() {
3197 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3198 return cvtUint
3199 case Float32, Float64:
3200 return cvtUintFloat
3201 case String:
3202 return cvtUintString
3203 }
3204
3205 case Float32, Float64:
3206 switch dst.Kind() {
3207 case Int, Int8, Int16, Int32, Int64:
3208 return cvtFloatInt
3209 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3210 return cvtFloatUint
3211 case Float32, Float64:
3212 return cvtFloat
3213 }
3214
3215 case Complex64, Complex128:
3216 switch dst.Kind() {
3217 case Complex64, Complex128:
3218 return cvtComplex
3219 }
3220
3221 case String:
3222 if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
3223 switch dst.Elem().Kind() {
3224 case Uint8:
3225 return cvtStringBytes
3226 case Int32:
3227 return cvtStringRunes
3228 }
3229 }
3230
3231 case Slice:
3232 if dst.Kind() == String && src.Elem().PkgPath() == "" {
3233 switch src.Elem().Kind() {
3234 case Uint8:
3235 return cvtBytesString
3236 case Int32:
3237 return cvtRunesString
3238 }
3239 }
3240
3241
3242 if dst.Kind() == Pointer && dst.Elem().Kind() == Array && src.Elem() == dst.Elem().Elem() {
3243 return cvtSliceArrayPtr
3244 }
3245
3246 case Chan:
3247 if dst.Kind() == Chan && specialChannelAssignability(dst, src) {
3248 return cvtDirect
3249 }
3250 }
3251
3252
3253 if haveIdenticalUnderlyingType(dst, src, false) {
3254 return cvtDirect
3255 }
3256
3257
3258 if dst.Kind() == Pointer && dst.Name() == "" &&
3259 src.Kind() == Pointer && src.Name() == "" &&
3260 haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common(), false) {
3261 return cvtDirect
3262 }
3263
3264 if implements(dst, src) {
3265 if src.Kind() == Interface {
3266 return cvtI2I
3267 }
3268 return cvtT2I
3269 }
3270
3271 return nil
3272 }
3273
3274
3275
3276 func makeInt(f flag, bits uint64, t Type) Value {
3277 typ := t.common()
3278 ptr := unsafe_New(typ)
3279 switch typ.size {
3280 case 1:
3281 *(*uint8)(ptr) = uint8(bits)
3282 case 2:
3283 *(*uint16)(ptr) = uint16(bits)
3284 case 4:
3285 *(*uint32)(ptr) = uint32(bits)
3286 case 8:
3287 *(*uint64)(ptr) = bits
3288 }
3289 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3290 }
3291
3292
3293
3294 func makeFloat(f flag, v float64, t Type) Value {
3295 typ := t.common()
3296 ptr := unsafe_New(typ)
3297 switch typ.size {
3298 case 4:
3299 *(*float32)(ptr) = float32(v)
3300 case 8:
3301 *(*float64)(ptr) = v
3302 }
3303 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3304 }
3305
3306
3307 func makeFloat32(f flag, v float32, t Type) Value {
3308 typ := t.common()
3309 ptr := unsafe_New(typ)
3310 *(*float32)(ptr) = v
3311 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3312 }
3313
3314
3315
3316 func makeComplex(f flag, v complex128, t Type) Value {
3317 typ := t.common()
3318 ptr := unsafe_New(typ)
3319 switch typ.size {
3320 case 8:
3321 *(*complex64)(ptr) = complex64(v)
3322 case 16:
3323 *(*complex128)(ptr) = v
3324 }
3325 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3326 }
3327
3328 func makeString(f flag, v string, t Type) Value {
3329 ret := New(t).Elem()
3330 ret.SetString(v)
3331 ret.flag = ret.flag&^flagAddr | f
3332 return ret
3333 }
3334
3335 func makeBytes(f flag, v []byte, t Type) Value {
3336 ret := New(t).Elem()
3337 ret.SetBytes(v)
3338 ret.flag = ret.flag&^flagAddr | f
3339 return ret
3340 }
3341
3342 func makeRunes(f flag, v []rune, t Type) Value {
3343 ret := New(t).Elem()
3344 ret.setRunes(v)
3345 ret.flag = ret.flag&^flagAddr | f
3346 return ret
3347 }
3348
3349
3350
3351
3352
3353
3354
3355 func cvtInt(v Value, t Type) Value {
3356 return makeInt(v.flag.ro(), uint64(v.Int()), t)
3357 }
3358
3359
3360 func cvtUint(v Value, t Type) Value {
3361 return makeInt(v.flag.ro(), v.Uint(), t)
3362 }
3363
3364
3365 func cvtFloatInt(v Value, t Type) Value {
3366 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
3367 }
3368
3369
3370 func cvtFloatUint(v Value, t Type) Value {
3371 return makeInt(v.flag.ro(), uint64(v.Float()), t)
3372 }
3373
3374
3375 func cvtIntFloat(v Value, t Type) Value {
3376 return makeFloat(v.flag.ro(), float64(v.Int()), t)
3377 }
3378
3379
3380 func cvtUintFloat(v Value, t Type) Value {
3381 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
3382 }
3383
3384
3385 func cvtFloat(v Value, t Type) Value {
3386 if v.Type().Kind() == Float32 && t.Kind() == Float32 {
3387
3388
3389
3390 return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
3391 }
3392 return makeFloat(v.flag.ro(), v.Float(), t)
3393 }
3394
3395
3396 func cvtComplex(v Value, t Type) Value {
3397 return makeComplex(v.flag.ro(), v.Complex(), t)
3398 }
3399
3400
3401 func cvtIntString(v Value, t Type) Value {
3402 s := "\uFFFD"
3403 if x := v.Int(); int64(rune(x)) == x {
3404 s = string(rune(x))
3405 }
3406 return makeString(v.flag.ro(), s, t)
3407 }
3408
3409
3410 func cvtUintString(v Value, t Type) Value {
3411 s := "\uFFFD"
3412 if x := v.Uint(); uint64(rune(x)) == x {
3413 s = string(rune(x))
3414 }
3415 return makeString(v.flag.ro(), s, t)
3416 }
3417
3418
3419 func cvtBytesString(v Value, t Type) Value {
3420 return makeString(v.flag.ro(), string(v.Bytes()), t)
3421 }
3422
3423
3424 func cvtStringBytes(v Value, t Type) Value {
3425 return makeBytes(v.flag.ro(), []byte(v.String()), t)
3426 }
3427
3428
3429 func cvtRunesString(v Value, t Type) Value {
3430 return makeString(v.flag.ro(), string(v.runes()), t)
3431 }
3432
3433
3434 func cvtStringRunes(v Value, t Type) Value {
3435 return makeRunes(v.flag.ro(), []rune(v.String()), t)
3436 }
3437
3438
3439 func cvtSliceArrayPtr(v Value, t Type) Value {
3440 n := t.Elem().Len()
3441 if n > v.Len() {
3442 panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to pointer to array with length " + itoa.Itoa(n))
3443 }
3444 h := (*unsafeheader.Slice)(v.ptr)
3445 return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
3446 }
3447
3448
3449 func cvtDirect(v Value, typ Type) Value {
3450 f := v.flag
3451 t := typ.common()
3452 ptr := v.ptr
3453 if f&flagAddr != 0 {
3454
3455 c := unsafe_New(t)
3456 typedmemmove(t, c, ptr)
3457 ptr = c
3458 f &^= flagAddr
3459 }
3460 return Value{t, ptr, v.flag.ro() | f}
3461 }
3462
3463
3464 func cvtT2I(v Value, typ Type) Value {
3465 target := unsafe_New(typ.common())
3466 x := valueInterface(v, false)
3467 if typ.NumMethod() == 0 {
3468 *(*any)(target) = x
3469 } else {
3470 ifaceE2I(typ.(*rtype), x, target)
3471 }
3472 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
3473 }
3474
3475
3476 func cvtI2I(v Value, typ Type) Value {
3477 if v.IsNil() {
3478 ret := Zero(typ)
3479 ret.flag |= v.flag.ro()
3480 return ret
3481 }
3482 return cvtT2I(v.Elem(), typ)
3483 }
3484
3485
3486 func chancap(ch unsafe.Pointer) int
3487 func chanclose(ch unsafe.Pointer)
3488 func chanlen(ch unsafe.Pointer) int
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
3500
3501
3502 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
3503
3504 func makechan(typ *rtype, size int) (ch unsafe.Pointer)
3505 func makemap(t *rtype, cap int) (m unsafe.Pointer)
3506
3507
3508 func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
3509
3510
3511 func mapaccess_faststr(t *rtype, m unsafe.Pointer, key string) (val unsafe.Pointer)
3512
3513
3514 func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
3515
3516
3517 func mapassign_faststr(t *rtype, m unsafe.Pointer, key string, val unsafe.Pointer)
3518
3519
3520 func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
3521
3522
3523 func mapdelete_faststr(t *rtype, m unsafe.Pointer, key string)
3524
3525
3526 func mapiterinit(t *rtype, m unsafe.Pointer, it *hiter)
3527
3528
3529 func mapiterkey(it *hiter) (key unsafe.Pointer)
3530
3531
3532 func mapiterelem(it *hiter) (elem unsafe.Pointer)
3533
3534
3535 func mapiternext(it *hiter)
3536
3537
3538 func maplen(m unsafe.Pointer) int
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566 func call(stackArgsType *rtype, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
3567
3568 func ifaceE2I(t *rtype, src any, dst unsafe.Pointer)
3569
3570
3571
3572
3573 func memmove(dst, src unsafe.Pointer, size uintptr)
3574
3575
3576
3577
3578 func typedmemmove(t *rtype, dst, src unsafe.Pointer)
3579
3580
3581
3582
3583
3584 func typedmemmovepartial(t *rtype, dst, src unsafe.Pointer, off, size uintptr)
3585
3586
3587
3588
3589 func typedmemclr(t *rtype, ptr unsafe.Pointer)
3590
3591
3592
3593
3594
3595 func typedmemclrpartial(t *rtype, ptr unsafe.Pointer, off, size uintptr)
3596
3597
3598
3599
3600
3601 func typedslicecopy(elemType *rtype, dst, src unsafeheader.Slice) int
3602
3603
3604 func typehash(t *rtype, p unsafe.Pointer, h uintptr) uintptr
3605
3606 func verifyNotInHeapPtr(p uintptr) bool
3607
3608
3609
3610
3611 func escapes(x any) {
3612 if dummy.b {
3613 dummy.x = x
3614 }
3615 }
3616
3617 var dummy struct {
3618 b bool
3619 x any
3620 }
3621
View as plain text