tree_sitter_c2rust/core_wrapper/
alloc.rs

1use 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// Private
14#[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}