tree_sitter_c2rust/core_wrapper/
alloc.rs1use std::{alloc, ffi, ptr};
2use std::{alloc::Layout, mem::align_of};
3
4pub unsafe fn ts_set_allocator(
5 _new_malloc: Option<unsafe extern "C" fn(usize) -> *mut std::ffi::c_void>,
6 _new_calloc: Option<unsafe extern "C" fn(usize, usize) -> *mut std::ffi::c_void>,
7 _new_realloc: Option<
8 unsafe extern "C" fn(*mut std::ffi::c_void, usize) -> *mut std::ffi::c_void,
9 >,
10 _new_free: Option<unsafe extern "C" fn(*mut std::ffi::c_void)>,
11) {
12}
13#[inline]
15pub(crate) unsafe extern "C" fn ts_malloc(size: usize) -> *mut ffi::c_void {
16 if size == 0 {
17 return ptr::null_mut();
18 }
19
20 let (layout, offset_data) = Layout::new::<Layout>()
21 .extend(Layout::from_size_align(size, align_of::<*const u8>() * 2).unwrap())
22 .unwrap();
23 let result = alloc::alloc(layout);
24 if result.is_null() {
25 panic!("tree-sitter failed to allocate {} bytes", size);
26 }
27
28 *(result as *mut Layout) = layout;
29 (result as *mut u8).offset(offset_data as isize) as *mut ffi::c_void
30}
31
32#[inline]
33pub(crate) unsafe extern "C" fn ts_calloc(count: usize, size: usize) -> *mut ffi::c_void {
34 if count == 0 || size == 0 {
35 return ptr::null_mut();
36 }
37
38 let (layout, offset_data) = Layout::new::<Layout>()
39 .extend(Layout::from_size_align(size * count, align_of::<*const u8>() * 2).unwrap())
40 .unwrap();
41 let result = alloc::alloc_zeroed(layout);
42 if result.is_null() {
43 panic!("tree-sitter failed to allocate {} bytes", size);
44 }
45
46 *(result as *mut Layout) = layout;
47 (result as *mut u8).offset(offset_data as isize) as *mut ffi::c_void
48}
49
50#[inline]
51pub(crate) unsafe extern "C" fn ts_realloc(
52 buffer: *mut ffi::c_void,
53 size: usize,
54) -> *mut ffi::c_void {
55 if buffer.is_null() {
56 ts_malloc(size)
57 } else if size == 0 {
58 ts_free(buffer);
59 ptr::null_mut()
60 } else {
61 let (_, layout_offset) = Layout::new::<Layout>()
62 .extend(Layout::from_size_align(0, align_of::<*const u8>() * 2).unwrap())
63 .unwrap();
64
65 let buffer = (buffer as *mut u8).offset(-(layout_offset as isize));
66 let layout = *(buffer as *mut Layout);
67
68 let (new_layout, offset_data) = Layout::new::<Layout>()
69 .extend(Layout::from_size_align(size, layout.align()).unwrap())
70 .unwrap();
71
72 let result = alloc::realloc(buffer, layout, new_layout.size());
73 if result.is_null() {
74 panic!("tree-sitter failed to reallocate {} bytes", size);
75 }
76
77 *(result as *mut Layout) = new_layout;
78 (result as *mut u8).offset(offset_data as isize) as *mut ffi::c_void
79 }
80}
81
82#[inline]
83pub(crate) unsafe extern "C" fn ts_free(buffer: *mut ffi::c_void) {
84 if buffer.is_null() {
85 return;
86 }
87
88 let (_, layout_offset) = Layout::new::<Layout>()
89 .extend(Layout::from_size_align(0, align_of::<*const u8>() * 2).unwrap())
90 .unwrap();
91
92 let buffer = (buffer as *mut u8).offset(-(layout_offset as isize));
93 let layout = *(buffer as *mut Layout);
94
95 alloc::dealloc(buffer, layout);
96}