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  }