Merge pull request #2474 from Skgland/fix-looping-memory-allocation
Fix looping memory allocation
This commit is contained in:
@@ -371,7 +371,8 @@ impl<P, T: ArenaAllocated<Payload = P>> AllocateInArena<T> for P {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apparently this overlaps the planket impl above somehow
|
/* this isn't allowed due to https://github.com/rust-lang/rust/issues/20400 I think,
|
||||||
|
though P == ManuallyDrop<P> might also be a problem event though that shouldn't be possible
|
||||||
impl<P, T: ArenaAllocated<Payload = ManuallyDrop<P>>> AllocateInArena<T> for P {
|
impl<P, T: ArenaAllocated<Payload = ManuallyDrop<P>>> AllocateInArena<T> for P {
|
||||||
fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<T> {
|
fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<T> {
|
||||||
T::alloc(arena, ManuallyDrop::new(self))
|
T::alloc(arena, ManuallyDrop::new(self))
|
||||||
|
|||||||
22
src/ffi.rs
22
src/ffi.rs
@@ -21,7 +21,7 @@ and finally we add the pointer the size of what we've written.
|
|||||||
|
|
||||||
use crate::atom_table::Atom;
|
use crate::atom_table::Atom;
|
||||||
|
|
||||||
use std::alloc::{alloc, Layout};
|
use std::alloc::{self, Layout};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -223,7 +223,6 @@ impl ForeignFunctionTable {
|
|||||||
arg: &mut Value,
|
arg: &mut Value,
|
||||||
structs_table: &mut HashMap<String, StructImpl>,
|
structs_table: &mut HashMap<String, StructImpl>,
|
||||||
) -> Result<(Box<dyn Any>, usize, usize), FFIError> {
|
) -> Result<(Box<dyn Any>, usize, usize), FFIError> {
|
||||||
unsafe {
|
|
||||||
match arg {
|
match arg {
|
||||||
Value::Struct(ref name, ref mut struct_args) => {
|
Value::Struct(ref name, ref mut struct_args) => {
|
||||||
if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
|
if let Some(ref mut struct_type) = structs_table.clone().get_mut(name) {
|
||||||
@@ -234,7 +233,12 @@ impl ForeignFunctionTable {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let align = struct_type.ffi_type.alignment as usize;
|
let align = struct_type.ffi_type.alignment as usize;
|
||||||
let size = struct_type.ffi_type.size;
|
let size = struct_type.ffi_type.size;
|
||||||
let ptr = alloc(layout) as *mut c_void;
|
let ptr = unsafe { alloc::alloc(layout) as *mut c_void };
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
panic!("allocation failed")
|
||||||
|
}
|
||||||
|
|
||||||
let mut field_ptr = ptr;
|
let mut field_ptr = ptr;
|
||||||
|
|
||||||
#[allow(clippy::needless_range_loop)]
|
#[allow(clippy::needless_range_loop)]
|
||||||
@@ -259,6 +263,7 @@ impl ForeignFunctionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let field = struct_type.fields[i];
|
let field = struct_type.fields[i];
|
||||||
|
unsafe {
|
||||||
match (*field).type_ as u32 {
|
match (*field).type_ as u32 {
|
||||||
libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
|
libffi::raw::FFI_TYPE_UINT8 => try_write_int!(u8),
|
||||||
libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
|
libffi::raw::FFI_TYPE_SINT8 => try_write_int!(i8),
|
||||||
@@ -294,8 +299,10 @@ impl ForeignFunctionTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::from_raw_with_void_ptr)]
|
#[allow(clippy::from_raw_with_void_ptr)]
|
||||||
Ok((Box::from_raw(ptr), size, align))
|
Ok((unsafe { Box::from_raw(ptr) }, size, align))
|
||||||
} else {
|
} else {
|
||||||
Err(FFIError::InvalidStructName)
|
Err(FFIError::InvalidStructName)
|
||||||
}
|
}
|
||||||
@@ -303,7 +310,6 @@ impl ForeignFunctionTable {
|
|||||||
_ => Err(FFIError::ValueCast),
|
_ => Err(FFIError::ValueCast),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn exec(&mut self, name: &str, mut args: Vec<Value>) -> Result<Value, FFIError> {
|
pub fn exec(&mut self, name: &str, mut args: Vec<Value>) -> Result<Value, FFIError> {
|
||||||
let function_impl = self.table.get_mut(name).ok_or(FFIError::FunctionNotFound)?;
|
let function_impl = self.table.get_mut(name).ok_or(FFIError::FunctionNotFound)?;
|
||||||
@@ -377,7 +383,11 @@ impl ForeignFunctionTable {
|
|||||||
struct_type.ffi_type.alignment.into(),
|
struct_type.ffi_type.alignment.into(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.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(
|
libffi::raw::ffi_call(
|
||||||
&mut function_impl.cif,
|
&mut function_impl.cif,
|
||||||
|
|||||||
@@ -174,7 +174,9 @@ impl Stack {
|
|||||||
let ptr = self.buf.alloc(frame_size);
|
let ptr = self.buf.alloc(frame_size);
|
||||||
|
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
self.buf.grow();
|
if !self.buf.grow() {
|
||||||
|
panic!("growing the stack failed")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,22 +41,35 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
|||||||
|
|
||||||
unsafe fn init_at_size(&mut self, cap: usize) {
|
unsafe fn init_at_size(&mut self, cap: usize) {
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(cap, T::align());
|
let layout = alloc::Layout::from_size_align_unchecked(cap, T::align());
|
||||||
|
let new_base = alloc::alloc(layout).cast_const();
|
||||||
self.base = alloc::alloc(layout) as *const _;
|
if new_base.is_null() {
|
||||||
|
panic!(
|
||||||
|
"failed to allocate in init_at_size for {}",
|
||||||
|
std::any::type_name::<Self>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.base = new_base;
|
||||||
self.top = self.base.add(cap);
|
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() {
|
if self.base.is_null() {
|
||||||
self.init_at_size(T::init_size());
|
self.init_at_size(T::init_size());
|
||||||
|
true
|
||||||
} else {
|
} else {
|
||||||
let size = self.size();
|
let size = self.size();
|
||||||
let layout = alloc::Layout::from_size_align_unchecked(size, T::align());
|
let layout = alloc::Layout::from_size_align_unchecked(size, T::align());
|
||||||
|
|
||||||
self.base = alloc::realloc(self.base as *mut _, layout, size * 2) as *const _;
|
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.top = (self.base as usize + size * 2) as *const _;
|
||||||
*self.ptr.get_mut() = (self.base as usize + size) as *mut _;
|
*self.ptr.get_mut() = (self.base as usize + size) as *mut _;
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user