github.com/niubaoshu/gotiny@v0.0.4-0.20211018120156-10d393f19ad0/unsafe.go (about) 1 package gotiny 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 const ( 9 kindDirectIface = 1 << 5 10 ) 11 12 // rtype is the common implementation of most values. 13 // It is embedded in other struct types. 14 // 15 // rtype must be kept in sync with reflect/type.go:/^type._type. 16 type rtype struct { 17 _ uintptr 18 _ uintptr // number of bytes in the type that can contain pointers 19 _ uint32 // hash of type; avoids computation in hash tables 20 _ uint8 // extra type information flags 21 _ uint8 // alignment of variable with this type 22 _ uint8 // alignment of struct field with this type 23 kind uint8 // enumeration for C 24 _ uintptr // algorithm table 25 _ uintptr // garbage collection data 26 _ int32 // string form 27 _ int32 // type for pointer to this type, may be zero 28 } 29 30 // ifaceIndir reports whether t is stored indirectly in an interface value. 31 func ifaceDirect(t *rtype) bool { 32 return t.kind&kindDirectIface != 0 33 } 34 35 func directType(rt *reflect.Type) bool { 36 return ifaceDirect((*rtype)((*[2]unsafe.Pointer)(unsafe.Pointer(rt))[1])) 37 } 38 39 type refVal struct { 40 _ unsafe.Pointer 41 ptr unsafe.Pointer 42 flag flag 43 } 44 45 type flag uintptr 46 47 //go:linkname flagIndir reflect.flagIndir 48 const flagIndir flag = 1 << 7 49 50 func getUnsafePointer(rv *reflect.Value) unsafe.Pointer { 51 vv := (*refVal)(unsafe.Pointer(rv)) 52 if vv.flag&flagIndir == 0 { 53 return unsafe.Pointer(&vv.ptr) 54 } else { 55 return vv.ptr 56 } 57 }