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

Feature/wasi cross platform skeleton #307

Merged
merged 13 commits into from
Apr 1, 2019
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion lib/wasi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ authors = ["The Wasmer Engineering Team <[email protected]>"]
edition = "2018"

[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
libc = "0.2.50"
rand = "0.6.5"
71 changes: 64 additions & 7 deletions lib/wasi/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
#![allow(unused)]

mod types;
pub mod types;
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod unix;
#[cfg(any(target_os = "windows"))]
pub mod windows;

use self::types::*;
use crate::{
ptr::{Array, WasmPtr},
state::WasiState,
};
use rand::{thread_rng, Rng};
use wasmer_runtime_core::{memory::Memory, vm::Ctx};

#[cfg(any(target_os = "linux", target_os = "macos"))]
pub use unix::*;

#[cfg(any(target_os = "windows"))]
pub use windows::*;

#[allow(clippy::mut_from_ref)]
fn get_wasi_state(ctx: &Ctx) -> &mut WasiState {
unsafe { &mut *(ctx.data as *mut WasiState) }
Expand Down Expand Up @@ -99,15 +109,28 @@ pub fn clock_res_get(
clock_id: __wasi_clockid_t,
resolution: WasmPtr<__wasi_timestamp_t>,
) -> __wasi_errno_t {
unimplemented!()
let memory = ctx.memory(0);

if let Some(out_addr) = resolution.deref(memory) {
platform_clock_res_get(clock_id, out_addr)
} else {
__WASI_EFAULT
}
}

pub fn clock_time_get(
ctx: &mut Ctx,
clock_id: __wasi_clockid_t,
precision: __wasi_timestamp_t,
time: WasmPtr<__wasi_timestamp_t>,
) -> __wasi_errno_t {
unimplemented!()
let memory = ctx.memory(0);

if let Some(out_addr) = time.deref(memory) {
platform_clock_time_get(clock_id, precision, out_addr)
} else {
__WASI_EFAULT
}
}

/// ### `environ_get()`
Expand Down Expand Up @@ -225,6 +248,7 @@ pub fn fd_filestat_set_times(
) -> __wasi_errno_t {
unimplemented!()
}

pub fn fd_pread(
ctx: &mut Ctx,
fd: __wasi_fd_t,
Expand All @@ -233,8 +257,17 @@ pub fn fd_pread(
offset: __wasi_filesize_t,
nread: WasmPtr<u32>,
) -> __wasi_errno_t {
unimplemented!()
let memory = ctx.memory(0);

if let ((Some(iov_cells), Some(nread_cell))) =
(iovs.deref(memory, 0, iovs_len), nread.deref(memory))
{
platform_fd_pread(fd, iov_cells, iovs_len, offset, nread_cell)
} else {
__WASI_EFAULT
}
}

pub fn fd_prestat_get(
ctx: &mut Ctx,
fd: __wasi_fd_t,
Expand Down Expand Up @@ -429,12 +462,36 @@ pub fn proc_exit(ctx: &mut Ctx, rval: __wasi_exitcode_t) {
pub fn proc_raise(ctx: &mut Ctx, sig: __wasi_signal_t) -> __wasi_errno_t {
unimplemented!()
}

/// ### `random_get()`
/// Fill buffer with high-quality random data. This function may be slow and block
/// Inputs:
/// - `void *buf`
/// A pointer to a buffer where the random bytes will be written
/// - `size_t buf_len`
/// The number of bytes that will be written
pub fn random_get(ctx: &mut Ctx, buf: WasmPtr<u8, Array>, buf_len: u32) -> __wasi_errno_t {
unimplemented!()
let mut rng = thread_rng();
let memory = ctx.memory(0);

if let Some(buf) = buf.deref(memory, 0, buf_len) {
for i in 0..(buf_len as usize) {
let random_byte = rng.gen::<u8>();
buf[i].set(random_byte);
}
} else {
return __WASI_EFAULT;
}

__WASI_ESUCCESS
}

/// ### `sched_yield()`
/// Yields execution of the thread
pub fn sched_yield(ctx: &mut Ctx) -> __wasi_errno_t {
unimplemented!()
__WASI_ESUCCESS
}

pub fn sock_recv(
ctx: &mut Ctx,
sock: __wasi_fd_t,
Expand Down
20 changes: 20 additions & 0 deletions lib/wasi/src/syscalls/types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(non_camel_case_types)]

use crate::ptr::{Array, WasmPtr};
use std::mem;
use wasmer_runtime_core::types::{ValueError, ValueType};

pub type __wasi_advice_t = u8;
Expand Down Expand Up @@ -212,6 +213,25 @@ pub struct __wasi_iovec_t {
pub buf_len: u32,
}

impl ValueType for __wasi_iovec_t {
fn into_le(self, buffer: &mut [u8]) {
self.buf
.into_le(&mut buffer[..mem::size_of::<WasmPtr<u8, Array>>()]);
self.buf_len
.into_le(&mut buffer[mem::size_of::<WasmPtr<u8, Array>>()..]);
}

fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
if buffer.len() >= mem::size_of::<__wasi_iovec_t>() {
let buf = ValueType::from_le(&buffer[..mem::size_of::<WasmPtr<u8, Array>>()])?;
let buf_len = ValueType::from_le(&buffer[mem::size_of::<WasmPtr<u8, Array>>()..])?;
Ok(Self { buf, buf_len })
} else {
Err(ValueError::BufferTooSmall)
}
}
}

pub type __wasi_linkcount_t = u32;

pub type __wasi_lookupflags_t = u32;
Expand Down
36 changes: 36 additions & 0 deletions lib/wasi/src/syscalls/unix/linux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::syscalls::types::*;
use std::cell::Cell;
use std::mem;

use libc::preadv;

pub fn platform_fd_pread(
fd: __wasi_fd_t,
iovs: &[Cell<__wasi_iovec_t>],
iovs_len: u32,
offset: __wasi_filesize_t,
nread: &Cell<u32>,
) -> __wasi_errno_t {
let (result, iovec) = unsafe {
let mut iovec = vec![mem::uninitialized(); iovs_len as usize];
(
preadv(
fd as i32,
iovec.as_mut_ptr(),
iovs_len as i32,
offset as i64,
),
iovec,
)
};
nread.set(result as u32);
/*for (i, arr_cell) in iovs.iter().enumerate() {
let wasi_iovec = __wasi_iovec_t {
buf: iovec[i] as _,
buf_len: iovec[i].iov_len as u32,
};
arr_cell.set(wasi_iovec);
}*/

__WASI_ESUCCESS
}
12 changes: 12 additions & 0 deletions lib/wasi/src/syscalls/unix/macos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::syscalls::types::*;
use std::cell::Cell;

pub fn platform_fd_pread(
fd: __wasi_fd_t,
iovs: &[Cell<__wasi_iovec_t>],
iovs_len: u32,
offset: __wasi_filesize_t,
nread: &Cell<u32>,
) -> __wasi_errno_t {
unimplemented!()
}
71 changes: 71 additions & 0 deletions lib/wasi/src/syscalls/unix/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#[cfg(target_os = "linux")]
pub mod linux;

#[cfg(target_os = "macos")]
pub mod macos;

#[cfg(target_os = "linux")]
pub use linux::*;

#[cfg(target_os = "macos")]
pub use macos::*;

use crate::syscalls::types::*;
use libc::{
clock_getres, clock_gettime, timespec, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID,
CLOCK_REALTIME, CLOCK_THREAD_CPUTIME_ID,
};
use std::cell::Cell;
use std::mem;

pub fn platform_clock_res_get(
clock_id: __wasi_clockid_t,
resolution: &Cell<__wasi_timestamp_t>,
) -> __wasi_errno_t {
let unix_clock_id = match clock_id {
__WASI_CLOCK_MONOTONIC => CLOCK_MONOTONIC,
__WASI_CLOCK_PROCESS_CPUTIME_ID => CLOCK_PROCESS_CPUTIME_ID,
__WASI_CLOCK_REALTIME => CLOCK_REALTIME,
__WASI_CLOCK_THREAD_CPUTIME_ID => CLOCK_THREAD_CPUTIME_ID,
_ => return __WASI_EINVAL,
};

let (output, timespec_out) = unsafe {
let mut timespec_out: timespec = mem::uninitialized();
(clock_getres(unix_clock_id, &mut timespec_out), timespec_out)
};

resolution.set(timespec_out.tv_nsec as __wasi_timestamp_t);

// TODO: map output of clock_getres to __wasi_errno_t
__WASI_ESUCCESS
}

pub fn platform_clock_time_get(
clock_id: __wasi_clockid_t,
precision: __wasi_timestamp_t,
time: &Cell<__wasi_timestamp_t>,
) -> __wasi_errno_t {
let unix_clock_id = match clock_id {
__WASI_CLOCK_MONOTONIC => CLOCK_MONOTONIC,
__WASI_CLOCK_PROCESS_CPUTIME_ID => CLOCK_PROCESS_CPUTIME_ID,
__WASI_CLOCK_REALTIME => CLOCK_REALTIME,
__WASI_CLOCK_THREAD_CPUTIME_ID => CLOCK_THREAD_CPUTIME_ID,
_ => return __WASI_EINVAL,
};

let (output, timespec_out) = unsafe {
let mut timespec_out: timespec = mem::uninitialized();
(
clock_gettime(unix_clock_id, &mut timespec_out),
timespec_out,
)
};

// TODO: adjust output by precision...

time.set(timespec_out.tv_nsec as __wasi_timestamp_t);

// TODO: map output of clock_gettime to __wasi_errno_t
__WASI_ESUCCESS
}
27 changes: 27 additions & 0 deletions lib/wasi/src/syscalls/windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::syscalls::types::*;
use std::cell::Cell;

pub fn platform_clock_res_get(
clock_id: __wasi_clockid_t,
resolution: &Cell<__wasi_timestamp_t>,
) -> __wasi_errno_t {
__WASI_EINVAL
}

pub fn platform_clock_time_get(
clock_id: __wasi_clockid_t,
precision: __wasi_timestamp_t,
time: &Cell<__wasi_timestamp_t>,
) -> __wasi_errno_t {
unimplemented!()
}

pub fn platform_fd_pread(
fd: __wasi_fd_t,
iovs: &[Cell<__wasi_iovec_t>],
iovs_len: u32,
offset: __wasi_filesize_t,
nread: &Cell<u32>,
) -> __wasi_errno_t {
unimplemented!()
}