1
2
3
4
5 package reflectlite
6
7 import (
8 "internal/abi"
9 "internal/goarch"
10 "internal/unsafeheader"
11 "runtime"
12 "unsafe"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 type Value struct {
37
38
39 typ_ *abi.Type
40
41
42
43 ptr unsafe.Pointer
44
45
46
47
48
49
50
51
52
53
54
55
56
57 flag
58
59
60
61
62
63
64 }
65
66 type flag uintptr
67
68 const (
69 flagKindWidth = 5
70 flagKindMask flag = 1<<flagKindWidth - 1
71 flagStickyRO flag = 1 << 5
72 flagEmbedRO flag = 1 << 6
73 flagIndir flag = 1 << 7
74 flagAddr flag = 1 << 8
75 flagMethod flag = 1 << 9
76 flagMethodShift = 10
77 flagRO flag = flagStickyRO | flagEmbedRO
78 )
79
80 func (f flag) kind() Kind {
81 return Kind(f & flagKindMask)
82 }
83
84 func (f flag) ro() flag {
85 if f&flagRO != 0 {
86 return flagStickyRO
87 }
88 return 0
89 }
90
91 func (v Value) typ() *abi.Type {
92
93
94
95
96
97 return (*abi.Type)(abi.NoEscape(unsafe.Pointer(v.typ_)))
98 }
99
100
101
102 func (v Value) pointer() unsafe.Pointer {
103 if v.typ().Size() != goarch.PtrSize || !v.typ().Pointers() {
104 panic("can't call pointer on a non-pointer Value")
105 }
106 if v.flag&flagIndir != 0 {
107 return *(*unsafe.Pointer)(v.ptr)
108 }
109 return v.ptr
110 }
111
112
113 func packEface(v Value) any {
114 t := v.typ()
115 var i any
116 e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
117
118 switch {
119 case t.IfaceIndir():
120 if v.flag&flagIndir == 0 {
121 panic("bad indir")
122 }
123
124 ptr := v.ptr
125 if v.flag&flagAddr != 0 {
126 c := unsafe_New(t)
127 typedmemmove(t, c, ptr)
128 ptr = c
129 }
130 e.Data = ptr
131 case v.flag&flagIndir != 0:
132
133
134 e.Data = *(*unsafe.Pointer)(v.ptr)
135 default:
136
137 e.Data = v.ptr
138 }
139
140
141
142
143 e.Type = t
144 return i
145 }
146
147
148 func unpackEface(i any) Value {
149 e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
150
151 t := e.Type
152 if t == nil {
153 return Value{}
154 }
155 f := flag(t.Kind())
156 if t.IfaceIndir() {
157 f |= flagIndir
158 }
159 return Value{t, e.Data, f}
160 }
161
162
163
164
165 type ValueError struct {
166 Method string
167 Kind Kind
168 }
169
170 func (e *ValueError) Error() string {
171 if e.Kind == 0 {
172 return "reflect: call of " + e.Method + " on zero Value"
173 }
174 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
175 }
176
177
178
179 func methodName() string {
180 pc, _, _, _ := runtime.Caller(2)
181 f := runtime.FuncForPC(pc)
182 if f == nil {
183 return "unknown method"
184 }
185 return f.Name()
186 }
187
188
189
190 func (f flag) mustBeExported() {
191 if f == 0 {
192 panic(&ValueError{methodName(), 0})
193 }
194 if f&flagRO != 0 {
195 panic("reflect: " + methodName() + " using value obtained using unexported field")
196 }
197 }
198
199
200
201
202 func (f flag) mustBeAssignable() {
203 if f == 0 {
204 panic(&ValueError{methodName(), abi.Invalid})
205 }
206
207 if f&flagRO != 0 {
208 panic("reflect: " + methodName() + " using value obtained using unexported field")
209 }
210 if f&flagAddr == 0 {
211 panic("reflect: " + methodName() + " using unaddressable value")
212 }
213 }
214
215
216
217
218
219
220 func (v Value) CanSet() bool {
221 return v.flag&(flagAddr|flagRO) == flagAddr
222 }
223
224
225
226
227
228 func (v Value) Elem() Value {
229 k := v.kind()
230 switch k {
231 case abi.Interface:
232 var eface any
233 if v.typ().NumMethod() == 0 {
234 eface = *(*any)(v.ptr)
235 } else {
236 eface = (any)(*(*interface {
237 M()
238 })(v.ptr))
239 }
240 x := unpackEface(eface)
241 if x.flag != 0 {
242 x.flag |= v.flag.ro()
243 }
244 return x
245 case abi.Pointer:
246 ptr := v.ptr
247 if v.flag&flagIndir != 0 {
248 ptr = *(*unsafe.Pointer)(ptr)
249 }
250
251 if ptr == nil {
252 return Value{}
253 }
254 tt := (*ptrType)(unsafe.Pointer(v.typ()))
255 typ := tt.Elem
256 fl := v.flag&flagRO | flagIndir | flagAddr
257 fl |= flag(typ.Kind())
258 return Value{typ, ptr, fl}
259 }
260 panic(&ValueError{"reflectlite.Value.Elem", v.kind()})
261 }
262
263 func valueInterface(v Value) any {
264 if v.flag == 0 {
265 panic(&ValueError{"reflectlite.Value.Interface", 0})
266 }
267
268 if v.kind() == abi.Interface {
269
270
271
272 if v.numMethod() == 0 {
273 return *(*any)(v.ptr)
274 }
275 return *(*interface {
276 M()
277 })(v.ptr)
278 }
279
280 return packEface(v)
281 }
282
283
284
285
286
287
288
289
290 func (v Value) IsNil() bool {
291 k := v.kind()
292 switch k {
293 case abi.Chan, abi.Func, abi.Map, abi.Pointer, abi.UnsafePointer:
294
295
296
297 ptr := v.ptr
298 if v.flag&flagIndir != 0 {
299 ptr = *(*unsafe.Pointer)(ptr)
300 }
301 return ptr == nil
302 case abi.Interface, abi.Slice:
303
304
305 return *(*unsafe.Pointer)(v.ptr) == nil
306 }
307 panic(&ValueError{"reflectlite.Value.IsNil", v.kind()})
308 }
309
310
311
312
313
314
315 func (v Value) IsValid() bool {
316 return v.flag != 0
317 }
318
319
320
321 func (v Value) Kind() Kind {
322 return v.kind()
323 }
324
325
326
327
328 func chanlen(unsafe.Pointer) int
329
330
331 func maplen(unsafe.Pointer) int
332
333
334
335 func (v Value) Len() int {
336 k := v.kind()
337 switch k {
338 case abi.Array:
339 tt := (*arrayType)(unsafe.Pointer(v.typ()))
340 return int(tt.Len)
341 case abi.Chan:
342 return chanlen(v.pointer())
343 case abi.Map:
344 return maplen(v.pointer())
345 case abi.Slice:
346
347 return (*unsafeheader.Slice)(v.ptr).Len
348 case abi.String:
349
350 return (*unsafeheader.String)(v.ptr).Len
351 }
352 panic(&ValueError{"reflect.Value.Len", v.kind()})
353 }
354
355
356 func (v Value) numMethod() int {
357 if v.typ() == nil {
358 panic(&ValueError{"reflectlite.Value.NumMethod", abi.Invalid})
359 }
360 return v.typ().NumMethod()
361 }
362
363
364
365
366 func (v Value) Set(x Value) {
367 v.mustBeAssignable()
368 x.mustBeExported()
369 var target unsafe.Pointer
370 if v.kind() == abi.Interface {
371 target = v.ptr
372 }
373 x = x.assignTo("reflectlite.Set", v.typ(), target)
374 if x.flag&flagIndir != 0 {
375 typedmemmove(v.typ(), v.ptr, x.ptr)
376 } else {
377 *(*unsafe.Pointer)(v.ptr) = x.ptr
378 }
379 }
380
381
382 func (v Value) Type() Type {
383 f := v.flag
384 if f == 0 {
385 panic(&ValueError{"reflectlite.Value.Type", abi.Invalid})
386 }
387
388 return toRType(v.typ())
389 }
390
391
394
395
396
397
398 func unsafe_New(*abi.Type) unsafe.Pointer
399
400
401
402 func ValueOf(i any) Value {
403 if i == nil {
404 return Value{}
405 }
406 return unpackEface(i)
407 }
408
409
410
411
412 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
413
414
415
416
417 switch {
418 case directlyAssignable(dst, v.typ()):
419
420
421 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
422 fl |= flag(dst.Kind())
423 return Value{dst, v.ptr, fl}
424
425 case implements(dst, v.typ()):
426 if target == nil {
427 target = unsafe_New(dst)
428 }
429 if v.Kind() == abi.Interface && v.IsNil() {
430
431
432
433 return Value{dst, nil, flag(abi.Interface)}
434 }
435 x := valueInterface(v)
436 if dst.NumMethod() == 0 {
437 *(*any)(target) = x
438 } else {
439 ifaceE2I(dst, x, target)
440 }
441 return Value{dst, target, flagIndir | flag(abi.Interface)}
442 }
443
444
445 panic(context + ": value of type " + toRType(v.typ()).String() + " is not assignable to type " + toRType(dst).String())
446 }
447
448
449
450
451
452
453
454
455 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
456 return add(p, uintptr(i)*eltSize, "i < len")
457 }
458
459 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
460
461
462
463
464 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
465
466
467
468
469 func escapes(x any) {
470 if dummy.b {
471 dummy.x = x
472 }
473 }
474
475 var dummy struct {
476 b bool
477 x any
478 }
479
View as plain text