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