#![allow(
clippy::undocumented_unsafe_blocks,
reason = "this module is the raw allocator; each function documents its \
own contract under `# Safety`"
)]
#[cfg(target_os = "windows")]
mod imp {
use core::ffi::c_void;
const GPTR: u32 = 0x0040;
#[link(name = "kernel32")]
unsafe extern "system" {
fn GlobalAlloc(uflags: u32, dwbytes: usize) -> *mut c_void;
fn GlobalFree(hmem: *mut c_void) -> *mut c_void;
}
pub unsafe fn alloc_zeroed(size: usize) -> *mut u8 {
unsafe { GlobalAlloc(GPTR, size) }.cast()
}
pub unsafe fn free(ptr: *mut u8) {
if !ptr.is_null() {
unsafe { GlobalFree(ptr.cast()) };
}
}
}
#[cfg(not(target_os = "windows"))]
mod imp {
use alloc::alloc::{Layout, alloc_zeroed as rust_alloc_zeroed, dealloc};
const HEADER: usize = core::mem::size_of::<usize>();
const ALIGN: usize = core::mem::align_of::<usize>();
pub unsafe fn alloc_zeroed(size: usize) -> *mut u8 {
let total = HEADER + size;
let Ok(layout) = Layout::from_size_align(total, ALIGN) else {
return core::ptr::null_mut();
};
let base = unsafe { rust_alloc_zeroed(layout) };
if base.is_null() {
return base;
}
unsafe { base.cast::<usize>().write(total) };
unsafe { base.add(HEADER) }
}
pub unsafe fn free(ptr: *mut u8) {
if ptr.is_null() {
return;
}
let base = unsafe { ptr.sub(HEADER) };
let total = unsafe { base.cast::<usize>().read() };
let layout = Layout::from_size_align(total, ALIGN).expect("valid layout");
unsafe { dealloc(base, layout) };
}
}
pub use imp::{alloc_zeroed, free};