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