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 return Value{typ, nil, fl | flagIndir}
1294 }
1295
1296
1297
1298
1299
1300
1301 ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
1302 return Value{typ, ptr, fl}
1303 }
1304
1305
1306
1307
1308 func (v Value) FieldByIndex(index []int) Value {
1309 if len(index) == 1 {
1310 return v.Field(index[0])
1311 }
1312 v.mustBe(Struct)
1313 for i, x := range index {
1314 if i > 0 {
1315 if v.Kind() == Pointer && v.typ().Elem().Kind() == abi.Struct {
1316 if v.IsNil() {
1317 panic("reflect: indirection through nil pointer to embedded struct")
1318 }
1319 v = v.Elem()
1320 }
1321 }
1322 v = v.Field(x)
1323 }
1324 return v
1325 }
1326
1327
1328
1329
1330
1331 func (v Value) FieldByIndexErr(index []int) (Value, error) {
1332 if len(index) == 1 {
1333 return v.Field(index[0]), nil
1334 }
1335 v.mustBe(Struct)
1336 for i, x := range index {
1337 if i > 0 {
1338 if v.Kind() == Ptr && v.typ().Elem().Kind() == abi.Struct {
1339 if v.IsNil() {
1340 return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + nameFor(v.typ().Elem()))
1341 }
1342 v = v.Elem()
1343 }
1344 }
1345 v = v.Field(x)
1346 }
1347 return v, nil
1348 }
1349
1350
1351
1352
1353 func (v Value) FieldByName(name string) Value {
1354 v.mustBe(Struct)
1355 if f, ok := toRType(v.typ()).FieldByName(name); ok {
1356 return v.FieldByIndex(f.Index)
1357 }
1358 return Value{}
1359 }
1360
1361
1362
1363
1364
1365 func (v Value) FieldByNameFunc(match func(string) bool) Value {
1366 if f, ok := toRType(v.typ()).FieldByNameFunc(match); ok {
1367 return v.FieldByIndex(f.Index)
1368 }
1369 return Value{}
1370 }
1371
1372
1373 func (v Value) CanFloat() bool {
1374 switch v.kind() {
1375 case Float32, Float64:
1376 return true
1377 default:
1378 return false
1379 }
1380 }
1381
1382
1383
1384 func (v Value) Float() float64 {
1385 k := v.kind()
1386 switch k {
1387 case Float32:
1388 return float64(*(*float32)(v.ptr))
1389 case Float64:
1390 return *(*float64)(v.ptr)
1391 }
1392 panic(&ValueError{"reflect.Value.Float", v.kind()})
1393 }
1394
1395 var uint8Type = rtypeOf(uint8(0))
1396
1397
1398
1399 func (v Value) Index(i int) Value {
1400 switch v.kind() {
1401 case Array:
1402 tt := (*arrayType)(unsafe.Pointer(v.typ()))
1403 if uint(i) >= uint(tt.Len) {
1404 panic("reflect: array index out of range")
1405 }
1406 typ := tt.Elem
1407 offset := uintptr(i) * typ.Size()
1408
1409
1410
1411
1412
1413
1414 val := add(v.ptr, offset, "same as &v[i], i < tt.len")
1415 fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind())
1416 return Value{typ, val, fl}
1417
1418 case Slice:
1419
1420
1421 s := (*unsafeheader.Slice)(v.ptr)
1422 if uint(i) >= uint(s.Len) {
1423 panic("reflect: slice index out of range")
1424 }
1425 tt := (*sliceType)(unsafe.Pointer(v.typ()))
1426 typ := tt.Elem
1427 val := arrayAt(s.Data, i, typ.Size(), "i < s.Len")
1428 fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
1429 return Value{typ, val, fl}
1430
1431 case String:
1432 s := (*unsafeheader.String)(v.ptr)
1433 if uint(i) >= uint(s.Len) {
1434 panic("reflect: string index out of range")
1435 }
1436 p := arrayAt(s.Data, i, 1, "i < s.Len")
1437 fl := v.flag.ro() | flag(Uint8) | flagIndir
1438 return Value{uint8Type, p, fl}
1439 }
1440 panic(&ValueError{"reflect.Value.Index", v.kind()})
1441 }
1442
1443
1444 func (v Value) CanInt() bool {
1445 switch v.kind() {
1446 case Int, Int8, Int16, Int32, Int64:
1447 return true
1448 default:
1449 return false
1450 }
1451 }
1452
1453
1454
1455 func (v Value) Int() int64 {
1456 k := v.kind()
1457 p := v.ptr
1458 switch k {
1459 case Int:
1460 return int64(*(*int)(p))
1461 case Int8:
1462 return int64(*(*int8)(p))
1463 case Int16:
1464 return int64(*(*int16)(p))
1465 case Int32:
1466 return int64(*(*int32)(p))
1467 case Int64:
1468 return *(*int64)(p)
1469 }
1470 panic(&ValueError{"reflect.Value.Int", v.kind()})
1471 }
1472
1473
1474 func (v Value) CanInterface() bool {
1475 if v.flag == 0 {
1476 panic(&ValueError{"reflect.Value.CanInterface", Invalid})
1477 }
1478 return v.flag&flagRO == 0
1479 }
1480
1481
1482
1483
1484
1485
1486
1487
1488 func (v Value) Interface() (i any) {
1489 return valueInterface(v, true)
1490 }
1491
1492 func valueInterface(v Value, safe bool) any {
1493 if v.flag == 0 {
1494 panic(&ValueError{"reflect.Value.Interface", Invalid})
1495 }
1496 if safe && v.flag&flagRO != 0 {
1497
1498
1499
1500 panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
1501 }
1502 if v.flag&flagMethod != 0 {
1503 v = makeMethodValue("Interface", v)
1504 }
1505
1506 if v.kind() == Interface {
1507
1508 return packIfaceValueIntoEmptyIface(v)
1509 }
1510
1511 return packEface(v)
1512 }
1513
1514
1515
1516
1517 func TypeAssert[T any](v Value) (T, bool) {
1518 if v.flag == 0 {
1519 panic(&ValueError{"reflect.TypeAssert", Invalid})
1520 }
1521 if v.flag&flagRO != 0 {
1522
1523
1524
1525 panic("reflect.TypeAssert: cannot return value obtained from unexported field or method")
1526 }
1527
1528 if v.flag&flagMethod != 0 {
1529 v = makeMethodValue("TypeAssert", v)
1530 }
1531
1532 typ := abi.TypeFor[T]()
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553 if v.kind() == Interface {
1554 v, ok := packIfaceValueIntoEmptyIface(v).(T)
1555 return v, ok
1556 }
1557
1558
1559
1560
1561
1562 if typ.Kind() == abi.Interface {
1563
1564
1565 iface := *(*any)(unsafe.Pointer(&abi.EmptyInterface{Type: v.typ(), Data: nil}))
1566 if out, ok := iface.(T); ok {
1567
1568
1569
1570 (*abi.CommonInterface)(unsafe.Pointer(&out)).Data = packEfaceData(v)
1571 return out, true
1572 }
1573 var zero T
1574 return zero, false
1575 }
1576
1577
1578
1579 if typ != v.typ() {
1580 var zero T
1581 return zero, false
1582 }
1583 if v.flag&flagIndir == 0 {
1584 return *(*T)(unsafe.Pointer(&v.ptr)), true
1585 }
1586 return *(*T)(v.ptr), true
1587 }
1588
1589
1590
1591
1592 func packIfaceValueIntoEmptyIface(v Value) any {
1593
1594
1595 if v.NumMethod() == 0 {
1596 return *(*any)(v.ptr)
1597 }
1598 return *(*interface {
1599 M()
1600 })(v.ptr)
1601 }
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612 func (v Value) InterfaceData() [2]uintptr {
1613 v.mustBe(Interface)
1614
1615 escapes(v.ptr)
1616
1617
1618
1619
1620
1621 return *(*[2]uintptr)(v.ptr)
1622 }
1623
1624
1625
1626
1627
1628
1629
1630
1631 func (v Value) IsNil() bool {
1632 k := v.kind()
1633 switch k {
1634 case Chan, Func, Map, Pointer, UnsafePointer:
1635 if v.flag&flagMethod != 0 {
1636 return false
1637 }
1638 ptr := v.ptr
1639 if v.flag&flagIndir != 0 {
1640 ptr = *(*unsafe.Pointer)(ptr)
1641 }
1642 return ptr == nil
1643 case Interface, Slice:
1644
1645
1646 return *(*unsafe.Pointer)(v.ptr) == nil
1647 }
1648 panic(&ValueError{"reflect.Value.IsNil", v.kind()})
1649 }
1650
1651
1652
1653
1654
1655
1656 func (v Value) IsValid() bool {
1657 return v.flag != 0
1658 }
1659
1660
1661
1662 func (v Value) IsZero() bool {
1663 switch v.kind() {
1664 case Bool:
1665 return !v.Bool()
1666 case Int, Int8, Int16, Int32, Int64:
1667 return v.Int() == 0
1668 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
1669 return v.Uint() == 0
1670 case Float32, Float64:
1671 return v.Float() == 0
1672 case Complex64, Complex128:
1673 return v.Complex() == 0
1674 case Array:
1675 if v.flag&flagIndir == 0 {
1676 return v.ptr == nil
1677 }
1678 if v.ptr == unsafe.Pointer(&zeroVal[0]) {
1679 return true
1680 }
1681 typ := (*abi.ArrayType)(unsafe.Pointer(v.typ()))
1682
1683 if typ.Equal != nil && typ.Size() <= abi.ZeroValSize {
1684
1685
1686
1687 return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0]))
1688 }
1689 if typ.TFlag&abi.TFlagRegularMemory != 0 {
1690
1691
1692 return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
1693 }
1694 n := int(typ.Len)
1695 for i := 0; i < n; i++ {
1696 if !v.Index(i).IsZero() {
1697 return false
1698 }
1699 }
1700 return true
1701 case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
1702 return v.IsNil()
1703 case String:
1704 return v.Len() == 0
1705 case Struct:
1706 if v.flag&flagIndir == 0 {
1707 return v.ptr == nil
1708 }
1709 if v.ptr == unsafe.Pointer(&zeroVal[0]) {
1710 return true
1711 }
1712 typ := (*abi.StructType)(unsafe.Pointer(v.typ()))
1713
1714 if typ.Equal != nil && typ.Size() <= abi.ZeroValSize {
1715
1716 return typ.Equal(abi.NoEscape(v.ptr), unsafe.Pointer(&zeroVal[0]))
1717 }
1718 if typ.TFlag&abi.TFlagRegularMemory != 0 {
1719
1720
1721 return isZero(unsafe.Slice(((*byte)(v.ptr)), typ.Size()))
1722 }
1723
1724 n := v.NumField()
1725 for i := 0; i < n; i++ {
1726 if !v.Field(i).IsZero() && v.Type().Field(i).Name != "_" {
1727 return false
1728 }
1729 }
1730 return true
1731 default:
1732
1733
1734 panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
1735 }
1736 }
1737
1738
1739
1740 func isZero(b []byte) bool {
1741 if len(b) == 0 {
1742 return true
1743 }
1744 const n = 32
1745
1746 for uintptr(unsafe.Pointer(&b[0]))%8 != 0 {
1747 if b[0] != 0 {
1748 return false
1749 }
1750 b = b[1:]
1751 if len(b) == 0 {
1752 return true
1753 }
1754 }
1755 for len(b)%8 != 0 {
1756 if b[len(b)-1] != 0 {
1757 return false
1758 }
1759 b = b[:len(b)-1]
1760 }
1761 if len(b) == 0 {
1762 return true
1763 }
1764 w := unsafe.Slice((*uint64)(unsafe.Pointer(&b[0])), len(b)/8)
1765 for len(w)%n != 0 {
1766 if w[0] != 0 {
1767 return false
1768 }
1769 w = w[1:]
1770 }
1771 for len(w) >= n {
1772 if w[0] != 0 || w[1] != 0 || w[2] != 0 || w[3] != 0 ||
1773 w[4] != 0 || w[5] != 0 || w[6] != 0 || w[7] != 0 ||
1774 w[8] != 0 || w[9] != 0 || w[10] != 0 || w[11] != 0 ||
1775 w[12] != 0 || w[13] != 0 || w[14] != 0 || w[15] != 0 ||
1776 w[16] != 0 || w[17] != 0 || w[18] != 0 || w[19] != 0 ||
1777 w[20] != 0 || w[21] != 0 || w[22] != 0 || w[23] != 0 ||
1778 w[24] != 0 || w[25] != 0 || w[26] != 0 || w[27] != 0 ||
1779 w[28] != 0 || w[29] != 0 || w[30] != 0 || w[31] != 0 {
1780 return false
1781 }
1782 w = w[n:]
1783 }
1784 return true
1785 }
1786
1787
1788
1789 func (v Value) SetZero() {
1790 v.mustBeAssignable()
1791 switch v.kind() {
1792 case Bool:
1793 *(*bool)(v.ptr) = false
1794 case Int:
1795 *(*int)(v.ptr) = 0
1796 case Int8:
1797 *(*int8)(v.ptr) = 0
1798 case Int16:
1799 *(*int16)(v.ptr) = 0
1800 case Int32:
1801 *(*int32)(v.ptr) = 0
1802 case Int64:
1803 *(*int64)(v.ptr) = 0
1804 case Uint:
1805 *(*uint)(v.ptr) = 0
1806 case Uint8:
1807 *(*uint8)(v.ptr) = 0
1808 case Uint16:
1809 *(*uint16)(v.ptr) = 0
1810 case Uint32:
1811 *(*uint32)(v.ptr) = 0
1812 case Uint64:
1813 *(*uint64)(v.ptr) = 0
1814 case Uintptr:
1815 *(*uintptr)(v.ptr) = 0
1816 case Float32:
1817 *(*float32)(v.ptr) = 0
1818 case Float64:
1819 *(*float64)(v.ptr) = 0
1820 case Complex64:
1821 *(*complex64)(v.ptr) = 0
1822 case Complex128:
1823 *(*complex128)(v.ptr) = 0
1824 case String:
1825 *(*string)(v.ptr) = ""
1826 case Slice:
1827 *(*unsafeheader.Slice)(v.ptr) = unsafeheader.Slice{}
1828 case Interface:
1829 *(*abi.EmptyInterface)(v.ptr) = abi.EmptyInterface{}
1830 case Chan, Func, Map, Pointer, UnsafePointer:
1831 *(*unsafe.Pointer)(v.ptr) = nil
1832 case Array, Struct:
1833 typedmemclr(v.typ(), v.ptr)
1834 default:
1835
1836
1837 panic(&ValueError{"reflect.Value.SetZero", v.Kind()})
1838 }
1839 }
1840
1841
1842
1843 func (v Value) Kind() Kind {
1844 return v.kind()
1845 }
1846
1847
1848
1849 func (v Value) Len() int {
1850
1851 if v.kind() == Slice {
1852 return (*unsafeheader.Slice)(v.ptr).Len
1853 }
1854 return v.lenNonSlice()
1855 }
1856
1857 func (v Value) lenNonSlice() int {
1858 switch k := v.kind(); k {
1859 case Array:
1860 tt := (*arrayType)(unsafe.Pointer(v.typ()))
1861 return int(tt.Len)
1862 case Chan:
1863 return chanlen(v.pointer())
1864 case Map:
1865 return maplen(v.pointer())
1866 case String:
1867
1868 return (*unsafeheader.String)(v.ptr).Len
1869 case Ptr:
1870 if v.typ().Elem().Kind() == abi.Array {
1871 return v.typ().Elem().Len()
1872 }
1873 panic("reflect: call of reflect.Value.Len on ptr to non-array Value")
1874 }
1875 panic(&ValueError{"reflect.Value.Len", v.kind()})
1876 }
1877
1878
1879
1880 func copyVal(typ *abi.Type, fl flag, ptr unsafe.Pointer) Value {
1881 if !typ.IsDirectIface() {
1882
1883
1884 c := unsafe_New(typ)
1885 typedmemmove(typ, c, ptr)
1886 return Value{typ, c, fl | flagIndir}
1887 }
1888 return Value{typ, *(*unsafe.Pointer)(ptr), fl}
1889 }
1890
1891
1892
1893
1894
1895
1896
1897
1898 func (v Value) Method(i int) Value {
1899 if v.typ() == nil {
1900 panic(&ValueError{"reflect.Value.Method", Invalid})
1901 }
1902 if v.flag&flagMethod != 0 || uint(i) >= uint(toRType(v.typ()).NumMethod()) {
1903 panic("reflect: Method index out of range")
1904 }
1905 if v.typ().Kind() == abi.Interface && v.IsNil() {
1906 panic("reflect: Method on nil interface value")
1907 }
1908 fl := v.flag.ro() | (v.flag & flagIndir)
1909 fl |= flag(Func)
1910 fl |= flag(i)<<flagMethodShift | flagMethod
1911 return Value{v.typ(), v.ptr, fl}
1912 }
1913
1914
1915
1916
1917
1918
1919 func (v Value) NumMethod() int {
1920 if v.typ() == nil {
1921 panic(&ValueError{"reflect.Value.NumMethod", Invalid})
1922 }
1923 if v.flag&flagMethod != 0 {
1924 return 0
1925 }
1926 return toRType(v.typ()).NumMethod()
1927 }
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938 func (v Value) MethodByName(name string) Value {
1939 if v.typ() == nil {
1940 panic(&ValueError{"reflect.Value.MethodByName", Invalid})
1941 }
1942 if v.flag&flagMethod != 0 {
1943 return Value{}
1944 }
1945 m, ok := toRType(v.typ()).MethodByName(name)
1946 if !ok {
1947 return Value{}
1948 }
1949 return v.Method(m.Index)
1950 }
1951
1952
1953
1954 func (v Value) NumField() int {
1955 v.mustBe(Struct)
1956 tt := (*structType)(unsafe.Pointer(v.typ()))
1957 return len(tt.Fields)
1958 }
1959
1960
1961
1962 func (v Value) OverflowComplex(x complex128) bool {
1963 k := v.kind()
1964 switch k {
1965 case Complex64:
1966 return overflowFloat32(real(x)) || overflowFloat32(imag(x))
1967 case Complex128:
1968 return false
1969 }
1970 panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
1971 }
1972
1973
1974
1975 func (v Value) OverflowFloat(x float64) bool {
1976 k := v.kind()
1977 switch k {
1978 case Float32:
1979 return overflowFloat32(x)
1980 case Float64:
1981 return false
1982 }
1983 panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
1984 }
1985
1986 func overflowFloat32(x float64) bool {
1987 if x < 0 {
1988 x = -x
1989 }
1990 return math.MaxFloat32 < x && x <= math.MaxFloat64
1991 }
1992
1993
1994
1995 func (v Value) OverflowInt(x int64) bool {
1996 k := v.kind()
1997 switch k {
1998 case Int, Int8, Int16, Int32, Int64:
1999 bitSize := v.typ().Size() * 8
2000 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
2001 return x != trunc
2002 }
2003 panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
2004 }
2005
2006
2007
2008 func (v Value) OverflowUint(x uint64) bool {
2009 k := v.kind()
2010 switch k {
2011 case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
2012 bitSize := v.typ_.Size() * 8
2013 trunc := (x << (64 - bitSize)) >> (64 - bitSize)
2014 return x != trunc
2015 }
2016 panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
2017 }
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040 func (v Value) Pointer() uintptr {
2041
2042 escapes(v.ptr)
2043
2044 k := v.kind()
2045 switch k {
2046 case Pointer:
2047 if !v.typ().Pointers() {
2048 val := *(*uintptr)(v.ptr)
2049
2050
2051 if !verifyNotInHeapPtr(val) {
2052 panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
2053 }
2054 return val
2055 }
2056 fallthrough
2057 case Chan, Map, UnsafePointer:
2058 return uintptr(v.pointer())
2059 case Func:
2060 if v.flag&flagMethod != 0 {
2061
2062
2063
2064
2065
2066
2067 return methodValueCallCodePtr()
2068 }
2069 p := v.pointer()
2070
2071
2072 if p != nil {
2073 p = *(*unsafe.Pointer)(p)
2074 }
2075 return uintptr(p)
2076 case Slice:
2077 return uintptr((*unsafeheader.Slice)(v.ptr).Data)
2078 case String:
2079 return uintptr((*unsafeheader.String)(v.ptr).Data)
2080 }
2081 panic(&ValueError{"reflect.Value.Pointer", v.kind()})
2082 }
2083
2084
2085
2086
2087
2088
2089 func (v Value) Recv() (x Value, ok bool) {
2090 v.mustBe(Chan)
2091 v.mustBeExported()
2092 return v.recv(false)
2093 }
2094
2095
2096
2097 func (v Value) recv(nb bool) (val Value, ok bool) {
2098 tt := (*chanType)(unsafe.Pointer(v.typ()))
2099 if ChanDir(tt.Dir)&RecvDir == 0 {
2100 panic("reflect: recv on send-only channel")
2101 }
2102 t := tt.Elem
2103 val = Value{t, nil, flag(t.Kind())}
2104 var p unsafe.Pointer
2105 if !t.IsDirectIface() {
2106 p = unsafe_New(t)
2107 val.ptr = p
2108 val.flag |= flagIndir
2109 } else {
2110 p = unsafe.Pointer(&val.ptr)
2111 }
2112 selected, ok := chanrecv(v.pointer(), nb, p)
2113 if !selected {
2114 val = Value{}
2115 }
2116 return
2117 }
2118
2119
2120
2121
2122 func (v Value) Send(x Value) {
2123 v.mustBe(Chan)
2124 v.mustBeExported()
2125 v.send(x, false)
2126 }
2127
2128
2129
2130 func (v Value) send(x Value, nb bool) (selected bool) {
2131 tt := (*chanType)(unsafe.Pointer(v.typ()))
2132 if ChanDir(tt.Dir)&SendDir == 0 {
2133 panic("reflect: send on recv-only channel")
2134 }
2135 x.mustBeExported()
2136 x = x.assignTo("reflect.Value.Send", tt.Elem, nil)
2137 var p unsafe.Pointer
2138 if x.flag&flagIndir != 0 {
2139 p = x.ptr
2140 } else {
2141 p = unsafe.Pointer(&x.ptr)
2142 }
2143 return chansend(v.pointer(), p, nb)
2144 }
2145
2146
2147
2148
2149
2150 func (v Value) Set(x Value) {
2151 v.mustBeAssignable()
2152 x.mustBeExported()
2153 var target unsafe.Pointer
2154 if v.kind() == Interface {
2155 target = v.ptr
2156 }
2157 x = x.assignTo("reflect.Set", v.typ(), target)
2158 if x.flag&flagIndir != 0 {
2159 if x.ptr == unsafe.Pointer(&zeroVal[0]) {
2160 typedmemclr(v.typ(), v.ptr)
2161 } else {
2162 typedmemmove(v.typ(), v.ptr, x.ptr)
2163 }
2164 } else {
2165 *(*unsafe.Pointer)(v.ptr) = x.ptr
2166 }
2167 }
2168
2169
2170
2171 func (v Value) SetBool(x bool) {
2172 v.mustBeAssignable()
2173 v.mustBe(Bool)
2174 *(*bool)(v.ptr) = x
2175 }
2176
2177
2178
2179
2180 func (v Value) SetBytes(x []byte) {
2181 v.mustBeAssignable()
2182 v.mustBe(Slice)
2183 if toRType(v.typ()).Elem().Kind() != Uint8 {
2184 panic("reflect.Value.SetBytes of non-byte slice")
2185 }
2186 *(*[]byte)(v.ptr) = x
2187 }
2188
2189
2190
2191
2192 func (v Value) setRunes(x []rune) {
2193 v.mustBeAssignable()
2194 v.mustBe(Slice)
2195 if v.typ().Elem().Kind() != abi.Int32 {
2196 panic("reflect.Value.setRunes of non-rune slice")
2197 }
2198 *(*[]rune)(v.ptr) = x
2199 }
2200
2201
2202
2203
2204 func (v Value) SetComplex(x complex128) {
2205 v.mustBeAssignable()
2206 switch k := v.kind(); k {
2207 default:
2208 panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
2209 case Complex64:
2210 *(*complex64)(v.ptr) = complex64(x)
2211 case Complex128:
2212 *(*complex128)(v.ptr) = x
2213 }
2214 }
2215
2216
2217
2218
2219 func (v Value) SetFloat(x float64) {
2220 v.mustBeAssignable()
2221 switch k := v.kind(); k {
2222 default:
2223 panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
2224 case Float32:
2225 *(*float32)(v.ptr) = float32(x)
2226 case Float64:
2227 *(*float64)(v.ptr) = x
2228 }
2229 }
2230
2231
2232
2233
2234 func (v Value) SetInt(x int64) {
2235 v.mustBeAssignable()
2236 switch k := v.kind(); k {
2237 default:
2238 panic(&ValueError{"reflect.Value.SetInt", v.kind()})
2239 case Int:
2240 *(*int)(v.ptr) = int(x)
2241 case Int8:
2242 *(*int8)(v.ptr) = int8(x)
2243 case Int16:
2244 *(*int16)(v.ptr) = int16(x)
2245 case Int32:
2246 *(*int32)(v.ptr) = int32(x)
2247 case Int64:
2248 *(*int64)(v.ptr) = x
2249 }
2250 }
2251
2252
2253
2254
2255
2256 func (v Value) SetLen(n int) {
2257 v.mustBeAssignable()
2258 v.mustBe(Slice)
2259 s := (*unsafeheader.Slice)(v.ptr)
2260 if uint(n) > uint(s.Cap) {
2261 panic("reflect: slice length out of range in SetLen")
2262 }
2263 s.Len = n
2264 }
2265
2266
2267
2268
2269
2270 func (v Value) SetCap(n int) {
2271 v.mustBeAssignable()
2272 v.mustBe(Slice)
2273 s := (*unsafeheader.Slice)(v.ptr)
2274 if n < s.Len || n > s.Cap {
2275 panic("reflect: slice capacity out of range in SetCap")
2276 }
2277 s.Cap = n
2278 }
2279
2280
2281
2282
2283 func (v Value) SetUint(x uint64) {
2284 v.mustBeAssignable()
2285 switch k := v.kind(); k {
2286 default:
2287 panic(&ValueError{"reflect.Value.SetUint", v.kind()})
2288 case Uint:
2289 *(*uint)(v.ptr) = uint(x)
2290 case Uint8:
2291 *(*uint8)(v.ptr) = uint8(x)
2292 case Uint16:
2293 *(*uint16)(v.ptr) = uint16(x)
2294 case Uint32:
2295 *(*uint32)(v.ptr) = uint32(x)
2296 case Uint64:
2297 *(*uint64)(v.ptr) = x
2298 case Uintptr:
2299 *(*uintptr)(v.ptr) = uintptr(x)
2300 }
2301 }
2302
2303
2304
2305
2306 func (v Value) SetPointer(x unsafe.Pointer) {
2307 v.mustBeAssignable()
2308 v.mustBe(UnsafePointer)
2309 *(*unsafe.Pointer)(v.ptr) = x
2310 }
2311
2312
2313
2314 func (v Value) SetString(x string) {
2315 v.mustBeAssignable()
2316 v.mustBe(String)
2317 *(*string)(v.ptr) = x
2318 }
2319
2320
2321
2322
2323 func (v Value) Slice(i, j int) Value {
2324 var (
2325 cap int
2326 typ *sliceType
2327 base unsafe.Pointer
2328 )
2329 switch kind := v.kind(); kind {
2330 default:
2331 panic(&ValueError{"reflect.Value.Slice", v.kind()})
2332
2333 case Array:
2334 if v.flag&flagAddr == 0 {
2335 panic("reflect.Value.Slice: slice of unaddressable array")
2336 }
2337 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2338 cap = int(tt.Len)
2339 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2340 base = v.ptr
2341
2342 case Slice:
2343 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2344 s := (*unsafeheader.Slice)(v.ptr)
2345 base = s.Data
2346 cap = s.Cap
2347
2348 case String:
2349 s := (*unsafeheader.String)(v.ptr)
2350 if i < 0 || j < i || j > s.Len {
2351 panic("reflect.Value.Slice: string slice index out of bounds")
2352 }
2353 var t unsafeheader.String
2354 if i < s.Len {
2355 t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
2356 }
2357 return Value{v.typ(), unsafe.Pointer(&t), v.flag}
2358 }
2359
2360 if i < 0 || j < i || j > cap {
2361 panic("reflect.Value.Slice: slice index out of bounds")
2362 }
2363
2364
2365 var x []unsafe.Pointer
2366
2367
2368 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2369 s.Len = j - i
2370 s.Cap = cap - i
2371 if cap-i > 0 {
2372 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < cap")
2373 } else {
2374
2375 s.Data = base
2376 }
2377
2378 fl := v.flag.ro() | flagIndir | flag(Slice)
2379 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2380 }
2381
2382
2383
2384
2385 func (v Value) Slice3(i, j, k int) Value {
2386 var (
2387 cap int
2388 typ *sliceType
2389 base unsafe.Pointer
2390 )
2391 switch kind := v.kind(); kind {
2392 default:
2393 panic(&ValueError{"reflect.Value.Slice3", v.kind()})
2394
2395 case Array:
2396 if v.flag&flagAddr == 0 {
2397 panic("reflect.Value.Slice3: slice of unaddressable array")
2398 }
2399 tt := (*arrayType)(unsafe.Pointer(v.typ()))
2400 cap = int(tt.Len)
2401 typ = (*sliceType)(unsafe.Pointer(tt.Slice))
2402 base = v.ptr
2403
2404 case Slice:
2405 typ = (*sliceType)(unsafe.Pointer(v.typ()))
2406 s := (*unsafeheader.Slice)(v.ptr)
2407 base = s.Data
2408 cap = s.Cap
2409 }
2410
2411 if i < 0 || j < i || k < j || k > cap {
2412 panic("reflect.Value.Slice3: slice index out of bounds")
2413 }
2414
2415
2416
2417 var x []unsafe.Pointer
2418
2419
2420 s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
2421 s.Len = j - i
2422 s.Cap = k - i
2423 if k-i > 0 {
2424 s.Data = arrayAt(base, i, typ.Elem.Size(), "i < k <= cap")
2425 } else {
2426
2427 s.Data = base
2428 }
2429
2430 fl := v.flag.ro() | flagIndir | flag(Slice)
2431 return Value{typ.Common(), unsafe.Pointer(&x), fl}
2432 }
2433
2434
2435
2436
2437
2438
2439
2440 func (v Value) String() string {
2441
2442 if v.kind() == String {
2443 return *(*string)(v.ptr)
2444 }
2445 return v.stringNonString()
2446 }
2447
2448 func (v Value) stringNonString() string {
2449 if v.kind() == Invalid {
2450 return "<invalid Value>"
2451 }
2452
2453
2454 return "<" + v.Type().String() + " Value>"
2455 }
2456
2457
2458
2459
2460
2461
2462 func (v Value) TryRecv() (x Value, ok bool) {
2463 v.mustBe(Chan)
2464 v.mustBeExported()
2465 return v.recv(true)
2466 }
2467
2468
2469
2470
2471
2472 func (v Value) TrySend(x Value) bool {
2473 v.mustBe(Chan)
2474 v.mustBeExported()
2475 return v.send(x, true)
2476 }
2477
2478
2479 func (v Value) Type() Type {
2480 if v.flag != 0 && v.flag&flagMethod == 0 {
2481 return (*rtype)(abi.NoEscape(unsafe.Pointer(v.typ_)))
2482 }
2483 return v.typeSlow()
2484 }
2485
2486
2487 func (v Value) typeSlow() Type {
2488 return toRType(v.abiTypeSlow())
2489 }
2490
2491 func (v Value) abiType() *abi.Type {
2492 if v.flag != 0 && v.flag&flagMethod == 0 {
2493 return v.typ()
2494 }
2495 return v.abiTypeSlow()
2496 }
2497
2498 func (v Value) abiTypeSlow() *abi.Type {
2499 if v.flag == 0 {
2500 panic(&ValueError{"reflect.Value.Type", Invalid})
2501 }
2502
2503 typ := v.typ()
2504 if v.flag&flagMethod == 0 {
2505 return v.typ()
2506 }
2507
2508
2509
2510 i := int(v.flag) >> flagMethodShift
2511 if v.typ().Kind() == abi.Interface {
2512
2513 tt := (*interfaceType)(unsafe.Pointer(typ))
2514 if uint(i) >= uint(len(tt.Methods)) {
2515 panic("reflect: internal error: invalid method index")
2516 }
2517 m := &tt.Methods[i]
2518 return typeOffFor(typ, m.Typ)
2519 }
2520
2521 ms := typ.ExportedMethods()
2522 if uint(i) >= uint(len(ms)) {
2523 panic("reflect: internal error: invalid method index")
2524 }
2525 m := ms[i]
2526 return typeOffFor(typ, m.Mtyp)
2527 }
2528
2529
2530 func (v Value) CanUint() bool {
2531 switch v.kind() {
2532 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
2533 return true
2534 default:
2535 return false
2536 }
2537 }
2538
2539
2540
2541 func (v Value) Uint() uint64 {
2542 k := v.kind()
2543 p := v.ptr
2544 switch k {
2545 case Uint:
2546 return uint64(*(*uint)(p))
2547 case Uint8:
2548 return uint64(*(*uint8)(p))
2549 case Uint16:
2550 return uint64(*(*uint16)(p))
2551 case Uint32:
2552 return uint64(*(*uint32)(p))
2553 case Uint64:
2554 return *(*uint64)(p)
2555 case Uintptr:
2556 return uint64(*(*uintptr)(p))
2557 }
2558 panic(&ValueError{"reflect.Value.Uint", v.kind()})
2559 }
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570 func (v Value) UnsafeAddr() uintptr {
2571 if v.typ() == nil {
2572 panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
2573 }
2574 if v.flag&flagAddr == 0 {
2575 panic("reflect.Value.UnsafeAddr of unaddressable value")
2576 }
2577
2578 escapes(v.ptr)
2579 return uintptr(v.ptr)
2580 }
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596 func (v Value) UnsafePointer() unsafe.Pointer {
2597 k := v.kind()
2598 switch k {
2599 case Pointer:
2600 if !v.typ().Pointers() {
2601
2602
2603 if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
2604 panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
2605 }
2606 return *(*unsafe.Pointer)(v.ptr)
2607 }
2608 fallthrough
2609 case Chan, Map, UnsafePointer:
2610 return v.pointer()
2611 case Func:
2612 if v.flag&flagMethod != 0 {
2613
2614
2615
2616
2617
2618
2619 code := methodValueCallCodePtr()
2620 return *(*unsafe.Pointer)(unsafe.Pointer(&code))
2621 }
2622 p := v.pointer()
2623
2624
2625 if p != nil {
2626 p = *(*unsafe.Pointer)(p)
2627 }
2628 return p
2629 case Slice:
2630 return (*unsafeheader.Slice)(v.ptr).Data
2631 case String:
2632 return (*unsafeheader.String)(v.ptr).Data
2633 }
2634 panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
2635 }
2636
2637
2638
2639
2640
2641
2642
2643 func (v Value) Fields() iter.Seq2[StructField, Value] {
2644 t := v.Type()
2645 if t.Kind() != Struct {
2646 panic("reflect: Fields of non-struct type " + t.String())
2647 }
2648 return func(yield func(StructField, Value) bool) {
2649 for i := range v.NumField() {
2650 if !yield(t.Field(i), v.Field(i)) {
2651 return
2652 }
2653 }
2654 }
2655 }
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668 func (v Value) Methods() iter.Seq2[Method, Value] {
2669 return func(yield func(Method, Value) bool) {
2670 rtype := v.Type()
2671 for i := range v.NumMethod() {
2672 if !yield(rtype.Method(i), v.Method(i)) {
2673 return
2674 }
2675 }
2676 }
2677 }
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687 type StringHeader struct {
2688 Data uintptr
2689 Len int
2690 }
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700 type SliceHeader struct {
2701 Data uintptr
2702 Len int
2703 Cap int
2704 }
2705
2706 func typesMustMatch(what string, t1, t2 Type) {
2707 if t1 != t2 {
2708 panic(what + ": " + t1.String() + " != " + t2.String())
2709 }
2710 }
2711
2712
2713
2714
2715
2716
2717
2718
2719 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
2720 return add(p, uintptr(i)*eltSize, "i < len")
2721 }
2722
2723
2724
2725
2726
2727
2728
2729 func (v Value) Grow(n int) {
2730 v.mustBeAssignable()
2731 v.mustBe(Slice)
2732 v.grow(n)
2733 }
2734
2735
2736 func (v Value) grow(n int) {
2737 p := (*unsafeheader.Slice)(v.ptr)
2738 switch {
2739 case n < 0:
2740 panic("reflect.Value.Grow: negative len")
2741 case p.Len+n < 0:
2742 panic("reflect.Value.Grow: slice overflow")
2743 case p.Len+n > p.Cap:
2744 t := v.typ().Elem()
2745 *p = growslice(t, *p, n)
2746 }
2747 }
2748
2749
2750
2751
2752
2753
2754
2755 func (v Value) extendSlice(n int) Value {
2756 v.mustBeExported()
2757 v.mustBe(Slice)
2758
2759
2760 sh := *(*unsafeheader.Slice)(v.ptr)
2761 s := &sh
2762 v.ptr = unsafe.Pointer(s)
2763 v.flag = flagIndir | flag(Slice)
2764
2765 v.grow(n)
2766 s.Len += n
2767 return v
2768 }
2769
2770
2771
2772
2773 func (v Value) Clear() {
2774 switch v.Kind() {
2775 case Slice:
2776 sh := *(*unsafeheader.Slice)(v.ptr)
2777 st := (*sliceType)(unsafe.Pointer(v.typ()))
2778 typedarrayclear(st.Elem, sh.Data, sh.Len)
2779 case Map:
2780 mapclear(v.typ(), v.pointer())
2781 default:
2782 panic(&ValueError{"reflect.Value.Clear", v.Kind()})
2783 }
2784 }
2785
2786
2787
2788 func Append(s Value, x ...Value) Value {
2789 s.mustBe(Slice)
2790 n := s.Len()
2791 s = s.extendSlice(len(x))
2792 for i, v := range x {
2793 s.Index(n + i).Set(v)
2794 }
2795 return s
2796 }
2797
2798
2799
2800 func AppendSlice(s, t Value) Value {
2801 s.mustBe(Slice)
2802 t.mustBe(Slice)
2803 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
2804 ns := s.Len()
2805 nt := t.Len()
2806 s = s.extendSlice(nt)
2807 Copy(s.Slice(ns, ns+nt), t)
2808 return s
2809 }
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819 func Copy(dst, src Value) int {
2820 dk := dst.kind()
2821 if dk != Array && dk != Slice {
2822 panic(&ValueError{"reflect.Copy", dk})
2823 }
2824 if dk == Array {
2825 dst.mustBeAssignable()
2826 }
2827 dst.mustBeExported()
2828
2829 sk := src.kind()
2830 var stringCopy bool
2831 if sk != Array && sk != Slice {
2832 stringCopy = sk == String && dst.typ().Elem().Kind() == abi.Uint8
2833 if !stringCopy {
2834 panic(&ValueError{"reflect.Copy", sk})
2835 }
2836 }
2837 src.mustBeExported()
2838
2839 de := dst.typ().Elem()
2840 if !stringCopy {
2841 se := src.typ().Elem()
2842 typesMustMatch("reflect.Copy", toType(de), toType(se))
2843 }
2844
2845 var ds, ss unsafeheader.Slice
2846 if dk == Array {
2847 ds.Data = dst.ptr
2848 ds.Len = dst.Len()
2849 ds.Cap = ds.Len
2850 } else {
2851 ds = *(*unsafeheader.Slice)(dst.ptr)
2852 }
2853 if sk == Array {
2854 ss.Data = src.ptr
2855 ss.Len = src.Len()
2856 ss.Cap = ss.Len
2857 } else if sk == Slice {
2858 ss = *(*unsafeheader.Slice)(src.ptr)
2859 } else {
2860 sh := *(*unsafeheader.String)(src.ptr)
2861 ss.Data = sh.Data
2862 ss.Len = sh.Len
2863 ss.Cap = sh.Len
2864 }
2865
2866 return typedslicecopy(de.Common(), ds, ss)
2867 }
2868
2869
2870
2871 type runtimeSelect struct {
2872 dir SelectDir
2873 typ *rtype
2874 ch unsafe.Pointer
2875 val unsafe.Pointer
2876 }
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889 func rselect([]runtimeSelect) (chosen int, recvOK bool)
2890
2891
2892 type SelectDir int
2893
2894
2895
2896 const (
2897 _ SelectDir = iota
2898 SelectSend
2899 SelectRecv
2900 SelectDefault
2901 )
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919 type SelectCase struct {
2920 Dir SelectDir
2921 Chan Value
2922 Send Value
2923 }
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
2934 if len(cases) > 65536 {
2935 panic("reflect.Select: too many cases (max 65536)")
2936 }
2937
2938
2939
2940 var runcases []runtimeSelect
2941 if len(cases) > 4 {
2942
2943 runcases = make([]runtimeSelect, len(cases))
2944 } else {
2945
2946 runcases = make([]runtimeSelect, len(cases), 4)
2947 }
2948
2949 haveDefault := false
2950 for i, c := range cases {
2951 rc := &runcases[i]
2952 rc.dir = c.Dir
2953 switch c.Dir {
2954 default:
2955 panic("reflect.Select: invalid Dir")
2956
2957 case SelectDefault:
2958 if haveDefault {
2959 panic("reflect.Select: multiple default cases")
2960 }
2961 haveDefault = true
2962 if c.Chan.IsValid() {
2963 panic("reflect.Select: default case has Chan value")
2964 }
2965 if c.Send.IsValid() {
2966 panic("reflect.Select: default case has Send value")
2967 }
2968
2969 case SelectSend:
2970 ch := c.Chan
2971 if !ch.IsValid() {
2972 break
2973 }
2974 ch.mustBe(Chan)
2975 ch.mustBeExported()
2976 tt := (*chanType)(unsafe.Pointer(ch.typ()))
2977 if ChanDir(tt.Dir)&SendDir == 0 {
2978 panic("reflect.Select: SendDir case using recv-only channel")
2979 }
2980 rc.ch = ch.pointer()
2981 rc.typ = toRType(&tt.Type)
2982 v := c.Send
2983 if !v.IsValid() {
2984 panic("reflect.Select: SendDir case missing Send value")
2985 }
2986 v.mustBeExported()
2987 v = v.assignTo("reflect.Select", tt.Elem, nil)
2988 if v.flag&flagIndir != 0 {
2989 rc.val = v.ptr
2990 } else {
2991 rc.val = unsafe.Pointer(&v.ptr)
2992 }
2993
2994
2995 escapes(rc.val)
2996
2997 case SelectRecv:
2998 if c.Send.IsValid() {
2999 panic("reflect.Select: RecvDir case has Send value")
3000 }
3001 ch := c.Chan
3002 if !ch.IsValid() {
3003 break
3004 }
3005 ch.mustBe(Chan)
3006 ch.mustBeExported()
3007 tt := (*chanType)(unsafe.Pointer(ch.typ()))
3008 if ChanDir(tt.Dir)&RecvDir == 0 {
3009 panic("reflect.Select: RecvDir case using send-only channel")
3010 }
3011 rc.ch = ch.pointer()
3012 rc.typ = toRType(&tt.Type)
3013 rc.val = unsafe_New(tt.Elem)
3014 }
3015 }
3016
3017 chosen, recvOK = rselect(runcases)
3018 if runcases[chosen].dir == SelectRecv {
3019 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
3020 t := tt.Elem
3021 p := runcases[chosen].val
3022 fl := flag(t.Kind())
3023 if !t.IsDirectIface() {
3024 recv = Value{t, p, fl | flagIndir}
3025 } else {
3026 recv = Value{t, *(*unsafe.Pointer)(p), fl}
3027 }
3028 }
3029 return chosen, recv, recvOK
3030 }
3031
3032
3035
3036
3037
3038
3039 func unsafe_New(*abi.Type) unsafe.Pointer
3040
3041
3042 func unsafe_NewArray(*abi.Type, int) unsafe.Pointer
3043
3044
3045
3046 func MakeSlice(typ Type, len, cap int) Value {
3047 if typ.Kind() != Slice {
3048 panic("reflect.MakeSlice of non-slice type")
3049 }
3050 if len < 0 {
3051 panic("reflect.MakeSlice: negative len")
3052 }
3053 if cap < 0 {
3054 panic("reflect.MakeSlice: negative cap")
3055 }
3056 if len > cap {
3057 panic("reflect.MakeSlice: len > cap")
3058 }
3059
3060 s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
3061 return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
3062 }
3063
3064
3065
3066
3067
3068 func SliceAt(typ Type, p unsafe.Pointer, n int) Value {
3069 unsafeslice(typ.common(), p, n)
3070 s := unsafeheader.Slice{Data: p, Len: n, Cap: n}
3071 return Value{SliceOf(typ).common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
3072 }
3073
3074
3075 func MakeChan(typ Type, buffer int) Value {
3076 if typ.Kind() != Chan {
3077 panic("reflect.MakeChan of non-chan type")
3078 }
3079 if buffer < 0 {
3080 panic("reflect.MakeChan: negative buffer size")
3081 }
3082 if typ.ChanDir() != BothDir {
3083 panic("reflect.MakeChan: unidirectional channel type")
3084 }
3085 t := typ.common()
3086 ch := makechan(t, buffer)
3087 return Value{t, ch, flag(Chan)}
3088 }
3089
3090
3091 func MakeMap(typ Type) Value {
3092 return MakeMapWithSize(typ, 0)
3093 }
3094
3095
3096
3097 func MakeMapWithSize(typ Type, n int) Value {
3098 if typ.Kind() != Map {
3099 panic("reflect.MakeMapWithSize of non-map type")
3100 }
3101 t := typ.common()
3102 m := makemap(t, n)
3103 return Value{t, m, flag(Map)}
3104 }
3105
3106
3107
3108
3109 func Indirect(v Value) Value {
3110 if v.Kind() != Pointer {
3111 return v
3112 }
3113 return v.Elem()
3114 }
3115
3116
3117
3118 func ValueOf(i any) Value {
3119 if i == nil {
3120 return Value{}
3121 }
3122 return unpackEface(i)
3123 }
3124
3125
3126
3127
3128
3129
3130 func Zero(typ Type) Value {
3131 if typ == nil {
3132 panic("reflect: Zero(nil)")
3133 }
3134 t := &typ.(*rtype).t
3135 fl := flag(t.Kind())
3136 if !t.IsDirectIface() {
3137 var p unsafe.Pointer
3138 if t.Size() <= abi.ZeroValSize {
3139 p = unsafe.Pointer(&zeroVal[0])
3140 } else {
3141 p = unsafe_New(t)
3142 }
3143 return Value{t, p, fl | flagIndir}
3144 }
3145 return Value{t, nil, fl}
3146 }
3147
3148
3149 var zeroVal [abi.ZeroValSize]byte
3150
3151
3152
3153 func New(typ Type) Value {
3154 if typ == nil {
3155 panic("reflect: New(nil)")
3156 }
3157 t := &typ.(*rtype).t
3158 pt := ptrTo(t)
3159 if !pt.IsDirectIface() {
3160
3161 panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
3162 }
3163 ptr := unsafe_New(t)
3164 fl := flag(Pointer)
3165 return Value{pt, ptr, fl}
3166 }
3167
3168
3169
3170 func NewAt(typ Type, p unsafe.Pointer) Value {
3171 fl := flag(Pointer)
3172 t := typ.(*rtype)
3173 return Value{t.ptrTo(), p, fl}
3174 }
3175
3176
3177
3178
3179
3180
3181 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
3182 if v.flag&flagMethod != 0 {
3183 v = makeMethodValue(context, v)
3184 }
3185
3186 switch {
3187 case directlyAssignable(dst, v.typ()):
3188
3189
3190 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
3191 fl |= flag(dst.Kind())
3192 return Value{dst, v.ptr, fl}
3193
3194 case implements(dst, v.typ()):
3195 if v.Kind() == Interface && v.IsNil() {
3196
3197
3198
3199 return Value{dst, nil, flag(Interface)}
3200 }
3201 x := valueInterface(v, false)
3202 if target == nil {
3203 target = unsafe_New(dst)
3204 }
3205 if dst.NumMethod() == 0 {
3206 *(*any)(target) = x
3207 } else {
3208 ifaceE2I(dst, x, target)
3209 }
3210 return Value{dst, target, flagIndir | flag(Interface)}
3211 }
3212
3213
3214 panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
3215 }
3216
3217
3218
3219
3220 func (v Value) Convert(t Type) Value {
3221 if v.flag&flagMethod != 0 {
3222 v = makeMethodValue("Convert", v)
3223 }
3224 op := convertOp(t.common(), v.typ())
3225 if op == nil {
3226 panic("reflect.Value.Convert: value of type " + stringFor(v.typ()) + " cannot be converted to type " + t.String())
3227 }
3228 return op(v, t)
3229 }
3230
3231
3232
3233 func (v Value) CanConvert(t Type) bool {
3234 vt := v.Type()
3235 if !vt.ConvertibleTo(t) {
3236 return false
3237 }
3238
3239
3240 switch {
3241 case vt.Kind() == Slice && t.Kind() == Array:
3242 if t.Len() > v.Len() {
3243 return false
3244 }
3245 case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
3246 n := t.Elem().Len()
3247 if n > v.Len() {
3248 return false
3249 }
3250 }
3251 return true
3252 }
3253
3254
3255
3256
3257
3258 func (v Value) Comparable() bool {
3259 k := v.Kind()
3260 switch k {
3261 case Invalid:
3262 return false
3263
3264 case Array:
3265 switch v.Type().Elem().Kind() {
3266 case Interface, Array, Struct:
3267 for i := 0; i < v.Type().Len(); i++ {
3268 if !v.Index(i).Comparable() {
3269 return false
3270 }
3271 }
3272 return true
3273 }
3274 return v.Type().Comparable()
3275
3276 case Interface:
3277 return v.IsNil() || v.Elem().Comparable()
3278
3279 case Struct:
3280 for _, value := range v.Fields() {
3281 if !value.Comparable() {
3282 return false
3283 }
3284 }
3285 return true
3286
3287 default:
3288 return v.Type().Comparable()
3289 }
3290 }
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300 func (v Value) Equal(u Value) bool {
3301 if v.Kind() == Interface {
3302 v = v.Elem()
3303 }
3304 if u.Kind() == Interface {
3305 u = u.Elem()
3306 }
3307
3308 if !v.IsValid() || !u.IsValid() {
3309 return v.IsValid() == u.IsValid()
3310 }
3311
3312 if v.Kind() != u.Kind() || v.Type() != u.Type() {
3313 return false
3314 }
3315
3316
3317
3318 switch v.Kind() {
3319 default:
3320 panic("reflect.Value.Equal: invalid Kind")
3321 case Bool:
3322 return v.Bool() == u.Bool()
3323 case Int, Int8, Int16, Int32, Int64:
3324 return v.Int() == u.Int()
3325 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3326 return v.Uint() == u.Uint()
3327 case Float32, Float64:
3328 return v.Float() == u.Float()
3329 case Complex64, Complex128:
3330 return v.Complex() == u.Complex()
3331 case String:
3332 return v.String() == u.String()
3333 case Chan, Pointer, UnsafePointer:
3334 return v.Pointer() == u.Pointer()
3335 case Array:
3336
3337 vl := v.Len()
3338 if vl == 0 {
3339
3340 if !v.Type().Elem().Comparable() {
3341 break
3342 }
3343 return true
3344 }
3345 for i := 0; i < vl; i++ {
3346 if !v.Index(i).Equal(u.Index(i)) {
3347 return false
3348 }
3349 }
3350 return true
3351 case Struct:
3352
3353 nf := v.NumField()
3354 for i := 0; i < nf; i++ {
3355 if !v.Field(i).Equal(u.Field(i)) {
3356 return false
3357 }
3358 }
3359 return true
3360 case Func, Map, Slice:
3361 break
3362 }
3363 panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
3364 }
3365
3366
3367
3368 func convertOp(dst, src *abi.Type) func(Value, Type) Value {
3369 switch Kind(src.Kind()) {
3370 case Int, Int8, Int16, Int32, Int64:
3371 switch Kind(dst.Kind()) {
3372 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3373 return cvtInt
3374 case Float32, Float64:
3375 return cvtIntFloat
3376 case String:
3377 return cvtIntString
3378 }
3379
3380 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3381 switch Kind(dst.Kind()) {
3382 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3383 return cvtUint
3384 case Float32, Float64:
3385 return cvtUintFloat
3386 case String:
3387 return cvtUintString
3388 }
3389
3390 case Float32, Float64:
3391 switch Kind(dst.Kind()) {
3392 case Int, Int8, Int16, Int32, Int64:
3393 return cvtFloatInt
3394 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3395 return cvtFloatUint
3396 case Float32, Float64:
3397 return cvtFloat
3398 }
3399
3400 case Complex64, Complex128:
3401 switch Kind(dst.Kind()) {
3402 case Complex64, Complex128:
3403 return cvtComplex
3404 }
3405
3406 case String:
3407 if dst.Kind() == abi.Slice && pkgPathFor(dst.Elem()) == "" {
3408 switch Kind(dst.Elem().Kind()) {
3409 case Uint8:
3410 return cvtStringBytes
3411 case Int32:
3412 return cvtStringRunes
3413 }
3414 }
3415
3416 case Slice:
3417 if dst.Kind() == abi.String && pkgPathFor(src.Elem()) == "" {
3418 switch Kind(src.Elem().Kind()) {
3419 case Uint8:
3420 return cvtBytesString
3421 case Int32:
3422 return cvtRunesString
3423 }
3424 }
3425
3426
3427 if dst.Kind() == abi.Pointer && dst.Elem().Kind() == abi.Array && src.Elem() == dst.Elem().Elem() {
3428 return cvtSliceArrayPtr
3429 }
3430
3431
3432 if dst.Kind() == abi.Array && src.Elem() == dst.Elem() {
3433 return cvtSliceArray
3434 }
3435
3436 case Chan:
3437 if dst.Kind() == abi.Chan && specialChannelAssignability(dst, src) {
3438 return cvtDirect
3439 }
3440 }
3441
3442
3443 if haveIdenticalUnderlyingType(dst, src, false) {
3444 return cvtDirect
3445 }
3446
3447
3448 if dst.Kind() == abi.Pointer && nameFor(dst) == "" &&
3449 src.Kind() == abi.Pointer && nameFor(src) == "" &&
3450 haveIdenticalUnderlyingType(elem(dst), elem(src), false) {
3451 return cvtDirect
3452 }
3453
3454 if implements(dst, src) {
3455 if src.Kind() == abi.Interface {
3456 return cvtI2I
3457 }
3458 return cvtT2I
3459 }
3460
3461 return nil
3462 }
3463
3464
3465
3466 func makeInt(f flag, bits uint64, t Type) Value {
3467 typ := t.common()
3468 ptr := unsafe_New(typ)
3469 switch typ.Size() {
3470 case 1:
3471 *(*uint8)(ptr) = uint8(bits)
3472 case 2:
3473 *(*uint16)(ptr) = uint16(bits)
3474 case 4:
3475 *(*uint32)(ptr) = uint32(bits)
3476 case 8:
3477 *(*uint64)(ptr) = bits
3478 }
3479 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3480 }
3481
3482
3483
3484 func makeFloat(f flag, v float64, t Type) Value {
3485 typ := t.common()
3486 ptr := unsafe_New(typ)
3487 switch typ.Size() {
3488 case 4:
3489 *(*float32)(ptr) = float32(v)
3490 case 8:
3491 *(*float64)(ptr) = v
3492 }
3493 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3494 }
3495
3496
3497 func makeFloat32(f flag, v float32, t Type) Value {
3498 typ := t.common()
3499 ptr := unsafe_New(typ)
3500 *(*float32)(ptr) = v
3501 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3502 }
3503
3504
3505
3506 func makeComplex(f flag, v complex128, t Type) Value {
3507 typ := t.common()
3508 ptr := unsafe_New(typ)
3509 switch typ.Size() {
3510 case 8:
3511 *(*complex64)(ptr) = complex64(v)
3512 case 16:
3513 *(*complex128)(ptr) = v
3514 }
3515 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3516 }
3517
3518 func makeString(f flag, v string, t Type) Value {
3519 ret := New(t).Elem()
3520 ret.SetString(v)
3521 ret.flag = ret.flag&^flagAddr | f
3522 return ret
3523 }
3524
3525 func makeBytes(f flag, v []byte, t Type) Value {
3526 ret := New(t).Elem()
3527 ret.SetBytes(v)
3528 ret.flag = ret.flag&^flagAddr | f
3529 return ret
3530 }
3531
3532 func makeRunes(f flag, v []rune, t Type) Value {
3533 ret := New(t).Elem()
3534 ret.setRunes(v)
3535 ret.flag = ret.flag&^flagAddr | f
3536 return ret
3537 }
3538
3539
3540
3541
3542
3543
3544
3545 func cvtInt(v Value, t Type) Value {
3546 return makeInt(v.flag.ro(), uint64(v.Int()), t)
3547 }
3548
3549
3550 func cvtUint(v Value, t Type) Value {
3551 return makeInt(v.flag.ro(), v.Uint(), t)
3552 }
3553
3554
3555 func cvtFloatInt(v Value, t Type) Value {
3556 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
3557 }
3558
3559
3560 func cvtFloatUint(v Value, t Type) Value {
3561 return makeInt(v.flag.ro(), uint64(v.Float()), t)
3562 }
3563
3564
3565 func cvtIntFloat(v Value, t Type) Value {
3566 return makeFloat(v.flag.ro(), float64(v.Int()), t)
3567 }
3568
3569
3570 func cvtUintFloat(v Value, t Type) Value {
3571 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
3572 }
3573
3574
3575 func cvtFloat(v Value, t Type) Value {
3576 if v.Type().Kind() == Float32 && t.Kind() == Float32 {
3577
3578
3579
3580 return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
3581 }
3582 return makeFloat(v.flag.ro(), v.Float(), t)
3583 }
3584
3585
3586 func cvtComplex(v Value, t Type) Value {
3587 return makeComplex(v.flag.ro(), v.Complex(), t)
3588 }
3589
3590
3591 func cvtIntString(v Value, t Type) Value {
3592 s := "\uFFFD"
3593 if x := v.Int(); int64(rune(x)) == x {
3594 s = string(rune(x))
3595 }
3596 return makeString(v.flag.ro(), s, t)
3597 }
3598
3599
3600 func cvtUintString(v Value, t Type) Value {
3601 s := "\uFFFD"
3602 if x := v.Uint(); uint64(rune(x)) == x {
3603 s = string(rune(x))
3604 }
3605 return makeString(v.flag.ro(), s, t)
3606 }
3607
3608
3609 func cvtBytesString(v Value, t Type) Value {
3610 return makeString(v.flag.ro(), string(v.Bytes()), t)
3611 }
3612
3613
3614 func cvtStringBytes(v Value, t Type) Value {
3615 return makeBytes(v.flag.ro(), []byte(v.String()), t)
3616 }
3617
3618
3619 func cvtRunesString(v Value, t Type) Value {
3620 return makeString(v.flag.ro(), string(v.runes()), t)
3621 }
3622
3623
3624 func cvtStringRunes(v Value, t Type) Value {
3625 return makeRunes(v.flag.ro(), []rune(v.String()), t)
3626 }
3627
3628
3629 func cvtSliceArrayPtr(v Value, t Type) Value {
3630 n := t.Elem().Len()
3631 if n > v.Len() {
3632 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to pointer to array with length " + strconv.Itoa(n))
3633 }
3634 h := (*unsafeheader.Slice)(v.ptr)
3635 return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
3636 }
3637
3638
3639 func cvtSliceArray(v Value, t Type) Value {
3640 n := t.Len()
3641 if n > v.Len() {
3642 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to array with length " + strconv.Itoa(n))
3643 }
3644 h := (*unsafeheader.Slice)(v.ptr)
3645 typ := t.common()
3646 ptr := h.Data
3647 c := unsafe_New(typ)
3648 typedmemmove(typ, c, ptr)
3649 ptr = c
3650
3651 return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
3652 }
3653
3654
3655 func cvtDirect(v Value, typ Type) Value {
3656 f := v.flag
3657 t := typ.common()
3658 ptr := v.ptr
3659 if f&flagAddr != 0 {
3660
3661 c := unsafe_New(t)
3662 typedmemmove(t, c, ptr)
3663 ptr = c
3664 f &^= flagAddr
3665 }
3666 return Value{t, ptr, v.flag.ro() | f}
3667 }
3668
3669
3670 func cvtT2I(v Value, typ Type) Value {
3671 target := unsafe_New(typ.common())
3672 x := valueInterface(v, false)
3673 if typ.NumMethod() == 0 {
3674 *(*any)(target) = x
3675 } else {
3676 ifaceE2I(typ.common(), x, target)
3677 }
3678 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
3679 }
3680
3681
3682 func cvtI2I(v Value, typ Type) Value {
3683 if v.IsNil() {
3684 ret := Zero(typ)
3685 ret.flag |= v.flag.ro()
3686 return ret
3687 }
3688 return cvtT2I(v.Elem(), typ)
3689 }
3690
3691
3692
3693
3694 func chancap(ch unsafe.Pointer) int
3695
3696
3697 func chanclose(ch unsafe.Pointer)
3698
3699
3700 func chanlen(ch unsafe.Pointer) int
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
3711
3712
3713 func chansend0(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
3714
3715 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
3716 contentEscapes(val)
3717 return chansend0(ch, val, nb)
3718 }
3719
3720 func makechan(typ *abi.Type, size int) (ch unsafe.Pointer)
3721 func makemap(t *abi.Type, cap int) (m unsafe.Pointer)
3722
3723
3724 func mapaccess(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
3725
3726
3727 func mapaccess_faststr(t *abi.Type, m unsafe.Pointer, key string) (val unsafe.Pointer)
3728
3729
3730 func mapassign0(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer)
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742 func mapassign(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer) {
3743 contentEscapes(key)
3744 contentEscapes(val)
3745 mapassign0(t, m, key, val)
3746 }
3747
3748
3749 func mapassign_faststr0(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer)
3750
3751 func mapassign_faststr(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer) {
3752 contentEscapes((*unsafeheader.String)(unsafe.Pointer(&key)).Data)
3753 contentEscapes(val)
3754 mapassign_faststr0(t, m, key, val)
3755 }
3756
3757
3758 func mapdelete(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer)
3759
3760
3761 func mapdelete_faststr(t *abi.Type, m unsafe.Pointer, key string)
3762
3763
3764 func maplen(m unsafe.Pointer) int
3765
3766 func mapclear(t *abi.Type, m unsafe.Pointer)
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794 func call(stackArgsType *abi.Type, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
3795
3796 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
3797
3798
3799
3800
3801 func memmove(dst, src unsafe.Pointer, size uintptr)
3802
3803
3804
3805
3806 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
3807
3808
3809
3810
3811 func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
3812
3813
3814
3815
3816
3817 func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
3818
3819
3820
3821
3822
3823 func typedslicecopy(t *abi.Type, dst, src unsafeheader.Slice) int
3824
3825
3826
3827
3828
3829 func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
3830
3831
3832 func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
3833
3834 func verifyNotInHeapPtr(p uintptr) bool
3835
3836
3837 func growslice(t *abi.Type, old unsafeheader.Slice, num int) unsafeheader.Slice
3838
3839
3840 func unsafeslice(t *abi.Type, ptr unsafe.Pointer, len int)
3841
3842
3843
3844
3845 func escapes(x any) {
3846 if dummy.b {
3847 dummy.x = x
3848 }
3849 }
3850
3851 var dummy struct {
3852 b bool
3853 x any
3854 }
3855
3856
3857
3858
3859
3860 func contentEscapes(x unsafe.Pointer) {
3861 if dummy.b {
3862 escapes(*(*any)(x))
3863 }
3864 }
3865
View as plain text