add wasmptr memory abstraction to emscripten; update wasi array access

This commit is contained in:
Mark McCaskey
2019-06-06 15:45:19 -07:00
parent 4913cfaff4
commit d7ea46bab7
4 changed files with 145 additions and 19 deletions

View File

@ -29,6 +29,13 @@ impl<T: Copy, Ty> WasmPtr<T, Ty> {
}
}
#[inline(always)]
fn align_pointer(ptr: usize, align: usize) -> usize {
// clears bits below aligment amount (assumes power of 2) to align pointer
debug_assert!(align.count_ones() == 1);
ptr & !(align - 1)
}
impl<T: Copy + ValueType> WasmPtr<T, Item> {
#[inline]
pub fn deref<'a>(self, memory: &'a Memory) -> Result<&'a Cell<T>, __wasi_errno_t> {
@ -36,9 +43,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Item> {
return Err(__WASI_EFAULT);
}
unsafe {
// clears bits below aligment amount (assumes power of 2) to align pointer
let aligner = |ptr: usize, align: usize| ptr & !(align - 1);
let cell_ptr = aligner(
let cell_ptr = align_pointer(
memory.view::<u8>().as_ptr().add(self.offset as usize) as usize,
mem::align_of::<T>(),
) as *const Cell<T>;
@ -61,12 +66,15 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
return Err(__WASI_EFAULT);
}
// gets the size of the item in the array with padding added such that
// for any index, we will always result an aligned memory access
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
let base_idx = (self.offset as usize) / item_size;
unsafe {
let cell_ptrs = memory.view::<T>().get_unchecked(
((self.offset as usize) / mem::size_of::<T>()) + (index as usize)
..((self.offset() as usize) / mem::size_of::<T>())
+ ((index + length) as usize),
) as *const _;
let cell_ptrs = memory
.view::<T>()
.get_unchecked(base_idx + (index as usize)..base_idx + ((index + length) as usize))
as *const _;
Ok(&*cell_ptrs)
}
}