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 early exit example #1657

Merged
merged 5 commits into from
Sep 30, 2020
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
7 changes: 3 additions & 4 deletions .tarpaulin.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
[cranelift_coverage]
features = "cranelift,singlepass,llvm,test-no-traps,test-cranelift"
examples = ["early-exit", "engine-jit", "engine-native", "engine-headless", "cross-compilation", "compiler-cranelift", "exported-function", "wasi"]
release = true

[llvm_coverage]
features = "cranelift,singlepass,llvm,test-no-traps,test-llvm"
examples = ["compiler-llvm"]
release = true

[singlepass_coverage]
features = "cranelift,singlepass,llvm,test-no-traps,test-singlepass"
release = true

[feature_a_and_b_coverage]
features = "feature_a feature_b"
examples = ["compiler-singlepass"]
release = true

[report]
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## **[Unreleased]**
- [#1657](https://github.com/wasmerio/wasmer/pull/1657) Implement `wasm_trap_t` and `wasm_frame_t` for Wasm C API; add examples in Rust and C of exiting early with a host function.
- [#1645](https://github.com/wasmerio/wasmer/pull/1645) Move the install script to https://github.com/wasmerio/wasmer-install

## 1.0.0-alpha3 - 2020-09-14
Expand Down
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ test-no-traps = ["wasmer-wast/test-no-traps"]
name = "static_and_dynamic_functions"
harness = false

[[example]]
name = "early-exit"
path = "examples/early_exit.rs"
required-features = ["cranelift"]

[[example]]
name = "engine-jit"
path = "examples/engine_jit.rs"
Expand Down
82 changes: 82 additions & 0 deletions examples/early_exit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! This example shows how the host can terminate execution of Wasm early from
//! inside a host function called by the Wasm.

use anyhow::bail;
use std::fmt;
use wasmer::{imports, wat2wasm, Function, Instance, Module, NativeFunc, RuntimeError, Store};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_engine_jit::JIT;

// First we need to create an error type that we'll use to signal the end of execution.
#[derive(Debug, Clone, Copy)]
struct ExitCode(u32);

// This type must implement `std::error::Error` so we must also implement `std::fmt::Display` for it.
impl fmt::Display for ExitCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}

// And then we implement `std::error::Error`.
impl std::error::Error for ExitCode {}

// The host function that we'll use to terminate execution.
fn early_exit() {
// This is where it happens.
RuntimeError::raise(Box::new(ExitCode(1)));
}

fn main() -> anyhow::Result<()> {
// Let's declare the Wasm module with the text representation.
let wasm_bytes = wat2wasm(
br#"
(module
(type $run_t (func (param i32 i32) (result i32)))
(type $early_exit_t (func (param) (result)))
(import "env" "early_exit" (func $early_exit (type $early_exit_t)))
(func $run (type $run_t) (param $x i32) (param $y i32) (result i32)
(call $early_exit)
(i32.add
local.get $x
local.get $y))
(export "run" (func $run)))
"#,
)?;

let store = Store::new(&JIT::new(&Cranelift::default()).engine());
let module = Module::new(&store, wasm_bytes)?;

let import_object = imports! {
"env" => {
"early_exit" => Function::new_native(&store, early_exit),
}
};
let instance = Instance::new(&module, &import_object)?;

// Get the `run` function which we'll use as our entrypoint.
let run_func: NativeFunc<(i32, i32), i32> =
instance.exports.get_native_function("run").unwrap();

// When we call a function it can either succeed or fail.
match run_func.call(1, 7) {
Ok(result) => {
bail!(
"Expected early termination with `ExitCode`, found: {}",
result
);
}
// We're expecting it to fail.
// We attempt to downcast the error into the error type that we were expecting.
Err(e) => match e.downcast::<ExitCode>() {
// We found the exit code used to terminate execution.
Ok(exit_code) => {
println!("Exited early with exit code: {}", exit_code);
Ok(())
}
Err(e) => {
bail!("Unknown error `{}` found. expected `ErrorCode`", e);
}
},
}
}
5 changes: 2 additions & 3 deletions examples/engine_cross_compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@ use wasmer_engine_native::Native;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Let's declare the Wasm module with the text representation.
let wasm_bytes = wat2wasm(
r#"
br#"
(module
(type $sum_t (func (param i32 i32) (result i32)))
(func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.add)
(export "sum" (func $sum_f)))
"#
.as_bytes(),
"#,
)?;

// Define a compiler configuration.
Expand Down
6 changes: 3 additions & 3 deletions examples/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use wasmer_engine_jit::JIT;
use wasmer_wasi::WasiState;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm_path = format!(
"{}/tests/wasi-wast/wasi/unstable/hello.wasm",
std::env::var("CARGO_MANIFEST_DIR").unwrap()
let wasm_path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/wasi-wast/wasi/unstable/hello.wasm"
);
// Let's declare the Wasm module with the text representation.
let wasm_bytes = std::fs::read(wasm_path)?;
Expand Down
4 changes: 2 additions & 2 deletions lib/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ pub use wasmer_compiler::{
};
pub use wasmer_compiler::{CpuFeature, Features, Target};
pub use wasmer_engine::{
ChainableNamedResolver, DeserializeError, Engine, InstantiationError, LinkError, NamedResolver,
NamedResolverChain, Resolver, RuntimeError, SerializeError,
ChainableNamedResolver, DeserializeError, Engine, FrameInfo, InstantiationError, LinkError,
NamedResolver, NamedResolverChain, Resolver, RuntimeError, SerializeError,
};
pub use wasmer_types::{
Atomically, Bytes, GlobalInit, LocalFunctionIndex, MemoryView, Pages, ValueType,
Expand Down
Loading