Skip to content

Commit

Permalink
Merge pull request #144 from wasmerio/feat-cherry-picked
Browse files Browse the repository at this point in the history
Cherry-picked from #131
  • Loading branch information
syrusakbary authored Jul 8, 2020
2 parents ba60724 + bec12c4 commit df9fcf3
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 181 deletions.
55 changes: 51 additions & 4 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,50 @@ mod inner {
}
}

#[cfg(test)]
mod test_into_result {
use super::*;
use std::convert::Infallible;

#[test]
fn test_into_result_over_t() {
let x: i32 = 42;
let result_of_x: Result<i32, Infallible> = x.into_result();

assert_eq!(result_of_x.unwrap(), x);
}

#[test]
fn test_into_result_over_result() {
{
let x: Result<i32, Infallible> = Ok(42);
let result_of_x: Result<i32, Infallible> = x.into_result();

assert_eq!(result_of_x, x);
}

{
use std::{error, fmt};

#[derive(Debug, PartialEq)]
struct E;

impl fmt::Display for E {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "E")
}
}

impl error::Error for E {}

let x: Result<Infallible, E> = Err(E);
let result_of_x: Result<Infallible, E> = x.into_result();

assert_eq!(result_of_x.unwrap_err(), E);
}
}
}

/// The `HostFunction` trait represents the set of functions that
/// can be used as host function. To uphold this statement, it is
/// necessary for a function to be transformed into a pointer to
Expand Down Expand Up @@ -881,7 +925,7 @@ mod inner {
/// This is a function that wraps the real host
/// function. Its address will be used inside the
/// runtime.
extern fn func_wrapper<$( $x, )* Rets, RetsAsResult, Func>( _: usize, $($x: $x::Native, )* ) -> Rets::CStruct
extern fn func_wrapper<$( $x, )* Rets, RetsAsResult, Func>( _: usize, $( $x: $x::Native, )* ) -> Rets::CStruct
where
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
Expand All @@ -900,10 +944,12 @@ mod inner {
}
}

func_wrapper::<$( $x, )* Rets, RetsAsResult, Self> as *const VMFunctionBody
func_wrapper::< $( $x, )* Rets, RetsAsResult, Self > as *const VMFunctionBody
}
}

// Implement `HostFunction` for a function that has the same arity than the tuple.
// This specific function has an environment.
#[allow(unused_parens)]
impl< $( $x, )* Rets, RetsAsResult, Env, Func >
HostFunction<( $( $x ),* ), Rets, WithEnv, Env>
Expand Down Expand Up @@ -942,7 +988,7 @@ mod inner {
}
}

func_wrapper::<$( $x, )* Rets, RetsAsResult, Env, Self> as *const VMFunctionBody
func_wrapper::< $( $x, )* Rets, RetsAsResult, Env, Self > as *const VMFunctionBody
}
}

Expand Down Expand Up @@ -993,7 +1039,8 @@ mod inner {

// Implement `WasmTypeList` on `Infallible`, which means that
// `Infallible` can be used as a returned type of a host function
// to express that it doesn't return.
// to express that it doesn't return, or to express that it cannot
// fail (with `Result<_, Infallible>`).
impl WasmTypeList for Infallible {
type CStruct = Self;
type Array = [i128; 0];
Expand Down
5 changes: 3 additions & 2 deletions lib/engine/src/trap/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ impl RuntimeError {
// theory) we should only see user errors which were originally
// created from our own `Trap` type (see the trampoline module
// with functions).
// Self::new(format!("{}", error))
*error.downcast().expect("only `Trap` errors are supported")
*error
.downcast()
.expect("only `RuntimeError` errors are supported")
}
Trap::Runtime {
pc,
Expand Down
170 changes: 0 additions & 170 deletions tests/compilers/functions.rs

This file was deleted.

88 changes: 84 additions & 4 deletions tests/compilers/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
use crate::utils::get_store;
use anyhow::Result;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use std::sync::Arc;
use std::convert::Infallible;
use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc,
};
use wasmer::*;

fn get_module(store: &Store) -> Result<Module> {
Expand Down Expand Up @@ -120,7 +123,7 @@ fn dynamic_function_with_env() -> Result<()> {
}

#[test]
fn native_function() -> Result<()> {
fn static_function() -> Result<()> {
let store = get_store();
let module = get_module(&store)?;

Expand Down Expand Up @@ -158,7 +161,45 @@ fn native_function() -> Result<()> {
}

#[test]
fn native_function_with_env() -> Result<()> {
fn static_function_with_results() -> Result<()> {
let store = get_store();
let module = get_module(&store)?;

static HITS: AtomicUsize = AtomicUsize::new(0);
Instance::new(
&module,
&imports! {
"host" => {
"0" => Function::new(&store, || {
assert_eq!(HITS.fetch_add(1, SeqCst), 0);
}),
"1" => Function::new(&store, |x: i32| -> Result<i32, Infallible> {
assert_eq!(x, 0);
assert_eq!(HITS.fetch_add(1, SeqCst), 1);
Ok(1)
}),
"2" => Function::new(&store, |x: i32, y: i64| {
assert_eq!(x, 2);
assert_eq!(y, 3);
assert_eq!(HITS.fetch_add(1, SeqCst), 2);
}),
"3" => Function::new(&store, |a: i32, b: i64, c: i32, d: f32, e: f64| {
assert_eq!(a, 100);
assert_eq!(b, 200);
assert_eq!(c, 300);
assert_eq!(d, 400.0);
assert_eq!(e, 500.0);
assert_eq!(HITS.fetch_add(1, SeqCst), 3);
}),
},
},
)?;
assert_eq!(HITS.load(SeqCst), 4);
Ok(())
}

#[test]
fn static_function_with_env() -> Result<()> {
let store = get_store();
let module = get_module(&store)?;

Expand Down Expand Up @@ -194,3 +235,42 @@ fn native_function_with_env() -> Result<()> {
assert_eq!(env.load(SeqCst), 4);
Ok(())
}

#[test]
fn static_function_that_fails() -> Result<()> {
use std::{error, fmt};

let store = get_store();
let wat = r#"
(import "host" "0" (func))
(func $foo
call 0
)
(start $foo)
"#;

let module = Module::new(&store, &wat)?;

let result = Instance::new(
&module,
&imports! {
"host" => {
"0" => Function::new(&store, || -> Result<Infallible, RuntimeError> {
Err(RuntimeError::new("oops"))
}),
},
},
);

assert!(result.is_err());

match result {
Err(InstantiationError::Start(runtime_error)) => {
assert_eq!(runtime_error.message(), "oops")
}
_ => assert!(false),
}

Ok(())
}
Loading

0 comments on commit df9fcf3

Please sign in to comment.