5 // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
6 // Use of this source code is governed by a MIT license found in the LICENSE file.
17 // This file has unsafe variants of some helper methods.
18 // NOTE: See helper_not_unsafe.go for the usage information.
20 // var zeroRTv [4]uintptr
22 const safeMode = false
23 const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
25 type unsafeString struct {
30 type unsafeSlice struct {
36 type unsafeIntf struct {
41 type unsafeReflectValue struct {
47 func stringView(v []byte) string {
51 bx := (*unsafeSlice)(unsafe.Pointer(&v))
52 return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
55 func bytesView(v string) []byte {
59 sx := (*unsafeString)(unsafe.Pointer(&v))
60 return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
63 func definitelyNil(v interface{}) bool {
64 // There is no global way of checking if an interface is nil.
65 // For true references (map, ptr, func, chan), you can just look
66 // at the word of the interface. However, for slices, you have to dereference
67 // the word, and get a pointer to the 3-word interface value.
69 // However, the following are cheap calls
70 // - TypeOf(interface): cheap 2-line call.
71 // - ValueOf(interface{}): expensive
72 // - type.Kind: cheap call through an interface
73 // - Value.Type(): cheap call
74 // except it's a method value (e.g. r.Read, which implies that it is a Func)
76 return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
79 func rv2i(rv reflect.Value) interface{} {
80 // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
82 // Currently, we use this fragile method that taps into implememtation details from
83 // the source go stdlib reflect/value.go, and trims the implementation.
85 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
86 // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
87 var ptr unsafe.Pointer
88 if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
89 ptr = *(*unsafe.Pointer)(urv.ptr)
93 return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
96 func rt2id(rt reflect.Type) uintptr {
97 return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
100 func rv2rtid(rv reflect.Value) uintptr {
101 return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
104 func i2rtid(i interface{}) uintptr {
105 return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
108 // --------------------------
110 func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
111 urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
116 case reflect.Invalid:
119 return (*unsafeString)(urv.ptr).Len == 0
121 return (*unsafeSlice)(urv.ptr).Len == 0
123 return !*(*bool)(urv.ptr)
125 return *(*int)(urv.ptr) == 0
127 return *(*int8)(urv.ptr) == 0
129 return *(*int16)(urv.ptr) == 0
131 return *(*int32)(urv.ptr) == 0
133 return *(*int64)(urv.ptr) == 0
135 return *(*uint)(urv.ptr) == 0
137 return *(*uint8)(urv.ptr) == 0
139 return *(*uint16)(urv.ptr) == 0
141 return *(*uint32)(urv.ptr) == 0
143 return *(*uint64)(urv.ptr) == 0
144 case reflect.Uintptr:
145 return *(*uintptr)(urv.ptr) == 0
146 case reflect.Float32:
147 return *(*float32)(urv.ptr) == 0
148 case reflect.Float64:
149 return *(*float64)(urv.ptr) == 0
150 case reflect.Interface:
151 isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
156 return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
160 // isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
161 isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
166 return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
170 return isEmptyStruct(v, tinfos, deref, checkStruct)
171 case reflect.Map, reflect.Array, reflect.Chan:
177 // --------------------------
179 // atomicTypeInfoSlice contains length and pointer to the array for a slice.
180 // It is expected to be 2 words.
182 // Previously, we atomically loaded and stored the length and array pointer separately,
183 // which could lead to some races.
184 // We now just atomically store and load the pointer to the value directly.
186 type atomicTypeInfoSlice struct { // expected to be 2 words
187 l int // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
188 v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
191 func (x *atomicTypeInfoSlice) load() []rtid2ti {
192 xp := unsafe.Pointer(x)
193 x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
197 return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
200 func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
201 s := (*unsafeSlice)(unsafe.Pointer(&p))
202 xp := unsafe.Pointer(x)
203 atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
206 // --------------------------
207 type atomicClsErr struct {
211 func (x *atomicClsErr) load() clsErr {
212 xp := unsafe.Pointer(&x.v)
213 return *(*clsErr)(atomic.LoadPointer(&xp))
216 func (x *atomicClsErr) store(p clsErr) {
217 xp := unsafe.Pointer(&x.v)
218 atomic.StorePointer(&xp, unsafe.Pointer(&p))
221 // --------------------------
222 func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
223 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
224 *(*[]byte)(urv.ptr) = d.rawBytes()
227 func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
228 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
229 *(*string)(urv.ptr) = d.d.DecodeString()
232 func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
233 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
234 *(*bool)(urv.ptr) = d.d.DecodeBool()
237 func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
238 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
239 *(*time.Time)(urv.ptr) = d.d.DecodeTime()
242 func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
243 fv := d.d.DecodeFloat64()
244 if chkOvf.Float32(fv) {
245 d.errorf("float32 overflow: %v", fv)
247 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
248 *(*float32)(urv.ptr) = float32(fv)
251 func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
252 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
253 *(*float64)(urv.ptr) = d.d.DecodeFloat64()
256 func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
257 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
258 *(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
261 func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
262 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
263 *(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
266 func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
267 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
268 *(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
271 func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
272 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
273 *(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
276 func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
277 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
278 *(*int64)(urv.ptr) = d.d.DecodeInt64()
281 func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
282 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
283 *(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
286 func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
287 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
288 *(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
291 func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
292 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
293 *(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
296 func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
297 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
298 *(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
301 func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
302 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
303 *(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
306 func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
307 urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
308 *(*uint64)(urv.ptr) = d.d.DecodeUint64()
313 func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
314 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
315 e.e.EncodeBool(*(*bool)(v.ptr))
318 func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
319 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
320 e.e.EncodeTime(*(*time.Time)(v.ptr))
323 func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
324 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
325 e.e.EncodeString(cUTF8, *(*string)(v.ptr))
328 func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
329 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
330 e.e.EncodeFloat64(*(*float64)(v.ptr))
333 func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
334 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
335 e.e.EncodeFloat32(*(*float32)(v.ptr))
338 func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
339 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
340 e.e.EncodeInt(int64(*(*int)(v.ptr)))
343 func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
344 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
345 e.e.EncodeInt(int64(*(*int8)(v.ptr)))
348 func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
349 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
350 e.e.EncodeInt(int64(*(*int16)(v.ptr)))
353 func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
354 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
355 e.e.EncodeInt(int64(*(*int32)(v.ptr)))
358 func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
359 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
360 e.e.EncodeInt(int64(*(*int64)(v.ptr)))
363 func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
364 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
365 e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
368 func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
369 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
370 e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
373 func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
374 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
375 e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
378 func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
379 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
380 e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
383 func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
384 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
385 e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
388 func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
389 v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
390 e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
395 // func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
396 // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
397 // // if urv.flag&unsafeFlagIndir != 0 {
398 // // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
400 // *(*[]byte)(urv.ptr) = d.rawBytes()
403 // func rv0t(rt reflect.Type) reflect.Value {
404 // ut := (*unsafeIntf)(unsafe.Pointer(&rt))
405 // // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
406 // uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
407 // return *(*reflect.Value)(unsafe.Pointer(&uv})
410 // func rv2i(rv reflect.Value) interface{} {
411 // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
412 // // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
413 // var ptr unsafe.Pointer
414 // // kk := reflect.Kind(urv.flag & (1<<5 - 1))
415 // // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
416 // if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
417 // ptr = *(*unsafe.Pointer)(urv.ptr)
421 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
422 // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
423 // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
426 // func definitelyNil(v interface{}) bool {
427 // var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
428 // if ui.word == nil {
431 // var tk = reflect.TypeOf(v).Kind()
432 // return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
433 // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
434 // v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
437 // func keepAlive4BytesView(v string) {
438 // runtime.KeepAlive(v)
441 // func keepAlive4StringView(v []byte) {
442 // runtime.KeepAlive(v)
445 // func rt2id(rt reflect.Type) uintptr {
446 // return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
447 // // var i interface{} = rt
448 // // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
449 // // return ((*unsafeIntf)(unsafe.Pointer(&i))).word
452 // func rv2i(rv reflect.Value) interface{} {
453 // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
454 // // non-reference type: already indir
455 // // reference type: depend on flagIndir property ('cos maybe was double-referenced)
456 // // const (unsafeRvFlagKindMask = 1<<5 - 1 , unsafeRvFlagIndir = 1 << 7 )
457 // // rvk := reflect.Kind(urv.flag & (1<<5 - 1))
458 // // if (rvk == reflect.Chan ||
459 // // rvk == reflect.Func ||
460 // // rvk == reflect.Interface ||
461 // // rvk == reflect.Map ||
462 // // rvk == reflect.Ptr ||
463 // // rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
464 // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
465 // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
467 // if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
468 // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
469 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
471 // // fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
472 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
476 // unsafeRvFlagKindMask = 1<<5 - 1
477 // unsafeRvKindDirectIface = 1 << 5
478 // unsafeRvFlagIndir = 1 << 7
479 // unsafeRvFlagAddr = 1 << 8
480 // unsafeRvFlagMethod = 1 << 9
482 // _USE_RV_INTERFACE bool = false
483 // _UNSAFE_RV_DEBUG = true
486 // type unsafeRtype struct {
497 // func _rv2i(rv reflect.Value) interface{} {
498 // // Note: From use,
499 // // - it's never an interface
500 // // - the only calls here are for ifaceIndir types.
501 // // (though that conditional is wrong)
502 // // To know for sure, we need the value of t.kind (which is not exposed).
504 // // Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
505 // // - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
506 // // - Type Direct, Value indirect: ==> map???
507 // // - Type Direct, Value direct: ==> pointers, unsafe.Pointer, func, chan, map
510 // // if typeIndirect { } else if valueIndirect { } else { }
512 // // Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
514 // if _USE_RV_INTERFACE {
515 // return rv.Interface()
517 // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
519 // // if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
520 // // println("***** IS flag method or interface: delegating to rv.Interface()")
521 // // return rv.Interface()
524 // // if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
525 // // println("***** IS Interface: delegate to rv.Interface")
526 // // return rv.Interface()
528 // // if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
529 // // if urv.flag&unsafeRvFlagAddr == 0 {
530 // // println("***** IS ifaceIndir typ")
531 // // // ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
532 // // // return *(*interface{})(unsafe.Pointer(&ui))
533 // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
535 // // } else if urv.flag&unsafeRvFlagIndir != 0 {
536 // // println("***** IS flagindir")
537 // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
539 // // println("***** NOT flagindir")
540 // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
542 // // println("***** default: delegate to rv.Interface")
544 // urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
545 // if _UNSAFE_RV_DEBUG {
546 // fmt.Printf(">>>> start: %v: ", rv.Type())
547 // fmt.Printf("%v - %v\n", *urv, *urt)
549 // if urt.kind&unsafeRvKindDirectIface == 0 {
550 // if _UNSAFE_RV_DEBUG {
551 // fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
553 // // println("***** IS ifaceIndir typ")
554 // // if true || urv.flag&unsafeRvFlagAddr == 0 {
555 // // // println(" ***** IS NOT addr")
556 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
558 // } else if urv.flag&unsafeRvFlagIndir != 0 {
559 // if _UNSAFE_RV_DEBUG {
560 // fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
562 // // println("***** IS flagindir")
563 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
565 // if _UNSAFE_RV_DEBUG {
566 // fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
568 // // println("***** NOT flagindir")
569 // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
571 // // println("***** default: delegating to rv.Interface()")
572 // // return rv.Interface()
575 // var staticM0 = make(map[string]uint64)
576 // var staticI0 = (int32)(-5)
578 // func staticRv2iTest() {
580 // m0 := make(map[string]uint16)
582 // for _, i := range []interface{}{
591 // complex(float32(19), 5),
592 // complex(float64(-32), 7),
593 // [4]uint64{1, 2, 3, 4},
594 // (chan<- int)(nil), // chan,
596 // io.Writer(ioutil.Discard),
597 // make(map[string]uint),
598 // (map[string]uint)(nil),
606 // []uint32{6, 7, 8},
612 // unsafe.Pointer(&i0),
614 // i2 := rv2i(reflect.ValueOf(i))
615 // eq := reflect.DeepEqual(i, i2)
616 // fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
625 // func rv2i(rv reflect.Value) interface{} {
626 // if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
627 // return rv.Interface()
629 // // var i interface{}
630 // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
632 // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
633 // // fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
634 // if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
635 // if urv.flag&unsafeRvFlagAddr != 0 {
636 // println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
637 // return rv.Interface()
639 // println("****** indirect type/kind")
641 // } else if urv.flag&unsafeRvFlagIndir != 0 {
642 // println("****** unsafe rv flag indir")
643 // ui.word = *(*unsafe.Pointer)(urv.ptr)
645 // println("****** default: assign prt to word directly")
648 // // ui.word = urv.ptr
650 // // fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
651 // // fmt.Printf("(binary) ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
652 // return *(*interface{})(unsafe.Pointer(&ui))