From bd09343fcad694128b559da0ce4c6e383eb29d93 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 28 Mar 2019 17:09:39 -0700 Subject: [PATCH 01/12] add structure for cross-platform wasi syscall implementations --- lib/wasi/src/syscalls/mod.rs | 20 +++++++++++++------- lib/wasi/src/syscalls/unix/linux.rs | 19 +++++++++++++++++++ lib/wasi/src/syscalls/unix/macos.rs | 19 +++++++++++++++++++ lib/wasi/src/syscalls/unix/mod.rs | 11 +++++++++++ lib/wasi/src/syscalls/windows.rs | 19 +++++++++++++++++++ 5 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 lib/wasi/src/syscalls/unix/linux.rs create mode 100644 lib/wasi/src/syscalls/unix/macos.rs create mode 100644 lib/wasi/src/syscalls/unix/mod.rs create mode 100644 lib/wasi/src/syscalls/windows.rs diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 0c5f2f9b018..077a61155f6 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1,6 +1,19 @@ +pub mod types; +#[cfg(any(target_os = "linux", target_os = "macos"))] +pub mod unix; +#[cfg(any(target_os = "windows"))] +pub mod windows; + use crate::state::WasiState; +use types::*; 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) } @@ -59,13 +72,6 @@ pub fn args_sizes_get(ctx: &mut Ctx, argc_out: u32, argv_buf_size_out: u32) { memory.view::()[(argv_buf_size_out / 4) as usize].set(total_arg_size as u32); } -pub fn clock_res_get(ctx: &mut Ctx) { - unimplemented!() -} -pub fn clock_time_get(ctx: &mut Ctx) { - unimplemented!() -} - /// ### `environ_get()` /// Read environment variable data. /// The sizes of the buffers should match that returned by [`environ_sizes_get()`](#environ_sizes_get). diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs new file mode 100644 index 00000000000..c3556faba0b --- /dev/null +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -0,0 +1,19 @@ +use crate::syscalls::types::*; +use wasmer_runtime_core::{memory::Memory, vm::Ctx}; + +pub fn clock_res_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + resolution: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { + __WASI_EINVAL +} + +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!() +} diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs new file mode 100644 index 00000000000..c3556faba0b --- /dev/null +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -0,0 +1,19 @@ +use crate::syscalls::types::*; +use wasmer_runtime_core::{memory::Memory, vm::Ctx}; + +pub fn clock_res_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + resolution: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { + __WASI_EINVAL +} + +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!() +} diff --git a/lib/wasi/src/syscalls/unix/mod.rs b/lib/wasi/src/syscalls/unix/mod.rs new file mode 100644 index 00000000000..8fab04668ff --- /dev/null +++ b/lib/wasi/src/syscalls/unix/mod.rs @@ -0,0 +1,11 @@ +#[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::*; diff --git a/lib/wasi/src/syscalls/windows.rs b/lib/wasi/src/syscalls/windows.rs new file mode 100644 index 00000000000..c3556faba0b --- /dev/null +++ b/lib/wasi/src/syscalls/windows.rs @@ -0,0 +1,19 @@ +use crate::syscalls::types::*; +use wasmer_runtime_core::{memory::Memory, vm::Ctx}; + +pub fn clock_res_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + resolution: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { + __WASI_EINVAL +} + +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!() +} From ea27effdb3d95907c3d8d34e4442b9cdf2ced20c Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 10:20:08 -0700 Subject: [PATCH 02/12] keeep top level wasi calls that call out to platform-specific impls --- lib/wasi/src/syscalls/mod.rs | 17 +++++++++++++++++ lib/wasi/src/syscalls/unix/linux.rs | 4 ++-- lib/wasi/src/syscalls/unix/macos.rs | 4 ++-- lib/wasi/src/syscalls/windows.rs | 4 ++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 077a61155f6..380adc68bdb 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -72,6 +72,23 @@ pub fn args_sizes_get(ctx: &mut Ctx, argc_out: u32, argv_buf_size_out: u32) { memory.view::()[(argv_buf_size_out / 4) as usize].set(total_arg_size as u32); } +pub fn clock_res_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + resolution: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { + platform_clock_res_get(ctx, clock_id, resolution) +} + +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 { + platform_clock_time_get(ctx, clock_id, precision, time) +} + /// ### `environ_get()` /// Read environment variable data. /// The sizes of the buffers should match that returned by [`environ_sizes_get()`](#environ_sizes_get). diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index c3556faba0b..43ca2cb6dab 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1,7 +1,7 @@ use crate::syscalls::types::*; use wasmer_runtime_core::{memory::Memory, vm::Ctx}; -pub fn clock_res_get( +pub fn platform_clock_res_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, resolution: WasmPtr<__wasi_timestamp_t>, @@ -9,7 +9,7 @@ pub fn clock_res_get( __WASI_EINVAL } -pub fn clock_time_get( +pub fn platform_clock_time_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs index c3556faba0b..43ca2cb6dab 100644 --- a/lib/wasi/src/syscalls/unix/macos.rs +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -1,7 +1,7 @@ use crate::syscalls::types::*; use wasmer_runtime_core::{memory::Memory, vm::Ctx}; -pub fn clock_res_get( +pub fn platform_clock_res_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, resolution: WasmPtr<__wasi_timestamp_t>, @@ -9,7 +9,7 @@ pub fn clock_res_get( __WASI_EINVAL } -pub fn clock_time_get( +pub fn platform_clock_time_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, diff --git a/lib/wasi/src/syscalls/windows.rs b/lib/wasi/src/syscalls/windows.rs index c3556faba0b..43ca2cb6dab 100644 --- a/lib/wasi/src/syscalls/windows.rs +++ b/lib/wasi/src/syscalls/windows.rs @@ -1,7 +1,7 @@ use crate::syscalls::types::*; use wasmer_runtime_core::{memory::Memory, vm::Ctx}; -pub fn clock_res_get( +pub fn platform_clock_res_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, resolution: WasmPtr<__wasi_timestamp_t>, @@ -9,7 +9,7 @@ pub fn clock_res_get( __WASI_EINVAL } -pub fn clock_time_get( +pub fn platform_clock_time_get( ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, From 23c09ac0429f78fdf4e82c255b85beda541241ed Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 11:04:38 -0700 Subject: [PATCH 03/12] add imports --- lib/wasi/src/syscalls/unix/linux.rs | 1 + lib/wasi/src/syscalls/unix/macos.rs | 1 + lib/wasi/src/syscalls/windows.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 43ca2cb6dab..78ee51c9a0b 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1,4 +1,5 @@ use crate::syscalls::types::*; +use crate::ptr::{Array, WasmPtr}, use wasmer_runtime_core::{memory::Memory, vm::Ctx}; pub fn platform_clock_res_get( diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs index 43ca2cb6dab..78ee51c9a0b 100644 --- a/lib/wasi/src/syscalls/unix/macos.rs +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -1,4 +1,5 @@ use crate::syscalls::types::*; +use crate::ptr::{Array, WasmPtr}, use wasmer_runtime_core::{memory::Memory, vm::Ctx}; pub fn platform_clock_res_get( diff --git a/lib/wasi/src/syscalls/windows.rs b/lib/wasi/src/syscalls/windows.rs index 43ca2cb6dab..78ee51c9a0b 100644 --- a/lib/wasi/src/syscalls/windows.rs +++ b/lib/wasi/src/syscalls/windows.rs @@ -1,4 +1,5 @@ use crate::syscalls::types::*; +use crate::ptr::{Array, WasmPtr}, use wasmer_runtime_core::{memory::Memory, vm::Ctx}; pub fn platform_clock_res_get( From 48d34d9522e0fbeba3b2001dec649117c00675c6 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 11:38:48 -0700 Subject: [PATCH 04/12] improve calling of platform-specific code and impl linux clock calls --- Cargo.lock | 1 + lib/wasi/Cargo.toml | 3 +- lib/wasi/src/syscalls/mod.rs | 16 +++++++-- lib/wasi/src/syscalls/unix/linux.rs | 50 ++++++++++++++++++++++++----- lib/wasi/src/syscalls/unix/macos.rs | 9 ++---- lib/wasi/src/syscalls/windows.rs | 9 ++---- 6 files changed, 65 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18ac80db931..53f1b1d5f4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1482,6 +1482,7 @@ dependencies = [ name = "wasmer-wasi" version = "0.1.0" dependencies = [ + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.2.1", ] diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 17a2f14f429..3d2151d3e13 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -5,4 +5,5 @@ authors = ["The Wasmer Engineering Team "] edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } \ No newline at end of file +wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } +libc = "0.2.50" \ No newline at end of file diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 0ccc7bd649a..95d5f5240fe 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -108,7 +108,13 @@ pub fn clock_res_get( clock_id: __wasi_clockid_t, resolution: WasmPtr<__wasi_timestamp_t>, ) -> __wasi_errno_t { - platform_clock_res_get(ctx, clock_id, resolution) + 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( @@ -117,7 +123,13 @@ pub fn clock_time_get( precision: __wasi_timestamp_t, time: WasmPtr<__wasi_timestamp_t>, ) -> __wasi_errno_t { - platform_clock_time_get(ctx, clock_id, precision, time) + 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()` diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 78ee51c9a0b..e68d470fad6 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1,20 +1,54 @@ use crate::syscalls::types::*; -use crate::ptr::{Array, WasmPtr}, -use wasmer_runtime_core::{memory::Memory, vm::Ctx}; +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( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, - resolution: WasmPtr<__wasi_timestamp_t>, + resolution: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { - __WASI_EINVAL + let linux_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 = unsafe { + let mut timespec_out: timespec = mem::uninitialized(); + clock_getres(linux_clock_id, &mut 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( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, - time: WasmPtr<__wasi_timestamp_t>, + time: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { - unimplemented!() + let linux_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 = unsafe { + let mut timespec_out: timespec = mem::uninitialized(); + clock_gettime(linux_clock_id, precision, &mut timespec_out); + }; + + resolution.set(timespec_out.tv_nsec as __wasi_timestamp_t); + + // TODO: map output of clock_gettime to __wasi_errno_t + __WASI_ESUCCESS } diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs index 78ee51c9a0b..6273695d322 100644 --- a/lib/wasi/src/syscalls/unix/macos.rs +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -1,20 +1,17 @@ use crate::syscalls::types::*; -use crate::ptr::{Array, WasmPtr}, -use wasmer_runtime_core::{memory::Memory, vm::Ctx}; +use std::cell::Cell; pub fn platform_clock_res_get( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, - resolution: WasmPtr<__wasi_timestamp_t>, + resolution: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { __WASI_EINVAL } pub fn platform_clock_time_get( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, - time: WasmPtr<__wasi_timestamp_t>, + time: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { unimplemented!() } diff --git a/lib/wasi/src/syscalls/windows.rs b/lib/wasi/src/syscalls/windows.rs index 78ee51c9a0b..6273695d322 100644 --- a/lib/wasi/src/syscalls/windows.rs +++ b/lib/wasi/src/syscalls/windows.rs @@ -1,20 +1,17 @@ use crate::syscalls::types::*; -use crate::ptr::{Array, WasmPtr}, -use wasmer_runtime_core::{memory::Memory, vm::Ctx}; +use std::cell::Cell; pub fn platform_clock_res_get( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, - resolution: WasmPtr<__wasi_timestamp_t>, + resolution: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { __WASI_EINVAL } pub fn platform_clock_time_get( - ctx: &mut Ctx, clock_id: __wasi_clockid_t, precision: __wasi_timestamp_t, - time: WasmPtr<__wasi_timestamp_t>, + time: &Cell<__wasi_timestamp_t>, ) -> __wasi_errno_t { unimplemented!() } From de241a03f9bed9cef6b197f92e47b64a435a3871 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 11:43:32 -0700 Subject: [PATCH 05/12] fix linux impl bugs --- lib/wasi/src/syscalls/unix/linux.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index e68d470fad6..80a079b9be7 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -42,12 +42,17 @@ pub fn platform_clock_time_get( _ => return __WASI_EINVAL, }; - let output = unsafe { + let (output, timespec_out) = unsafe { let mut timespec_out: timespec = mem::uninitialized(); - clock_gettime(linux_clock_id, precision, &mut timespec_out); + ( + clock_gettime(linux_clock_id, &mut timespec_out), + timespec_out, + ) }; - resolution.set(timespec_out.tv_nsec as __wasi_timestamp_t); + // 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 From 1f8b90b57eb802b792e6b1042373d1e73454e21c Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 12:33:32 -0700 Subject: [PATCH 06/12] probably actually fix linux for real though --- lib/wasi/src/syscalls/unix/linux.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 80a079b9be7..8cc6320c6fd 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -18,9 +18,12 @@ pub fn platform_clock_res_get( _ => return __WASI_EINVAL, }; - let output = unsafe { + let (output, timespec_out) = unsafe { let mut timespec_out: timespec = mem::uninitialized(); - clock_getres(linux_clock_id, &mut timespec_out); + ( + clock_getres(linux_clock_id, &mut timespec_out), + timespec_out, + ) }; resolution.set(timespec_out.tv_nsec as __wasi_timestamp_t); From 28d9d1fe8784b23dae13b6104721a35abe126f49 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 12:39:48 -0700 Subject: [PATCH 07/12] move linux impl to unix (it works on osx too!) --- lib/wasi/src/syscalls/unix/linux.rs | 61 ----------------------------- lib/wasi/src/syscalls/unix/macos.rs | 16 -------- lib/wasi/src/syscalls/unix/mod.rs | 60 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 77 deletions(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 8cc6320c6fd..8b137891791 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1,62 +1 @@ -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 linux_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(linux_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 linux_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(linux_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 -} diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs index 6273695d322..8b137891791 100644 --- a/lib/wasi/src/syscalls/unix/macos.rs +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -1,17 +1 @@ -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!() -} diff --git a/lib/wasi/src/syscalls/unix/mod.rs b/lib/wasi/src/syscalls/unix/mod.rs index 8fab04668ff..915699c24ec 100644 --- a/lib/wasi/src/syscalls/unix/mod.rs +++ b/lib/wasi/src/syscalls/unix/mod.rs @@ -9,3 +9,63 @@ 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 +} From 88212d356fe07b8e69c53db5a41bf7e6f15902fa Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 13:06:06 -0700 Subject: [PATCH 08/12] implement random_get() --- Cargo.lock | 1 + lib/wasi/Cargo.toml | 3 ++- lib/wasi/src/syscalls/mod.rs | 29 +++++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53f1b1d5f4b..f15fd52757c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1483,6 +1483,7 @@ name = "wasmer-wasi" version = "0.1.0" dependencies = [ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.2.1", ] diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 3d2151d3e13..2b3efd25bf0 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -6,4 +6,5 @@ edition = "2018" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } -libc = "0.2.50" \ No newline at end of file +libc = "0.2.50" +rand = "0.6.5" \ No newline at end of file diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 95d5f5240fe..48a8c30677d 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -10,6 +10,7 @@ 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"))] @@ -451,12 +452,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, 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::(); + 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, From 35fbf573c92098ab4cc95880ac78ff94bd6d56c8 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 15:10:46 -0700 Subject: [PATCH 09/12] add pread on linux --- lib/wasi/src/syscalls/mod.rs | 12 +++++++++++- lib/wasi/src/syscalls/types.rs | 20 ++++++++++++++++++++ lib/wasi/src/syscalls/unix/linux.rs | 26 ++++++++++++++++++++++++++ lib/wasi/src/syscalls/unix/macos.rs | 11 +++++++++++ lib/wasi/src/syscalls/windows.rs | 10 ++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 48a8c30677d..a7bbecb4ede 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -248,6 +248,7 @@ pub fn fd_filestat_set_times( ) -> __wasi_errno_t { unimplemented!() } + pub fn fd_pread( ctx: &mut Ctx, fd: __wasi_fd_t, @@ -256,8 +257,17 @@ pub fn fd_pread( offset: __wasi_filesize_t, nread: WasmPtr, ) -> __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, diff --git a/lib/wasi/src/syscalls/types.rs b/lib/wasi/src/syscalls/types.rs index 7995e86bec8..7f4cba575b8 100644 --- a/lib/wasi/src/syscalls/types.rs +++ b/lib/wasi/src/syscalls/types.rs @@ -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; @@ -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::>()]); + self.buf_len + .into_le(&mut buffer[mem::size_of::>()..]); + } + + fn from_le(buffer: &[u8]) -> Result { + if buffer.len() >= mem::size_of::<__wasi_iovec_t>() { + let buf = ValueType::from_le(&buffer[..mem::size_of::>()])?; + let buf_len = ValueType::from_le(&buffer[mem::size_of::>()..])?; + Ok(Self { buf, buf_len }) + } else { + Err(ValueError::BufferTooSmall) + } + } +} + pub type __wasi_linkcount_t = u32; pub type __wasi_lookupflags_t = u32; diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 8b137891791..cf62cc3800a 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1 +1,27 @@ +use crate::syscalls::types::*; +use std::cell::Cell; +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, +) -> __wasi_errno_t { + let (result, iovec) = unsafe { + let mut iovec = vec![mem::uninitialized(); iovs_len as usize]; + (preadv(fd, &mut iovec, iovs_len, offset), iovec) + }; + nread.set(result); + for (arr_cell, i) in iov_arr.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 +} diff --git a/lib/wasi/src/syscalls/unix/macos.rs b/lib/wasi/src/syscalls/unix/macos.rs index 8b137891791..748a58fb388 100644 --- a/lib/wasi/src/syscalls/unix/macos.rs +++ b/lib/wasi/src/syscalls/unix/macos.rs @@ -1 +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, +) -> __wasi_errno_t { + unimplemented!() +} diff --git a/lib/wasi/src/syscalls/windows.rs b/lib/wasi/src/syscalls/windows.rs index 6273695d322..5ea255f0a06 100644 --- a/lib/wasi/src/syscalls/windows.rs +++ b/lib/wasi/src/syscalls/windows.rs @@ -15,3 +15,13 @@ pub fn platform_clock_time_get( ) -> __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, +) -> __wasi_errno_t { + unimplemented!() +} From 5dcb95dd7a344c0e9256657b515ae562155df78f Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 15:17:42 -0700 Subject: [PATCH 10/12] fix basic errors in linux impl --- lib/wasi/src/syscalls/unix/linux.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index cf62cc3800a..1454bea5565 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -1,5 +1,6 @@ use crate::syscalls::types::*; use std::cell::Cell; +use std::mem; use libc::preadv; @@ -12,10 +13,18 @@ pub fn platform_fd_pread( ) -> __wasi_errno_t { let (result, iovec) = unsafe { let mut iovec = vec![mem::uninitialized(); iovs_len as usize]; - (preadv(fd, &mut iovec, iovs_len, offset), iovec) + ( + preadv( + fd as i32, + iovec.as_mut_ptr(), + iovs_len as i32, + offset as i64, + ), + iovec, + ) }; - nread.set(result); - for (arr_cell, i) in iov_arr.iter().enumerate() { + nread.set(result as u32); + for (arr_cell, i) in iovs.iter().enumerate() { let wasi_iovec = __wasi_iovec_t { buf: iovec[i] as _, buf_len: iovec[i].iov_len as u32, From e7a5c01ef8dba3676d2c783c15c0003d1981af45 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 15:21:54 -0700 Subject: [PATCH 11/12] fix backward enumerate --- lib/wasi/src/syscalls/unix/linux.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 1454bea5565..601c49075f1 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -24,7 +24,7 @@ pub fn platform_fd_pread( ) }; nread.set(result as u32); - for (arr_cell, i) in iovs.iter().enumerate() { + 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, From e156ea2509582348dc20d3ce672d6a348be6b585 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 29 Mar 2019 17:02:58 -0700 Subject: [PATCH 12/12] comment out write logic in linux fd_pread until design discussion --- lib/wasi/src/syscalls/unix/linux.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/wasi/src/syscalls/unix/linux.rs b/lib/wasi/src/syscalls/unix/linux.rs index 601c49075f1..627f95bf15c 100644 --- a/lib/wasi/src/syscalls/unix/linux.rs +++ b/lib/wasi/src/syscalls/unix/linux.rs @@ -24,13 +24,13 @@ pub fn platform_fd_pread( ) }; nread.set(result as u32); - for (i, arr_cell) in iovs.iter().enumerate() { + /*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 }