Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper types and wasi function signatures #306

Merged
merged 3 commits into from
Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/runtime-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ where
{
const TYPE: Type;
}

unsafe impl WasmExternType for i8 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for u8 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for i16 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for u16 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for i32 {
const TYPE: Type = Type::I32;
}
Expand Down
1 change: 1 addition & 0 deletions lib/wasi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod ptr;
mod state;
mod syscalls;
mod utils;
Expand Down
112 changes: 112 additions & 0 deletions lib/wasi/src/ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use std::{cell::Cell, fmt, marker::PhantomData, mem};
use wasmer_runtime_core::{
memory::Memory,
types::{Type, ValueError, ValueType, WasmExternType},
};

pub struct Array;
pub struct Item;

#[repr(transparent)]
pub struct WasmPtr<T: Copy, Ty = Item> {
offset: u32,
_phantom: PhantomData<(T, Ty)>,
}

impl<T: Copy, Ty> WasmPtr<T, Ty> {
#[inline]
pub fn new(offset: u32) -> Self {
Self {
offset,
_phantom: PhantomData,
}
}

#[inline]
pub fn offset(self) -> u32 {
self.offset
}
}

impl<T: Copy + ValueType> WasmPtr<T, Item> {
#[inline]
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
return None;
}
unsafe {
let cell_ptr = memory
.view::<T>()
.get_unchecked((self.offset() as usize) / mem::size_of::<T>())
as *const _;
Some(&*cell_ptr)
}
}
}

impl<T: Copy + ValueType> WasmPtr<T, Array> {
#[inline]
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
if (self.offset as usize) + (mem::size_of::<T>() * ((index + length) as usize))
>= memory.size().bytes().0
{
return None;
}

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 _;
Some(&*cell_ptrs)
}
}
}

unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
const TYPE: Type = Type::I32;
}

impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {
fn into_le(self, buffer: &mut [u8]) {
buffer[..mem::size_of::<u32>()].copy_from_slice(&self.offset.to_le_bytes());
}
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
if buffer.len() >= mem::size_of::<Self>() {
let mut array = [0u8; mem::size_of::<u32>()];
array.copy_from_slice(&buffer[..mem::size_of::<u32>()]);
Ok(Self {
offset: u32::from_le_bytes(array),
_phantom: PhantomData,
})
} else {
Err(ValueError::BufferTooSmall)
}
}
}

impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
fn clone(&self) -> Self {
Self {
offset: self.offset,
_phantom: PhantomData,
}
}
}

impl<T: Copy, Ty> Copy for WasmPtr<T, Ty> {}

impl<T: Copy, Ty> PartialEq for WasmPtr<T, Ty> {
fn eq(&self, other: &Self) -> bool {
self.offset == other.offset
}
}

impl<T: Copy, Ty> Eq for WasmPtr<T, Ty> {}

impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "WasmPtr({:#x})", self.offset)
}
}
Loading