Source file
src/reflect/value.go
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
42 typ_ *abi.Type
43
44
45
46 ptr unsafe.Pointer
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 flag
63
64
65
66
67
68
69 }
70
71 type flag uintptr
72
73 const (
74 flagKindWidth = 5
75 flagKindMask flag = 1<<flagKindWidth - 1
76 flagStickyRO flag = 1 << 5
77 flagEmbedRO flag = 1 << 6
78 flagIndir flag = 1 << 7
79 flagAddr flag = 1 << 8
80 flagMethod flag = 1 << 9
81 flagMethodShift = 10
82 flagRO flag = flagStickyRO | flagEmbedRO
83 )
84
85 func (f flag) kind() Kind {
86 return Kind(f & flagKindMask)
87 }
88
89 func (f flag) ro() flag {
90 if f&flagRO != 0 {
91 return flagStickyRO
92 }
93 return 0
94 }
95
96
97
98
99 func (v Value) typ() *abi.Type {
100
101
102
103
104
105 return (*abi.Type)(abi.NoEscape(unsafe.Pointer(v.typ_)))
106 }
107
108
109
110
111 func (v Value) pointer() unsafe.Pointer {
112 if v.typ().Size() != goarch.PtrSize || !v.typ().Pointers() {
113 panic("can't call pointer on a non-pointer Value")
114 }
115 if v.flag&flagIndir != 0 {
116 return *(*unsafe.Pointer)(v.ptr)
117 }
118 return v.ptr
119 }
120
121
122 func packEface(v Value) any {
123 t := v.typ()
124 var i any
125 e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
126
127 switch {
128 case t.IfaceIndir():
129 if v.flag&flagIndir == 0 {
130 panic("bad indir")
131 }
132
133 ptr := v.ptr
134 if v.flag&flagAddr != 0 {
135 c := unsafe_New(t)
136 typedmemmove(t, c, ptr)
137 ptr = c
138 }
139 e.Data = ptr
140 case v.flag&flagIndir != 0:
141
142
143 e.Data = *(*unsafe.Pointer)(v.ptr)
144 default:
145
146 e.Data = v.ptr
147 }
148
149
150
151
152 e.Type = t
153 return i
154 }
155
156
157 func unpackEface(i any) Value {
158 e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
159
160 t := e.Type
161 if t == nil {
162 return Value{}
163 }
164 f := flag(t.Kind())
165 if t.IfaceIndir() {
166 f |= flagIndir
167 }
168 return Value{t, e.Data, f}
169 }
170
171
172
173
174 type ValueError struct {
175 Method string
176 Kind Kind
177 }
178
179 func (e *ValueError) Error() string {
180 if e.Kind == 0 {
181 return "reflect: call of " + e.Method + " on zero Value"
182 }
183 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
184 }
185
186
187 func valueMethodName() string {
188 var pc [5]uintptr
189 n := runtime.Callers(1, pc[:])
190 frames := runtime.CallersFrames(pc[:n])
191 var frame runtime.Frame
192 for more := true; more; {
193 const prefix = "reflect.Value."
194 frame, more = frames.Next()
195 name := frame.Function
196 if len(name) > len(prefix) && name[:len(prefix)] == prefix {
197 methodName := name[len(prefix):]
198 if len(methodName) > 0 && 'A' <= methodName[0] && methodName[0] <= 'Z' {
199 return name
200 }
201 }
202 }
203 return "unknown method"
204 }
205
206
207 type nonEmptyInterface struct {
208 itab *abi.ITab
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{ptrTo(v.typ()), 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 = rtypeOf(([]byte)(nil))
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() != abi.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() != abi.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() != abi.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 *abi.Type
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(toRType(targ)) {
440 panic("reflect: " + op + " using " + xt.String() + " as type " + stringFor(targ))
441 }
442 }
443 if !isSlice && isVariadic {
444
445 m := len(in) - n
446 slice := MakeSlice(toRType(t.In(n)), m, m)
447 elem := toRType(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", stringFor(&t.Type))
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 := toRType(t.In(i))
519
520
521
522 v = v.assignTo("reflect.Value.Call", &targ.t, 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.t, 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(toRType(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, add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
622
623
624
625
626 continue
627 }
628
629
630 if !tv.IfaceIndir() {
631
632
633 if steps[0].kind != abiStepPointer {
634 print("kind=", steps[0].kind, ", type=", stringFor(tv), "\n")
635 panic("mismatch between ABI description and types")
636 }
637 ret[i] = Value{tv, 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)
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, 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.InSlice() {
713 if typ.Size() == 0 {
714 in = append(in, Zero(toRType(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 typ.IfaceIndir() {
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 typ.IfaceIndir() {
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=", stringFor(typ), "\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.OutSlice() {
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 *abi.Type, t *funcType, fn unsafe.Pointer) {
876 i := methodIndex
877 if v.typ().Kind() == abi.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.Type
891 fn = unsafe.Pointer(&unsafe.Slice(&iface.itab.Fun[0], i+1)[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 !nameOffFor(v.typ(), m.Name).IsExported() {
901 panic("reflect: " + op + " of unexported method")
902 }
903 ifn := textOffFor(v.typ(), m.Ifn)
904 fn = unsafe.Pointer(&ifn)
905 t = (*funcType)(unsafe.Pointer(typeOffFor(v.typ(), 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() == abi.Interface {
917
918 iface := (*nonEmptyInterface)(v.ptr)
919 *(*unsafe.Pointer)(p) = iface.word
920 } else if v.flag&flagIndir != 0 && !t.IfaceIndir() {
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.InSlice() {
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() == abi.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
1180 func (v Value) Close() {
1181 v.mustBe(Chan)
1182 v.mustBeExported()
1183 tt := (*chanType)(unsafe.Pointer(v.typ()))
1184 if ChanDir(tt.Dir)&SendDir == 0 {
1185 panic("reflect: close of receive-only channel")
1186 }
1187
1188 chanclose(v.pointer())
1189 }
1190
1191
1192 func (v Value) CanComplex() bool {
1193 switch v.kind() {
1194 case Complex64, Complex128:
1195 return true
1196 default:
1197 return false
1198 }
1199 }
1200
1201
1202
1203 func (v Value) Complex() complex128 {
1204 k := v.kind()
1205 switch k {
1206 case Complex64:
1207 return complex128(*(*complex64)(v.ptr))
1208 case Complex128:
1209 return *(*complex128)(v.ptr)
1210 }
1211 panic(&ValueError{"reflect.Value.Complex", v.kind()})
1212 }
1213
1214
1215
1216
1217
1218 func (v Value) Elem() Value {
1219 k := v.kind()
1220 switch k {
1221 case Interface:
1222 var eface any
1223 if v.typ().NumMethod() == 0 {
1224 eface = *(*any)(v.ptr)
1225 } else {
1226 eface = (any)(*(*interface {
1227 M()
1228 })(v.ptr))
1229 }
1230 x := unpackEface(eface)
1231 if x.flag != 0 {
1232 x.flag |= v.flag.ro()
1233 }
1234 return x
1235 case Pointer:
1236 ptr := v.ptr
1237 if v.flag&flagIndir != 0 {
1238 if v.typ().IfaceIndir() {
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 if !verifyNotInHeapPtr(*(*uintptr)(ptr)) {
1250 panic("reflect: reflect.Value.Elem on an invalid notinheap pointer")
1251 }
1252 }
1253 ptr = *(*unsafe.Pointer)(ptr)
1254 }
1255
1256 if ptr == nil {
1257 return Value{}
1258 }
1259 tt := (*ptrType)(unsafe.Pointer(v.typ()))
1260 typ := tt.Elem
1261 fl := v.flag&flagRO | flagIndir | flagAddr
1262 fl |= flag(typ.Kind())
1263 return Value{typ, ptr, fl}
1264 }
1265 panic(&ValueError{"reflect.Value.Elem", v.kind()})
1266 }
1267
1268
1269
1270 func (v Value) Field(i int) Value {
1271 if v.kind() != Struct {
1272 panic(&ValueError{"reflect.Value.Field", v.kind()})
1273 }
1274 tt := (*structType)(unsafe.Pointer(v.typ()))
1275 if uint(i) >= uint(len(tt.Fields)) {
1276 panic("reflect: Field index out of range")
1277 }
1278 field := &tt.Fields[i]
1279 typ := field.Typ
1280
1281
1282 fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
1283
1284 if !field.Name.IsExported() {
1285 if field.Embedded() {
1286 fl |= flagEmbedRO
1287 } else {
1288 fl |= flagStickyRO
1289 }
1290 }
1291
1292
1293
1294
1295
1296 ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
1297 return Value{typ, ptr, fl}
1298 }
1299
1300
1301
1302
1303 func (v Value) FieldByIndex(index []int) Value {
1304 if len(index) == 1 {
1305 return v.Field(index[0])
1306 }
1307 v.mustBe(Struct)
1308 for i, x := range index {
1309 if i > 0 {
1310 if v.Kind() == Pointer && v.typ().Elem().Kind() == abi.Struct {
1311 if v.IsNil() {
1312 panic("reflect: indirection through nil pointer to embedded struct")
1313 }
1314 v = v.Elem()
1315 }
1316 }
1317 v = v.Field(x)
1318 }
1319 return v
1320 }
1321
1322
1323
1324
1325
1326 func (v Value) FieldByIndexErr(index []int) (Value, error) {
1327 if len(index) == 1 {
1328 return v.Field(index[0]), nil
1329 }
1330 v.mustBe(Struct)
1331 for i, x := range index {
1332 if i > 0 {
1333 if v.Kind() == Ptr && v.typ().Elem().Kind() == abi.Struct {
1334 if v.IsNil() {
1335 return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + nameFor(v.typ().Elem()))
1336 }
1337 v = v.Elem()
1338 }
1339 }
1340 v = v.Field(x)
1341 }
1342 return v, nil
1343 }
1344
1345
1346
1347
1348 func (v Value) FieldByName(name string) Value {
1349 v.mustBe(Struct)
1350 if f, ok := toRType(v.typ()).FieldByName(name); ok {
1351 return v.FieldByIndex(f.Index)
1352 }
1353 return Value{}
1354 }
1355
1356
1357
1358
1359
1360 func (v Value) FieldByNameFunc(match func(string) bool) Value {
1361 if f, ok := toRType(v.typ()).FieldByNameFunc(match); ok {
1362 return v.FieldByIndex(f.Index)
1363 }
1364 return Value{}
1365 }
1366
1367
1368 func (v Value) CanFloat() bool {
1369 switch v.kind() {
1370 case Float32, Float64:
1371 return true
1372 default:
1373 return false
1374 }
1375 }
1376
1377
1378
1379 func (v Value) Float() float64 {
1380 k := v.kind()
1381 switch k {
1382 case Float32:
1383 return float64(*(*float32)(v.ptr))
1384 case Float64:
1385 return *(*float64)(v.ptr)
1386 }
1387 panic(&ValueError{"reflect.Value.Float", v.kind()})
1388 }
1389
1390 var uint8Type = rtypeOf(uint8(0))
1391
1392
1393
1394 func (v Value) Index(i int) Value {
1395 switch v.kind() {
1396 case Array:
1397 tt := (*arrayType)(unsafe.Pointer(v.typ()))
1398 if uint(i) >= uint(tt.Len) {
1399 panic("reflect: array index out of range")
1400 }
1401 typ := tt.Elem
1402 offset := uintptr(i) * typ.Size()
1403
1404
1405
1406
1407
1408
1409 val := add(v.ptr, offset, "same as &v[i], i < tt.len")
1410 fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind())
1411 return Value{typ, val, fl}
1412
1413 case Slice:
1414
1415
1416 s := (*unsafeheader.Slice)(v.ptr)
1417 if uint(i) >= uint(s.Len) {
1418 panic("reflect: slice index out of range")
1419 }
1420 tt := (*sliceType)(unsafe.Pointer(v.typ()))
1421 typ := tt.Elem
1422 val := arrayAt(s.Data, i, typ.Size(), "i < s.Len")
1423 fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
1424 return Value{typ, val, fl}
1425
1426 case String:
1427 s := (*unsafeheader.String)(v.ptr)
1428 if uint(i) >= uint(s.Len) {
1429 panic("reflect: string index out of range")
1430 }
1431 p := arrayAt(s.Data, i, 1, "i < s.Len")
1432 fl := v.flag.ro() | flag(Uint8) | flagIndir
1433 return Value{uint8Type, p, fl}
1434 }
1435 panic(&ValueError{"reflect.Value.Index", v.kind()})
1436 }
1437
1438
1439 func (v Value) CanInt() bool {
1440 switch v.kind() {
1441 case Int, Int8, Int16, Int32, Int64:
1442 return true
1443 default:
1444 return false
1445 }
1446 }
1447
1448
1449
1450 func (v Value) Int() int64 {
1451 k := v.kind()
1452 p := v.ptr
1453 switch k {
1454 case Int:
1455 return int64(*(*int)(p))
1456 case Int8:
1457 return int64(*(*int8)(p))
1458 case Int16:
1459 return int64(*(*int16)(p))
1460 case Int32:
1461 return int64(*(*int32)(p))
1462 case Int64:
1463 return *(*int64)(p)
1464 }
1465 panic(&ValueError{"reflect.Value.Int", v.kind()})
1466 }
1467
1468
1469 func (v Value) CanInterface() bool {
1470 if v.flag == 0 {
1471 panic(&ValueError{"reflect.Value.CanInterface", Invalid})
1472 }
1473 return v.flag&flagRO == 0
1474 }
1475
1476
1477
1478
1479
1480
1481
1482
1483 func (v Value) Interface() (i any) {
1484 return valueInterface(v, true)
1485 }
1486
1487 func valueInterface(v Value, safe bool) any {
1488 if v.flag == 0 {
1489 panic(&ValueError{"reflect.Value.Interface", Invalid})
1490 }
1491 if safe && v.flag&flagRO != 0 {
1492
1493
1494
1495 panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
1496 }
1497 if v.flag&flagMethod != 0 {
1498 v = makeMethodValue("Interface", v)
1499 }
1500
1501 if v.kind() == Interface {
1502
1503
1504
1505 if v.NumMethod() == 0 {
1506 return *(*any)(v.ptr)
1507 }
1508 return *(*interface {
1509 M()
1510 })(v.ptr)
1511 }
1512
1513 return packEface(v)
1514 }
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525 func (v Value) InterfaceData() [2]uintptr {
1526 v.mustBe(Interface)
1527
1528 escapes(v.ptr)
1529
1530
1531
1532
1533
1534 return *(*[2]uintptr)(v.ptr)
1535 }
1536
1537
1538
1539
1540
1541
1542
1543
1544 func (v Value) IsNil() bool {
1545 k := v.kind()
1546 switch k {
1547 case Chan, Func, Map, Pointer, UnsafePointer:
1548 if v.flag&flagMethod != 0 {
1549 return false
1550 }
1551 ptr := v.ptr
1552 if v.flag&flagIndir != 0 {
1553 ptr = *(*unsafe.Pointer)(ptr)
1554 }
1555 return ptr == nil
1556 case Interface, Slice:
1557
1558
1559 return *(*unsafe.Pointer)(v.ptr) == nil
1560 }
1561 panic(&ValueError{"reflect.Value.IsNil", v.kind()})
1562 }
1563
1564
1565
1566
1567
1568
1569 func (v Value) IsValid() bool {
1570 return v.flag != 0
1571 }
1572
1573
1574
1575 func (v Value) IsZero() bool {
1576 switch v.kind() {
1577 case Bool:
1578 return !v.Bool()
1579 case Int, Int8, Int16, Int32, Int64:
1580 return v.Int() == 0
1581 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
1582 return v.Uint() == 0
1583 case Float32, Float64:
1584 return v.Float() == 0
1585 case Complex64, Complex128:
1586 return v.Complex() == 0
1587 case Array:
1588 if v.flag&flagIndir == 0 {
1589 return v.ptr == nil
1590 }
1591 typ := (*abi.ArrayType)(unsafe.Pointer(v.typ()))
1592
1593 if typ.Equal != nil && typ.Size() <= abi.ZeroValSize {
1594
1595
1596
1597 return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0]))
1598 }
1599 if typ.TFlag&abi.TFlagRegularMemory != 0 {
1600
1601
1602 return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
1603 }
1604 n := int(typ.Len)
1605 for i := 0; i < n; i++ {
1606 if !v.Index(i).IsZero() {
1607 return false
1608 }
1609 }
1610 return true
1611 case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
1612 return v.IsNil()
1613 case String:
1614 return v.Len() == 0
1615 case Struct:
1616 if v.flag&flagIndir == 0 {
1617 return v.ptr == nil
1618 }
1619 typ := (*abi.StructType)(unsafe.Pointer(v.typ()))
1620
1621 if typ.Equal != nil && typ.Size() <= abi.ZeroValSize {
1622
1623 return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0]))
1624 }
1625 if typ.TFlag&abi.TFlagRegularMemory != 0 {
1626
1627
1628 return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
1629 }
1630
1631 n := v.NumField()
1632 for i := 0; i < n; i++ {
1633 if !v.Field(i).IsZero() && v.Type().Field(i).Name != "_" {
1634 return false
1635 }
1636 }
1637 return true
1638 default:
1639
1640
1641 panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
1642 }
1643 }
1644
1645
1646
1647 func isZero(b []byte) bool {
1648 if len(b) == 0 {
1649 return true
1650 }
1651 const n = 32
1652
1653 for uintptr(unsafe.Pointer(&b[0]))%8 != 0 {
1654 if b[0] != 0 {
1655 return false
1656 }
1657 b = b[1:]
1658 if len(b) == 0 {
1659 return true
1660 }
1661 }
1662 for len(b)%8 != 0 {
1663 if b[len(b)-1] != 0 {
1664 return false
1665 }
1666 b = b[:len(b)-1]
1667 }
1668 if len(b) == 0 {
1669 return true
1670 }
1671 w := unsafe.Slice((*uint64)(unsafe.Pointer(&b[0])), len(b)/8)
1672 for len(w)%n != 0 {
1673 if w[0] != 0 {
1674 return false
1675 }
1676 w = w[1:]
1677 }
1678 for len(w) >= n {
1679 if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 ||
1680 w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 ||
1681 w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 ||
1682 w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 ||
1683 w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 ||
1684 w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 ||
1685 w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 ||
1686 w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 {
1687 return false
1688 }
1689 w = w[n:]
1690 }
1691 return true
1692 }
1693
1694
1695
1696 func (v Value) SetZero() {
1697 v.mustBeAssignable()
1698 switch v.kind() {
1699 case Bool:
1700 *(*bool)(v.ptr) = false
1701 case Int:
1702 *(*int)(v.ptr) = 0
1703 case Int8:
1704 *(*int8)(v.ptr) = 0
1705 case Int16:
1706 *(*int16)(v.ptr) = 0
1707 case Int32:
1708 *(*int32)(v.ptr) = 0
1709 case Int64:
1710 *(*int64)(v.ptr) = 0
1711 case Uint:
1712 *(*uint)(v.ptr) = 0
1713 case Uint8:
1714 *(*uint8)(v.ptr) = 0
1715 case Uint16:
1716 *(*uint16)(v.ptr) = 0
1717 case Uint32:
1718 *(*uint32)(v.ptr) = 0
1719 case Uint64:
1720 *(*uint64)(v.ptr) = 0
1721 case Uintptr:
1722 *(*uintptr)(v.ptr) = 0
1723 case Float32:
1724 *(*float32)(v.ptr) = 0
1725 case Float64:
1726 *(*float64)(v.ptr) = 0
1727 case Complex64:
1728 *(*complex64)(v.ptr) = 0
1729 case Complex128:
1730 *(*complex128)(v.ptr) = 0
1731 case String:
1732 *(*string)(v.ptr) = ""
1733 case Slice:
1734 *(*unsafeheader.Slice)(v.ptr) = unsafeheader.Slice{}
1735 case Interface:
1736 *(*abi.EmptyInterface)(v.ptr) = abi.EmptyInterface{}
1737 case Chan, Func, Map, Pointer, UnsafePointer:
1738 *(*unsafe.Pointer)(v.ptr) = nil
1739 case Array, Struct:
1740 typedmemclr(v.typ(), v.ptr)
1741 default:
1742
1743
1744 panic(&ValueError{"reflect.Value.SetZero", v.Kind()})
1745 }
1746 }
1747
1748
1749
1750 func (v Value) Kind() Kind {
1751 return v.kind()
1752 }
1753
1754
1755
1756 func (v Value) Len() int {
1757
1758 if v.kind() == Slice {
1759 return (*unsafeheader.Slice)(v.ptr).Len
1760 }
1761 return v.lenNonSlice()
1762 }
1763
1764 func (v Value) lenNonSlice() int {
1765 switch k := v.kind(); k {
1766 case Array:
1767 tt := (*arrayType)(unsafe.Pointer(v.typ()))
1768 return int(tt.Len)
1769 case Chan:
1770 return chanlen(v.pointer())
1771 case Map:
1772 return maplen(v.pointer())
1773 case String:
1774
1775 return (*unsafeheader.String)(v.ptr).Len
1776 case Ptr:
1777 if v.typ().Elem().Kind() == abi.Array {
1778 return v.typ().Elem().Len()
1779 }
1780 panic("reflect: call of reflect.Value.Len on ptr to non-array Value")
1781 }
1782 panic(&ValueError{"reflect.Value.Len", v.kind()})
1783 }
1784
1785
1786
1787 func copyVal(typ *abi.Type, fl flag, ptr unsafe.Pointer) Value {
1788 if typ.IfaceIndir() {
1789
1790
1791 c := unsafe_New(typ)
1792 typedmemmove(typ, c, ptr)
1793 return Value{typ, c, fl | flagIndir}
1794 }
1795 return Value{typ, *(*unsafe.Pointer)(ptr), fl}
1796 }
1797
1798
1799
1800
1801
1802 func (v Value) Method(i int) Value {
1803 if v.typ() == nil {
1804 panic(&ValueError{"reflect.Value.Method", Invalid})
1805 }
1806 if v.flag&flagMethod != 0 || uint(i) >= uint(toRType(v.typ()).NumMethod()) {
1807 panic("reflect: Method index out of range")
1808 }
1809 if v.typ().Kind() == abi.Interface && v.IsNil() {
1810 panic("reflect: Method on nil interface value")
1811 }
1812 fl := v.flag.ro() | (v.flag & flagIndir)
1813 fl |= flag(Func)
1814 fl |= flag(i)<<flagMethodShift | flagMethod
1815 return Value{v.typ(), v.ptr, fl}
1816 }
1817
1818
1819
1820
1821
1822
1823 func (v Value) NumMethod() int {
1824 if v.typ() == nil {
1825 panic(&ValueError{"reflect.Value.NumMethod", Invalid})
1826 }
1827 if v.flag&flagMethod != 0 {
1828 return 0
1829 }
1830 return toRType(v.typ()).NumMethod()
1831 }
1832
1833
1834
1835
1836
1837
1838 func (v Value) MethodByName(name string) Value {
1839 if v.typ() == nil {
1840 panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1841 }
1842 if v.flag&flagMethod != 0 {
1843 return Value{}
1844 }
1845 m, ok := toRType(v.typ()).MethodByName(name)
1846 if !ok {
1847 return Value{}
1848 }
1849 return v.Method(m.Index)
1850 }
1851
1852
1853
1854 func (v Value) NumField() int {
1855 v.mustBe(Struct)
1856 tt := (*structType)(unsafe.Pointer(v.typ()))
1857 return len(tt.Fields)
1858 }
1859
1860
1861
1862 func (v Value) OverflowComplex(x complex128) bool {
1863 k := v.kind()
1864 switch k {
1865 case Complex64:
1866 return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1867 case Complex128:
1868 return false
1869 }
1870 panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
1871 }
1872
1873
1874
1875 func (v Value) OverflowFloat(x float64) bool {
1876 k := v.kind()
1877 switch k {
1878 case Float32:
1879 return overflowFloat32(x)
1880 case Float64:
1881 return false
1882 }
1883 panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
1884 }
1885
1886 func overflowFloat32(x float64) bool {
1887 if x < 0 {
1888 x = -x
1889 }
1890 return math.MaxFloat32 < x && x <= math.MaxFloat64
1891 }
1892
1893
1894
1895 func (v Value) OverflowInt(x int64) bool {
1896 k := v.kind()
1897 switch k {
1898 case Int, Int8, Int16, Int32, Int64:
1899 bitSize := v.typ().Size() * 8
1900 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1901 return x != trunc
1902 }
1903 panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
1904 }
1905
1906
1907
1908 func (v Value) OverflowUint(x uint64) bool {
1909 k := v.kind()
1910 switch k {
1911 case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
1912 bitSize := v.typ_.Size() * 8
1913 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
1914 return x != trunc
1915 }
1916 panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
1917 }
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940 func (v Value) Pointer() uintptr {
1941
1942 escapes(v.ptr)
1943
1944 k := v.kind()
1945 switch k {
1946 case Pointer:
1947 if !v.typ().Pointers() {
1948 val := *(*uintptr)(v.ptr)
1949
1950
1951 if !verifyNotInHeapPtr(val) {
1952 panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
1953 }
1954 return val
1955 }
1956 fallthrough
1957 case Chan, Map, UnsafePointer:
1958 return uintptr(v.pointer())
1959 case Func:
1960 if v.flag&flagMethod != 0 {
1961
1962
1963
1964
1965
1966
1967 return methodValueCallCodePtr()
1968 }
1969 p := v.pointer()
1970
1971
1972 if p != nil {
1973 p = *(*unsafe.Pointer)(p)
1974 }
1975 return uintptr(p)
1976 case Slice:
1977 return uintptr((*unsafeheader.Slice)(v.ptr).Data)
1978 case String:
1979 return uintptr((*unsafeheader.String)(v.ptr).Data)
1980 }
1981 panic(&ValueError{"reflect.Value.Pointer", v.kind()})
1982 }
1983
1984
1985
1986
1987
1988
1989 func (v Value) Recv() (x Value, ok bool) {
1990 v.mustBe(Chan)
1991 v.mustBeExported()
1992 return v.recv(false)
1993 }
1994
1995
1996
1997 func (v Value) recv(nb bool) (val Value, ok bool) {
1998 tt := (*chanType)(unsafe.Pointer(v.typ()))
1999 if ChanDir(tt.Dir)&RecvDir == 0 {
2000 panic("reflect: recv on send-only channel")
2001 }
2002 t := tt.Elem
2003 val = Value{t, nil, flag(t.Kind())}
2004 var p unsafe.Pointer
2005 if t.IfaceIndir() {
2006 p = unsafe_New(t)
2007 val.ptr = p
2008 val.flag |= flagIndir
2009 } else {
2010 p = unsafe.Pointer(&val.ptr)
2011 }
2012 selected, ok := chanrecv(v.pointer(), nb, p)
2013 if !selected {
2014 val = Value{}
2015 }
2016 return
2017 }
2018
2019
2020
2021
2022 func (v Value) Send(x Value) {
2023 v.mustBe(Chan)
2024 v.mustBeExported()
2025 v.send(x, false)
2026 }
2027
2028
2029
2030 func (v Value) send(x Value, nb bool) (selected bool) {
2031 tt := (*chanType)(unsafe.Pointer(v.typ()))
2032 if ChanDir(tt.Dir)&SendDir == 0 {
2033 panic("reflect: send on recv-only channel")
2034 }
2035 x.mustBeExported()
2036 x = x.assignTo("reflect.Value.Send", tt.Elem, nil)
2037 var p unsafe.Pointer
2038 if x.flag&flagIndir != 0 {
2039 p = x.ptr
2040 } else {
2041 p = unsafe.Pointer(&x.ptr)
2042 }
2043 return chansend(v.pointer(), p, nb)
2044 }
2045
2046
2047
2048
2049
2050 func (v Value) Set(x Value) {
2051 v.mustBeAssignable()
2052 x.mustBeExported()
2053 var target unsafe.Pointer
2054 if v.kind() == Interface {
2055 target = v.ptr
2056 }
2057 x = x.assignTo("reflect.Set", v.typ(), target)
2058 if x.flag&flagIndir != 0 {
2059 if x.ptr == unsafe.Pointer(&zeroVal[0]) {
2060 typedmemclr(v.typ(), v.ptr)
2061 } else {
2062 typedmemmove(v.typ(), v.ptr, x.ptr)
2063 }
2064 } else {
2065 *(*unsafe.Pointer)(v.ptr) = x.ptr
2066 }
2067 }
2068
2069
2070
2071 func (v Value) SetBool(x bool) {
2072 v.mustBeAssignable()
2073 v.mustBe(Bool)
2074 *(*bool)(v.ptr) = x
2075 }
2076
2077
2078
2079
2080 func (v Value) SetBytes(x []byte) {
2081 v.mustBeAssignable()
2082 v.mustBe(Slice)
2083 if toRType(v.typ()).Elem().Kind() != Uint8 {
2084 panic("reflect.Value.SetBytes of non-byte slice")
2085 }
2086 *(*[]byte)(v.ptr) = x
2087 }
2088
2089
2090
2091
2092 func (v Value) setRunes(x []rune) {
2093 v.mustBeAssignable()
2094 v.mustBe(Slice)
2095 if v.typ().Elem().Kind() != abi.Int32 {
2096 panic("reflect.Value.setRunes of non-rune slice")
2097 }
2098 *(*[]rune)(v.ptr) = x
2099 }
2100
2101
2102
2103
2104 func (v Value) SetComplex(x complex128) {
2105 v.mustBeAssignable()
2106 switch k := v.kind(); k {
2107 default:
2108 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
2109 case Complex64:
2110 *(*complex64)(v.ptr) = complex64(x)
2111 case Complex128:
2112 *(*complex128)(v.ptr) = x
2113 }
2114 }
2115
2116
2117
2118
2119 func (v Value) SetFloat(x float64) {
2120 v.mustBeAssignable()
2121 switch k := v.kind(); k {
2122 default:
2123 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
2124 case Float32:
2125 *(*float32)(v.ptr) = float32(x)
2126 case Float64:
2127 *(*float64)(v.ptr) = x
2128 }
2129 }
2130
2131
2132
2133
2134 func (v Value) SetInt(x int64) {
2135 v.mustBeAssignable()
2136 switch k := v.kind(); k {
2137 default:
2138 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
2139 case Int:
2140 *(*int)(v.ptr) = int(x)
2141 case Int8:
2142 *(*int8)(v.ptr) = int8(x)
2143 case Int16:
2144 *(*int16)(v.ptr) = int16(x)
2145 case Int32:
2146 *(*int32)(v.ptr) = int32(x)
2147 case Int64:
2148 *(*int64)(v.ptr) = x
2149 }
2150 }
2151
2152
2153
2154
2155
2156 func (v Value) SetLen(n int) {
2157 v.mustBeAssignable()
2158 v.mustBe(Slice)
2159 s := (*unsafeheader.Slice)(v.ptr)
2160 if uint(n) > uint(s.Cap) {
2161 panic("reflect: slice length out of range in SetLen")
2162 }
2163 s.Len = n
2164 }
2165
2166
2167
2168
2169
2170 func (v Value) SetCap(n int) {
2171 v.mustBeAssignable()
2172 v.mustBe(Slice)
2173 s := (*unsafeheader.Slice)(v.ptr)
2174 if n < s.Len || n > s.Cap {
2175 panic("reflect: slice capacity out of range in SetCap")
2176 }
2177 s.Cap = n
2178 }
2179
2180
2181
2182
2183 func (v Value) SetUint(x uint64) {
2184 v.mustBeAssignable()
2185 switch k := v.kind(); k {
2186 default:
2187 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
2188 case Uint:
2189 *(*uint)(v.ptr) = uint(x)
2190 case Uint8:
2191 *(*uint8)(v.ptr) = uint8(x)
2192 case Uint16:
2193 *(*uint16)(v.ptr) = uint16(x)
2194 case Uint32:
2195 *(*uint32)(v.ptr) = uint32(x)
2196 case Uint64:
2197 *(*uint64)(v.ptr) = x
2198 case Uintptr:
2199 *(*uintptr)(v.ptr) = uintptr(x)
2200 }
2201 }
2202
2203
2204
2205
2206 func (v Value) SetPointer(x unsafe.Pointer) {
2207 v.mustBeAssignable()
2208 v.mustBe(UnsafePointer)
2209 *(*unsafe.Pointer)(v.ptr) = x
2210 }
2211
2212
2213
2214 func (v Value) SetString(x string) {
2215 v.mustBeAssignable()
2216 v.mustBe(String)
2217 *(*string)(v.ptr) = x
2218 }
2219
2220
2221
2222
2223 func (v Value) Slice(i, j int) Value {
2224 var (
2225 cap int
2226 typ *sliceType
2227 base unsafe.Pointer
2228 )
2229 switch kind := v.kind(); kind {
2230 default:
2231 panic(&ValueError{"reflect.Value.Slice", v.kind()})
2232
2233 case Array:
2234 if v.flag&flagAddr == 0 {
2235 panic("reflect.Value.Slice: slice of unaddressable array")
2236 }
2237 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2238 cap = int(tt.Len)
2239 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2240 base = v.ptr
2241
2242 case Slice:
2243 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2244 s := (*unsafeheader.Slice)(v.ptr)
2245 base = s.Data
2246 cap = s.Cap
2247
2248 case String:
2249 s := (*unsafeheader.String)(v.ptr)
2250 if i < 0 || j < i || j > s.Len {
2251 panic("reflect.Value.Slice: string slice index out of bounds")
2252 }
2253 var t unsafeheader.String
2254 if i < s.Len {
2255 t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
2256 }
2257 return Value{v.typ(), unsafe.Pointer(&t), v.flag}
2258 }
2259
2260 if i < 0 || j < i || j > cap {
2261 panic("reflect.Value.Slice: slice index out of bounds")
2262 }
2263
2264
2265 var x []unsafe.Pointer
2266
2267
2268 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2269 s.Len = j - i
2270 s.Cap = cap - i
2271 if cap-i > 0 {
2272 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < cap")
2273 } else {
2274
2275 s.Data = base
2276 }
2277
2278 fl := v.flag.ro() | flagIndir | flag(Slice)
2279 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2280 }
2281
2282
2283
2284
2285 func (v Value) Slice3(i, j, k int) Value {
2286 var (
2287 cap int
2288 typ *sliceType
2289 base unsafe.Pointer
2290 )
2291 switch kind := v.kind(); kind {
2292 default:
2293 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
2294
2295 case Array:
2296 if v.flag&flagAddr == 0 {
2297 panic("reflect.Value.Slice3: slice of unaddressable array")
2298 }
2299 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2300 cap = int(tt.Len)
2301 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2302 base = v.ptr
2303
2304 case Slice:
2305 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2306 s := (*unsafeheader.Slice)(v.ptr)
2307 base = s.Data
2308 cap = s.Cap
2309 }
2310
2311 if i < 0 || j < i || k < j || k > cap {
2312 panic("reflect.Value.Slice3: slice index out of bounds")
2313 }
2314
2315
2316
2317 var x []unsafe.Pointer
2318
2319
2320 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2321 s.Len = j - i
2322 s.Cap = k - i
2323 if k-i > 0 {
2324 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < k <= cap")
2325 } else {
2326
2327 s.Data = base
2328 }
2329
2330 fl := v.flag.ro() | flagIndir | flag(Slice)
2331 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2332 }
2333
2334
2335
2336
2337
2338
2339
2340 func (v Value) String() string {
2341
2342 if v.kind() == String {
2343 return *(*string)(v.ptr)
2344 }
2345 return v.stringNonString()
2346 }
2347
2348 func (v Value) stringNonString() string {
2349 if v.kind() == Invalid {
2350 return "<invalid Value>"
2351 }
2352
2353
2354 return "<" + v.Type().String() + " Value>"
2355 }
2356
2357
2358
2359
2360
2361
2362 func (v Value) TryRecv() (x Value, ok bool) {
2363 v.mustBe(Chan)
2364 v.mustBeExported()
2365 return v.recv(true)
2366 }
2367
2368
2369
2370
2371
2372 func (v Value) TrySend(x Value) bool {
2373 v.mustBe(Chan)
2374 v.mustBeExported()
2375 return v.send(x, true)
2376 }
2377
2378
2379 func (v Value) Type() Type {
2380 if v.flag != 0 && v.flag&flagMethod == 0 {
2381 return (*rtype)(abi.NoEscape(unsafe.Pointer(v.typ_)))
2382 }
2383 return v.typeSlow()
2384 }
2385
2386
2387 func (v Value) typeSlow() Type {
2388 return toRType(v.abiTypeSlow())
2389 }
2390
2391 func (v Value) abiType() *abi.Type {
2392 if v.flag != 0 && v.flag&flagMethod == 0 {
2393 return v.typ()
2394 }
2395 return v.abiTypeSlow()
2396 }
2397
2398 func (v Value) abiTypeSlow() *abi.Type {
2399 if v.flag == 0 {
2400 panic(&ValueError{"reflect.Value.Type", Invalid})
2401 }
2402
2403 typ := v.typ()
2404 if v.flag&flagMethod == 0 {
2405 return v.typ()
2406 }
2407
2408
2409
2410 i := int(v.flag) >> flagMethodShift
2411 if v.typ().Kind() == abi.Interface {
2412
2413 tt := (*interfaceType)(unsafe.Pointer(typ))
2414 if uint(i) >= uint(len(tt.Methods)) {
2415 panic("reflect: internal error: invalid method index")
2416 }
2417 m := &tt.Methods[i]
2418 return typeOffFor(typ, m.Typ)
2419 }
2420
2421 ms := typ.ExportedMethods()
2422 if uint(i) >= uint(len(ms)) {
2423 panic("reflect: internal error: invalid method index")
2424 }
2425 m := ms[i]
2426 return typeOffFor(typ, m.Mtyp)
2427 }
2428
2429
2430 func (v Value) CanUint() bool {
2431 switch v.kind() {
2432 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2433 return true
2434 default:
2435 return false
2436 }
2437 }
2438
2439
2440
2441 func (v Value) Uint() uint64 {
2442 k := v.kind()
2443 p := v.ptr
2444 switch k {
2445 case Uint:
2446 return uint64(*(*uint)(p))
2447 case Uint8:
2448 return uint64(*(*uint8)(p))
2449 case Uint16:
2450 return uint64(*(*uint16)(p))
2451 case Uint32:
2452 return uint64(*(*uint32)(p))
2453 case Uint64:
2454 return *(*uint64)(p)
2455 case Uintptr:
2456 return uint64(*(*uintptr)(p))
2457 }
2458 panic(&ValueError{"reflect.Value.Uint", v.kind()})
2459 }
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470 func (v Value) UnsafeAddr() uintptr {
2471 if v.typ() == nil {
2472 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
2473 }
2474 if v.flag&flagAddr == 0 {
2475 panic("reflect.Value.UnsafeAddr of unaddressable value")
2476 }
2477
2478 escapes(v.ptr)
2479 return uintptr(v.ptr)
2480 }
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496 func (v Value) UnsafePointer() unsafe.Pointer {
2497 k := v.kind()
2498 switch k {
2499 case Pointer:
2500 if !v.typ().Pointers() {
2501
2502
2503 if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
2504 panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
2505 }
2506 return *(*unsafe.Pointer)(v.ptr)
2507 }
2508 fallthrough
2509 case Chan, Map, UnsafePointer:
2510 return v.pointer()
2511 case Func:
2512 if v.flag&flagMethod != 0 {
2513
2514
2515
2516
2517
2518
2519 code := methodValueCallCodePtr()
2520 return *(*unsafe.Pointer)(unsafe.Pointer(&code))
2521 }
2522 p := v.pointer()
2523
2524
2525 if p != nil {
2526 p = *(*unsafe.Pointer)(p)
2527 }
2528 return p
2529 case Slice:
2530 return (*unsafeheader.Slice)(v.ptr).Data
2531 case String:
2532 return (*unsafeheader.String)(v.ptr).Data
2533 }
2534 panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
2535 }
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545 type StringHeader struct {
2546 Data uintptr
2547 Len int
2548 }
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558 type SliceHeader struct {
2559 Data uintptr
2560 Len int
2561 Cap int
2562 }
2563
2564 func typesMustMatch(what string, t1, t2 Type) {
2565 if t1 != t2 {
2566 panic(what + ": " + t1.String() + " != " + t2.String())
2567 }
2568 }
2569
2570
2571
2572
2573
2574
2575
2576
2577 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
2578 return add(p, uintptr(i)*eltSize, "i < len")
2579 }
2580
2581
2582
2583
2584
2585
2586
2587 func (v Value) Grow(n int) {
2588 v.mustBeAssignable()
2589 v.mustBe(Slice)
2590 v.grow(n)
2591 }
2592
2593
2594 func (v Value) grow(n int) {
2595 p := (*unsafeheader.Slice)(v.ptr)
2596 switch {
2597 case n < 0:
2598 panic("reflect.Value.Grow: negative len")
2599 case p.Len+n < 0:
2600 panic("reflect.Value.Grow: slice overflow")
2601 case p.Len+n > p.Cap:
2602 t := v.typ().Elem()
2603 *p = growslice(t, *p, n)
2604 }
2605 }
2606
2607
2608
2609
2610
2611
2612
2613 func (v Value) extendSlice(n int) Value {
2614 v.mustBeExported()
2615 v.mustBe(Slice)
2616
2617
2618 sh := *(*unsafeheader.Slice)(v.ptr)
2619 s := &sh
2620 v.ptr = unsafe.Pointer(s)
2621 v.flag = flagIndir | flag(Slice)
2622
2623 v.grow(n)
2624 s.Len += n
2625 return v
2626 }
2627
2628
2629
2630
2631 func (v Value) Clear() {
2632 switch v.Kind() {
2633 case Slice:
2634 sh := *(*unsafeheader.Slice)(v.ptr)
2635 st := (*sliceType)(unsafe.Pointer(v.typ()))
2636 typedarrayclear(st.Elem, sh.Data, sh.Len)
2637 case Map:
2638 mapclear(v.typ(), v.pointer())
2639 default:
2640 panic(&ValueError{"reflect.Value.Clear", v.Kind()})
2641 }
2642 }
2643
2644
2645
2646 func Append(s Value, x ...Value) Value {
2647 s.mustBe(Slice)
2648 n := s.Len()
2649 s = s.extendSlice(len(x))
2650 for i, v := range x {
2651 s.Index(n + i).Set(v)
2652 }
2653 return s
2654 }
2655
2656
2657
2658 func AppendSlice(s, t Value) Value {
2659 s.mustBe(Slice)
2660 t.mustBe(Slice)
2661 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
2662 ns := s.Len()
2663 nt := t.Len()
2664 s = s.extendSlice(nt)
2665 Copy(s.Slice(ns, ns+nt), t)
2666 return s
2667 }
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677 func Copy(dst, src Value) int {
2678 dk := dst.kind()
2679 if dk != Array && dk != Slice {
2680 panic(&ValueError{"reflect.Copy", dk})
2681 }
2682 if dk == Array {
2683 dst.mustBeAssignable()
2684 }
2685 dst.mustBeExported()
2686
2687 sk := src.kind()
2688 var stringCopy bool
2689 if sk != Array && sk != Slice {
2690 stringCopy = sk == String && dst.typ().Elem().Kind() == abi.Uint8
2691 if !stringCopy {
2692 panic(&ValueError{"reflect.Copy", sk})
2693 }
2694 }
2695 src.mustBeExported()
2696
2697 de := dst.typ().Elem()
2698 if !stringCopy {
2699 se := src.typ().Elem()
2700 typesMustMatch("reflect.Copy", toType(de), toType(se))
2701 }
2702
2703 var ds, ss unsafeheader.Slice
2704 if dk == Array {
2705 ds.Data = dst.ptr
2706 ds.Len = dst.Len()
2707 ds.Cap = ds.Len
2708 } else {
2709 ds = *(*unsafeheader.Slice)(dst.ptr)
2710 }
2711 if sk == Array {
2712 ss.Data = src.ptr
2713 ss.Len = src.Len()
2714 ss.Cap = ss.Len
2715 } else if sk == Slice {
2716 ss = *(*unsafeheader.Slice)(src.ptr)
2717 } else {
2718 sh := *(*unsafeheader.String)(src.ptr)
2719 ss.Data = sh.Data
2720 ss.Len = sh.Len
2721 ss.Cap = sh.Len
2722 }
2723
2724 return typedslicecopy(de.Common(), ds, ss)
2725 }
2726
2727
2728
2729 type runtimeSelect struct {
2730 dir SelectDir
2731 typ *rtype
2732 ch unsafe.Pointer
2733 val unsafe.Pointer
2734 }
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747 func rselect([]runtimeSelect) (chosen int, recvOK bool)
2748
2749
2750 type SelectDir int
2751
2752
2753
2754 const (
2755 _ SelectDir = iota
2756 SelectSend
2757 SelectRecv
2758 SelectDefault
2759 )
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777 type SelectCase struct {
2778 Dir SelectDir
2779 Chan Value
2780 Send Value
2781 }
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
2792 if len(cases) > 65536 {
2793 panic("reflect.Select: too many cases (max 65536)")
2794 }
2795
2796
2797
2798 var runcases []runtimeSelect
2799 if len(cases) > 4 {
2800
2801 runcases = make([]runtimeSelect, len(cases))
2802 } else {
2803
2804 runcases = make([]runtimeSelect, len(cases), 4)
2805 }
2806
2807 haveDefault := false
2808 for i, c := range cases {
2809 rc := &runcases[i]
2810 rc.dir = c.Dir
2811 switch c.Dir {
2812 default:
2813 panic("reflect.Select: invalid Dir")
2814
2815 case SelectDefault:
2816 if haveDefault {
2817 panic("reflect.Select: multiple default cases")
2818 }
2819 haveDefault = true
2820 if c.Chan.IsValid() {
2821 panic("reflect.Select: default case has Chan value")
2822 }
2823 if c.Send.IsValid() {
2824 panic("reflect.Select: default case has Send value")
2825 }
2826
2827 case SelectSend:
2828 ch := c.Chan
2829 if !ch.IsValid() {
2830 break
2831 }
2832 ch.mustBe(Chan)
2833 ch.mustBeExported()
2834 tt := (*chanType)(unsafe.Pointer(ch.typ()))
2835 if ChanDir(tt.Dir)&SendDir == 0 {
2836 panic("reflect.Select: SendDir case using recv-only channel")
2837 }
2838 rc.ch = ch.pointer()
2839 rc.typ = toRType(&tt.Type)
2840 v := c.Send
2841 if !v.IsValid() {
2842 panic("reflect.Select: SendDir case missing Send value")
2843 }
2844 v.mustBeExported()
2845 v = v.assignTo("reflect.Select", tt.Elem, nil)
2846 if v.flag&flagIndir != 0 {
2847 rc.val = v.ptr
2848 } else {
2849 rc.val = unsafe.Pointer(&v.ptr)
2850 }
2851
2852
2853 escapes(rc.val)
2854
2855 case SelectRecv:
2856 if c.Send.IsValid() {
2857 panic("reflect.Select: RecvDir case has Send value")
2858 }
2859 ch := c.Chan
2860 if !ch.IsValid() {
2861 break
2862 }
2863 ch.mustBe(Chan)
2864 ch.mustBeExported()
2865 tt := (*chanType)(unsafe.Pointer(ch.typ()))
2866 if ChanDir(tt.Dir)&RecvDir == 0 {
2867 panic("reflect.Select: RecvDir case using send-only channel")
2868 }
2869 rc.ch = ch.pointer()
2870 rc.typ = toRType(&tt.Type)
2871 rc.val = unsafe_New(tt.Elem)
2872 }
2873 }
2874
2875 chosen, recvOK = rselect(runcases)
2876 if runcases[chosen].dir == SelectRecv {
2877 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
2878 t := tt.Elem
2879 p := runcases[chosen].val
2880 fl := flag(t.Kind())
2881 if t.IfaceIndir() {
2882 recv = Value{t, p, fl | flagIndir}
2883 } else {
2884 recv = Value{t, *(*unsafe.Pointer)(p), fl}
2885 }
2886 }
2887 return chosen, recv, recvOK
2888 }
2889
2890
2893
2894
2895
2896
2897 func unsafe_New(*abi.Type) unsafe.Pointer
2898
2899
2900 func unsafe_NewArray(*abi.Type, int) unsafe.Pointer
2901
2902
2903
2904 func MakeSlice(typ Type, len, cap int) Value {
2905 if typ.Kind() != Slice {
2906 panic("reflect.MakeSlice of non-slice type")
2907 }
2908 if len < 0 {
2909 panic("reflect.MakeSlice: negative len")
2910 }
2911 if cap < 0 {
2912 panic("reflect.MakeSlice: negative cap")
2913 }
2914 if len > cap {
2915 panic("reflect.MakeSlice: len > cap")
2916 }
2917
2918 s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
2919 return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
2920 }
2921
2922
2923
2924
2925
2926 func SliceAt(typ Type, p unsafe.Pointer, n int) Value {
2927 unsafeslice(typ.common(), p, n)
2928 s := unsafeheader.Slice{Data: p, Len: n, Cap: n}
2929 return Value{SliceOf(typ).common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
2930 }
2931
2932
2933 func MakeChan(typ Type, buffer int) Value {
2934 if typ.Kind() != Chan {
2935 panic("reflect.MakeChan of non-chan type")
2936 }
2937 if buffer < 0 {
2938 panic("reflect.MakeChan: negative buffer size")
2939 }
2940 if typ.ChanDir() != BothDir {
2941 panic("reflect.MakeChan: unidirectional channel type")
2942 }
2943 t := typ.common()
2944 ch := makechan(t, buffer)
2945 return Value{t, ch, flag(Chan)}
2946 }
2947
2948
2949 func MakeMap(typ Type) Value {
2950 return MakeMapWithSize(typ, 0)
2951 }
2952
2953
2954
2955 func MakeMapWithSize(typ Type, n int) Value {
2956 if typ.Kind() != Map {
2957 panic("reflect.MakeMapWithSize of non-map type")
2958 }
2959 t := typ.common()
2960 m := makemap(t, n)
2961 return Value{t, m, flag(Map)}
2962 }
2963
2964
2965
2966
2967 func Indirect(v Value) Value {
2968 if v.Kind() != Pointer {
2969 return v
2970 }
2971 return v.Elem()
2972 }
2973
2974
2975
2976 func ValueOf(i any) Value {
2977 if i == nil {
2978 return Value{}
2979 }
2980 return unpackEface(i)
2981 }
2982
2983
2984
2985
2986
2987
2988 func Zero(typ Type) Value {
2989 if typ == nil {
2990 panic("reflect: Zero(nil)")
2991 }
2992 t := &typ.(*rtype).t
2993 fl := flag(t.Kind())
2994 if t.IfaceIndir() {
2995 var p unsafe.Pointer
2996 if t.Size() <= abi.ZeroValSize {
2997 p = unsafe.Pointer(&zeroVal[0])
2998 } else {
2999 p = unsafe_New(t)
3000 }
3001 return Value{t, p, fl | flagIndir}
3002 }
3003 return Value{t, nil, fl}
3004 }
3005
3006
3007 var zeroVal [abi.ZeroValSize]byte
3008
3009
3010
3011 func New(typ Type) Value {
3012 if typ == nil {
3013 panic("reflect: New(nil)")
3014 }
3015 t := &typ.(*rtype).t
3016 pt := ptrTo(t)
3017 if pt.IfaceIndir() {
3018
3019 panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
3020 }
3021 ptr := unsafe_New(t)
3022 fl := flag(Pointer)
3023 return Value{pt, ptr, fl}
3024 }
3025
3026
3027
3028 func NewAt(typ Type, p unsafe.Pointer) Value {
3029 fl := flag(Pointer)
3030 t := typ.(*rtype)
3031 return Value{t.ptrTo(), p, fl}
3032 }
3033
3034
3035
3036
3037
3038
3039 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
3040 if v.flag&flagMethod != 0 {
3041 v = makeMethodValue(context, v)
3042 }
3043
3044 switch {
3045 case directlyAssignable(dst, v.typ()):
3046
3047
3048 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
3049 fl |= flag(dst.Kind())
3050 return Value{dst, v.ptr, fl}
3051
3052 case implements(dst, v.typ()):
3053 if v.Kind() == Interface && v.IsNil() {
3054
3055
3056
3057 return Value{dst, nil, flag(Interface)}
3058 }
3059 x := valueInterface(v, false)
3060 if target == nil {
3061 target = unsafe_New(dst)
3062 }
3063 if dst.NumMethod() == 0 {
3064 *(*any)(target) = x
3065 } else {
3066 ifaceE2I(dst, x, target)
3067 }
3068 return Value{dst, target, flagIndir | flag(Interface)}
3069 }
3070
3071
3072 panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
3073 }
3074
3075
3076
3077
3078 func (v Value) Convert(t Type) Value {
3079 if v.flag&flagMethod != 0 {
3080 v = makeMethodValue("Convert", v)
3081 }
3082 op := convertOp(t.common(), v.typ())
3083 if op == nil {
3084 panic("reflect.Value.Convert: value of type " + stringFor(v.typ()) + " cannot be converted to type " + t.String())
3085 }
3086 return op(v, t)
3087 }
3088
3089
3090
3091 func (v Value) CanConvert(t Type) bool {
3092 vt := v.Type()
3093 if !vt.ConvertibleTo(t) {
3094 return false
3095 }
3096
3097
3098 switch {
3099 case vt.Kind() == Slice && t.Kind() == Array:
3100 if t.Len() > v.Len() {
3101 return false
3102 }
3103 case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
3104 n := t.Elem().Len()
3105 if n > v.Len() {
3106 return false
3107 }
3108 }
3109 return true
3110 }
3111
3112
3113
3114
3115
3116 func (v Value) Comparable() bool {
3117 k := v.Kind()
3118 switch k {
3119 case Invalid:
3120 return false
3121
3122 case Array:
3123 switch v.Type().Elem().Kind() {
3124 case Interface, Array, Struct:
3125 for i := 0; i < v.Type().Len(); i++ {
3126 if !v.Index(i).Comparable() {
3127 return false
3128 }
3129 }
3130 return true
3131 }
3132 return v.Type().Comparable()
3133
3134 case Interface:
3135 return v.IsNil() || v.Elem().Comparable()
3136
3137 case Struct:
3138 for i := 0; i < v.NumField(); i++ {
3139 if !v.Field(i).Comparable() {
3140 return false
3141 }
3142 }
3143 return true
3144
3145 default:
3146 return v.Type().Comparable()
3147 }
3148 }
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158 func (v Value) Equal(u Value) bool {
3159 if v.Kind() == Interface {
3160 v = v.Elem()
3161 }
3162 if u.Kind() == Interface {
3163 u = u.Elem()
3164 }
3165
3166 if !v.IsValid() || !u.IsValid() {
3167 return v.IsValid() == u.IsValid()
3168 }
3169
3170 if v.Kind() != u.Kind() || v.Type() != u.Type() {
3171 return false
3172 }
3173
3174
3175
3176 switch v.Kind() {
3177 default:
3178 panic("reflect.Value.Equal: invalid Kind")
3179 case Bool:
3180 return v.Bool() == u.Bool()
3181 case Int, Int8, Int16, Int32, Int64:
3182 return v.Int() == u.Int()
3183 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3184 return v.Uint() == u.Uint()
3185 case Float32, Float64:
3186 return v.Float() == u.Float()
3187 case Complex64, Complex128:
3188 return v.Complex() == u.Complex()
3189 case String:
3190 return v.String() == u.String()
3191 case Chan, Pointer, UnsafePointer:
3192 return v.Pointer() == u.Pointer()
3193 case Array:
3194
3195 vl := v.Len()
3196 if vl == 0 {
3197
3198 if !v.Type().Elem().Comparable() {
3199 break
3200 }
3201 return true
3202 }
3203 for i := 0; i < vl; i++ {
3204 if !v.Index(i).Equal(u.Index(i)) {
3205 return false
3206 }
3207 }
3208 return true
3209 case Struct:
3210
3211 nf := v.NumField()
3212 for i := 0; i < nf; i++ {
3213 if !v.Field(i).Equal(u.Field(i)) {
3214 return false
3215 }
3216 }
3217 return true
3218 case Func, Map, Slice:
3219 break
3220 }
3221 panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
3222 }
3223
3224
3225
3226 func convertOp(dst, src *abi.Type) func(Value, Type) Value {
3227 switch Kind(src.Kind()) {
3228 case Int, Int8, Int16, Int32, Int64:
3229 switch Kind(dst.Kind()) {
3230 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3231 return cvtInt
3232 case Float32, Float64:
3233 return cvtIntFloat
3234 case String:
3235 return cvtIntString
3236 }
3237
3238 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3239 switch Kind(dst.Kind()) {
3240 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3241 return cvtUint
3242 case Float32, Float64:
3243 return cvtUintFloat
3244 case String:
3245 return cvtUintString
3246 }
3247
3248 case Float32, Float64:
3249 switch Kind(dst.Kind()) {
3250 case Int, Int8, Int16, Int32, Int64:
3251 return cvtFloatInt
3252 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3253 return cvtFloatUint
3254 case Float32, Float64:
3255 return cvtFloat
3256 }
3257
3258 case Complex64, Complex128:
3259 switch Kind(dst.Kind()) {
3260 case Complex64, Complex128:
3261 return cvtComplex
3262 }
3263
3264 case String:
3265 if dst.Kind() == abi.Slice && pkgPathFor(dst.Elem()) == "" {
3266 switch Kind(dst.Elem().Kind()) {
3267 case Uint8:
3268 return cvtStringBytes
3269 case Int32:
3270 return cvtStringRunes
3271 }
3272 }
3273
3274 case Slice:
3275 if dst.Kind() == abi.String && pkgPathFor(src.Elem()) == "" {
3276 switch Kind(src.Elem().Kind()) {
3277 case Uint8:
3278 return cvtBytesString
3279 case Int32:
3280 return cvtRunesString
3281 }
3282 }
3283
3284
3285 if dst.Kind() == abi.Pointer && dst.Elem().Kind() == abi.Array && src.Elem() == dst.Elem().Elem() {
3286 return cvtSliceArrayPtr
3287 }
3288
3289
3290 if dst.Kind() == abi.Array && src.Elem() == dst.Elem() {
3291 return cvtSliceArray
3292 }
3293
3294 case Chan:
3295 if dst.Kind() == abi.Chan && specialChannelAssignability(dst, src) {
3296 return cvtDirect
3297 }
3298 }
3299
3300
3301 if haveIdenticalUnderlyingType(dst, src, false) {
3302 return cvtDirect
3303 }
3304
3305
3306 if dst.Kind() == abi.Pointer && nameFor(dst) == "" &&
3307 src.Kind() == abi.Pointer && nameFor(src) == "" &&
3308 haveIdenticalUnderlyingType(elem(dst), elem(src), false) {
3309 return cvtDirect
3310 }
3311
3312 if implements(dst, src) {
3313 if src.Kind() == abi.Interface {
3314 return cvtI2I
3315 }
3316 return cvtT2I
3317 }
3318
3319 return nil
3320 }
3321
3322
3323
3324 func makeInt(f flag, bits uint64, t Type) Value {
3325 typ := t.common()
3326 ptr := unsafe_New(typ)
3327 switch typ.Size() {
3328 case 1:
3329 *(*uint8)(ptr) = uint8(bits)
3330 case 2:
3331 *(*uint16)(ptr) = uint16(bits)
3332 case 4:
3333 *(*uint32)(ptr) = uint32(bits)
3334 case 8:
3335 *(*uint64)(ptr) = bits
3336 }
3337 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3338 }
3339
3340
3341
3342 func makeFloat(f flag, v float64, t Type) Value {
3343 typ := t.common()
3344 ptr := unsafe_New(typ)
3345 switch typ.Size() {
3346 case 4:
3347 *(*float32)(ptr) = float32(v)
3348 case 8:
3349 *(*float64)(ptr) = v
3350 }
3351 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3352 }
3353
3354
3355 func makeFloat32(f flag, v float32, t Type) Value {
3356 typ := t.common()
3357 ptr := unsafe_New(typ)
3358 *(*float32)(ptr) = v
3359 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3360 }
3361
3362
3363
3364 func makeComplex(f flag, v complex128, t Type) Value {
3365 typ := t.common()
3366 ptr := unsafe_New(typ)
3367 switch typ.Size() {
3368 case 8:
3369 *(*complex64)(ptr) = complex64(v)
3370 case 16:
3371 *(*complex128)(ptr) = v
3372 }
3373 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3374 }
3375
3376 func makeString(f flag, v string, t Type) Value {
3377 ret := New(t).Elem()
3378 ret.SetString(v)
3379 ret.flag = ret.flag&^flagAddr | f
3380 return ret
3381 }
3382
3383 func makeBytes(f flag, v []byte, t Type) Value {
3384 ret := New(t).Elem()
3385 ret.SetBytes(v)
3386 ret.flag = ret.flag&^flagAddr | f
3387 return ret
3388 }
3389
3390 func makeRunes(f flag, v []rune, t Type) Value {
3391 ret := New(t).Elem()
3392 ret.setRunes(v)
3393 ret.flag = ret.flag&^flagAddr | f
3394 return ret
3395 }
3396
3397
3398
3399
3400
3401
3402
3403 func cvtInt(v Value, t Type) Value {
3404 return makeInt(v.flag.ro(), uint64(v.Int()), t)
3405 }
3406
3407
3408 func cvtUint(v Value, t Type) Value {
3409 return makeInt(v.flag.ro(), v.Uint(), t)
3410 }
3411
3412
3413 func cvtFloatInt(v Value, t Type) Value {
3414 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
3415 }
3416
3417
3418 func cvtFloatUint(v Value, t Type) Value {
3419 return makeInt(v.flag.ro(), uint64(v.Float()), t)
3420 }
3421
3422
3423 func cvtIntFloat(v Value, t Type) Value {
3424 return makeFloat(v.flag.ro(), float64(v.Int()), t)
3425 }
3426
3427
3428 func cvtUintFloat(v Value, t Type) Value {
3429 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
3430 }
3431
3432
3433 func cvtFloat(v Value, t Type) Value {
3434 if v.Type().Kind() == Float32 && t.Kind() == Float32 {
3435
3436
3437
3438 return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
3439 }
3440 return makeFloat(v.flag.ro(), v.Float(), t)
3441 }
3442
3443
3444 func cvtComplex(v Value, t Type) Value {
3445 return makeComplex(v.flag.ro(), v.Complex(), t)
3446 }
3447
3448
3449 func cvtIntString(v Value, t Type) Value {
3450 s := "\uFFFD"
3451 if x := v.Int(); int64(rune(x)) == x {
3452 s = string(rune(x))
3453 }
3454 return makeString(v.flag.ro(), s, t)
3455 }
3456
3457
3458 func cvtUintString(v Value, t Type) Value {
3459 s := "\uFFFD"
3460 if x := v.Uint(); uint64(rune(x)) == x {
3461 s = string(rune(x))
3462 }
3463 return makeString(v.flag.ro(), s, t)
3464 }
3465
3466
3467 func cvtBytesString(v Value, t Type) Value {
3468 return makeString(v.flag.ro(), string(v.Bytes()), t)
3469 }
3470
3471
3472 func cvtStringBytes(v Value, t Type) Value {
3473 return makeBytes(v.flag.ro(), []byte(v.String()), t)
3474 }
3475
3476
3477 func cvtRunesString(v Value, t Type) Value {
3478 return makeString(v.flag.ro(), string(v.runes()), t)
3479 }
3480
3481
3482 func cvtStringRunes(v Value, t Type) Value {
3483 return makeRunes(v.flag.ro(), []rune(v.String()), t)
3484 }
3485
3486
3487 func cvtSliceArrayPtr(v Value, t Type) Value {
3488 n := t.Elem().Len()
3489 if n > v.Len() {
3490 panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to pointer to array with length " + itoa.Itoa(n))
3491 }
3492 h := (*unsafeheader.Slice)(v.ptr)
3493 return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
3494 }
3495
3496
3497 func cvtSliceArray(v Value, t Type) Value {
3498 n := t.Len()
3499 if n > v.Len() {
3500 panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to array with length " + itoa.Itoa(n))
3501 }
3502 h := (*unsafeheader.Slice)(v.ptr)
3503 typ := t.common()
3504 ptr := h.Data
3505 c := unsafe_New(typ)
3506 typedmemmove(typ, c, ptr)
3507 ptr = c
3508
3509 return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
3510 }
3511
3512
3513 func cvtDirect(v Value, typ Type) Value {
3514 f := v.flag
3515 t := typ.common()
3516 ptr := v.ptr
3517 if f&flagAddr != 0 {
3518
3519 c := unsafe_New(t)
3520 typedmemmove(t, c, ptr)
3521 ptr = c
3522 f &^= flagAddr
3523 }
3524 return Value{t, ptr, v.flag.ro() | f}
3525 }
3526
3527
3528 func cvtT2I(v Value, typ Type) Value {
3529 target := unsafe_New(typ.common())
3530 x := valueInterface(v, false)
3531 if typ.NumMethod() == 0 {
3532 *(*any)(target) = x
3533 } else {
3534 ifaceE2I(typ.common(), x, target)
3535 }
3536 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
3537 }
3538
3539
3540 func cvtI2I(v Value, typ Type) Value {
3541 if v.IsNil() {
3542 ret := Zero(typ)
3543 ret.flag |= v.flag.ro()
3544 return ret
3545 }
3546 return cvtT2I(v.Elem(), typ)
3547 }
3548
3549
3550
3551
3552 func chancap(ch unsafe.Pointer) int
3553
3554
3555 func chanclose(ch unsafe.Pointer)
3556
3557
3558 func chanlen(ch unsafe.Pointer) int
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
3569
3570
3571 func chansend0(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
3572
3573 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
3574 contentEscapes(val)
3575 return chansend0(ch, val, nb)
3576 }
3577
3578 func makechan(typ *abi.Type, size int) (ch unsafe.Pointer)
3579 func makemap(t *abi.Type, cap int) (m unsafe.Pointer)
3580
3581
3582 func mapaccess(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
3583
3584
3585 func mapaccess_faststr(t *abi.Type, m unsafe.Pointer, key string) (val unsafe.Pointer)
3586
3587
3588 func mapassign0(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer)
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600 func mapassign(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer) {
3601 contentEscapes(key)
3602 contentEscapes(val)
3603 mapassign0(t, m, key, val)
3604 }
3605
3606
3607 func mapassign_faststr0(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer)
3608
3609 func mapassign_faststr(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer) {
3610 contentEscapes((*unsafeheader.String)(unsafe.Pointer(&key)).Data)
3611 contentEscapes(val)
3612 mapassign_faststr0(t, m, key, val)
3613 }
3614
3615
3616 func mapdelete(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer)
3617
3618
3619 func mapdelete_faststr(t *abi.Type, m unsafe.Pointer, key string)
3620
3621
3622 func maplen(m unsafe.Pointer) int
3623
3624 func mapclear(t *abi.Type, m unsafe.Pointer)
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652 func call(stackArgsType *abi.Type, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
3653
3654 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
3655
3656
3657
3658
3659 func memmove(dst, src unsafe.Pointer, size uintptr)
3660
3661
3662
3663
3664 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
3665
3666
3667
3668
3669 func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
3670
3671
3672
3673
3674
3675 func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
3676
3677
3678
3679
3680
3681 func typedslicecopy(t *abi.Type, dst, src unsafeheader.Slice) int
3682
3683
3684
3685
3686
3687 func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
3688
3689
3690 func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
3691
3692 func verifyNotInHeapPtr(p uintptr) bool
3693
3694
3695 func growslice(t *abi.Type, old unsafeheader.Slice, num int) unsafeheader.Slice
3696
3697
3698 func unsafeslice(t *abi.Type, ptr unsafe.Pointer, len int)
3699
3700
3701
3702
3703 func escapes(x any) {
3704 if dummy.b {
3705 dummy.x = x
3706 }
3707 }
3708
3709 var dummy struct {
3710 b bool
3711 x any
3712 }
3713
3714
3715
3716
3717
3718 func contentEscapes(x unsafe.Pointer) {
3719 if dummy.b {
3720 escapes(*(*any)(x))
3721 }
3722 }
3723
View as plain text