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 serialization for WASI state #726

Merged
merged 11 commits into from
Sep 4, 2019
83 changes: 83 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ wabt = "0.9.1"
glob = "0.3.0"
rustc_version = "0.2.3"

[dev-dependencies]
serde = { version = "1", features = ["derive"] } # used by the plugin example
typetag = "0.1" # used by the plugin example

[features]
default = ["fast-tests", "wasi", "backend-cranelift"]
"loader-kernel" = ["wasmer-kernel-loader"]
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ wasitests-singlepass: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features singlepass -- --test-threads=1

wasitests-cranelift: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture

wasitests-llvm: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features llvm -- --test-threads=1

wasitests-unit:
wasitests-unit: wasitests-setup
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture
cargo test --manifest-path lib/wasi/Cargo.toml --release

wasitests: wasitests-unit wasitests-singlepass wasitests-cranelift wasitests-llvm
Expand Down
5 changes: 4 additions & 1 deletion examples/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use serde::{Deserialize, Serialize};
use wasmer_runtime::{func, imports, instantiate};
use wasmer_runtime_core::vm::Ctx;
use wasmer_wasi::{
Expand All @@ -13,7 +14,7 @@ fn it_works(_ctx: &mut Ctx) -> i32 {
5
}

#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct LoggingWrapper {
pub wasm_module_name: String,
}
Expand Down Expand Up @@ -86,6 +87,8 @@ impl std::io::Write for LoggingWrapper {
}

// the WasiFile methods aren't relevant for a write-only Stdout-like implementation
// we must use typetag and serde so that our trait objects can be safely Serialized and Deserialized
#[typetag::serde]
impl WasiFile for LoggingWrapper {
fn last_accessed(&self) -> u64 {
0
Expand Down
1 change: 1 addition & 0 deletions lib/wasi-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ build = "build/mod.rs"

[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
wasmer-runtime = { path = "../runtime", version = "0.6.0" }
wasmer-wasi = { path = "../wasi", version = "0.6.0" }
# hack to get tests to work
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
Expand Down
61 changes: 60 additions & 1 deletion lib/wasi-tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,60 @@
// nothing to see here
#![cfg(test)]
use wasmer_runtime::{compile, Func};
use wasmer_runtime_core::vm::Ctx;
use wasmer_wasi::{state::*, *};

use std::ffi::c_void;

#[test]
fn serializing_works() {
let args = vec![
b"program_name".into_iter().cloned().collect(),
b"arg1".into_iter().cloned().collect(),
];
let envs = vec![
b"PATH=/bin".into_iter().cloned().collect(),
b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
];
let wasm_binary = include_bytes!("../wasitests/fd_read.wasm");
let import_object = generate_import_object(
args.clone(),
envs.clone(),
vec![],
vec![(
".".to_string(),
std::path::PathBuf::from("wasitests/test_fs/hamlet"),
)],
);
let module = compile(&wasm_binary[..])
.map_err(|e| format!("Can't compile module: {:?}", e))
.unwrap();

let state_bytes = {
let instance = module.instantiate(&import_object).unwrap();

let start: Func<(), ()> = instance.func("_start").unwrap();
start.call().unwrap();
let state = get_wasi_state(instance.context());

assert_eq!(state.args, args);
assert_eq!(state.envs, envs);
let bytes = state.freeze().unwrap();

bytes
};

let mut instance = module.instantiate(&import_object).unwrap();

let wasi_state = Box::new(WasiState::unfreeze(&state_bytes).unwrap());

instance.context_mut().data = Box::into_raw(wasi_state) as *mut c_void;

let second_entry: Func<(), i32> = instance.func("second_entry").unwrap();
let result = second_entry.call().unwrap();
assert_eq!(result, true as i32);
}

#[allow(clippy::mut_from_ref)]
pub(crate) fn get_wasi_state(ctx: &Ctx) -> &mut WasiState {
unsafe { state::get_wasi_state(&mut *(ctx as *const Ctx as *mut Ctx)) }
}
14 changes: 14 additions & 0 deletions lib/wasi-tests/tests/wasitests/fd_read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#[test]
fn test_fd_read() {
assert_wasi_output!(
"../../wasitests/fd_read.wasm",
"fd_read",
vec![],
vec![(
".".to_string(),
::std::path::PathBuf::from("wasitests/test_fs/hamlet")
),],
vec![],
"../../wasitests/fd_read.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi-tests/tests/wasitests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod create_dir;
mod envvar;
mod fd_allocate;
mod fd_pread;
mod fd_read;
mod fd_sync;
mod file_metadata;
mod fs_sandbox_test;
Expand Down
3 changes: 3 additions & 0 deletions lib/wasi-tests/wasitests/fd_read.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SCENE IV. The Queen's closet.

Enter QUEEN GERTRUDE and POLO
Loading