#![no_std]
#![allow(clippy::style)]
extern crate alloc;
pub mod align;
use core::{mem, ptr};
use core::ffi::c_void;
use core::convert::TryInto;
use alloc::alloc::Layout;
pub const DEFAULT_ALIGNMENT: align::Alignment = {
#[cfg(any(target_os = "macos", all(windows, target_pointer_width = "64")))]
{
align::Alignment::new(16)
}
#[cfg(not(any(target_os = "macos", all(windows, target_pointer_width = "64"))))]
{
align::Alignment::new(8)
}
};
const LAYOUT_OFFSET: usize = mem::size_of::<usize>();
#[cold]
#[inline(never)]
fn unlikely_null() -> *mut c_void {
ptr::null_mut()
}
#[inline(always)]
unsafe fn get_ptr_size(ptr: *mut c_void) -> usize {
let mem = (ptr as *mut u8).offset(-(LAYOUT_OFFSET as isize));
let size = ptr::read(mem as *const usize);
size.saturating_sub(LAYOUT_OFFSET)
}
#[inline]
pub unsafe extern "C" fn rust_malloc(mut size: usize) -> *mut c_void {
if size != 0 {
size = LAYOUT_OFFSET.saturating_add(DEFAULT_ALIGNMENT.next(size));
if let Ok(layout) = Layout::from_size_align(size, DEFAULT_ALIGNMENT.into_raw()) {
let mem = alloc::alloc::alloc(layout);
if !mem.is_null() {
ptr::write(mem as *mut usize, size);
return mem.add(LAYOUT_OFFSET) as _;
}
}
}
unlikely_null()
}
#[inline]
pub unsafe extern "C" fn generic_rust_malloc<T: Into<usize>>(size: T) -> *mut c_void {
rust_malloc(size.into())
}
#[inline]
pub unsafe extern "C" fn generic_try_rust_malloc<T: TryInto<usize>>(size: T) -> *mut c_void {
if let Ok(size) = size.try_into() {
rust_malloc(size)
} else {
unlikely_null()
}
}
#[inline]
pub unsafe extern "C" fn rust_realloc(mut old_ptr: *mut c_void, mut new_size: usize) -> *mut c_void {
if new_size != 0 {
new_size = LAYOUT_OFFSET.saturating_add(DEFAULT_ALIGNMENT.next(new_size));
old_ptr = (old_ptr as *mut u8).offset(-(LAYOUT_OFFSET as isize)) as _;
let size = ptr::read(old_ptr as *const usize);
let layout = Layout::from_size_align_unchecked(size, DEFAULT_ALIGNMENT.into_raw());
let new_ptr = alloc::alloc::realloc(old_ptr as _, layout, new_size);
if !new_ptr.is_null() {
ptr::write(new_ptr as *mut usize, new_size);
return new_ptr.add(LAYOUT_OFFSET) as _;
}
}
unlikely_null()
}
#[inline]
pub unsafe extern "C" fn generic_rust_realloc<T: Into<usize>>(mem: *mut c_void, size: T) -> *mut c_void {
rust_realloc(mem, size.into())
}
#[inline]
pub unsafe extern "C" fn generic_try_rust_realloc<T: TryInto<usize>>(mem: *mut c_void, size: T) -> *mut c_void {
if let Ok(size) = size.try_into() {
rust_realloc(mem, size)
} else {
unlikely_null()
}
}
#[inline]
pub unsafe extern "C" fn rust_calloc(mut size: usize) -> *mut c_void {
let ptr = rust_malloc(size);
if !ptr.is_null() {
size = get_ptr_size(ptr);
ptr::write_bytes(ptr as *mut u8, 0, size);
ptr
} else {
unlikely_null()
}
}
#[inline]
pub unsafe extern "C" fn rust_size(mem: *mut c_void) -> usize {
if !mem.is_null() {
get_ptr_size(mem)
} else {
0
}
}
#[inline]
pub unsafe extern "C" fn rust_free(mem: *mut c_void) {
if !mem.is_null() {
let mem = (mem as *mut u8).offset(-(LAYOUT_OFFSET as isize));
let size = ptr::read(mem as *const usize);
let layout = Layout::from_size_align_unchecked(size, DEFAULT_ALIGNMENT.into_raw());
alloc::alloc::dealloc(mem, layout);
}
}