github.com/wI2L/jettison@v0.7.5-0.20230106001914-c70014c6417a/unsafe.go (about)

     1  package jettison
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  )
     7  
     8  // eface is the runtime representation of
     9  // the empty interface.
    10  type eface struct {
    11  	rtype unsafe.Pointer
    12  	word  unsafe.Pointer
    13  }
    14  
    15  // sliceHeader is the runtime representation
    16  // of a slice.
    17  type sliceHeader struct {
    18  	Data unsafe.Pointer
    19  	Len  int
    20  	Cap  int
    21  }
    22  
    23  // stringHeader is the runtime representation
    24  // of a string.
    25  type stringHeader struct {
    26  	Data unsafe.Pointer
    27  	Len  int
    28  }
    29  
    30  //nolint:staticcheck
    31  //go:nosplit
    32  func noescape(p unsafe.Pointer) unsafe.Pointer {
    33  	x := uintptr(p)
    34  	return unsafe.Pointer(x ^ 0)
    35  }
    36  
    37  func unpackEface(i interface{}) *eface {
    38  	return (*eface)(unsafe.Pointer(&i))
    39  }
    40  
    41  func packEface(p unsafe.Pointer, t reflect.Type, ptr bool) interface{} {
    42  	var i interface{}
    43  	e := (*eface)(unsafe.Pointer(&i))
    44  	e.rtype = unpackEface(t).word
    45  
    46  	if ptr {
    47  		// Value is indirect, but interface is
    48  		// direct. We need to load the data at
    49  		// p into the interface data word.
    50  		e.word = *(*unsafe.Pointer)(p)
    51  	} else {
    52  		// Value is direct, and so is the interface.
    53  		e.word = p
    54  	}
    55  	return i
    56  }
    57  
    58  // sp2b converts a string pointer to a byte slice.
    59  //go:nosplit
    60  func sp2b(p unsafe.Pointer) []byte {
    61  	shdr := (*stringHeader)(p)
    62  	return *(*[]byte)(unsafe.Pointer(&sliceHeader{
    63  		Data: shdr.Data,
    64  		Len:  shdr.Len,
    65  		Cap:  shdr.Len,
    66  	}))
    67  }