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