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