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