github.com/gotranspile/cxgo@v0.3.7/runtime/libc/memory.go (about) 1 package libc 2 3 import ( 4 "unsafe" 5 ) 6 7 var allocs syncMap[unsafe.Pointer, []byte] 8 9 // makePad creates a slice with a given size, but adds padding before and after the slice. 10 // It is required to make some unsafe C code work, e.g. indexing elements after the slice end. 11 func makePad(sz int, pad int) []byte { 12 if sz <= 0 { 13 panic("size should be > 0") 14 } 15 if pad == 0 { 16 pad = int(unsafe.Sizeof(uintptr(0))) 17 } 18 p := make([]byte, sz+pad*2) 19 p = p[pad:] 20 p = p[:sz:sz] 21 return p 22 } 23 24 func malloc(sz int) []byte { 25 b := makePad(sz, 0) 26 p := unsafe.Pointer(&b[0]) 27 allocs.Store(p, b) 28 return b 29 } 30 31 // Malloc allocates a region of memory. 32 func Malloc(sz int) unsafe.Pointer { 33 b := malloc(sz) 34 return unsafe.Pointer(&b[0]) 35 } 36 37 // Calloc allocates a region of memory for num elements of size sz. 38 func Calloc(num, sz int) unsafe.Pointer { 39 if num == 0 { 40 return nil 41 } 42 if sz <= 0 { 43 panic("size should be > 0") 44 } 45 b := makePad(num*sz, sz) 46 p := unsafe.Pointer(&b[0]) 47 allocs.Store(p, b) 48 return p 49 } 50 51 func withSize(p unsafe.Pointer) ([]byte, bool) { 52 return allocs.Load(p) 53 } 54 55 func Realloc(buf unsafe.Pointer, sz int) unsafe.Pointer { 56 if buf == nil { 57 return Malloc(sz) 58 } 59 p := malloc(sz) 60 src, ok := withSize(buf) 61 if !ok { 62 panic("realloc of a pointer not managed by cxgo") 63 } 64 copy(p, src) 65 Free(buf) 66 return unsafe.Pointer(&p[0]) 67 } 68 69 // Free marks the memory as freed. May be a nop in Go. 70 func Free(p unsafe.Pointer) { 71 allocs.Delete(p) 72 } 73 74 // ToPointer converts a uintptr to unsafe.Pointer. 75 func ToPointer(p uintptr) unsafe.Pointer { 76 return unsafe.Pointer(p) 77 } 78 79 // ToUintptr converts a unsafe.Pointer to uintptr. 80 func ToUintptr(p unsafe.Pointer) uintptr { 81 return uintptr(p) 82 } 83 84 // PointerDiff calculates (a - b). 85 func PointerDiff(a, b unsafe.Pointer) int { 86 return int(uintptr(a) - uintptr(b)) 87 } 88 89 // IndexUnsafePtr unsafely moves a pointer by i bytes. An offset may be negative. 90 // 91 // Deprecated: use unsafe.Add 92 func IndexUnsafePtr(p unsafe.Pointer, i int) unsafe.Pointer { 93 return unsafe.Add(p, i) 94 } 95 96 // IndexBytePtr unsafely moves a byte pointer by i bytes. An offset may be negative. 97 // 98 // Deprecated: use unsafe.Add 99 func IndexBytePtr(p *byte, i int) *byte { 100 return (*byte)(unsafe.Add(unsafe.Pointer(p), i)) 101 } 102 103 // UnsafeBytesN makes a slice of a given size starting at ptr. 104 // 105 // Deprecated: use unsafe.Slice 106 func UnsafeBytesN(ptr unsafe.Pointer, sz int) []byte { 107 return unsafe.Slice((*byte)(ptr), sz) 108 } 109 110 // BytesN makes a slice of a given size starting at ptr. 111 // It accepts a *byte instead of unsafe pointer as UnsafeBytesN does, which allows to avoid unsafe import. 112 // 113 // Deprecated: use unsafe.Slice 114 func BytesN(p *byte, sz int) []byte { 115 return unsafe.Slice(p, sz) 116 } 117 118 // UnsafeUint16N makes a uint16 slice of a given size starting at ptr. 119 // 120 // Deprecated: use unsafe.Slice 121 func UnsafeUint16N(ptr unsafe.Pointer, sz int) []uint16 { 122 return unsafe.Slice((*WChar)(ptr), sz) 123 } 124 125 // Uint16N makes a uint16 slice of a given size starting at ptr. 126 // It accepts a *uint16 instead of unsafe pointer as UnsafeUint16N does, which allows to avoid unsafe import. 127 // 128 // Deprecated: use unsafe.Slice 129 func Uint16N(p *uint16, sz int) []uint16 { 130 return unsafe.Slice(p, sz) 131 } 132 133 // UnsafeUint32N makes a uint32 slice of a given size starting at ptr. 134 // 135 // Deprecated: use unsafe.Slice 136 func UnsafeUint32N(ptr unsafe.Pointer, sz int) []uint32 { 137 return unsafe.Slice((*uint32)(ptr), sz) 138 } 139 140 // Uint32N makes a uint32 slice of a given size starting at ptr. 141 // It accepts a *uint32 instead of unsafe pointer as UnsafeUint32N does, which allows to avoid unsafe import. 142 // 143 // Deprecated: use unsafe.Slice 144 func Uint32N(p *uint32, sz int) []uint32 { 145 return unsafe.Slice(p, sz) 146 }