use crate::atom_table::Atom;
-use std::alloc::{alloc, Layout};
+use std::alloc::{self, Layout};
use std::any::Any;
use std::collections::HashMap;
use std::convert::TryFrom;
arg: &mut Value,
structs_table: &mut HashMap<String, StructImpl>,
) -> Result<(Box<dyn Any>, usize, usize), FFIError> {
- unsafe {
- match arg {
- Value::Struct(ref name, ref mut struct_args) => {
- if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
- let layout = Layout::from_size_align(
- struct_type.ffi_type.size,
- struct_type.ffi_type.alignment.into(),
- )
- .unwrap();
- let align = struct_type.ffi_type.alignment as usize;
- let size = struct_type.ffi_type.size;
- let ptr = alloc(layout) as *mut c_void;
- let mut field_ptr = ptr;
-
- #[allow(clippy::needless_range_loop)]
- for i in 0..(struct_type.fields.len() - 1) {
- macro_rules! try_write_int {
- ($type:ty) => {{
- field_ptr = field_ptr
- .add(field_ptr.align_offset(std::mem::align_of::<$type>()));
- let n: $type = <$type>::try_from(struct_args[i].as_int()?)
- .map_err(|_| FFIError::ValueDontFit)?;
- std::ptr::write(field_ptr as *mut $type, n);
- field_ptr = field_ptr.add(std::mem::size_of::<$type>());
- }};
- }
+ match arg {
+ Value::Struct(ref name, ref mut struct_args) => {
+ if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
+ let layout = Layout::from_size_align(
+ struct_type.ffi_type.size,
+ struct_type.ffi_type.alignment.into(),
+ )
+ .unwrap();
+ let align = struct_type.ffi_type.alignment as usize;
+ let size = struct_type.ffi_type.size;
+ let ptr = unsafe { alloc::alloc(layout) as *mut c_void };
- macro_rules! write {
- ($type:ty, $value:expr) => {{
- let data: $type = $value;
- std::ptr::write(field_ptr as *mut $type, data);
- field_ptr = field_ptr.add(align);
- }};
- }
+ if ptr.is_null() {
+ panic!("allocation failed")
+ }
- let field = struct_type.fields[i];
+ let mut field_ptr = ptr;
+
+ #[allow(clippy::needless_range_loop)]
+ for i in 0..(struct_type.fields.len() - 1) {
+ macro_rules! try_write_int {
+ ($type:ty) => {{
+ field_ptr = field_ptr
+ .add(field_ptr.align_offset(std::mem::align_of::<$type>()));
+ let n: $type = <$type>::try_from(struct_args[i].as_int()?)
+ .map_err(|_| FFIError::ValueDontFit)?;
+ std::ptr::write(field_ptr as *mut $type, n);
+ field_ptr = field_ptr.add(std::mem::size_of::<$type>());
+ }};
+ }
+
+ macro_rules! write {
+ ($type:ty, $value:expr) => {{
+ let data: $type = $value;
+ std::ptr::write(field_ptr as *mut $type, data);
+ field_ptr = field_ptr.add(align);
+ }};
+ }
+
+ let field = struct_type.fields[i];
+ unsafe {
match (*field).type_ as u32 {
libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
}
}
}
- #[allow(clippy::from_raw_with_void_ptr)]
- Ok((Box::from_raw(ptr), size, align))
- } else {
- Err(FFIError::InvalidStructName)
}
+
+ #[allow(clippy::from_raw_with_void_ptr)]
+ Ok((unsafe { Box::from_raw(ptr) }, size, align))
+ } else {
+ Err(FFIError::InvalidStructName)
}
- _ => Err(FFIError::ValueCast),
}
+ _ => Err(FFIError::ValueCast),
}
}
struct_type.ffi_type.alignment.into(),
)
.unwrap();
- let ptr = alloc(layout) as *mut c_void;
+ let ptr = alloc::alloc(layout) as *mut c_void;
+
+ if ptr.is_null() {
+ panic!("allocation failed")
+ }
libffi::raw::ffi_call(
&mut function_impl.cif,
unsafe fn init_at_size(&mut self, cap: usize) {
let layout = alloc::Layout::from_size_align_unchecked(cap, T::align());
-
- self.base = alloc::alloc(layout) as *const _;
+ let new_base = alloc::alloc(layout).cast_const();
+ if new_base.is_null() {
+ panic!("failed to allocate for init_at_size");
+ }
+ self.base = new_base;
self.top = self.base.add(cap);
- *self.ptr.get_mut() = self.base as *mut _;
+ *self.ptr.get_mut() = self.base.cast_mut();
}
- pub unsafe fn grow(&mut self) {
+ pub unsafe fn grow(&mut self) -> bool {
if self.base.is_null() {
self.init_at_size(T::init_size());
+ true
} else {
let size = self.size();
let layout = alloc::Layout::from_size_align_unchecked(size, T::align());
- self.base = alloc::realloc(self.base as *mut _, layout, size * 2) as *const _;
- self.top = (self.base as usize + size * 2) as *const _;
- *self.ptr.get_mut() = (self.base as usize + size) as *mut _;
+ let new_base = alloc::realloc(self.base.cast_mut(), layout, size * 2).cast_const();
+ if new_base.is_null() {
+ false
+ } else {
+ self.base = new_base;
+ self.top = (self.base as usize + size * 2) as *const _;
+ *self.ptr.get_mut() = (self.base as usize + size) as *mut _;
+ true
+ }
}
}