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