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