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 rtype := v.Type()
2682 n := v.NumMethod()
2683 return func(yield func(Method, Value) bool) {
2684 for i := range n {
2685 if !yield(rtype.Method(i), v.Method(i)) {
2686 return
2687 }
2688 }
2689 }
2690 }
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700 type StringHeader struct {
2701 Data uintptr
2702 Len int
2703 }
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713 type SliceHeader struct {
2714 Data uintptr
2715 Len int
2716 Cap int
2717 }
2718
2719 func typesMustMatch(what string, t1, t2 Type) {
2720 if t1 != t2 {
2721 panic(what + ": " + t1.String() + " != " + t2.String())
2722 }
2723 }
2724
2725
2726
2727
2728
2729
2730
2731
2732 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
2733 return add(p, uintptr(i)*eltSize, "i < len")
2734 }
2735
2736
2737
2738
2739
2740
2741
2742 func (v Value) Grow(n int) {
2743 v.mustBeAssignable()
2744 v.mustBe(Slice)
2745 v.grow(n)
2746 }
2747
2748
2749 func (v Value) grow(n int) {
2750 p := (*unsafeheader.Slice)(v.ptr)
2751 switch {
2752 case n < 0:
2753 panic("reflect.Value.Grow: negative len")
2754 case p.Len+n < 0:
2755 panic("reflect.Value.Grow: slice overflow")
2756 case p.Len+n > p.Cap:
2757 t := v.typ().Elem()
2758 *p = growslice(t, *p, n)
2759 }
2760 }
2761
2762
2763
2764
2765
2766
2767
2768 func (v Value) extendSlice(n int) Value {
2769 v.mustBeExported()
2770 v.mustBe(Slice)
2771
2772
2773 sh := *(*unsafeheader.Slice)(v.ptr)
2774 s := &sh
2775 v.ptr = unsafe.Pointer(s)
2776 v.flag = flagIndir | flag(Slice)
2777
2778 v.grow(n)
2779 s.Len += n
2780 return v
2781 }
2782
2783
2784
2785
2786 func (v Value) Clear() {
2787 switch v.Kind() {
2788 case Slice:
2789 sh := *(*unsafeheader.Slice)(v.ptr)
2790 st := (*sliceType)(unsafe.Pointer(v.typ()))
2791 typedarrayclear(st.Elem, sh.Data, sh.Len)
2792 case Map:
2793 mapclear(v.typ(), v.pointer())
2794 default:
2795 panic(&ValueError{"reflect.Value.Clear", v.Kind()})
2796 }
2797 }
2798
2799
2800
2801 func Append(s Value, x ...Value) Value {
2802 s.mustBe(Slice)
2803 n := s.Len()
2804 s = s.extendSlice(len(x))
2805 for i, v := range x {
2806 s.Index(n + i).Set(v)
2807 }
2808 return s
2809 }
2810
2811
2812
2813 func AppendSlice(s, t Value) Value {
2814 s.mustBe(Slice)
2815 t.mustBe(Slice)
2816 typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
2817 ns := s.Len()
2818 nt := t.Len()
2819 s = s.extendSlice(nt)
2820 Copy(s.Slice(ns, ns+nt), t)
2821 return s
2822 }
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832 func Copy(dst, src Value) int {
2833 dk := dst.kind()
2834 if dk != Array && dk != Slice {
2835 panic(&ValueError{"reflect.Copy", dk})
2836 }
2837 if dk == Array {
2838 dst.mustBeAssignable()
2839 }
2840 dst.mustBeExported()
2841
2842 sk := src.kind()
2843 var stringCopy bool
2844 if sk != Array && sk != Slice {
2845 stringCopy = sk == String && dst.typ().Elem().Kind() == abi.Uint8
2846 if !stringCopy {
2847 panic(&ValueError{"reflect.Copy", sk})
2848 }
2849 }
2850 src.mustBeExported()
2851
2852 de := dst.typ().Elem()
2853 if !stringCopy {
2854 se := src.typ().Elem()
2855 typesMustMatch("reflect.Copy", toType(de), toType(se))
2856 }
2857
2858 var ds, ss unsafeheader.Slice
2859 if dk == Array {
2860 ds.Data = dst.ptr
2861 ds.Len = dst.Len()
2862 ds.Cap = ds.Len
2863 } else {
2864 ds = *(*unsafeheader.Slice)(dst.ptr)
2865 }
2866 if sk == Array {
2867 ss.Data = src.ptr
2868 ss.Len = src.Len()
2869 ss.Cap = ss.Len
2870 } else if sk == Slice {
2871 ss = *(*unsafeheader.Slice)(src.ptr)
2872 } else {
2873 sh := *(*unsafeheader.String)(src.ptr)
2874 ss.Data = sh.Data
2875 ss.Len = sh.Len
2876 ss.Cap = sh.Len
2877 }
2878
2879 return typedslicecopy(de.Common(), ds, ss)
2880 }
2881
2882
2883
2884 type runtimeSelect struct {
2885 dir SelectDir
2886 typ *rtype
2887 ch unsafe.Pointer
2888 val unsafe.Pointer
2889 }
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902 func rselect([]runtimeSelect) (chosen int, recvOK bool)
2903
2904
2905 type SelectDir int
2906
2907
2908
2909 const (
2910 _ SelectDir = iota
2911 SelectSend
2912 SelectRecv
2913 SelectDefault
2914 )
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932 type SelectCase struct {
2933 Dir SelectDir
2934 Chan Value
2935 Send Value
2936 }
2937
2938
2939
2940 const stackAllocSelectCases = 4
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964 var runcases []runtimeSelect
2965 if len(cases) > stackAllocSelectCases {
2966 runcases = make([]runtimeSelect, len(cases))
2967 }
2968 chosen, recv, recvOK = select0(cases, runcases)
2969 return
2970 }
2971
2972 func select0(cases []SelectCase, runcases []runtimeSelect) (chosen int, recv Value, recvOK bool) {
2973 if len(cases) > 65536 {
2974 panic("reflect.Select: too many cases (max 65536)")
2975 }
2976
2977
2978 if runcases == nil {
2979 runcases = make([]runtimeSelect, len(cases), stackAllocSelectCases)
2980 }
2981
2982 haveDefault := false
2983
2984
2985
2986
2987 for i, c := range cases {
2988 rc := &runcases[i]
2989 rc.dir = c.Dir
2990 switch c.Dir {
2991 default:
2992 panic("reflect.Select: invalid Dir")
2993
2994 case SelectDefault:
2995 if haveDefault {
2996 panic("reflect.Select: multiple default cases")
2997 }
2998 haveDefault = true
2999 if c.Chan.IsValid() {
3000 panic("reflect.Select: default case has Chan value")
3001 }
3002 if c.Send.IsValid() {
3003 panic("reflect.Select: default case has Send value")
3004 }
3005
3006 case SelectSend:
3007 ch := c.Chan
3008 if !ch.IsValid() {
3009 break
3010 }
3011 ch.mustBe(Chan)
3012 ch.mustBeExported()
3013 tt := (*chanType)(unsafe.Pointer(ch.typ()))
3014 if ChanDir(tt.Dir)&SendDir == 0 {
3015 panic("reflect.Select: SendDir case using recv-only channel")
3016 }
3017 rc.ch = ch.pointer()
3018 rc.typ = toRType(&tt.Type)
3019 v := c.Send
3020 if !v.IsValid() {
3021 panic("reflect.Select: SendDir case missing Send value")
3022 }
3023 v.mustBeExported()
3024 v = v.assignTo("reflect.Select", tt.Elem, nil)
3025 if v.flag&flagIndir != 0 {
3026 rc.val = v.ptr
3027 } else {
3028 rc.val = unsafe.Pointer(&v.ptr)
3029 }
3030
3031
3032 escapes(rc.val)
3033
3034 case SelectRecv:
3035 if c.Send.IsValid() {
3036 panic("reflect.Select: RecvDir case has Send value")
3037 }
3038 ch := c.Chan
3039 if !ch.IsValid() {
3040 break
3041 }
3042 ch.mustBe(Chan)
3043 ch.mustBeExported()
3044 tt := (*chanType)(unsafe.Pointer(ch.typ()))
3045 if ChanDir(tt.Dir)&RecvDir == 0 {
3046 panic("reflect.Select: RecvDir case using send-only channel")
3047 }
3048 rc.ch = ch.pointer()
3049 rc.typ = toRType(&tt.Type)
3050 rc.val = unsafe_New(tt.Elem)
3051 }
3052 }
3053
3054 chosen, recvOK = rselect(runcases)
3055 if runcases[chosen].dir == SelectRecv {
3056 tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
3057 t := tt.Elem
3058 p := runcases[chosen].val
3059 fl := flag(t.Kind())
3060 if !t.IsDirectIface() {
3061 recv = Value{t, p, fl | flagIndir}
3062 } else {
3063 recv = Value{t, *(*unsafe.Pointer)(p), fl}
3064 }
3065 }
3066 return chosen, recv, recvOK
3067 }
3068
3069
3072
3073
3074
3075
3076 func unsafe_New(*abi.Type) unsafe.Pointer
3077
3078
3079 func unsafe_NewArray(*abi.Type, int) unsafe.Pointer
3080
3081
3082
3083 func MakeSlice(typ Type, len, cap int) Value {
3084 if typ.Kind() != Slice {
3085 panic("reflect.MakeSlice of non-slice type")
3086 }
3087 if len < 0 {
3088 panic("reflect.MakeSlice: negative len")
3089 }
3090 if cap < 0 {
3091 panic("reflect.MakeSlice: negative cap")
3092 }
3093 if len > cap {
3094 panic("reflect.MakeSlice: len > cap")
3095 }
3096
3097 s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
3098 return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
3099 }
3100
3101
3102
3103
3104
3105 func SliceAt(typ Type, p unsafe.Pointer, n int) Value {
3106 unsafeslice(typ.common(), p, n)
3107 s := unsafeheader.Slice{Data: p, Len: n, Cap: n}
3108 return Value{SliceOf(typ).common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
3109 }
3110
3111
3112 func MakeChan(typ Type, buffer int) Value {
3113 if typ.Kind() != Chan {
3114 panic("reflect.MakeChan of non-chan type")
3115 }
3116 if buffer < 0 {
3117 panic("reflect.MakeChan: negative buffer size")
3118 }
3119 if typ.ChanDir() != BothDir {
3120 panic("reflect.MakeChan: unidirectional channel type")
3121 }
3122 t := typ.common()
3123 ch := makechan(t, buffer)
3124 return Value{t, ch, flag(Chan)}
3125 }
3126
3127
3128 func MakeMap(typ Type) Value {
3129 return MakeMapWithSize(typ, 0)
3130 }
3131
3132
3133
3134 func MakeMapWithSize(typ Type, n int) Value {
3135 if typ.Kind() != Map {
3136 panic("reflect.MakeMapWithSize of non-map type")
3137 }
3138 t := typ.common()
3139 m := makemap(t, n)
3140 return Value{t, m, flag(Map)}
3141 }
3142
3143
3144
3145
3146 func Indirect(v Value) Value {
3147 if v.Kind() != Pointer {
3148 return v
3149 }
3150 return v.Elem()
3151 }
3152
3153
3154
3155 func ValueOf(i any) Value {
3156 if i == nil {
3157 return Value{}
3158 }
3159 return unpackEface(i)
3160 }
3161
3162
3163
3164
3165
3166
3167 func Zero(typ Type) Value {
3168 if typ == nil {
3169 panic("reflect: Zero(nil)")
3170 }
3171 t := &typ.(*rtype).t
3172 fl := flag(t.Kind())
3173 if !t.IsDirectIface() {
3174 var p unsafe.Pointer
3175 if t.Size() <= abi.ZeroValSize {
3176 p = unsafe.Pointer(&zeroVal[0])
3177 } else {
3178 p = unsafe_New(t)
3179 }
3180 return Value{t, p, fl | flagIndir}
3181 }
3182 return Value{t, nil, fl}
3183 }
3184
3185
3186 var zeroVal [abi.ZeroValSize]byte
3187
3188
3189
3190 func New(typ Type) Value {
3191 if typ == nil {
3192 panic("reflect: New(nil)")
3193 }
3194 t := &typ.(*rtype).t
3195 pt := ptrTo(t)
3196 if !pt.IsDirectIface() {
3197
3198 panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
3199 }
3200 ptr := unsafe_New(t)
3201 fl := flag(Pointer)
3202 return Value{pt, ptr, fl}
3203 }
3204
3205
3206
3207 func NewAt(typ Type, p unsafe.Pointer) Value {
3208 fl := flag(Pointer)
3209 t := typ.(*rtype)
3210 return Value{t.ptrTo(), p, fl}
3211 }
3212
3213
3214
3215
3216
3217
3218 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
3219 if v.flag&flagMethod != 0 {
3220 v = makeMethodValue(context, v)
3221 }
3222
3223 switch {
3224 case directlyAssignable(dst, v.typ()):
3225
3226
3227 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
3228 fl |= flag(dst.Kind())
3229 return Value{dst, v.ptr, fl}
3230
3231 case implements(dst, v.typ()):
3232 if v.Kind() == Interface && v.IsNil() {
3233
3234
3235
3236 return Value{dst, nil, flag(Interface)}
3237 }
3238 x := valueInterface(v, false)
3239 if target == nil {
3240 target = unsafe_New(dst)
3241 }
3242 if dst.NumMethod() == 0 {
3243 *(*any)(target) = x
3244 } else {
3245 ifaceE2I(dst, x, target)
3246 }
3247 return Value{dst, target, flagIndir | flag(Interface)}
3248 }
3249
3250
3251 panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
3252 }
3253
3254
3255
3256
3257 func (v Value) Convert(t Type) Value {
3258 if v.flag&flagMethod != 0 {
3259 v = makeMethodValue("Convert", v)
3260 }
3261 op := convertOp(t.common(), v.typ())
3262 if op == nil {
3263 panic("reflect.Value.Convert: value of type " + stringFor(v.typ()) + " cannot be converted to type " + t.String())
3264 }
3265 return op(v, t)
3266 }
3267
3268
3269
3270 func (v Value) CanConvert(t Type) bool {
3271 vt := v.Type()
3272 if !vt.ConvertibleTo(t) {
3273 return false
3274 }
3275
3276
3277 switch {
3278 case vt.Kind() == Slice && t.Kind() == Array:
3279 if t.Len() > v.Len() {
3280 return false
3281 }
3282 case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
3283 n := t.Elem().Len()
3284 if n > v.Len() {
3285 return false
3286 }
3287 }
3288 return true
3289 }
3290
3291
3292
3293
3294
3295 func (v Value) Comparable() bool {
3296 k := v.Kind()
3297 switch k {
3298 case Invalid:
3299 return false
3300
3301 case Array:
3302 switch v.Type().Elem().Kind() {
3303 case Interface, Array, Struct:
3304 for i := 0; i < v.Type().Len(); i++ {
3305 if !v.Index(i).Comparable() {
3306 return false
3307 }
3308 }
3309 return true
3310 }
3311 return v.Type().Comparable()
3312
3313 case Interface:
3314 return v.IsNil() || v.Elem().Comparable()
3315
3316 case Struct:
3317 for _, value := range v.Fields() {
3318 if !value.Comparable() {
3319 return false
3320 }
3321 }
3322 return true
3323
3324 default:
3325 return v.Type().Comparable()
3326 }
3327 }
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337 func (v Value) Equal(u Value) bool {
3338 if v.Kind() == Interface {
3339 v = v.Elem()
3340 }
3341 if u.Kind() == Interface {
3342 u = u.Elem()
3343 }
3344
3345 if !v.IsValid() || !u.IsValid() {
3346 return v.IsValid() == u.IsValid()
3347 }
3348
3349 if v.Kind() != u.Kind() || v.Type() != u.Type() {
3350 return false
3351 }
3352
3353
3354
3355 switch v.Kind() {
3356 default:
3357 panic("reflect.Value.Equal: invalid Kind")
3358 case Bool:
3359 return v.Bool() == u.Bool()
3360 case Int, Int8, Int16, Int32, Int64:
3361 return v.Int() == u.Int()
3362 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3363 return v.Uint() == u.Uint()
3364 case Float32, Float64:
3365 return v.Float() == u.Float()
3366 case Complex64, Complex128:
3367 return v.Complex() == u.Complex()
3368 case String:
3369 return v.String() == u.String()
3370 case Chan, Pointer, UnsafePointer:
3371 return v.Pointer() == u.Pointer()
3372 case Array:
3373
3374 vl := v.Len()
3375 if vl == 0 {
3376
3377 if !v.Type().Elem().Comparable() {
3378 break
3379 }
3380 return true
3381 }
3382 for i := 0; i < vl; i++ {
3383 if !v.Index(i).Equal(u.Index(i)) {
3384 return false
3385 }
3386 }
3387 return true
3388 case Struct:
3389
3390 nf := v.NumField()
3391 for i := 0; i < nf; i++ {
3392 if !v.Field(i).Equal(u.Field(i)) {
3393 return false
3394 }
3395 }
3396 return true
3397 case Func, Map, Slice:
3398 break
3399 }
3400 panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
3401 }
3402
3403
3404
3405 func convertOp(dst, src *abi.Type) func(Value, Type) Value {
3406 switch Kind(src.Kind()) {
3407 case Int, Int8, Int16, Int32, Int64:
3408 switch Kind(dst.Kind()) {
3409 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3410 return cvtInt
3411 case Float32, Float64:
3412 return cvtIntFloat
3413 case String:
3414 return cvtIntString
3415 }
3416
3417 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3418 switch Kind(dst.Kind()) {
3419 case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3420 return cvtUint
3421 case Float32, Float64:
3422 return cvtUintFloat
3423 case String:
3424 return cvtUintString
3425 }
3426
3427 case Float32, Float64:
3428 switch Kind(dst.Kind()) {
3429 case Int, Int8, Int16, Int32, Int64:
3430 return cvtFloatInt
3431 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
3432 return cvtFloatUint
3433 case Float32, Float64:
3434 return cvtFloat
3435 }
3436
3437 case Complex64, Complex128:
3438 switch Kind(dst.Kind()) {
3439 case Complex64, Complex128:
3440 return cvtComplex
3441 }
3442
3443 case String:
3444 if dst.Kind() == abi.Slice {
3445 switch Kind(dst.Elem().Kind()) {
3446 case Uint8:
3447 return cvtStringBytes
3448 case Int32:
3449 return cvtStringRunes
3450 }
3451 }
3452
3453 case Slice:
3454 if dst.Kind() == abi.String {
3455 switch Kind(src.Elem().Kind()) {
3456 case Uint8:
3457 return cvtBytesString
3458 case Int32:
3459 return cvtRunesString
3460 }
3461 }
3462
3463
3464 if dst.Kind() == abi.Pointer && dst.Elem().Kind() == abi.Array && src.Elem() == dst.Elem().Elem() {
3465 return cvtSliceArrayPtr
3466 }
3467
3468
3469 if dst.Kind() == abi.Array && src.Elem() == dst.Elem() {
3470 return cvtSliceArray
3471 }
3472
3473 case Chan:
3474 if dst.Kind() == abi.Chan && specialChannelAssignability(dst, src) {
3475 return cvtDirect
3476 }
3477 }
3478
3479
3480 if haveIdenticalUnderlyingType(dst, src, false) {
3481 return cvtDirect
3482 }
3483
3484
3485 if dst.Kind() == abi.Pointer && nameFor(dst) == "" &&
3486 src.Kind() == abi.Pointer && nameFor(src) == "" &&
3487 haveIdenticalUnderlyingType(elem(dst), elem(src), false) {
3488 return cvtDirect
3489 }
3490
3491 if implements(dst, src) {
3492 if src.Kind() == abi.Interface {
3493 return cvtI2I
3494 }
3495 return cvtT2I
3496 }
3497
3498 return nil
3499 }
3500
3501
3502
3503 func makeInt(f flag, bits uint64, t Type) Value {
3504 typ := t.common()
3505 ptr := unsafe_New(typ)
3506 switch typ.Size() {
3507 case 1:
3508 *(*uint8)(ptr) = uint8(bits)
3509 case 2:
3510 *(*uint16)(ptr) = uint16(bits)
3511 case 4:
3512 *(*uint32)(ptr) = uint32(bits)
3513 case 8:
3514 *(*uint64)(ptr) = bits
3515 }
3516 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3517 }
3518
3519
3520
3521 func makeFloat(f flag, v float64, t Type) Value {
3522 typ := t.common()
3523 ptr := unsafe_New(typ)
3524 switch typ.Size() {
3525 case 4:
3526 *(*float32)(ptr) = float32(v)
3527 case 8:
3528 *(*float64)(ptr) = v
3529 }
3530 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3531 }
3532
3533
3534 func makeFloat32(f flag, v float32, t Type) Value {
3535 typ := t.common()
3536 ptr := unsafe_New(typ)
3537 *(*float32)(ptr) = v
3538 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3539 }
3540
3541
3542
3543 func makeComplex(f flag, v complex128, t Type) Value {
3544 typ := t.common()
3545 ptr := unsafe_New(typ)
3546 switch typ.Size() {
3547 case 8:
3548 *(*complex64)(ptr) = complex64(v)
3549 case 16:
3550 *(*complex128)(ptr) = v
3551 }
3552 return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
3553 }
3554
3555 func makeString(f flag, v string, t Type) Value {
3556 ret := New(t).Elem()
3557 ret.SetString(v)
3558 ret.flag = ret.flag&^flagAddr | f
3559 return ret
3560 }
3561
3562 func makeBytes(f flag, v []byte, t Type) Value {
3563 ret := New(t).Elem()
3564 ret.SetBytes(v)
3565 ret.flag = ret.flag&^flagAddr | f
3566 return ret
3567 }
3568
3569 func makeRunes(f flag, v []rune, t Type) Value {
3570 ret := New(t).Elem()
3571 ret.setRunes(v)
3572 ret.flag = ret.flag&^flagAddr | f
3573 return ret
3574 }
3575
3576
3577
3578
3579
3580
3581
3582 func cvtInt(v Value, t Type) Value {
3583 return makeInt(v.flag.ro(), uint64(v.Int()), t)
3584 }
3585
3586
3587 func cvtUint(v Value, t Type) Value {
3588 return makeInt(v.flag.ro(), v.Uint(), t)
3589 }
3590
3591
3592 func cvtFloatInt(v Value, t Type) Value {
3593 return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
3594 }
3595
3596
3597 func cvtFloatUint(v Value, t Type) Value {
3598 return makeInt(v.flag.ro(), uint64(v.Float()), t)
3599 }
3600
3601
3602 func cvtIntFloat(v Value, t Type) Value {
3603 return makeFloat(v.flag.ro(), float64(v.Int()), t)
3604 }
3605
3606
3607 func cvtUintFloat(v Value, t Type) Value {
3608 return makeFloat(v.flag.ro(), float64(v.Uint()), t)
3609 }
3610
3611
3612 func cvtFloat(v Value, t Type) Value {
3613 if v.Type().Kind() == Float32 && t.Kind() == Float32 {
3614
3615
3616
3617 return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
3618 }
3619 return makeFloat(v.flag.ro(), v.Float(), t)
3620 }
3621
3622
3623 func cvtComplex(v Value, t Type) Value {
3624 return makeComplex(v.flag.ro(), v.Complex(), t)
3625 }
3626
3627
3628 func cvtIntString(v Value, t Type) Value {
3629 s := "\uFFFD"
3630 if x := v.Int(); int64(rune(x)) == x {
3631 s = string(rune(x))
3632 }
3633 return makeString(v.flag.ro(), s, t)
3634 }
3635
3636
3637 func cvtUintString(v Value, t Type) Value {
3638 s := "\uFFFD"
3639 if x := v.Uint(); uint64(rune(x)) == x {
3640 s = string(rune(x))
3641 }
3642 return makeString(v.flag.ro(), s, t)
3643 }
3644
3645
3646 func cvtBytesString(v Value, t Type) Value {
3647 return makeString(v.flag.ro(), string(v.Bytes()), t)
3648 }
3649
3650
3651 func cvtStringBytes(v Value, t Type) Value {
3652 return makeBytes(v.flag.ro(), []byte(v.String()), t)
3653 }
3654
3655
3656 func cvtRunesString(v Value, t Type) Value {
3657 return makeString(v.flag.ro(), string(v.runes()), t)
3658 }
3659
3660
3661 func cvtStringRunes(v Value, t Type) Value {
3662 return makeRunes(v.flag.ro(), []rune(v.String()), t)
3663 }
3664
3665
3666 func cvtSliceArrayPtr(v Value, t Type) Value {
3667 n := t.Elem().Len()
3668 if n > v.Len() {
3669 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to pointer to array with length " + strconv.Itoa(n))
3670 }
3671 h := (*unsafeheader.Slice)(v.ptr)
3672 return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
3673 }
3674
3675
3676 func cvtSliceArray(v Value, t Type) Value {
3677 n := t.Len()
3678 if n > v.Len() {
3679 panic("reflect: cannot convert slice with length " + strconv.Itoa(v.Len()) + " to array with length " + strconv.Itoa(n))
3680 }
3681 h := (*unsafeheader.Slice)(v.ptr)
3682 typ := t.common()
3683 ptr := h.Data
3684 c := unsafe_New(typ)
3685 typedmemmove(typ, c, ptr)
3686 ptr = c
3687
3688 return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
3689 }
3690
3691
3692 func cvtDirect(v Value, typ Type) Value {
3693 f := v.flag
3694 t := typ.common()
3695 ptr := v.ptr
3696 if f&flagAddr != 0 {
3697
3698 c := unsafe_New(t)
3699 typedmemmove(t, c, ptr)
3700 ptr = c
3701 f &^= flagAddr
3702 }
3703 return Value{t, ptr, v.flag.ro() | f}
3704 }
3705
3706
3707 func cvtT2I(v Value, typ Type) Value {
3708 target := unsafe_New(typ.common())
3709 x := valueInterface(v, false)
3710 if typ.NumMethod() == 0 {
3711 *(*any)(target) = x
3712 } else {
3713 ifaceE2I(typ.common(), x, target)
3714 }
3715 return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
3716 }
3717
3718
3719 func cvtI2I(v Value, typ Type) Value {
3720 if v.IsNil() {
3721 ret := Zero(typ)
3722 ret.flag |= v.flag.ro()
3723 return ret
3724 }
3725 return cvtT2I(v.Elem(), typ)
3726 }
3727
3728
3729
3730
3731 func chancap(ch unsafe.Pointer) int
3732
3733
3734 func chanclose(ch unsafe.Pointer)
3735
3736
3737 func chanlen(ch unsafe.Pointer) int
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747 func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
3748
3749
3750 func chansend0(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
3751
3752 func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
3753 contentEscapes(val)
3754 return chansend0(ch, val, nb)
3755 }
3756
3757 func makechan(typ *abi.Type, size int) (ch unsafe.Pointer)
3758 func makemap(t *abi.Type, cap int) (m unsafe.Pointer)
3759
3760
3761 func mapaccess(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
3762
3763
3764 func mapaccess_faststr(t *abi.Type, m unsafe.Pointer, key string) (val unsafe.Pointer)
3765
3766
3767 func mapassign0(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer)
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779 func mapassign(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer) {
3780 contentEscapes(key)
3781 contentEscapes(val)
3782 mapassign0(t, m, key, val)
3783 }
3784
3785
3786 func mapassign_faststr0(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer)
3787
3788 func mapassign_faststr(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer) {
3789 contentEscapes((*unsafeheader.String)(unsafe.Pointer(&key)).Data)
3790 contentEscapes(val)
3791 mapassign_faststr0(t, m, key, val)
3792 }
3793
3794
3795 func mapdelete(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer)
3796
3797
3798 func mapdelete_faststr(t *abi.Type, m unsafe.Pointer, key string)
3799
3800
3801 func maplen(m unsafe.Pointer) int
3802
3803 func mapclear(t *abi.Type, m unsafe.Pointer)
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
3831 func call(stackArgsType *abi.Type, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
3832
3833 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
3834
3835
3836
3837
3838 func memmove(dst, src unsafe.Pointer, size uintptr)
3839
3840
3841
3842
3843 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
3844
3845
3846
3847
3848 func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
3849
3850
3851
3852
3853
3854 func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
3855
3856
3857
3858
3859
3860 func typedslicecopy(t *abi.Type, dst, src unsafeheader.Slice) int
3861
3862
3863
3864
3865
3866 func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
3867
3868
3869 func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
3870
3871 func verifyNotInHeapPtr(p uintptr) bool
3872
3873
3874 func growslice(t *abi.Type, old unsafeheader.Slice, num int) unsafeheader.Slice
3875
3876
3877 func unsafeslice(t *abi.Type, ptr unsafe.Pointer, len int)
3878
3879
3880
3881
3882 func escapes(x any) {
3883 if dummy.b {
3884 dummy.x = x
3885 }
3886 }
3887
3888 var dummy struct {
3889 b bool
3890 x any
3891 }
3892
3893
3894
3895
3896
3897 func contentEscapes(x unsafe.Pointer) {
3898 if dummy.b {
3899 escapes(*(*any)(x))
3900 }
3901 }
3902
View as plain text