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