From 9c7619c80e433e8ff18982bc28f5dc6b0e8f8cb2 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 5 Dec 2023 17:42:20 -0500 Subject: [PATCH] Add functions to allocate large statically sized arrays on the heap. --- src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index da6cb26..dff4a75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,42 @@ pub fn is_default(v: &V) -> bool { V::default().eq(v) } +/// Allocate and initialize a large array with a simple type. +/// This is a workaround for the fact that Box::new([ARRAY]) will overflow the stack if the +/// array is too large, a known issue with current Rust. It can go away when this is fixed. +/// None is returned if a memory allocation error occurs. +#[inline] +pub fn alloc_array(initial_value: T) -> Option> { + unsafe { + let mem: *mut T = std::alloc::alloc(std::alloc::Layout::new::<[T; N]>()).cast(); + if mem.is_null() { + return None; + } + for i in 0..N { + mem.add(i).write(initial_value); + } + return Some(Box::from_raw(mem.cast())); + } +} + +/// Allocate and initialize a large array using a generator. +/// This is a workaround for the fact that Box::new([ARRAY]) will overflow the stack if the +/// array is too large, a known issue with current Rust. It can go away when this is fixed. +/// None is returned if a memory allocation error occurs. +#[inline] +pub fn alloc_array_with T, const N: usize>(mut f: F) -> Option> { + unsafe { + let mem: *mut T = std::alloc::alloc(std::alloc::Layout::new::<[T; N]>()).cast(); + if mem.is_null() { + return None; + } + for i in 0..N { + mem.add(i).write(f(i)); + } + return Some(Box::from_raw(mem.cast())); + } +} + #[cold] #[inline(never)] pub extern "C" fn unlikely_branch() {}