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 target = v.ptr
2170 }
2171 x = x.assignTo("reflect.Set", v.typ(), target)
2172 if x.flag&flagIndir != 0 {
2173 if x.ptr == unsafe.Pointer(&zeroVal[0]) {
2174 typedmemclr(v.typ(), v.ptr)
2175 } else {
2176 typedmemmove(v.typ(), v.ptr, x.ptr)
2177 }
2178 } else {
2179 *(*unsafe.Pointer)(v.ptr) = x.ptr
2180 }
2181 }
2182
2183
2184
2185 func (v Value) SetBool(x bool) {
2186 v.mustBeAssignable()
2187 v.mustBe(Bool)
2188 *(*bool)(v.ptr) = x
2189 }
2190
2191
2192
2193
2194 func (v Value) SetBytes(x []byte) {
2195 v.mustBeAssignable()
2196 v.mustBe(Slice)
2197 if toRType(v.typ()).Elem().Kind() != Uint8 {
2198 panic("reflect.Value.SetBytes of non-byte slice")
2199 }
2200 *(*[]byte)(v.ptr) = x
2201 }
2202
2203
2204
2205
2206 func (v Value) setRunes(x []rune) {
2207 v.mustBeAssignable()
2208 v.mustBe(Slice)
2209 if v.typ().Elem().Kind() != abi.Int32 {
2210 panic("reflect.Value.setRunes of non-rune slice")
2211 }
2212 *(*[]rune)(v.ptr) = x
2213 }
2214
2215
2216
2217
2218 func (v Value) SetComplex(x complex128) {
2219 v.mustBeAssignable()
2220 switch k := v.kind(); k {
2221 default:
2222 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
2223 case Complex64:
2224 *(*complex64)(v.ptr) = complex64(x)
2225 case Complex128:
2226 *(*complex128)(v.ptr) = x
2227 }
2228 }
2229
2230
2231
2232
2233 func (v Value) SetFloat(x float64) {
2234 v.mustBeAssignable()
2235 switch k := v.kind(); k {
2236 default:
2237 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
2238 case Float32:
2239 *(*float32)(v.ptr) = float32(x)
2240 case Float64:
2241 *(*float64)(v.ptr) = x
2242 }
2243 }
2244
2245
2246
2247
2248 func (v Value) SetInt(x int64) {
2249 v.mustBeAssignable()
2250 switch k := v.kind(); k {
2251 default:
2252 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
2253 case Int:
2254 *(*int)(v.ptr) = int(x)
2255 case Int8:
2256 *(*int8)(v.ptr) = int8(x)
2257 case Int16:
2258 *(*int16)(v.ptr) = int16(x)
2259 case Int32:
2260 *(*int32)(v.ptr) = int32(x)
2261 case Int64:
2262 *(*int64)(v.ptr) = x
2263 }
2264 }
2265
2266
2267
2268
2269
2270 func (v Value) SetLen(n int) {
2271 v.mustBeAssignable()
2272 v.mustBe(Slice)
2273 s := (*unsafeheader.Slice)(v.ptr)
2274 if uint(n) > uint(s.Cap) {
2275 panic("reflect: slice length out of range in SetLen")
2276 }
2277 s.Len = n
2278 }
2279
2280
2281
2282
2283
2284 func (v Value) SetCap(n int) {
2285 v.mustBeAssignable()
2286 v.mustBe(Slice)
2287 s := (*unsafeheader.Slice)(v.ptr)
2288 if n < s.Len || n > s.Cap {
2289 panic("reflect: slice capacity out of range in SetCap")
2290 }
2291 s.Cap = n
2292 }
2293
2294
2295
2296
2297 func (v Value) SetUint(x uint64) {
2298 v.mustBeAssignable()
2299 switch k := v.kind(); k {
2300 default:
2301 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
2302 case Uint:
2303 *(*uint)(v.ptr) = uint(x)
2304 case Uint8:
2305 *(*uint8)(v.ptr) = uint8(x)
2306 case Uint16:
2307 *(*uint16)(v.ptr) = uint16(x)
2308 case Uint32:
2309 *(*uint32)(v.ptr) = uint32(x)
2310 case Uint64:
2311 *(*uint64)(v.ptr) = x
2312 case Uintptr:
2313 *(*uintptr)(v.ptr) = uintptr(x)
2314 }
2315 }
2316
2317
2318
2319
2320 func (v Value) SetPointer(x unsafe.Pointer) {
2321 v.mustBeAssignable()
2322 v.mustBe(UnsafePointer)
2323 *(*unsafe.Pointer)(v.ptr) = x
2324 }
2325
2326
2327
2328 func (v Value) SetString(x string) {
2329 v.mustBeAssignable()
2330 v.mustBe(String)
2331 *(*string)(v.ptr) = x
2332 }
2333
2334
2335
2336
2337 func (v Value) Slice(i, j int) Value {
2338 var (
2339 cap int
2340 typ *sliceType
2341 base unsafe.Pointer
2342 )
2343 switch kind := v.kind(); kind {
2344 default:
2345 panic(&ValueError{"reflect.Value.Slice", v.kind()})
2346
2347 case Array:
2348 if v.flag&flagAddr == 0 {
2349 panic("reflect.Value.Slice: slice of unaddressable array")
2350 }
2351 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2352 cap = int(tt.Len)
2353 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2354 base = v.ptr
2355
2356 case Slice:
2357 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2358 s := (*unsafeheader.Slice)(v.ptr)
2359 base = s.Data
2360 cap = s.Cap
2361
2362 case String:
2363 s := (*unsafeheader.String)(v.ptr)
2364 if i < 0 || j < i || j > s.Len {
2365 panic("reflect.Value.Slice: string slice index out of bounds")
2366 }
2367 var t unsafeheader.String
2368 if i < s.Len {
2369 t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
2370 }
2371 return Value{v.typ(), unsafe.Pointer(&t), v.flag}
2372 }
2373
2374 if i < 0 || j < i || j > cap {
2375 panic("reflect.Value.Slice: slice index out of bounds")
2376 }
2377
2378
2379 var x []unsafe.Pointer
2380
2381
2382 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2383 s.Len = j - i
2384 s.Cap = cap - i
2385 if cap-i > 0 {
2386 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < cap")
2387 } else {
2388
2389 s.Data = base
2390 }
2391
2392 fl := v.flag.ro() | flagIndir | flag(Slice)
2393 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2394 }
2395
2396
2397
2398
2399 func (v Value) Slice3(i, j, k int) Value {
2400 var (
2401 cap int
2402 typ *sliceType
2403 base unsafe.Pointer
2404 )
2405 switch kind := v.kind(); kind {
2406 default:
2407 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
2408
2409 case Array:
2410 if v.flag&flagAddr == 0 {
2411 panic("reflect.Value.Slice3: slice of unaddressable array")
2412 }
2413 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2414 cap = int(tt.Len)
2415 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2416 base = v.ptr
2417
2418 case Slice:
2419 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2420 s := (*unsafeheader.Slice)(v.ptr)
2421 base = s.Data
2422 cap = s.Cap
2423 }
2424
2425 if i < 0 || j < i || k < j || k > cap {
2426 panic("reflect.Value.Slice3: slice index out of bounds")
2427 }
2428
2429
2430
2431 var x []unsafe.Pointer
2432
2433
2434 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2435 s.Len = j - i
2436 s.Cap = k - i
2437 if k-i > 0 {
2438 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < k <= cap")
2439 } else {
2440
2441 s.Data = base
2442 }
2443
2444 fl := v.flag.ro() | flagIndir | flag(Slice)
2445 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2446 }
2447
2448
2449
2450
2451
2452
2453
2454 func (v Value) String() string {
2455
2456 if v.kind() == String {
2457 return *(*string)(v.ptr)
2458 }
2459 return v.stringNonString()
2460 }
2461
2462 func (v Value) stringNonString() string {
2463 if v.kind() == Invalid {
2464 return "<invalid Value>"
2465 }
2466
2467
2468 return "<" + v.Type().String() + " Value>"
2469 }
2470
2471
2472
2473
2474
2475
2476 func (v Value) TryRecv() (x Value, ok bool) {
2477 v.mustBe(Chan)
2478 v.mustBeExported()
2479 return v.recv(true)
2480 }
2481
2482
2483
2484
2485
2486 func (v Value) TrySend(x Value) bool {
2487 v.mustBe(Chan)
2488 v.mustBeExported()
2489 return v.send(x, true)
2490 }
2491
2492
2493 func (v Value) Type() Type {
2494 if v.flag != 0 && v.flag&flagMethod == 0 {
2495 return (*rtype)(abi.NoEscape(unsafe.Pointer(v.typ_)))
2496 }
2497 return v.typeSlow()
2498 }
2499
2500
2501 func (v Value) typeSlow() Type {
2502 return toRType(v.abiTypeSlow())
2503 }
2504
2505 func (v Value) abiType() *abi.Type {
2506 if v.flag != 0 && v.flag&flagMethod == 0 {
2507 return v.typ()
2508 }
2509 return v.abiTypeSlow()
2510 }
2511
2512 func (v Value) abiTypeSlow() *abi.Type {
2513 if v.flag == 0 {
2514 panic(&ValueError{"reflect.Value.Type", Invalid})
2515 }
2516
2517 typ := v.typ()
2518 if v.flag&flagMethod == 0 {
2519 return v.typ()
2520 }
2521
2522
2523
2524 i := int(v.flag) >> flagMethodShift
2525 if v.typ().Kind() == abi.Interface {
2526
2527 tt := (*interfaceType)(unsafe.Pointer(typ))
2528 if uint(i) >= uint(len(tt.Methods)) {
2529 panic("reflect: internal error: invalid method index")
2530 }
2531 m := &tt.Methods[i]
2532 return typeOffFor(typ, m.Typ)
2533 }
2534
2535 ms := typ.ExportedMethods()
2536 if uint(i) >= uint(len(ms)) {
2537 panic("reflect: internal error: invalid method index")
2538 }
2539 m := ms[i]
2540 return typeOffFor(typ, m.Mtyp)
2541 }
2542
2543
2544 func (v Value) CanUint() bool {
2545 switch v.kind() {
2546 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2547 return true
2548 default:
2549 return false
2550 }
2551 }
2552
2553
2554
2555 func (v Value) Uint() uint64 {
2556 k := v.kind()
2557 p := v.ptr
2558 switch k {
2559 case Uint:
2560 return uint64(*(*uint)(p))
2561 case Uint8:
2562 return uint64(*(*uint8)(p))
2563 case Uint16:
2564 return uint64(*(*uint16)(p))
2565 case Uint32:
2566 return uint64(*(*uint32)(p))
2567 case Uint64:
2568 return *(*uint64)(p)
2569 case Uintptr:
2570 return uint64(*(*uintptr)(p))
2571 }
2572 panic(&ValueError{"reflect.Value.Uint", v.kind()})
2573 }
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584 func (v Value) UnsafeAddr() uintptr {
2585 if v.typ() == nil {
2586 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
2587 }
2588 if v.flag&flagAddr == 0 {
2589 panic("reflect.Value.UnsafeAddr of unaddressable value")
2590 }
2591
2592 escapes(v.ptr)
2593 return uintptr(v.ptr)
2594 }
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610 func (v Value) UnsafePointer() unsafe.Pointer {
2611 k := v.kind()
2612 switch k {
2613 case Pointer:
2614 if !v.typ().Pointers() {
2615
2616
2617 if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
2618 panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
2619 }
2620 return *(*unsafe.Pointer)(v.ptr)
2621 }
2622 fallthrough
2623 case Chan, Map, UnsafePointer:
2624 return v.pointer()
2625 case Func:
2626 if v.flag&flagMethod != 0 {
2627
2628
2629
2630
2631
2632
2633 code := methodValueCallCodePtr()
2634 return *(*unsafe.Pointer)(unsafe.Pointer(&code))
2635 }
2636 p := v.pointer()
2637
2638
2639 if p != nil {
2640 p = *(*unsafe.Pointer)(p)
2641 }
2642 return p
2643 case Slice:
2644 return (*unsafeheader.Slice)(v.ptr).Data
2645 case String:
2646 return (*unsafeheader.String)(v.ptr).Data
2647 }
2648 panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
2649 }
2650
2651
2652
2653
2654
2655
2656
2657 func (v Value) Fields() iter.Seq2[StructField, Value] {
2658 t := v.Type()
2659 if t.Kind() != Struct {
2660 panic("reflect: Fields of non-struct type " + t.String())
2661 }
2662 return func(yield func(StructField, Value) bool) {
2663 for i := range v.NumField() {
2664 if !yield(t.Field(i), v.Field(i)) {
2665 return
2666 }
2667 }
2668 }
2669 }
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682 func (v Value) Methods() iter.Seq2[Method, Value] {
2683 rtype := v.Type()
2684 n := v.NumMethod()
2685 return func(yield func(Method, Value) bool) {
2686 for i := range n {
2687 if !yield(rtype.Method(i), v.Method(i)) {
2688 return
2689 }
2690 }
2691 }
2692 }
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702 type StringHeader struct {
2703 Data uintptr
2704 Len int
2705 }
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715 type SliceHeader struct {
2716 Data uintptr
2717 Len int
2718 Cap int
2719 }
2720
2721 func typesMustMatch(what string, t1, t2 Type) {
2722 if t1 != t2 {
2723 panic(what + ": " + t1.String() + " != " + t2.String())
2724 }
2725 }
2726
2727
2728
2729
2730
2731
2732
2733
2734 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
2735 return add(p, uintptr(i)*eltSize, "i < len")
2736 }
2737
2738
2739
2740
2741
2742
2743
2744 func (v Value) Grow(n int) {
2745 v.mustBeAssignable()
2746 v.mustBe(Slice)
2747 v.grow(n)
2748 }
2749
2750
2751 func (v Value) grow(n int) {
2752 p := (*unsafeheader.Slice)(v.ptr)
2753 switch {
2754 case n < 0:
2755 panic("reflect.Value.Grow: negative len")
2756 case p.Len+n < 0:
2757 panic("reflect.Value.Grow: slice overflow")
2758 case p.Len+n > p.Cap:
2759 t := v.typ().Elem()
2760 *p = growslice(t, *p, n)
2761 }
2762 }
2763
2764
2765
2766
2767
2768
2769
2770 func (v Value) extendSlice(n int) Value {
2771 v.mustBeExported()
2772 v.mustBe(Slice)
2773
2774
2775 sh := *(*unsafeheader.Slice)(v.ptr)
2776 s := &sh
2777 v.ptr = unsafe.Pointer(s)
2778 v.flag = flagIndir | flag(Slice)
2779
2780 v.grow(n)
2781 s.Len += n
2782 return v
2783 }
2784
2785
2786
2787
2788 func (v Value) Clear() {
2789 switch v.Kind() {
2790 case Slice:
2791 sh := *(*unsafeheader.Slice)(v.ptr)
2792 st := (*sliceType)(unsafe.Pointer(v.typ()))
2793 typedarrayclear(st.Elem, sh.Data, sh.Len)
2794 case Map:
2795 mapclear(v.typ(), v.pointer())
2796 default:
2797 panic(&ValueError{"reflect.Value.Clear", v.Kind()})
2798 }
2799 }
2800
2801
2802
2803 func Append(s Value, x ...Value) Value {
2804 s.mustBe(Slice)
2805 n := s.Len()
2806 s = s.extendSlice(len(x))
2807 for i, v := range x {
2808 s.Index(n + i).Set(v)
2809 }
2810 return s
2811 }
2812
2813
2814
2815 func AppendSlice(s, t Value) Value {
2816 s.mustBe(Slice)
2817 t.mustBe(Slice)
2818 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
2819 ns := s.Len()
2820 nt := t.Len()
2821 s = s.extendSlice(nt)
2822 Copy(s.Slice(ns, ns+nt), t)
2823 return s
2824 }
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834 func Copy(dst, src Value) int {
2835 dk := dst.kind()
2836 if dk != Array && dk != Slice {
2837 panic(&ValueError{"reflect.Copy", dk})
2838 }
2839 if dk == Array {
2840 dst.mustBeAssignable()
2841 }
2842 dst.mustBeExported()
2843
2844 sk := src.kind()
2845 var stringCopy bool
2846 if sk != Array && sk != Slice {
2847 stringCopy = sk == String && dst.typ().Elem().Kind() == abi.Uint8
2848 if !stringCopy {
2849 panic(&ValueError{"reflect.Copy", sk})
2850 }
2851 }
2852 src.mustBeExported()
2853
2854 de := dst.typ().Elem()
2855 if !stringCopy {
2856 se := src.typ().Elem()
2857 typesMustMatch("reflect.Copy", toType(de), toType(se))
2858 }
2859
2860 var ds, ss unsafeheader.Slice
2861 if dk == Array {
2862 ds.Data = dst.ptr
2863 ds.Len = dst.Len()
2864 ds.Cap = ds.Len
2865 } else {
2866 ds = *(*unsafeheader.Slice)(dst.ptr)
2867 }
2868 if sk == Array {
2869 ss.Data = src.ptr
2870 ss.Len = src.Len()
2871 ss.Cap = ss.Len
2872 } else if sk == Slice {
2873 ss = *(*unsafeheader.Slice)(src.ptr)
2874 } else {
2875 sh := *(*unsafeheader.String)(src.ptr)
2876 ss.Data = sh.Data
2877 ss.Len = sh.Len
2878 ss.Cap = sh.Len
2879 }
2880
2881 return typedslicecopy(de.Common(), ds, ss)
2882 }
2883
2884
2885
2886 type runtimeSelect struct {
2887 dir SelectDir
2888 typ *rtype
2889 ch unsafe.Pointer
2890 val unsafe.Pointer
2891 }
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904 func rselect([]runtimeSelect) (chosen int, recvOK bool)
2905
2906
2907 type SelectDir int
2908
2909
2910
2911 const (
2912 _ SelectDir = iota
2913 SelectSend
2914 SelectRecv
2915 SelectDefault
2916 )
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934 type SelectCase struct {
2935 Dir SelectDir
2936 Chan Value
2937 Send Value
2938 }
2939
2940
2941
2942 const stackAllocSelectCases = 4
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966 var runcases []runtimeSelect
2967 if len(cases) > stackAllocSelectCases {
2968 runcases = make([]runtimeSelect, len(cases))
2969 }
2970 chosen, recv, recvOK = select0(cases, runcases)
2971 return
2972 }
2973
2974 func select0(cases []SelectCase, runcases []runtimeSelect) (chosen int, recv Value, recvOK bool) {
2975 if len(cases) > 65536 {
2976 panic("reflect.Select: too many cases (max 65536)")
2977 }
2978
2979
2980 if runcases == nil {
2981 runcases = make([]runtimeSelect, len(cases), stackAllocSelectCases)
2982 }
2983
2984 haveDefault := false
2985
2986
2987
2988
2989 for i, c := range cases {
2990 rc := &runcases[i]
2991 rc.dir = c.Dir
2992 switch c.Dir {
2993 default:
2994 panic("reflect.Select: invalid Dir")
2995
2996 case SelectDefault:
2997 if haveDefault {
2998 panic("reflect.Select: multiple default cases")
2999 }
3000 haveDefault = true
3001 if c.Chan.IsValid() {
3002 panic("reflect.Select: default case has Chan value")
3003 }
3004 if c.Send.IsValid() {
3005 panic("reflect.Select: default case has Send value")
3006 }
3007
3008 case SelectSend:
3009 ch := c.Chan
3010 if !ch.IsValid() {
3011 break
3012 }
3013 ch.mustBe(Chan)
3014 ch.mustBeExported()
3015 tt := (*chanType)(unsafe.Pointer(ch.typ()))
3016 if ChanDir(tt.Dir)&SendDir == 0 {
3017 panic("reflect.Select: SendDir case using recv-only channel")
3018 }
3019 rc.ch = ch.pointer()
3020 rc.typ = toRType(&tt.Type)
3021 v := c.Send
3022 if !v.IsValid() {
3023 panic("reflect.Select: SendDir case missing Send value")
3024 }
3025 v.mustBeExported()
3026 v = v.assignTo("reflect.Select", tt.Elem, nil)
3027 if v.flag&flagIndir != 0 {
3028 rc.val = v.ptr
3029 } else {
3030 rc.val = unsafe.Pointer(&v.ptr)
3031 }
3032
3033
3034 escapes(rc.val)
3035
3036 case SelectRecv:
3037 if c.Send.IsValid() {
3038 panic("reflect.Select: RecvDir case has Send value")
3039 }
3040 ch := c.Chan
3041 if !ch.IsValid() {
3042 break
3043 }
3044 ch.mustBe(Chan)
3045 ch.mustBeExported()
3046 tt := (*chanType)(unsafe.Pointer(ch.typ()))
3047 if ChanDir(tt.Dir)&RecvDir == 0 {
3048 panic("reflect.Select: RecvDir case using send-only channel")
3049 }
3050 rc.ch = ch.pointer()
3051 rc.typ = toRType(&tt.Type)
3052 rc.val = unsafe_New(tt.Elem)
3053 }
3054 }
3055
3056 chosen, recvOK = rselect(runcases)
3057 if runcases[chosen].dir == SelectRecv {
3058 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
3059 t := tt.Elem
3060 p := runcases[chosen].val
3061 fl := flag(t.Kind())
3062 if !t.IsDirectIface() {
3063 recv = Value{t, p, fl | flagIndir}
3064 } else {
3065 recv = Value{t, *(*unsafe.Pointer)(p), fl}
3066 }
3067 }
3068 return chosen, recv, recvOK
3069 }
3070
3071
3074
3075
3076
3077
3078 func unsafe_New(*abi.Type) unsafe.Pointer
3079
3080
3081 func unsafe_NewArray(*abi.Type, int) unsafe.Pointer
3082
3083
3084
3085 func MakeSlice(typ Type, len, cap int) Value {
3086 typ = toType(typ.common())
3087 if typ.Kind() != Slice {
3088 panic("reflect.MakeSlice of non-slice type")
3089 }
3090 if len < 0 {
3091 panic("reflect.MakeSlice: negative len")
3092 }
3093 if cap < 0 {
3094 panic("reflect.MakeSlice: negative cap")
3095 }
3096 if len > cap {
3097 panic("reflect.MakeSlice: len > cap")
3098 }
3099
3100 s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
3101 return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
3102 }
3103
3104
3105
3106
3107
3108 func SliceAt(typ Type, p unsafe.Pointer, n int) Value {
3109 unsafeslice(typ.common(), p, n)
3110 s := unsafeheader.Slice{Data: p, Len: n, Cap: n}
3111 return Value{SliceOf(typ).common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
3112 }
3113
3114
3115 func MakeChan(typ Type, buffer int) Value {
3116 typ = toType(typ.common())
3117 if typ.Kind() != Chan {
3118 panic("reflect.MakeChan of non-chan type")
3119 }
3120 if buffer < 0 {
3121 panic("reflect.MakeChan: negative buffer size")
3122 }
3123 if typ.ChanDir() != BothDir {
3124 panic("reflect.MakeChan: unidirectional channel type")
3125 }
3126 t := typ.common()
3127 ch := makechan(t, buffer)
3128 return Value{t, ch, flag(Chan)}
3129 }
3130
3131
3132 func MakeMap(typ Type) Value {
3133 return MakeMapWithSize(typ, 0)
3134 }
3135
3136
3137
3138 func MakeMapWithSize(typ Type, n int) Value {
3139 typ = toType(typ.common())
3140 if typ.Kind() != Map {
3141 panic("reflect.MakeMapWithSize of non-map type")
3142 }
3143 t := typ.common()
3144 m := makemap(t, n)
3145 return Value{t, m, flag(Map)}
3146 }
3147
3148
3149
3150
3151 func Indirect(v Value) Value {
3152 if v.Kind() != Pointer {
3153 return v
3154 }
3155 return v.Elem()
3156 }
3157
3158
3159
3160 func ValueOf(i any) Value {
3161 if i == nil {
3162 return Value{}
3163 }
3164 return unpackEface(i)
3165 }
3166
3167
3168
3169
3170
3171
3172 func Zero(typ Type) Value {
3173 if typ == nil {
3174 panic("reflect: Zero(nil)")
3175 }
3176 t := &typ.(*rtype).t
3177 fl := flag(t.Kind())
3178 if !t.IsDirectIface() {
3179 var p unsafe.Pointer
3180 if t.Size() <= abi.ZeroValSize {
3181 p = unsafe.Pointer(&zeroVal[0])
3182 } else {
3183 p = unsafe_New(t)
3184 }
3185 return Value{t, p, fl | flagIndir}
3186 }
3187 return Value{t, nil, fl}
3188 }
3189
3190
3191 var zeroVal [abi.ZeroValSize]byte
3192
3193
3194
3195 func New(typ Type) Value {
3196 if typ == nil {
3197 panic("reflect: New(nil)")
3198 }
3199 t := &typ.(*rtype).t
3200 pt := ptrTo(t)
3201 if !pt.IsDirectIface() {
3202
3203 panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
3204 }
3205 ptr := unsafe_New(t)
3206 fl := flag(Pointer)
3207 return Value{pt, ptr, fl}
3208 }
3209
3210
3211
3212 func NewAt(typ Type, p unsafe.Pointer) Value {
3213 fl := flag(Pointer)
3214 t := typ.(*rtype)
3215 return Value{t.ptrTo(), p, fl}
3216 }
3217
3218
3219
3220
3221
3222
3223 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
3224 if v.flag&flagMethod != 0 {
3225 v = makeMethodValue(context, v)
3226 }
3227
3228 switch {
3229 case directlyAssignable(dst, v.typ()):
3230
3231
3232 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
3233 fl |= flag(dst.Kind())
3234 return Value{dst, v.ptr, fl}
3235
3236 case implements(dst, v.typ()):
3237 if v.Kind() == Interface && v.IsNil() {
3238
3239
3240
3241 return Value{dst, nil, flag(Interface)}
3242 }
3243 x := valueInterface(v, false)
3244 if target == nil {
3245 target = unsafe_New(dst)
3246 }
3247 if dst.NumMethod() == 0 {
3248 *(*any)(target) = x
3249 } else {
3250 ifaceE2I(dst, x, target)
3251 }
3252 return Value{dst, target, flagIndir | flag(Interface)}
3253 }
3254
3255
3256 panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
3257 }
3258
3259
3260
3261
3262 func (v Value) Convert(t Type) Value {
3263 if v.flag&flagMethod != 0 {
3264 v = makeMethodValue("Convert", v)
3265 }
3266 t = toType(t.common())
3267 op := convertOp(t.common(), v.typ())
3268 if op == nil {
3269 panic("reflect.Value.Convert: value of type " + stringFor(v.typ()) + " cannot be converted to type " + t.String())
3270 }
3271 return op(v, t)
3272 }
3273
3274
3275
3276 func (v Value) CanConvert(t Type) bool {
3277 vt := v.Type()
3278 t = toType(t.common())
3279 if !vt.ConvertibleTo(t) {
3280 return false
3281 }
3282
3283
3284 switch {
3285 case vt.Kind() == Slice && t.Kind() == Array:
3286 if t.Len() > v.Len() {
3287 return false
3288 }
3289 case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
3290 n := t.Elem().Len()
3291 if n > v.Len() {
3292 return false
3293 }
3294 }
3295 return true
3296 }
3297
3298
3299
3300
3301
3302 func (v Value) Comparable() bool {
3303 k := v.Kind()
3304 switch k {
3305 case Invalid:
3306 return false
3307
3308 case Array:
3309 switch v.Type().Elem().Kind() {
3310 case Interface, Array, Struct:
3311 for i := 0; i < v.Type().Len(); i++ {
3312 if !v.Index(i).Comparable() {
3313 return false
3314 }
3315 }
3316 return true
3317 }
3318 return v.Type().Comparable()
3319
3320 case Interface:
3321 return v.IsNil() || v.Elem().Comparable()
3322
3323 case Struct:
3324 for _, value := range v.Fields() {
3325 if !value.Comparable() {
3326 return false
3327 }
3328 }
3329 return true
3330
3331 default:
3332 return v.Type().Comparable()
3333 }
3334 }
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344 func (v Value) Equal(u Value) bool {
3345 if v.Kind() == Interface {
3346 v = v.Elem()
3347 }
3348 if u.Kind() == Interface {
3349 u = u.Elem()
3350 }
3351
3352 if !v.IsValid() || !u.IsValid() {
3353 return v.IsValid() == u.IsValid()
3354 }
3355
3356 if v.Kind() != u.Kind() || v.Type() != u.Type() {
3357 return false
3358 }
3359
3360
3361
3362 switch v.Kind() {
3363 default:
3364 panic("reflect.Value.Equal: invalid Kind")
3365 case Bool:
3366 return v.Bool() == u.Bool()
3367 case Int, Int8, Int16, Int32, Int64:
3368 return v.Int() == u.Int()
3369 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3370 return v.Uint() == u.Uint()
3371 case Float32, Float64:
3372 return v.Float() == u.Float()
3373 case Complex64, Complex128:
3374 return v.Complex() == u.Complex()
3375 case String:
3376 return v.String() == u.String()
3377 case Chan, Pointer, UnsafePointer:
3378 return v.Pointer() == u.Pointer()
3379 case Array:
3380
3381 vl := v.Len()
3382 if vl == 0 {
3383
3384 if !v.Type().Elem().Comparable() {
3385 break
3386 }
3387 return true
3388 }
3389 for i := 0; i < vl; i++ {
3390 if !v.Index(i).Equal(u.Index(i)) {
3391 return false
3392 }
3393 }
3394 return true
3395 case Struct:
3396
3397 nf := v.NumField()
3398 for i := 0; i < nf; i++ {
3399 if !v.Field(i).Equal(u.Field(i)) {
3400 return false
3401 }
3402 }
3403 return true
3404 case Func, Map, Slice:
3405 break
3406 }
3407 panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
3408 }
3409
3410
3411
3412 func convertOp(dst, src *abi.Type) func(Value, Type) Value {
3413 switch Kind(src.Kind()) {
3414 case Int, Int8, Int16, Int32, Int64:
3415 switch Kind(dst.Kind()) {
3416 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3417 return cvtInt
3418 case Float32, Float64:
3419 return cvtIntFloat
3420 case String:
3421 return cvtIntString
3422 }
3423
3424 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3425 switch Kind(dst.Kind()) {
3426 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3427 return cvtUint
3428 case Float32, Float64:
3429 return cvtUintFloat
3430 case String:
3431 return cvtUintString
3432 }
3433
3434 case Float32, Float64:
3435 switch Kind(dst.Kind()) {
3436 case Int, Int8, Int16, Int32, Int64:
3437 return cvtFloatInt
3438 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3439 return cvtFloatUint
3440 case Float32, Float64:
3441 return cvtFloat
3442 }
3443
3444 case Complex64, Complex128:
3445 switch Kind(dst.Kind()) {
3446 case Complex64, Complex128:
3447 return cvtComplex
3448 }
3449
3450 case String:
3451 if dst.Kind() == abi.Slice {
3452 switch Kind(dst.Elem().Kind()) {
3453 case Uint8:
3454 return cvtStringBytes
3455 case Int32:
3456 return cvtStringRunes
3457 }
3458 }
3459
3460 case Slice:
3461 if dst.Kind() == abi.String {
3462 switch Kind(src.Elem().Kind()) {
3463 case Uint8:
3464 return cvtBytesString
3465 case Int32:
3466 return cvtRunesString
3467 }
3468 }
3469
3470
3471 if dst.Kind() == abi.Pointer && dst.Elem().Kind() == abi.Array && src.Elem() == dst.Elem().Elem() {
3472 return cvtSliceArrayPtr
3473 }
3474
3475
3476 if dst.Kind() == abi.Array && src.Elem() == dst.Elem() {
3477 return cvtSliceArray
3478 }
3479
3480 case Chan:
3481 if dst.Kind() == abi.Chan && specialChannelAssignability(dst, src) {
3482 return cvtDirect
3483 }
3484 }
3485
3486
3487 if haveIdenticalUnderlyingType(dst, src, false) {
3488 return cvtDirect
3489 }
3490
3491
3492 if dst.Kind() == abi.Pointer && nameFor(dst) == "" &&
3493 src.Kind() == abi.Pointer && nameFor(src) == "" &&
3494 haveIdenticalUnderlyingType(elem(dst), elem(src), false) {
3495 return cvtDirect
3496 }
3497
3498 if implements(dst, src) {
3499 if src.Kind() == abi.Interface {
3500 return cvtI2I
3501 }
3502 return cvtT2I
3503 }
3504
3505 return nil
3506 }
3507
3508
3509
3510 func makeInt(f flag, bits uint64, t Type) Value {
3511 typ := t.common()
3512 ptr := unsafe_New(typ)
3513 switch typ.Size() {
3514 case 1:
3515 *(*uint8)(ptr) = uint8(bits)
3516 case 2:
3517 *(*uint16)(ptr) = uint16(bits)
3518 case 4:
3519 *(*uint32)(ptr) = uint32(bits)
3520 case 8:
3521 *(*uint64)(ptr) = bits
3522 }
3523 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3524 }
3525
3526
3527
3528 func makeFloat(f flag, v float64, t Type) Value {
3529 typ := t.common()
3530 ptr := unsafe_New(typ)
3531 switch typ.Size() {
3532 case 4:
3533 *(*float32)(ptr) = float32(v)
3534 case 8:
3535 *(*float64)(ptr) = v
3536 }
3537 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3538 }
3539
3540
3541 func makeFloat32(f flag, v float32, t Type) Value {
3542 typ := t.common()
3543 ptr := unsafe_New(typ)
3544 *(*float32)(ptr) = v
3545 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3546 }
3547
3548
3549
3550 func makeComplex(f flag, v complex128, t Type) Value {
3551 typ := t.common()
3552 ptr := unsafe_New(typ)
3553 switch typ.Size() {
3554 case 8:
3555 *(*complex64)(ptr) = complex64(v)
3556 case 16:
3557 *(*complex128)(ptr) = v
3558 }
3559 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3560 }
3561
3562 func makeString(f flag, v string, t Type) Value {
3563 ret := New(t).Elem()
3564 ret.SetString(v)
3565 ret.flag = ret.flag&^flagAddr | f
3566 return ret
3567 }
3568
3569 func makeBytes(f flag, v []byte, t Type) Value {
3570 ret := New(t).Elem()
3571 ret.SetBytes(v)
3572 ret.flag = ret.flag&^flagAddr | f
3573 return ret
3574 }
3575
3576 func makeRunes(f flag, v []rune, t Type) Value {
3577 ret := New(t).Elem()
3578 ret.setRunes(v)
3579 ret.flag = ret.flag&^flagAddr | f
3580 return ret
3581 }
3582
3583
3584
3585
3586
3587
3588
3589 func cvtInt(v Value, t Type) Value {
3590 return makeInt(v.flag.ro(), uint64(v.Int()), t)
3591 }
3592
3593
3594 func cvtUint(v Value, t Type) Value {
3595 return makeInt(v.flag.ro(), v.Uint(), t)
3596 }
3597
3598
3599 func cvtFloatInt(v Value, t Type) Value {
3600 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
3601 }
3602
3603
3604 func cvtFloatUint(v Value, t Type) Value {
3605 return makeInt(v.flag.ro(), uint64(v.Float()), t)
3606 }
3607
3608
3609 func cvtIntFloat(v Value, t Type) Value {
3610 return makeFloat(v.flag.ro(), float64(v.Int()), t)
3611 }
3612
3613
3614 func cvtUintFloat(v Value, t Type) Value {
3615 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
3616 }
3617
3618
3619 func cvtFloat(v Value, t Type) Value {
3620 if v.Type().Kind() == Float32 && t.Kind() == Float32 {
3621
3622
3623
3624 return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
3625 }
3626 return makeFloat(v.flag.ro(), v.Float(), t)
3627 }
3628
3629
3630 func cvtComplex(v Value, t Type) Value {
3631 return makeComplex(v.flag.ro(), v.Complex(), t)
3632 }
3633
3634
3635 func cvtIntString(v Value, t Type) Value {
3636 s := "\uFFFD"
3637 if x := v.Int(); int64(rune(x)) == x {
3638 s = string(rune(x))
3639 }
3640 return makeString(v.flag.ro(), s, t)
3641 }
3642
3643
3644 func cvtUintString(v Value, t Type) Value {
3645 s := "\uFFFD"
3646 if x := v.Uint(); uint64(rune(x)) == x {
3647 s = string(rune(x))
3648 }
3649 return makeString(v.flag.ro(), s, t)
3650 }
3651
3652
3653 func cvtBytesString(v Value, t Type) Value {
3654 return makeString(v.flag.ro(), string(v.Bytes()), t)
3655 }
3656
3657
3658 func cvtStringBytes(v Value, t Type) Value {
3659 return makeBytes(v.flag.ro(), []byte(v.String()), t)
3660 }
3661
3662
3663 func cvtRunesString(v Value, t Type) Value {
3664 return makeString(v.flag.ro(), string(v.runes()), t)
3665 }
3666
3667
3668 func cvtStringRunes(v Value, t Type) Value {
3669 return makeRunes(v.flag.ro(), []rune(v.String()), t)
3670 }
3671
3672
3673 func cvtSliceArrayPtr(v Value, t Type) Value {
3674 n := t.Elem().Len()
3675 if n > v.Len() {
3676 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to pointer to array with length " + strconv.Itoa(n))
3677 }
3678 h := (*unsafeheader.Slice)(v.ptr)
3679 return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
3680 }
3681
3682
3683 func cvtSliceArray(v Value, t Type) Value {
3684 n := t.Len()
3685 if n > v.Len() {
3686 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to array with length " + strconv.Itoa(n))
3687 }
3688 h := (*unsafeheader.Slice)(v.ptr)
3689 typ := t.common()
3690 ptr := h.Data
3691 c := unsafe_New(typ)
3692 typedmemmove(typ, c, ptr)
3693 ptr = c
3694
3695 return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
3696 }
3697
3698
3699 func cvtDirect(v Value, typ Type) Value {
3700 f := v.flag
3701 t := typ.common()
3702 ptr := v.ptr
3703 if f&flagAddr != 0 {
3704
3705 c := unsafe_New(t)
3706 typedmemmove(t, c, ptr)
3707 ptr = c
3708 f &^= flagAddr
3709 }
3710 return Value{t, ptr, v.flag.ro() | f}
3711 }
3712
3713
3714 func cvtT2I(v Value, typ Type) Value {
3715 target := unsafe_New(typ.common())
3716 x := valueInterface(v, false)
3717 if typ.NumMethod() == 0 {
3718 *(*any)(target) = x
3719 } else {
3720 ifaceE2I(typ.common(), x, target)
3721 }
3722 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
3723 }
3724
3725
3726 func cvtI2I(v Value, typ Type) Value {
3727 if v.IsNil() {
3728 ret := Zero(typ)
3729 ret.flag |= v.flag.ro()
3730 return ret
3731 }
3732 return cvtT2I(v.Elem(), typ)
3733 }
3734
3735
3736
3737
3738 func chancap(ch unsafe.Pointer) int
3739
3740
3741 func chanclose(ch unsafe.Pointer)
3742
3743
3744 func chanlen(ch unsafe.Pointer) int
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
3755
3756
3757 func chansend0(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
3758
3759 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
3760 contentEscapes(val)
3761 return chansend0(ch, val, nb)
3762 }
3763
3764 func makechan(typ *abi.Type, size int) (ch unsafe.Pointer)
3765 func makemap(t *abi.Type, cap int) (m unsafe.Pointer)
3766
3767
3768 func mapaccess(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
3769
3770
3771 func mapaccess_faststr(t *abi.Type, m unsafe.Pointer, key string) (val unsafe.Pointer)
3772
3773
3774 func mapassign0(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer)
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786 func mapassign(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer) {
3787 contentEscapes(key)
3788 contentEscapes(val)
3789 mapassign0(t, m, key, val)
3790 }
3791
3792
3793 func mapassign_faststr0(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer)
3794
3795 func mapassign_faststr(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer) {
3796 contentEscapes((*unsafeheader.String)(unsafe.Pointer(&key)).Data)
3797 contentEscapes(val)
3798 mapassign_faststr0(t, m, key, val)
3799 }
3800
3801
3802 func mapdelete(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer)
3803
3804
3805 func mapdelete_faststr(t *abi.Type, m unsafe.Pointer, key string)
3806
3807
3808 func maplen(m unsafe.Pointer) int
3809
3810 func mapclear(t *abi.Type, m unsafe.Pointer)
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838 func call(stackArgsType *abi.Type, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
3839
3840 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
3841
3842
3843
3844
3845 func memmove(dst, src unsafe.Pointer, size uintptr)
3846
3847
3848
3849
3850 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
3851
3852
3853
3854
3855 func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
3856
3857
3858
3859
3860
3861 func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
3862
3863
3864
3865
3866
3867 func typedslicecopy(t *abi.Type, dst, src unsafeheader.Slice) int
3868
3869
3870
3871
3872
3873 func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
3874
3875
3876 func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
3877
3878 func verifyNotInHeapPtr(p uintptr) bool
3879
3880
3881 func growslice(t *abi.Type, old unsafeheader.Slice, num int) unsafeheader.Slice
3882
3883
3884 func unsafeslice(t *abi.Type, ptr unsafe.Pointer, len int)
3885
3886
3887
3888
3889 func escapes(x any) {
3890 if dummy.b {
3891 dummy.x = x
3892 }
3893 }
3894
3895 var dummy struct {
3896 b bool
3897 x any
3898 }
3899
3900
3901
3902
3903
3904 func contentEscapes(x unsafe.Pointer) {
3905 if dummy.b {
3906 escapes(*(*any)(x))
3907 }
3908 }
3909
View as plain text