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 }