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