#[doc(hidden)] #[macro_export] macro_rules! wasm_declare_vec_inner { ($name:ident) => { paste::item! { #[no_mangle] pub unsafe extern "C" fn [](out: *mut []) { // TODO: actually implement this [](out, 0); } } } } #[doc(hidden)] #[macro_export] macro_rules! wasm_declare_vec { ($name:ident) => { paste::item! { #[derive(Debug)] #[repr(C)] pub struct [] { pub size: usize, pub data: *mut [], } impl<'a> From]>> for [] { fn from(other: Vec<[]>) -> Self { let mut boxed_slice = other.into_boxed_slice(); let size = boxed_slice.len(); let data = boxed_slice.as_mut_ptr(); ::std::mem::forget(boxed_slice); Self { size, data, } } } impl<'a, T: Into<[]> + Clone> From<&'a [T]> for [] { fn from(other: &'a [T]) -> Self { let size = other.len(); let mut copied_data = other .iter() .cloned() .map(Into::into) .collect::]>>() .into_boxed_slice(); let data = copied_data.as_mut_ptr(); ::std::mem::forget(copied_data); Self { size, data, } } } impl [] { pub unsafe fn into_slice(&self) -> Option<&[[]]>{ if self.is_uninitialized() { return None; } Some(::std::slice::from_raw_parts(self.data, self.size)) } pub unsafe fn into_slice_mut(&mut self) -> Option<&mut [[]]>{ if self.is_uninitialized() { return None; } Some(::std::slice::from_raw_parts_mut(self.data, self.size)) } pub fn is_uninitialized(&self) -> bool { self.data.is_null() } } // TODO: investigate possible memory leak on `init` (owned pointer) #[no_mangle] pub unsafe extern "C" fn [](out: *mut [], length: usize, init: *mut []) { let mut bytes: Vec<[]> = Vec::with_capacity(length); for i in 0..length { bytes.push(::std::ptr::read(init.add(i))); } let pointer = bytes.as_mut_ptr(); debug_assert!(bytes.len() == bytes.capacity()); (*out).data = pointer; (*out).size = length; ::std::mem::forget(bytes); } #[no_mangle] pub unsafe extern "C" fn [](out: *mut [], length: usize) { let mut bytes: Vec<[]> = Vec::with_capacity(length); let pointer = bytes.as_mut_ptr(); (*out).data = pointer; (*out).size = length; ::std::mem::forget(bytes); } #[no_mangle] pub unsafe extern "C" fn [](ptr: *mut []) { let vec = &mut *ptr; if !vec.data.is_null() { Vec::from_raw_parts(vec.data, vec.size, vec.size); vec.data = ::std::ptr::null_mut(); vec.size = 0; } } } wasm_declare_vec_inner!($name); }; } #[doc(hidden)] #[macro_export] macro_rules! wasm_declare_boxed_vec { ($name:ident) => { paste::item! { #[derive(Debug)] #[repr(C)] pub struct [] { pub size: usize, pub data: *mut *mut [], } impl<'a> From]>>> for [] { fn from(other: Vec]>>) -> Self { let boxed_slice: Box<[Box<[]>]> = other.into_boxed_slice(); let mut boxed_slice: Box<[*mut []]> = unsafe { ::std::mem::transmute(boxed_slice) }; let size = boxed_slice.len(); let data = boxed_slice.as_mut_ptr(); ::std::mem::forget(boxed_slice); Self { size, data, } } } // TODO: do this properly impl [] { pub unsafe fn into_slice(&self) -> Option<&[Box<[]>]>{ if self.data.is_null() { return None; } let slice: &[*mut []] = ::std::slice::from_raw_parts(self.data, self.size); let slice: &[Box<[]>] = ::std::mem::transmute(slice); Some(slice) } } // TODO: investigate possible memory leak on `init` (owned pointer) #[no_mangle] pub unsafe extern "C" fn [](out: *mut [], length: usize, init: *const *mut []) { let mut bytes: Vec<*mut []> = Vec::with_capacity(length); for i in 0..length { bytes.push(*init.add(i)); } let pointer = bytes.as_mut_ptr(); debug_assert!(bytes.len() == bytes.capacity()); (*out).data = pointer; (*out).size = length; ::std::mem::forget(bytes); } #[no_mangle] pub unsafe extern "C" fn [](out: *mut [], length: usize) { let mut bytes: Vec<*mut []> = Vec::with_capacity(length); let pointer = bytes.as_mut_ptr(); (*out).data = pointer; (*out).size = length; ::std::mem::forget(bytes); } #[no_mangle] pub unsafe extern "C" fn [](ptr: *mut []) { let vec = &mut *ptr; if !vec.data.is_null() { let data: Vec<*mut []> = Vec::from_raw_parts(vec.data, vec.size, vec.size); let _data: Vec]>> = ::std::mem::transmute(data); vec.data = ::std::ptr::null_mut(); vec.size = 0; } } } wasm_declare_vec_inner!($name); }; } #[doc(hidden)] #[macro_export] macro_rules! wasm_declare_ref_base { ($name:ident) => { wasm_declare_own!($name); paste::item! { #[no_mangle] pub extern "C" fn [](_arg: *const []) -> *mut [] { todo!("in generated declare ref base"); //ptr::null_mut() } // TODO: finish this... } }; } #[doc(hidden)] #[macro_export] macro_rules! wasm_declare_own { ($name:ident) => { paste::item! { #[repr(C)] pub struct [] {} #[no_mangle] pub extern "C" fn [](_arg: *mut []) { todo!("in generated delete") } } }; } #[macro_export] macro_rules! c_try { ($expr:expr) => {{ let res: Result<_, _> = $expr; match res { Ok(val) => val, Err(err) => { crate::error::update_last_error(err); return None; } } }}; ($expr:expr, $e:expr) => {{ let opt: Option<_> = $expr; c_try!(opt.ok_or_else(|| $e)) }}; }