Issue 3223: more unsafe scope refinements
This commit is contained in:
25
src/ffi.rs
25
src/ffi.rs
@@ -65,21 +65,17 @@ impl FunctionImpl {
|
|||||||
Integer: From<T>,
|
Integer: From<T>,
|
||||||
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
||||||
{
|
{
|
||||||
unsafe {
|
let n = unsafe { self.cif.call::<T>(self.code_ptr, args) };
|
||||||
let n = self.cif.call::<T>(self.code_ptr, args);
|
|
||||||
Ok(Value::Number(fixnum!(Number, n, arena)))
|
Ok(Value::Number(fixnum!(Number, n, arena)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn call_float<T>(&self, args: &[Arg], _: &mut Arena) -> Result<Value, FfiError>
|
unsafe fn call_float<T>(&self, args: &[Arg], _: &mut Arena) -> Result<Value, FfiError>
|
||||||
where
|
where
|
||||||
T: Into<f64>,
|
T: Into<f64>,
|
||||||
{
|
{
|
||||||
unsafe {
|
let n = unsafe { self.cif.call::<T>(self.code_ptr, args) };
|
||||||
let n = self.cif.call::<T>(self.code_ptr, args);
|
|
||||||
Ok(Value::Number(Number::Float(OrderedFloat(n.into()))))
|
Ok(Value::Number(Number::Float(OrderedFloat(n.into()))))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn call_ptr(&self, args: &[Arg], arena: &mut Arena) -> Result<Value, FfiError> {
|
unsafe fn call_ptr(&self, args: &[Arg], arena: &mut Arena) -> Result<Value, FfiError> {
|
||||||
let ptr = unsafe { self.cif.call::<*mut c_void>(self.code_ptr, args) };
|
let ptr = unsafe { self.cif.call::<*mut c_void>(self.code_ptr, args) };
|
||||||
@@ -271,11 +267,9 @@ impl StructImpl {
|
|||||||
.extend(Layout::new::<T>())
|
.extend(Layout::new::<T>())
|
||||||
.map_err(|_| FfiError::LayoutError)?;
|
.map_err(|_| FfiError::LayoutError)?;
|
||||||
*layout = new_layout;
|
*layout = new_layout;
|
||||||
unsafe {
|
let n = unsafe { std::ptr::read::<T>(ptr.byte_offset(offset as isize).cast()) };
|
||||||
let n = std::ptr::read::<T>(ptr.byte_offset(offset as isize).cast());
|
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn read_int<T>(
|
unsafe fn read_int<T>(
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
@@ -286,11 +280,10 @@ impl StructImpl {
|
|||||||
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
||||||
Integer: From<T>,
|
Integer: From<T>,
|
||||||
{
|
{
|
||||||
unsafe {
|
|
||||||
let n = read_primitive::<T>(ptr, layout)?;
|
let n = unsafe { read_primitive::<T>(ptr, layout)? };
|
||||||
Ok(Value::Number(fixnum!(Number, n, arena)))
|
Ok(Value::Number(fixnum!(Number, n, arena)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn read_float<T>(
|
unsafe fn read_float<T>(
|
||||||
ptr: *mut c_void,
|
ptr: *mut c_void,
|
||||||
@@ -299,11 +292,9 @@ impl StructImpl {
|
|||||||
where
|
where
|
||||||
T: Into<f64>,
|
T: Into<f64>,
|
||||||
{
|
{
|
||||||
unsafe {
|
let n = unsafe { read_primitive::<T>(ptr, layout)? };
|
||||||
let n = read_primitive::<T>(ptr, layout)?;
|
|
||||||
Ok(Value::Number(Number::Float(OrderedFloat(n.into()))))
|
Ok(Value::Number(Number::Float(OrderedFloat(n.into()))))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut layout = Layout::from_size_align(0, 1).map_err(|_| FfiError::LayoutError)?;
|
let mut layout = Layout::from_size_align(0, 1).map_err(|_| FfiError::LayoutError)?;
|
||||||
|
|
||||||
@@ -803,11 +794,9 @@ impl ForeignFunctionTable {
|
|||||||
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
T: Copy + TryInto<i64> + MightNotFitInFixnum,
|
||||||
Integer: From<T>,
|
Integer: From<T>,
|
||||||
{
|
{
|
||||||
unsafe {
|
let n = unsafe { ptr.cast::<T>().read() };
|
||||||
let n = ptr.cast::<T>().read();
|
|
||||||
Value::Number(fixnum!(Number, n, arena))
|
Value::Number(fixnum!(Number, n, arena))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let ptr = ptr.as_ptr()?;
|
let ptr = ptr.as_ptr()?;
|
||||||
|
|
||||||
|
|||||||
@@ -71,14 +71,16 @@ impl InnerHeap {
|
|||||||
new_layout.size() <= isize::MAX as usize,
|
new_layout.size() <= isize::MAX as usize,
|
||||||
"Allocation too large. We should probably GC (TODO)"
|
"Allocation too large. We should probably GC (TODO)"
|
||||||
);
|
);
|
||||||
unsafe {
|
|
||||||
let new_ptr = if self.byte_cap == 0 {
|
let new_ptr = unsafe {
|
||||||
|
if self.byte_cap == 0 {
|
||||||
alloc::alloc(new_layout)
|
alloc::alloc(new_layout)
|
||||||
} else {
|
} else {
|
||||||
let old_layout =
|
let old_layout =
|
||||||
alloc::Layout::from_size_align(self.byte_cap, size_of::<HeapCellValue>())
|
alloc::Layout::from_size_align(self.byte_cap, size_of::<HeapCellValue>())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
alloc::realloc(self.ptr, old_layout, new_layout.size())
|
alloc::realloc(self.ptr, old_layout, new_layout.size())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !new_ptr.is_null() {
|
if !new_ptr.is_null() {
|
||||||
@@ -91,7 +93,6 @@ impl InnerHeap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for Heap {}
|
unsafe impl Send for Heap {}
|
||||||
unsafe impl Sync for Heap {}
|
unsafe impl Sync for Heap {}
|
||||||
@@ -109,8 +110,7 @@ unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan<'_> {
|
|||||||
.position(|b| *b == 0u8)
|
.position(|b| *b == 0u8)
|
||||||
.unwrap_or(heap_slice.len());
|
.unwrap_or(heap_slice.len());
|
||||||
|
|
||||||
unsafe {
|
let zero_byte_addr = unsafe { heap_slice.as_ptr().add(string_len) };
|
||||||
let zero_byte_addr = heap_slice.as_ptr().add(string_len);
|
|
||||||
|
|
||||||
let sentinel_len = pstr_sentinel_length(zero_byte_addr.addr());
|
let sentinel_len = pstr_sentinel_length(zero_byte_addr.addr());
|
||||||
let tail_idx = cell_index!(
|
let tail_idx = cell_index!(
|
||||||
@@ -121,11 +121,10 @@ unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan<'_> {
|
|||||||
let str_slice = &heap_slice[..string_len];
|
let str_slice = &heap_slice[..string_len];
|
||||||
|
|
||||||
HeapStringScan {
|
HeapStringScan {
|
||||||
string: std::str::from_utf8_unchecked(str_slice),
|
string: unsafe { std::str::from_utf8_unchecked(str_slice) },
|
||||||
tail_idx,
|
tail_idx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Same as scan_slice_to_str but assumes that the slice is from the start of a string.
|
// Same as scan_slice_to_str but assumes that the slice is from the start of a string.
|
||||||
// Can be used on strings out of the heap.
|
// Can be used on strings out of the heap.
|
||||||
@@ -143,13 +142,11 @@ unsafe fn scan_slice_to_str_from_start(heap_slice: &[u8]) -> HeapStringScan<'_>
|
|||||||
|
|
||||||
let str_slice = &heap_slice[..string_len];
|
let str_slice = &heap_slice[..string_len];
|
||||||
|
|
||||||
unsafe {
|
|
||||||
HeapStringScan {
|
HeapStringScan {
|
||||||
string: std::str::from_utf8_unchecked(str_slice),
|
string: unsafe { std::str::from_utf8_unchecked(str_slice) },
|
||||||
tail_idx,
|
tail_idx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum PStrContinuable {
|
pub(crate) enum PStrContinuable {
|
||||||
@@ -282,19 +279,21 @@ impl ReservedHeapSection {
|
|||||||
src.as_ptr(),
|
src.as_ptr(),
|
||||||
self.heap_ptr.add(heap_index!(self.heap_cell_len)),
|
self.heap_ptr.add(heap_index!(self.heap_cell_len)),
|
||||||
str_byte_len,
|
str_byte_len,
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let zero_region_idx = heap_index!(self.heap_cell_len) + str_byte_len;
|
let zero_region_idx = heap_index!(self.heap_cell_len) + str_byte_len;
|
||||||
let align_offset = pstr_sentinel_length(zero_region_idx);
|
let align_offset = pstr_sentinel_length(zero_region_idx);
|
||||||
|
|
||||||
ptr::write_bytes(self.heap_ptr.add(zero_region_idx), 0u8, align_offset);
|
unsafe { ptr::write_bytes(self.heap_ptr.add(zero_region_idx), 0u8, align_offset) };
|
||||||
|
|
||||||
cells_written = if align_offset == 1 {
|
cells_written = if align_offset == 1 {
|
||||||
ptr::write_bytes(
|
unsafe { ptr::write_bytes(
|
||||||
self.heap_ptr.add(zero_region_idx + 1),
|
self.heap_ptr.add(zero_region_idx + 1),
|
||||||
0u8,
|
0u8,
|
||||||
size_of::<HeapCellValue>(),
|
size_of::<HeapCellValue>(),
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// ensure there are at least two bytes in the boundary
|
// ensure there are at least two bytes in the boundary
|
||||||
// buffer separating the string data from the tail
|
// buffer separating the string data from the tail
|
||||||
@@ -305,7 +304,6 @@ impl ReservedHeapSection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.heap_cell_len += cells_written;
|
self.heap_cell_len += cells_written;
|
||||||
}
|
|
||||||
|
|
||||||
cells_written
|
cells_written
|
||||||
}
|
}
|
||||||
@@ -629,18 +627,16 @@ impl Heap {
|
|||||||
let len = heap_index_checked!(num_cells).ok_or(AllocError)?;
|
let len = heap_index_checked!(num_cells).ok_or(AllocError)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
|
||||||
if self.free_space() >= len {
|
if self.free_space() >= len {
|
||||||
section = ReservedHeapSection {
|
section = ReservedHeapSection {
|
||||||
heap_ptr: self.inner.ptr,
|
heap_ptr: self.inner.ptr,
|
||||||
heap_cell_len: self.cell_len(),
|
heap_cell_len: self.cell_len(),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
} else if !self.grow() {
|
} else if unsafe { !self.grow() } {
|
||||||
return Err(AllocError);
|
return Err(AllocError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(HeapWriter {
|
Ok(HeapWriter {
|
||||||
section,
|
section,
|
||||||
@@ -868,8 +864,8 @@ impl Heap {
|
|||||||
let align_offset = pstr_sentinel_length(s_len);
|
let align_offset = pstr_sentinel_length(s_len);
|
||||||
let copy_size = s_len + align_offset;
|
let copy_size = s_len + align_offset;
|
||||||
|
|
||||||
unsafe {
|
|
||||||
loop {
|
loop {
|
||||||
|
unsafe {
|
||||||
if self.free_space() >= copy_size {
|
if self.free_space() >= copy_size {
|
||||||
let slice =
|
let slice =
|
||||||
std::slice::from_raw_parts_mut(self.inner.ptr, self.inner.byte_len + s_len);
|
std::slice::from_raw_parts_mut(self.inner.ptr, self.inner.byte_len + s_len);
|
||||||
|
|||||||
Reference in New Issue
Block a user