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)(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 := (*emptyInterface)(unsafe.Pointer(&i))
117
118 switch {
119 case ifaceIndir(t):
120 if v.flag&flagIndir == 0 {
121 panic("bad indir")
122 }
123
124 ptr := v.ptr
125 if v.flag&flagAddr != 0 {
126
127
128 c := unsafe_New(t)
129 typedmemmove(t, c, ptr)
130 ptr = c
131 }
132 e.word = ptr
133 case v.flag&flagIndir != 0:
134
135
136 e.word = *(*unsafe.Pointer)(v.ptr)
137 default:
138
139 e.word = v.ptr
140 }
141
142
143
144
145 e.typ = t
146 return i
147 }
148
149
150 func unpackEface(i any) Value {
151 e := (*emptyInterface)(unsafe.Pointer(&i))
152
153 t := e.typ
154 if t == nil {
155 return Value{}
156 }
157 f := flag(t.Kind())
158 if ifaceIndir(t) {
159 f |= flagIndir
160 }
161 return Value{t, e.word, f}
162 }
163
164
165
166
167 type ValueError struct {
168 Method string
169 Kind Kind
170 }
171
172 func (e *ValueError) Error() string {
173 if e.Kind == 0 {
174 return "reflect: call of " + e.Method + " on zero Value"
175 }
176 return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
177 }
178
179
180
181 func methodName() string {
182 pc, _, _, _ := runtime.Caller(2)
183 f := runtime.FuncForPC(pc)
184 if f == nil {
185 return "unknown method"
186 }
187 return f.Name()
188 }
189
190
191 type emptyInterface struct {
192 typ *abi.Type
193 word unsafe.Pointer
194 }
195
196
197
198 func (f flag) mustBeExported() {
199 if f == 0 {
200 panic(&ValueError{methodName(), 0})
201 }
202 if f&flagRO != 0 {
203 panic("reflect: " + methodName() + " using value obtained using unexported field")
204 }
205 }
206
207
208
209
210 func (f flag) mustBeAssignable() {
211 if f == 0 {
212 panic(&ValueError{methodName(), abi.Invalid})
213 }
214
215 if f&flagRO != 0 {
216 panic("reflect: " + methodName() + " using value obtained using unexported field")
217 }
218 if f&flagAddr == 0 {
219 panic("reflect: " + methodName() + " using unaddressable value")
220 }
221 }
222
223
224
225
226
227
228 func (v Value) CanSet() bool {
229 return v.flag&(flagAddr|flagRO) == flagAddr
230 }
231
232
233
234
235
236 func (v Value) Elem() Value {
237 k := v.kind()
238 switch k {
239 case abi.Interface:
240 var eface any
241 if v.typ().NumMethod() == 0 {
242 eface = *(*any)(v.ptr)
243 } else {
244 eface = (any)(*(*interface {
245 M()
246 })(v.ptr))
247 }
248 x := unpackEface(eface)
249 if x.flag != 0 {
250 x.flag |= v.flag.ro()
251 }
252 return x
253 case abi.Pointer:
254 ptr := v.ptr
255 if v.flag&flagIndir != 0 {
256 ptr = *(*unsafe.Pointer)(ptr)
257 }
258
259 if ptr == nil {
260 return Value{}
261 }
262 tt := (*ptrType)(unsafe.Pointer(v.typ()))
263 typ := tt.Elem
264 fl := v.flag&flagRO | flagIndir | flagAddr
265 fl |= flag(typ.Kind())
266 return Value{typ, ptr, fl}
267 }
268 panic(&ValueError{"reflectlite.Value.Elem", v.kind()})
269 }
270
271 func valueInterface(v Value) any {
272 if v.flag == 0 {
273 panic(&ValueError{"reflectlite.Value.Interface", 0})
274 }
275
276 if v.kind() == abi.Interface {
277
278
279
280 if v.numMethod() == 0 {
281 return *(*any)(v.ptr)
282 }
283 return *(*interface {
284 M()
285 })(v.ptr)
286 }
287
288
289 return packEface(v)
290 }
291
292
293
294
295
296
297
298
299 func (v Value) IsNil() bool {
300 k := v.kind()
301 switch k {
302 case abi.Chan, abi.Func, abi.Map, abi.Pointer, abi.UnsafePointer:
303
304
305
306 ptr := v.ptr
307 if v.flag&flagIndir != 0 {
308 ptr = *(*unsafe.Pointer)(ptr)
309 }
310 return ptr == nil
311 case abi.Interface, abi.Slice:
312
313
314 return *(*unsafe.Pointer)(v.ptr) == nil
315 }
316 panic(&ValueError{"reflectlite.Value.IsNil", v.kind()})
317 }
318
319
320
321
322
323
324 func (v Value) IsValid() bool {
325 return v.flag != 0
326 }
327
328
329
330 func (v Value) Kind() Kind {
331 return v.kind()
332 }
333
334
335
336
337 func chanlen(unsafe.Pointer) int
338
339
340 func maplen(unsafe.Pointer) int
341
342
343
344 func (v Value) Len() int {
345 k := v.kind()
346 switch k {
347 case abi.Array:
348 tt := (*arrayType)(unsafe.Pointer(v.typ()))
349 return int(tt.Len)
350 case abi.Chan:
351 return chanlen(v.pointer())
352 case abi.Map:
353 return maplen(v.pointer())
354 case abi.Slice:
355
356 return (*unsafeheader.Slice)(v.ptr).Len
357 case abi.String:
358
359 return (*unsafeheader.String)(v.ptr).Len
360 }
361 panic(&ValueError{"reflect.Value.Len", v.kind()})
362 }
363
364
365 func (v Value) numMethod() int {
366 if v.typ() == nil {
367 panic(&ValueError{"reflectlite.Value.NumMethod", abi.Invalid})
368 }
369 return v.typ().NumMethod()
370 }
371
372
373
374
375 func (v Value) Set(x Value) {
376 v.mustBeAssignable()
377 x.mustBeExported()
378 var target unsafe.Pointer
379 if v.kind() == abi.Interface {
380 target = v.ptr
381 }
382 x = x.assignTo("reflectlite.Set", v.typ(), target)
383 if x.flag&flagIndir != 0 {
384 typedmemmove(v.typ(), v.ptr, x.ptr)
385 } else {
386 *(*unsafe.Pointer)(v.ptr) = x.ptr
387 }
388 }
389
390
391 func (v Value) Type() Type {
392 f := v.flag
393 if f == 0 {
394 panic(&ValueError{"reflectlite.Value.Type", abi.Invalid})
395 }
396
397 return toRType(v.typ())
398 }
399
400
403
404
405
406
407 func unsafe_New(*abi.Type) unsafe.Pointer
408
409
410
411 func ValueOf(i any) Value {
412 if i == nil {
413 return Value{}
414 }
415 return unpackEface(i)
416 }
417
418
419
420
421 func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
422
423
424
425
426 switch {
427 case directlyAssignable(dst, v.typ()):
428
429
430 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
431 fl |= flag(dst.Kind())
432 return Value{dst, v.ptr, fl}
433
434 case implements(dst, v.typ()):
435 if target == nil {
436 target = unsafe_New(dst)
437 }
438 if v.Kind() == abi.Interface && v.IsNil() {
439
440
441
442 return Value{dst, nil, flag(abi.Interface)}
443 }
444 x := valueInterface(v)
445 if dst.NumMethod() == 0 {
446 *(*any)(target) = x
447 } else {
448 ifaceE2I(dst, x, target)
449 }
450 return Value{dst, target, flagIndir | flag(abi.Interface)}
451 }
452
453
454 panic(context + ": value of type " + toRType(v.typ()).String() + " is not assignable to type " + toRType(dst).String())
455 }
456
457
458
459
460
461
462
463
464 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
465 return add(p, uintptr(i)*eltSize, "i < len")
466 }
467
468 func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
469
470
471
472
473 func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
474
475
476
477
478 func escapes(x any) {
479 if dummy.b {
480 dummy.x = x
481 }
482 }
483
484 var dummy struct {
485 b bool
486 x any
487 }
488
489
490 func noescape(p unsafe.Pointer) unsafe.Pointer {
491 x := uintptr(p)
492 return unsafe.Pointer(x ^ 0)
493 }
494
View as plain text