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