123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- // +build !safe
- // +build !appengine
- // +build go1.7
- // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
- // Use of this source code is governed by a MIT license found in the LICENSE file.
- package codec
- import (
- "reflect"
- "sync/atomic"
- "time"
- "unsafe"
- )
- // This file has unsafe variants of some helper methods.
- // NOTE: See helper_not_unsafe.go for the usage information.
- // var zeroRTv [4]uintptr
- const safeMode = false
- const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
- type unsafeString struct {
- Data unsafe.Pointer
- Len int
- }
- type unsafeSlice struct {
- Data unsafe.Pointer
- Len int
- Cap int
- }
- type unsafeIntf struct {
- typ unsafe.Pointer
- word unsafe.Pointer
- }
- type unsafeReflectValue struct {
- typ unsafe.Pointer
- ptr unsafe.Pointer
- flag uintptr
- }
- func stringView(v []byte) string {
- if len(v) == 0 {
- return ""
- }
- bx := (*unsafeSlice)(unsafe.Pointer(&v))
- return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
- }
- func bytesView(v string) []byte {
- if len(v) == 0 {
- return zeroByteSlice
- }
- sx := (*unsafeString)(unsafe.Pointer(&v))
- return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
- }
- func definitelyNil(v interface{}) bool {
- // There is no global way of checking if an interface is nil.
- // For true references (map, ptr, func, chan), you can just look
- // at the word of the interface. However, for slices, you have to dereference
- // the word, and get a pointer to the 3-word interface value.
- //
- // However, the following are cheap calls
- // - TypeOf(interface): cheap 2-line call.
- // - ValueOf(interface{}): expensive
- // - type.Kind: cheap call through an interface
- // - Value.Type(): cheap call
- // except it's a method value (e.g. r.Read, which implies that it is a Func)
- return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
- }
- func rv2i(rv reflect.Value) interface{} {
- // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
- //
- // Currently, we use this fragile method that taps into implememtation details from
- // the source go stdlib reflect/value.go, and trims the implementation.
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
- var ptr unsafe.Pointer
- if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
- ptr = *(*unsafe.Pointer)(urv.ptr)
- } else {
- ptr = urv.ptr
- }
- return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
- }
- func rt2id(rt reflect.Type) uintptr {
- return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
- }
- // func rv2rtid(rv reflect.Value) uintptr {
- // return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
- // }
- func i2rtid(i interface{}) uintptr {
- return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
- }
- // --------------------------
- func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
- if urv.flag == 0 {
- return true
- }
- switch v.Kind() {
- case reflect.Invalid:
- return true
- case reflect.String:
- return (*unsafeString)(urv.ptr).Len == 0
- case reflect.Slice:
- return (*unsafeSlice)(urv.ptr).Len == 0
- case reflect.Bool:
- return !*(*bool)(urv.ptr)
- case reflect.Int:
- return *(*int)(urv.ptr) == 0
- case reflect.Int8:
- return *(*int8)(urv.ptr) == 0
- case reflect.Int16:
- return *(*int16)(urv.ptr) == 0
- case reflect.Int32:
- return *(*int32)(urv.ptr) == 0
- case reflect.Int64:
- return *(*int64)(urv.ptr) == 0
- case reflect.Uint:
- return *(*uint)(urv.ptr) == 0
- case reflect.Uint8:
- return *(*uint8)(urv.ptr) == 0
- case reflect.Uint16:
- return *(*uint16)(urv.ptr) == 0
- case reflect.Uint32:
- return *(*uint32)(urv.ptr) == 0
- case reflect.Uint64:
- return *(*uint64)(urv.ptr) == 0
- case reflect.Uintptr:
- return *(*uintptr)(urv.ptr) == 0
- case reflect.Float32:
- return *(*float32)(urv.ptr) == 0
- case reflect.Float64:
- return *(*float64)(urv.ptr) == 0
- case reflect.Interface:
- isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
- if deref {
- if isnil {
- return true
- }
- return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
- }
- return isnil
- case reflect.Ptr:
- // isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
- isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
- if deref {
- if isnil {
- return true
- }
- return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
- }
- return isnil
- case reflect.Struct:
- return isEmptyStruct(v, tinfos, deref, checkStruct)
- case reflect.Map, reflect.Array, reflect.Chan:
- return v.Len() == 0
- }
- return false
- }
- // --------------------------
- // atomicXXX is expected to be 2 words (for symmetry with atomic.Value)
- //
- // Note that we do not atomically load/store length and data pointer separately,
- // as this could lead to some races. Instead, we atomically load/store cappedSlice.
- //
- // Note: with atomic.(Load|Store)Pointer, we MUST work with an unsafe.Pointer directly.
- // ----------------------
- type atomicTypeInfoSlice struct {
- v unsafe.Pointer // *[]rtid2ti
- _ uint64 // padding (atomicXXX expected to be 2 words)
- }
- func (x *atomicTypeInfoSlice) load() (s []rtid2ti) {
- x2 := atomic.LoadPointer(&x.v)
- if x2 != nil {
- s = *(*[]rtid2ti)(x2)
- }
- return
- }
- func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
- atomic.StorePointer(&x.v, unsafe.Pointer(&p))
- }
- // --------------------------
- type atomicRtidFnSlice struct {
- v unsafe.Pointer // *[]codecRtidFn
- // _ uint64 // padding (atomicXXX expected to be 2 words) (make 1 word so JsonHandle fits)
- }
- func (x *atomicRtidFnSlice) load() (s []codecRtidFn) {
- x2 := atomic.LoadPointer(&x.v)
- if x2 != nil {
- s = *(*[]codecRtidFn)(x2)
- }
- return
- }
- func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
- atomic.StorePointer(&x.v, unsafe.Pointer(&p))
- }
- // --------------------------
- type atomicClsErr struct {
- v unsafe.Pointer // *clsErr
- _ uint64 // padding (atomicXXX expected to be 2 words)
- }
- func (x *atomicClsErr) load() (e clsErr) {
- x2 := (*clsErr)(atomic.LoadPointer(&x.v))
- if x2 != nil {
- e = *x2
- }
- return
- }
- func (x *atomicClsErr) store(p clsErr) {
- atomic.StorePointer(&x.v, unsafe.Pointer(&p))
- }
- // --------------------------
- // to create a reflect.Value for each member field of decNaked,
- // we first create a global decNaked, and create reflect.Value
- // for them all.
- // This way, we have the flags and type in the reflect.Value.
- // Then, when a reflect.Value is called, we just copy it,
- // update the ptr to the decNaked's, and return it.
- type unsafeDecNakedWrapper struct {
- decNaked
- ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
- }
- func (n *unsafeDecNakedWrapper) init() {
- n.ru = reflect.ValueOf(&n.u).Elem()
- n.ri = reflect.ValueOf(&n.i).Elem()
- n.rf = reflect.ValueOf(&n.f).Elem()
- n.rl = reflect.ValueOf(&n.l).Elem()
- n.rs = reflect.ValueOf(&n.s).Elem()
- n.rt = reflect.ValueOf(&n.t).Elem()
- n.rb = reflect.ValueOf(&n.b).Elem()
- // n.rr[] = reflect.ValueOf(&n.)
- }
- var defUnsafeDecNakedWrapper unsafeDecNakedWrapper
- func init() {
- defUnsafeDecNakedWrapper.init()
- }
- func (n *decNaked) ru() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.ru
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.u)
- return
- }
- func (n *decNaked) ri() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.ri
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.i)
- return
- }
- func (n *decNaked) rf() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.rf
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.f)
- return
- }
- func (n *decNaked) rl() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.rl
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.l)
- return
- }
- func (n *decNaked) rs() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.rs
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.s)
- return
- }
- func (n *decNaked) rt() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.rt
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.t)
- return
- }
- func (n *decNaked) rb() (v reflect.Value) {
- v = defUnsafeDecNakedWrapper.rb
- ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.b)
- return
- }
- // --------------------------
- func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*[]byte)(urv.ptr) = d.rawBytes()
- }
- func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*string)(urv.ptr) = d.d.DecodeString()
- }
- func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*bool)(urv.ptr) = d.d.DecodeBool()
- }
- func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*time.Time)(urv.ptr) = d.d.DecodeTime()
- }
- func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*float32)(urv.ptr) = float32(d.decodeFloat32())
- }
- func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*float64)(urv.ptr) = d.d.DecodeFloat64()
- }
- func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
- }
- func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
- }
- func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
- }
- func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
- }
- func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*int64)(urv.ptr) = d.d.DecodeInt64()
- }
- func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
- }
- func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
- }
- func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
- }
- func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
- }
- func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
- }
- func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
- urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- *(*uint64)(urv.ptr) = d.d.DecodeUint64()
- }
- // ------------
- func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeBool(*(*bool)(v.ptr))
- }
- func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeTime(*(*time.Time)(v.ptr))
- }
- func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- s := *(*string)(v.ptr)
- if e.h.StringToRaw {
- e.e.EncodeStringBytesRaw(bytesView(s))
- } else {
- e.e.EncodeStringEnc(cUTF8, s)
- }
- }
- func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeFloat64(*(*float64)(v.ptr))
- }
- func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeFloat32(*(*float32)(v.ptr))
- }
- func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeInt(int64(*(*int)(v.ptr)))
- }
- func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeInt(int64(*(*int8)(v.ptr)))
- }
- func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeInt(int64(*(*int16)(v.ptr)))
- }
- func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeInt(int64(*(*int32)(v.ptr)))
- }
- func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeInt(int64(*(*int64)(v.ptr)))
- }
- func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
- }
- func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
- }
- func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
- }
- func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
- }
- func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
- }
- func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
- v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
- }
- // ------------
- // func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
- // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // // if urv.flag&unsafeFlagIndir != 0 {
- // // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
- // // }
- // *(*[]byte)(urv.ptr) = d.rawBytes()
- // }
- // func rv0t(rt reflect.Type) reflect.Value {
- // ut := (*unsafeIntf)(unsafe.Pointer(&rt))
- // // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
- // uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
- // return *(*reflect.Value)(unsafe.Pointer(&uv})
- // }
- // func rv2i(rv reflect.Value) interface{} {
- // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
- // var ptr unsafe.Pointer
- // // kk := reflect.Kind(urv.flag & (1<<5 - 1))
- // // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
- // if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
- // ptr = *(*unsafe.Pointer)(urv.ptr)
- // } else {
- // ptr = urv.ptr
- // }
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
- // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
- // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // }
- // func definitelyNil(v interface{}) bool {
- // var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
- // if ui.word == nil {
- // return true
- // }
- // var tk = reflect.TypeOf(v).Kind()
- // return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
- // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
- // v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
- // }
- // func keepAlive4BytesView(v string) {
- // runtime.KeepAlive(v)
- // }
- // func keepAlive4StringView(v []byte) {
- // runtime.KeepAlive(v)
- // }
- // func rt2id(rt reflect.Type) uintptr {
- // return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
- // // var i interface{} = rt
- // // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
- // // return ((*unsafeIntf)(unsafe.Pointer(&i))).word
- // }
- // func rv2i(rv reflect.Value) interface{} {
- // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // // non-reference type: already indir
- // // reference type: depend on flagIndir property ('cos maybe was double-referenced)
- // // const (unsafeRvFlagKindMask = 1<<5 - 1 , unsafeRvFlagIndir = 1 << 7 )
- // // rvk := reflect.Kind(urv.flag & (1<<5 - 1))
- // // if (rvk == reflect.Chan ||
- // // rvk == reflect.Func ||
- // // rvk == reflect.Interface ||
- // // rvk == reflect.Map ||
- // // rvk == reflect.Ptr ||
- // // rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
- // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
- // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
- // // }
- // if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
- // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
- // }
- // // fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // }
- // const (
- // unsafeRvFlagKindMask = 1<<5 - 1
- // unsafeRvKindDirectIface = 1 << 5
- // unsafeRvFlagIndir = 1 << 7
- // unsafeRvFlagAddr = 1 << 8
- // unsafeRvFlagMethod = 1 << 9
- // _USE_RV_INTERFACE bool = false
- // _UNSAFE_RV_DEBUG = true
- // )
- // type unsafeRtype struct {
- // _ [2]uintptr
- // _ uint32
- // _ uint8
- // _ uint8
- // _ uint8
- // kind uint8
- // _ [2]uintptr
- // _ int32
- // }
- // func _rv2i(rv reflect.Value) interface{} {
- // // Note: From use,
- // // - it's never an interface
- // // - the only calls here are for ifaceIndir types.
- // // (though that conditional is wrong)
- // // To know for sure, we need the value of t.kind (which is not exposed).
- // //
- // // Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
- // // - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
- // // - Type Direct, Value indirect: ==> map???
- // // - Type Direct, Value direct: ==> pointers, unsafe.Pointer, func, chan, map
- // //
- // // TRANSLATES TO:
- // // if typeIndirect { } else if valueIndirect { } else { }
- // //
- // // Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
- // if _USE_RV_INTERFACE {
- // return rv.Interface()
- // }
- // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // // if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
- // // println("***** IS flag method or interface: delegating to rv.Interface()")
- // // return rv.Interface()
- // // }
- // // if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
- // // println("***** IS Interface: delegate to rv.Interface")
- // // return rv.Interface()
- // // }
- // // if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
- // // if urv.flag&unsafeRvFlagAddr == 0 {
- // // println("***** IS ifaceIndir typ")
- // // // ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
- // // // return *(*interface{})(unsafe.Pointer(&ui))
- // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // // }
- // // } else if urv.flag&unsafeRvFlagIndir != 0 {
- // // println("***** IS flagindir")
- // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
- // // } else {
- // // println("***** NOT flagindir")
- // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // // }
- // // println("***** default: delegate to rv.Interface")
- // urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
- // if _UNSAFE_RV_DEBUG {
- // fmt.Printf(">>>> start: %v: ", rv.Type())
- // fmt.Printf("%v - %v\n", *urv, *urt)
- // }
- // if urt.kind&unsafeRvKindDirectIface == 0 {
- // if _UNSAFE_RV_DEBUG {
- // fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
- // }
- // // println("***** IS ifaceIndir typ")
- // // if true || urv.flag&unsafeRvFlagAddr == 0 {
- // // // println(" ***** IS NOT addr")
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // // }
- // } else if urv.flag&unsafeRvFlagIndir != 0 {
- // if _UNSAFE_RV_DEBUG {
- // fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
- // }
- // // println("***** IS flagindir")
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
- // } else {
- // if _UNSAFE_RV_DEBUG {
- // fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
- // }
- // // println("***** NOT flagindir")
- // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
- // }
- // // println("***** default: delegating to rv.Interface()")
- // // return rv.Interface()
- // }
- // var staticM0 = make(map[string]uint64)
- // var staticI0 = (int32)(-5)
- // func staticRv2iTest() {
- // i0 := (int32)(-5)
- // m0 := make(map[string]uint16)
- // m0["1"] = 1
- // for _, i := range []interface{}{
- // (int)(7),
- // (uint)(8),
- // (int16)(-9),
- // (uint16)(19),
- // (uintptr)(77),
- // (bool)(true),
- // float32(-32.7),
- // float64(64.9),
- // complex(float32(19), 5),
- // complex(float64(-32), 7),
- // [4]uint64{1, 2, 3, 4},
- // (chan<- int)(nil), // chan,
- // rv2i, // func
- // io.Writer(ioutil.Discard),
- // make(map[string]uint),
- // (map[string]uint)(nil),
- // staticM0,
- // m0,
- // &m0,
- // i0,
- // &i0,
- // &staticI0,
- // &staticM0,
- // []uint32{6, 7, 8},
- // "abc",
- // Raw{},
- // RawExt{},
- // &Raw{},
- // &RawExt{},
- // unsafe.Pointer(&i0),
- // } {
- // i2 := rv2i(reflect.ValueOf(i))
- // eq := reflect.DeepEqual(i, i2)
- // fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
- // }
- // // os.Exit(0)
- // }
- // func init() {
- // staticRv2iTest()
- // }
- // func rv2i(rv reflect.Value) interface{} {
- // if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
- // return rv.Interface()
- // }
- // // var i interface{}
- // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
- // var ui unsafeIntf
- // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
- // // fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
- // if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
- // if urv.flag&unsafeRvFlagAddr != 0 {
- // println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
- // return rv.Interface()
- // }
- // println("****** indirect type/kind")
- // ui.word = urv.ptr
- // } else if urv.flag&unsafeRvFlagIndir != 0 {
- // println("****** unsafe rv flag indir")
- // ui.word = *(*unsafe.Pointer)(urv.ptr)
- // } else {
- // println("****** default: assign prt to word directly")
- // ui.word = urv.ptr
- // }
- // // ui.word = urv.ptr
- // ui.typ = urv.typ
- // // fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
- // // fmt.Printf("(binary) ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
- // return *(*interface{})(unsafe.Pointer(&ui))
- // // return i
- // }
|