Repository navigation
Expand file tree
/
Copy pathallocator.go
More file actions
139 lines (123 loc) · 3.26 KB
/
Copy pathallocator.go
File metadata and controls
139 lines (123 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package tree_sitter
/*
#cgo CFLAGS: -Iinclude -Isrc -std=c11 -D_POSIX_C_SOURCE=200112L -D_DEFAULT_SOURCE
#include <tree_sitter/api.h>
#include "allocator.h"
*/
import "C"
import (
"sync/atomic"
"unsafe"
)
var (
malloc_fn atomic.Value
calloc_fn atomic.Value
realloc_fn atomic.Value
free_fn atomic.Value
)
func init() {
malloc_fn.Store((func(C.size_t) unsafe.Pointer)(nil))
calloc_fn.Store((func(C.size_t, C.size_t) unsafe.Pointer)(nil))
realloc_fn.Store((func(unsafe.Pointer, C.size_t) unsafe.Pointer)(nil))
free_fn.Store((func(unsafe.Pointer))(nil))
}
//export go_malloc
func go_malloc(size C.size_t) unsafe.Pointer {
if fn := malloc_fn.Load().(func(C.size_t) unsafe.Pointer); fn != nil {
return fn(size)
}
return C.malloc(size)
}
//export go_calloc
func go_calloc(num, size C.size_t) unsafe.Pointer {
if fn := calloc_fn.Load().(func(C.size_t, C.size_t) unsafe.Pointer); fn != nil {
return fn(num, size)
}
return C.calloc(num, size)
}
//export go_realloc
func go_realloc(ptr unsafe.Pointer, size C.size_t) unsafe.Pointer {
if fn := realloc_fn.Load().(func(unsafe.Pointer, C.size_t) unsafe.Pointer); fn != nil {
return fn(ptr, size)
}
return C.realloc(ptr, size)
}
//export go_free
func go_free(ptr unsafe.Pointer) {
if fn := free_fn.Load().(func(unsafe.Pointer)); fn != nil {
fn(ptr)
return
}
C.free(ptr)
}
// Sets the memory allocation functions that the core library should use.
func SetAllocator(
newMalloc func(size uint) unsafe.Pointer,
newCalloc func(num, size uint) unsafe.Pointer,
newRealloc func(ptr unsafe.Pointer, size uint) unsafe.Pointer,
newFree func(ptr unsafe.Pointer),
) {
if newMalloc == nil && newCalloc == nil && newRealloc == nil && newFree == nil {
malloc_fn.Store((func(C.size_t) unsafe.Pointer)(nil))
calloc_fn.Store((func(C.size_t, C.size_t) unsafe.Pointer)(nil))
realloc_fn.Store((func(unsafe.Pointer, C.size_t) unsafe.Pointer)(nil))
free_fn.Store((func(unsafe.Pointer))(nil))
C.ts_set_allocator(nil, nil, nil, nil)
return
}
if newMalloc != nil {
malloc_fn.Store(func(size C.size_t) unsafe.Pointer {
return newMalloc(uint(size))
})
} else {
malloc_fn.Store(func(size C.size_t) unsafe.Pointer {
return C.malloc(size)
})
}
if newCalloc != nil {
calloc_fn.Store(func(num, size C.size_t) unsafe.Pointer {
return newCalloc(uint(num), uint(size))
})
} else {
calloc_fn.Store(func(num, size C.size_t) unsafe.Pointer {
return C.calloc(num, size)
})
}
if newRealloc != nil {
realloc_fn.Store(func(ptr unsafe.Pointer, size C.size_t) unsafe.Pointer {
return newRealloc(ptr, uint(size))
})
} else {
realloc_fn.Store(func(ptr unsafe.Pointer, size C.size_t) unsafe.Pointer {
return C.realloc(ptr, size)
})
}
if newFree != nil {
free_fn.Store(func(ptr unsafe.Pointer) {
newFree(ptr)
})
} else {
free_fn.Store(func(ptr unsafe.Pointer) {
C.free(ptr)
})
}
var cMalloc, cCalloc, cRealloc, cFree unsafe.Pointer
if newMalloc != nil {
cMalloc = unsafe.Pointer(C.c_malloc_fn)
}
if newCalloc != nil {
cCalloc = unsafe.Pointer(C.c_calloc_fn)
}
if newRealloc != nil {
cRealloc = unsafe.Pointer(C.c_realloc_fn)
}
if newFree != nil {
cFree = unsafe.Pointer(C.c_free_fn)
}
C.ts_set_allocator(
(*[0]byte)(cMalloc),
(*[0]byte)(cCalloc),
(*[0]byte)(cRealloc),
(*[0]byte)(cFree),
)
}