2020-04-16 11:52:11 -07:00
#[ macro_use ]
mod utils ;
2020-04-15 16:31:05 -07:00
use std ::{ convert ::TryInto , sync ::Arc } ;
use wabt ::wat2wasm ;
use wasmer ::compiler ::{ compile_with , compiler_for_backend , Backend } ;
use wasmer ::error ::RuntimeError ;
use wasmer ::units ::Pages ;
use wasmer ::wasm ::{
DynFunc , Func , FuncSig , Global , Instance , Memory , MemoryDescriptor , Type , Value ,
} ;
use wasmer ::{ imports , vm , DynamicFunc } ;
fn runtime_core_new_api_works ( backend : Backend ) {
let wasm = r #"
( module
( type $type ( func ( param i32 ) ( result i32 ) ) )
( global ( export " my_global " ) i32 ( i32 . const 45 ) )
( func ( export " add_one " ) ( type $type )
( i32 . add ( get_local 0 )
( i32 . const 1 ) ) )
( func ( export " double " ) ( type $type )
( i32 . mul ( get_local 0 )
( i32 . const 2 ) ) )
) " #;
let wasm_binary = wat2wasm ( wasm . as_bytes ( ) ) . expect ( " WAST not valid or malformed " ) ;
let compiler = compiler_for_backend ( backend ) . expect ( " Backend not recognized " ) ;
let module = compile_with ( & wasm_binary , & * compiler ) . unwrap ( ) ;
let import_object = imports! { } ;
let instance = module . instantiate ( & import_object ) . unwrap ( ) ;
let my_global : Global = instance . exports . get ( " my_global " ) . unwrap ( ) ;
assert_eq! ( my_global . get ( ) , Value ::I32 ( 45 ) ) ;
let double : Func < i32 , i32 > = instance . exports . get ( " double " ) . unwrap ( ) ;
assert_eq! ( double . call ( 5 ) . unwrap ( ) , 10 ) ;
let add_one : DynFunc = instance . exports . get ( " add_one " ) . unwrap ( ) ;
assert_eq! ( add_one . call ( & [ Value ::I32 ( 5 ) ] ) . unwrap ( ) , & [ Value ::I32 ( 6 ) ] ) ;
let add_one_memory : Result < DynFunc , _ > = instance . exports . get ( " my_global " ) ;
assert! ( add_one_memory . is_err ( ) ) ;
}
2020-03-17 15:27:11 -07:00
2020-04-15 16:31:05 -07:00
macro_rules ! call_and_assert {
2020-03-05 14:17:04 +01:00
( $instance :ident , $function :ident ( $( $inputs :ty ) , * ) -> $output :ty , ( $( $arguments :expr ) , * ) = = $expected_value :expr ) = > {
#[ allow(unused_parens) ]
2020-03-26 18:13:45 -07:00
let $function : Func < ( $( $inputs ) , * ) , $output > = $instance . exports . get ( stringify! ( $function ) ) . expect ( concat! ( " Failed to get the ` " , stringify! ( $function ) , " ` export function. " ) ) ;
2019-11-04 15:40:20 +01:00
2020-03-05 14:17:04 +01:00
let result = $function . call ( $( $arguments ) , * ) ;
2019-11-04 15:40:20 +01:00
match ( result , $expected_value ) {
( Ok ( value ) , expected_value ) = > assert_eq! (
Ok ( value ) ,
expected_value ,
concat! ( " Expected right when calling ` " , stringify! ( $function ) , " `. " )
) ,
2020-04-24 14:30:14 -07:00
( Err ( RuntimeError ::User ( data ) ) , Err ( RuntimeError ::User ( expected_data ) ) ) = > {
2019-11-04 15:40:20 +01:00
if let ( Some ( data ) , Some ( expected_data ) ) = (
data . downcast_ref ::< & str > ( ) ,
expected_data . downcast_ref ::< & str > ( ) ,
) {
assert_eq! (
data , expected_data ,
concat! ( " Expected right when calling ` " , stringify! ( $function ) , " `. " )
)
} else if let ( Some ( data ) , Some ( expected_data ) ) = (
data . downcast_ref ::< String > ( ) ,
expected_data . downcast_ref ::< String > ( ) ,
) {
assert_eq! (
data , expected_data ,
concat! ( " Expected right when calling ` " , stringify! ( $function ) , " `. " )
)
} else {
assert! ( false , " Unexpected error, cannot compare it. " )
}
}
( result , expected_value ) = > assert! (
false ,
format! (
" Unexpected assertion for `{}`: left = `{:?}`, right = `{:?}`. " ,
stringify! ( $function ) ,
result ,
expected_value
)
) ,
}
} ;
2020-04-15 16:31:05 -07:00
}
/// The shift that is set in the instance memory. The value is part of
/// the result returned by the imported functions if the memory is
/// read properly.
const SHIFT : i32 = 10 ;
/// The shift that is captured in the environment of a closure. The
/// value is part of the result returned by the imported function if
/// the closure captures its environment properly.
#[ allow(non_upper_case_globals) ]
const shift : i32 = 100 ;
#[ cfg(all(unix, target_arch = " x86_64 " )) ]
fn imported_functions_forms ( backend : Backend , test : & dyn Fn ( & Instance ) ) {
const MODULE : & str = r #"
( module
( type $type ( func ( param i32 ) ( result i32 ) ) )
( import " env " " memory " ( memory 1 1 ) )
( import " env " " callback_fn " ( func $callback_fn ( type $type ) ) )
( import " env " " callback_closure " ( func $callback_closure ( type $type ) ) )
( import " env " " callback_fn_dynamic " ( func $callback_fn_dynamic ( type $type ) ) )
( import " env " " callback_fn_dynamic_panic " ( func $callback_fn_dynamic_panic ( type $type ) ) )
( import " env " " callback_closure_dynamic_0 " ( func $callback_closure_dynamic_0 ) )
( import " env " " callback_closure_dynamic_1 " ( func $callback_closure_dynamic_1 ( param i32 ) ( result i32 ) ) )
( import " env " " callback_closure_dynamic_2 " ( func $callback_closure_dynamic_2 ( param i32 i64 ) ( result i64 ) ) )
( import " env " " callback_closure_dynamic_3 " ( func $callback_closure_dynamic_3 ( param i32 i64 f32 ) ( result f32 ) ) )
( import " env " " callback_closure_dynamic_4 " ( func $callback_closure_dynamic_4 ( param i32 i64 f32 f64 ) ( result f64 ) ) )
( import " env " " callback_closure_with_env " ( func $callback_closure_with_env ( type $type ) ) )
( import " env " " callback_fn_with_vmctx " ( func $callback_fn_with_vmctx ( type $type ) ) )
( import " env " " callback_closure_with_vmctx " ( func $callback_closure_with_vmctx ( type $type ) ) )
( import " env " " callback_closure_with_vmctx_and_env " ( func $callback_closure_with_vmctx_and_env ( type $type ) ) )
( import " env " " callback_fn_trap " ( func $callback_fn_trap ( type $type ) ) )
( import " env " " callback_closure_trap " ( func $callback_closure_trap ( type $type ) ) )
( import " env " " callback_fn_trap_with_vmctx " ( func $callback_fn_trap_with_vmctx ( type $type ) ) )
( import " env " " callback_closure_trap_with_vmctx " ( func $callback_closure_trap_with_vmctx ( type $type ) ) )
( import " env " " callback_closure_trap_with_vmctx_and_env " ( func $callback_closure_trap_with_vmctx_and_env ( type $type ) ) )
( func ( export " function_fn " ) ( type $type )
get_local 0
call $callback_fn )
( func ( export " function_closure " ) ( type $type )
get_local 0
call $callback_closure )
( func ( export " function_fn_dynamic " ) ( type $type )
get_local 0
call $callback_fn_dynamic )
( func ( export " function_fn_dynamic_panic " ) ( type $type )
get_local 0
call $callback_fn_dynamic_panic )
( func ( export " function_closure_dynamic_0 " )
call $callback_closure_dynamic_0 )
( func ( export " function_closure_dynamic_1 " ) ( param i32 ) ( result i32 )
get_local 0
call $callback_closure_dynamic_1 )
( func ( export " function_closure_dynamic_2 " ) ( param i32 i64 ) ( result i64 )
get_local 0
get_local 1
call $callback_closure_dynamic_2 )
( func ( export " function_closure_dynamic_3 " ) ( param i32 i64 f32 ) ( result f32 )
get_local 0
get_local 1
get_local 2
call $callback_closure_dynamic_3 )
( func ( export " function_closure_dynamic_4 " ) ( param i32 i64 f32 f64 ) ( result f64 )
get_local 0
get_local 1
get_local 2
get_local 3
call $callback_closure_dynamic_4 )
( func ( export " function_closure_with_env " ) ( type $type )
get_local 0
call $callback_closure_with_env )
( func ( export " function_fn_with_vmctx " ) ( type $type )
get_local 0
call $callback_fn_with_vmctx )
( func ( export " function_closure_with_vmctx " ) ( type $type )
get_local 0
call $callback_closure_with_vmctx )
( func ( export " function_closure_with_vmctx_and_env " ) ( type $type )
get_local 0
call $callback_closure_with_vmctx_and_env )
( func ( export " function_fn_trap " ) ( type $type )
get_local 0
call $callback_fn_trap )
( func ( export " function_closure_trap " ) ( type $type )
get_local 0
call $callback_closure_trap )
( func ( export " function_fn_trap_with_vmctx " ) ( type $type )
get_local 0
call $callback_fn_trap_with_vmctx )
( func ( export " function_closure_trap_with_vmctx " ) ( type $type )
get_local 0
call $callback_closure_trap_with_vmctx )
( func ( export " function_closure_trap_with_vmctx_and_env " ) ( type $type )
get_local 0
call $callback_closure_trap_with_vmctx_and_env ) )
" #;
let wasm_binary = wat2wasm ( MODULE . as_bytes ( ) ) . expect ( " WAST not valid or malformed " ) ;
let compiler = compiler_for_backend ( backend ) . expect ( " Backend not recognized " ) ;
let module = compile_with ( & wasm_binary , & * compiler ) . unwrap ( ) ;
let memory_descriptor = MemoryDescriptor ::new ( Pages ( 1 ) , Some ( Pages ( 1 ) ) , false ) . unwrap ( ) ;
let memory = Memory ::new ( memory_descriptor ) . unwrap ( ) ;
memory . view ( ) [ 0 ] . set ( SHIFT ) ;
let import_object = imports! {
" env " = > {
" memory " = > memory . clone ( ) ,
// Regular function.
" callback_fn " = > Func ::new ( callback_fn ) ,
// Closure without a captured environment.
" callback_closure " = > Func ::new ( | n : i32 | -> Result < i32 , ( ) > {
Ok ( n + 1 )
} ) ,
// Regular polymorphic function.
" callback_fn_dynamic " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 ] , vec! [ Type ::I32 ] ) ) ,
callback_fn_dynamic ,
) ,
// Polymorphic function that panics.
" callback_fn_dynamic_panic " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 ] , vec! [ Type ::I32 ] ) ) ,
callback_fn_dynamic_panic ,
) ,
// Polymorphic closure “closures”.
" callback_closure_dynamic_0 " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ ] , vec! [ ] ) ) ,
| _ , inputs : & [ Value ] | -> Vec < Value > {
assert! ( inputs . is_empty ( ) ) ;
2019-11-04 15:40:20 +01:00
2020-04-15 16:31:05 -07:00
vec! [ ]
}
) ,
" callback_closure_dynamic_1 " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 ] , vec! [ Type ::I32 ] ) ) ,
move | vmctx : & mut vm ::Ctx , inputs : & [ Value ] | -> Vec < Value > {
assert_eq! ( inputs . len ( ) , 1 ) ;
let memory = vmctx . memory ( 0 ) ;
2020-03-05 14:17:04 +01:00
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
2020-04-15 16:31:05 -07:00
let n : i32 = ( & inputs [ 0 ] ) . try_into ( ) . unwrap ( ) ;
2020-03-05 14:17:04 +01:00
2020-04-15 16:31:05 -07:00
vec! [ Value ::I32 ( shift_ + n ) ]
}
) ,
" callback_closure_dynamic_2 " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 , Type ::I64 ] , vec! [ Type ::I64 ] ) ) ,
move | vmctx : & mut vm ::Ctx , inputs : & [ Value ] | -> Vec < Value > {
assert_eq! ( inputs . len ( ) , 2 ) ;
let memory = vmctx . memory ( 0 ) ;
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
let i : i32 = ( & inputs [ 0 ] ) . try_into ( ) . unwrap ( ) ;
let j : i64 = ( & inputs [ 1 ] ) . try_into ( ) . unwrap ( ) ;
2020-03-05 14:17:04 +01:00
2020-04-15 16:31:05 -07:00
vec! [ Value ::I64 ( shift_ as i64 + i as i64 + j ) ]
}
) ,
" callback_closure_dynamic_3 " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 , Type ::I64 , Type ::F32 ] , vec! [ Type ::F32 ] ) ) ,
move | vmctx : & mut vm ::Ctx , inputs : & [ Value ] | -> Vec < Value > {
assert_eq! ( inputs . len ( ) , 3 ) ;
2020-03-05 14:17:04 +01:00
let memory = vmctx . memory ( 0 ) ;
2020-04-15 16:31:05 -07:00
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
let i : i32 = ( & inputs [ 0 ] ) . try_into ( ) . unwrap ( ) ;
let j : i64 = ( & inputs [ 1 ] ) . try_into ( ) . unwrap ( ) ;
let k : f32 = ( & inputs [ 2 ] ) . try_into ( ) . unwrap ( ) ;
2020-03-05 14:17:04 +01:00
2020-04-15 16:31:05 -07:00
vec! [ Value ::F32 ( shift_ as f32 + i as f32 + j as f32 + k ) ]
}
) ,
" callback_closure_dynamic_4 " = > DynamicFunc ::new (
Arc ::new ( FuncSig ::new ( vec! [ Type ::I32 , Type ::I64 , Type ::F32 , Type ::F64 ] , vec! [ Type ::F64 ] ) ) ,
move | vmctx : & mut vm ::Ctx , inputs : & [ Value ] | -> Vec < Value > {
assert_eq! ( inputs . len ( ) , 4 ) ;
2020-03-05 14:17:04 +01:00
let memory = vmctx . memory ( 0 ) ;
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
2020-04-15 16:31:05 -07:00
let i : i32 = ( & inputs [ 0 ] ) . try_into ( ) . unwrap ( ) ;
let j : i64 = ( & inputs [ 1 ] ) . try_into ( ) . unwrap ( ) ;
let k : f32 = ( & inputs [ 2 ] ) . try_into ( ) . unwrap ( ) ;
let l : f64 = ( & inputs [ 3 ] ) . try_into ( ) . unwrap ( ) ;
2020-03-05 14:17:04 +01:00
2020-04-15 16:31:05 -07:00
vec! [ Value ::F64 ( shift_ as f64 + i as f64 + j as f64 + k as f64 + l ) ]
}
) ,
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
// Closure with a captured environment (a single variable + an instance of `Memory`).
" callback_closure_with_env " = > Func ::new ( move | n : i32 | -> Result < i32 , ( ) > {
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
Ok ( shift_ + n + 1 )
} ) ,
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
// Regular function with an explicit `vmctx`.
" callback_fn_with_vmctx " = > Func ::new ( callback_fn_with_vmctx ) ,
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
// Closure without a captured environment but with an explicit `vmctx`.
" callback_closure_with_vmctx " = > Func ::new ( | vmctx : & mut vm ::Ctx , n : i32 | -> Result < i32 , ( ) > {
let memory = vmctx . memory ( 0 ) ;
let shift_ : i32 = memory . view ( ) [ 0 ] . get ( ) ;
2019-11-04 13:02:29 +01:00
2020-04-15 16:31:05 -07:00
Ok ( shift_ + n + 1 )
} ) ,
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
// Closure with a captured environment (a single variable) and with an explicit `vmctx`.
" callback_closure_with_vmctx_and_env " = > Func ::new ( move | vmctx : & mut vm ::Ctx , n : i32 | -> Result < i32 , ( ) > {
let memory = vmctx . memory ( 0 ) ;
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
2019-11-04 15:21:09 +01:00
2020-04-15 16:31:05 -07:00
Ok ( shift_ + n + 1 )
} ) ,
2019-10-30 13:28:01 +01:00
2020-04-15 16:31:05 -07:00
// Trap a regular function.
" callback_fn_trap " = > Func ::new ( callback_fn_trap ) ,
2019-10-30 13:28:01 +01:00
2020-04-15 16:31:05 -07:00
// Trap a closure without a captured environment.
" callback_closure_trap " = > Func ::new ( | n : i32 | -> Result < i32 , String > {
Err ( format! ( " bar {} " , n + 1 ) )
} ) ,
2019-10-30 14:58:57 +01:00
2020-04-15 16:31:05 -07:00
// Trap a regular function with an explicit `vmctx`.
" callback_fn_trap_with_vmctx " = > Func ::new ( callback_fn_trap_with_vmctx ) ,
2020-03-05 14:17:04 +01:00
2020-04-15 16:31:05 -07:00
// Trap a closure without a captured environment but with an explicit `vmctx`.
" callback_closure_trap_with_vmctx " = > Func ::new ( | vmctx : & mut vm ::Ctx , n : i32 | -> Result < i32 , String > {
let memory = vmctx . memory ( 0 ) ;
let shift_ : i32 = memory . view ( ) [ 0 ] . get ( ) ;
2020-03-16 22:49:37 +08:00
2020-04-15 16:31:05 -07:00
Err ( format! ( " qux {} " , shift_ + n + 1 ) )
} ) ,
2019-10-30 13:28:01 +01:00
2020-04-15 16:31:05 -07:00
// Trap a closure with a captured environment (a single variable) and with an explicit `vmctx`.
" callback_closure_trap_with_vmctx_and_env " = > Func ::new ( move | vmctx : & mut vm ::Ctx , n : i32 | -> Result < i32 , String > {
let memory = vmctx . memory ( 0 ) ;
let shift_ = shift + memory . view ::< i32 > ( ) [ 0 ] . get ( ) ;
2019-10-30 13:28:01 +01:00
2020-04-15 16:31:05 -07:00
Err ( format! ( " ! {} " , shift_ + n + 1 ) )
} ) ,
} ,
} ;
let instance = module . instantiate ( & import_object ) . unwrap ( ) ;
test ( & instance ) ;
}
2019-10-30 14:58:57 +01:00
2020-04-15 16:31:05 -07:00
fn callback_fn ( n : i32 ) -> Result < i32 , ( ) > {
Ok ( n + 1 )
}
2019-10-30 13:28:01 +01:00
2020-04-15 16:31:05 -07:00
fn callback_fn_dynamic ( _ : & mut vm ::Ctx , inputs : & [ Value ] ) -> Vec < Value > {
match inputs [ 0 ] {
Value ::I32 ( x ) = > vec! [ Value ::I32 ( x + 1 ) ] ,
_ = > unreachable! ( ) ,
2020-04-06 14:13:54 -07:00
}
2020-04-15 16:31:05 -07:00
}
fn callback_fn_dynamic_panic ( _ : & mut vm ::Ctx , _ : & [ Value ] ) -> Vec < Value > {
panic! ( " test " ) ;
}
fn callback_fn_with_vmctx ( vmctx : & mut vm ::Ctx , n : i32 ) -> Result < i32 , ( ) > {
let memory = vmctx . memory ( 0 ) ;
let shift_ : i32 = memory . view ( ) [ 0 ] . get ( ) ;
Ok ( shift_ + n + 1 )
}
2019-11-04 15:40:20 +01:00
2020-04-15 16:31:05 -07:00
fn callback_fn_trap ( n : i32 ) -> Result < i32 , String > {
Err ( format! ( " foo {} " , n + 1 ) )
}
fn callback_fn_trap_with_vmctx ( vmctx : & mut vm ::Ctx , n : i32 ) -> Result < i32 , String > {
let memory = vmctx . memory ( 0 ) ;
let shift_ : i32 = memory . view ( ) [ 0 ] . get ( ) ;
Err ( format! ( " baz {} " , shift_ + n + 1 ) )
}
macro_rules ! test {
2020-04-16 11:52:11 -07:00
( $test_name :ident , $function :ident ( $( $inputs :ty ) , * ) -> $output :ty , ( $( $arguments :expr ) , * ) = = $expected_value :expr ) = > {
2020-04-03 16:27:49 -07:00
#[ cfg(all(unix, target_arch = " x86_64 " )) ]
2019-11-04 15:40:20 +01:00
#[ test ]
fn $test_name ( ) {
2020-04-16 11:52:11 -07:00
imported_functions_forms ( get_backend ( ) , & | instance | {
2020-03-05 14:17:04 +01:00
call_and_assert! ( instance , $function ( $( $inputs ) , * ) -> $output , ( $( $arguments ) , * ) = = $expected_value ) ;
2019-11-04 15:40:20 +01:00
} ) ;
}
2020-04-15 16:31:05 -07:00
}
2019-11-04 15:40:20 +01:00
}
2020-04-16 11:52:11 -07:00
wasmer_backends! {
2020-04-15 16:31:05 -07:00
use super ::* ;
2020-04-16 11:52:11 -07:00
test! ( test_fn , function_fn ( i32 ) -> i32 , ( 1 ) = = Ok ( 2 ) ) ;
test! ( test_closure , function_closure ( i32 ) -> i32 , ( 1 ) = = Ok ( 2 ) ) ;
test! ( test_fn_dynamic , function_fn_dynamic ( i32 ) -> i32 , ( 1 ) = = Ok ( 2 ) ) ;
2020-04-24 14:30:14 -07:00
test! ( test_fn_dynamic_panic , function_fn_dynamic_panic ( i32 ) -> i32 , ( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( " test " ) ) ) ) ;
2020-04-16 11:52:11 -07:00
test! (
test_closure_dynamic_0 ,
function_closure_dynamic_0 ( ( ) ) -> ( ) ,
( ) = = Ok ( ( ) )
) ;
test! (
test_closure_dynamic_1 ,
function_closure_dynamic_1 ( i32 ) -> i32 ,
( 1 ) = = Ok ( 1 + shift + SHIFT )
) ;
test! (
test_closure_dynamic_2 ,
function_closure_dynamic_2 ( i32 , i64 ) -> i64 ,
( 1 , 2 ) = = Ok ( 1 + 2 + shift as i64 + SHIFT as i64 )
) ;
test! (
test_closure_dynamic_3 ,
function_closure_dynamic_3 ( i32 , i64 , f32 ) -> f32 ,
( 1 , 2 , 3. ) = = Ok ( 1. + 2. + 3. + shift as f32 + SHIFT as f32 )
) ;
test! (
test_closure_dynamic_4 ,
function_closure_dynamic_4 ( i32 , i64 , f32 , f64 ) -> f64 ,
( 1 , 2 , 3. , 4. ) = = Ok ( 1. + 2. + 3. + 4. + shift as f64 + SHIFT as f64 )
) ;
test! (
test_closure_with_env ,
function_closure_with_env ( i32 ) -> i32 ,
( 1 ) = = Ok ( 2 + shift + SHIFT )
) ;
test! ( test_fn_with_vmctx , function_fn_with_vmctx ( i32 ) -> i32 , ( 1 ) = = Ok ( 2 + SHIFT ) ) ;
test! (
test_closure_with_vmctx ,
function_closure_with_vmctx ( i32 ) -> i32 ,
( 1 ) = = Ok ( 2 + SHIFT )
) ;
test! (
test_closure_with_vmctx_and_env ,
function_closure_with_vmctx_and_env ( i32 ) -> i32 ,
( 1 ) = = Ok ( 2 + shift + SHIFT )
) ;
test! (
test_fn_trap ,
function_fn_trap ( i32 ) -> i32 ,
2020-04-24 14:30:14 -07:00
( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( format! ( " foo {} " , 2 ) ) ) )
2020-04-16 11:52:11 -07:00
) ;
test! (
test_closure_trap ,
function_closure_trap ( i32 ) -> i32 ,
2020-04-24 14:30:14 -07:00
( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( format! ( " bar {} " , 2 ) ) ) )
2020-04-16 11:52:11 -07:00
) ;
test! (
test_fn_trap_with_vmctx ,
function_fn_trap_with_vmctx ( i32 ) -> i32 ,
2020-04-24 14:30:14 -07:00
( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( format! ( " baz {} " , 2 + SHIFT ) ) ) )
2020-04-16 11:52:11 -07:00
) ;
test! (
test_closure_trap_with_vmctx ,
function_closure_trap_with_vmctx ( i32 ) -> i32 ,
2020-04-24 14:30:14 -07:00
( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( format! ( " qux {} " , 2 + SHIFT ) ) ) )
2020-04-16 11:52:11 -07:00
) ;
test! (
test_closure_trap_with_vmctx_and_env ,
function_closure_trap_with_vmctx_and_env ( i32 ) -> i32 ,
2020-04-24 14:30:14 -07:00
( 1 ) = = Err ( RuntimeError ::User ( Box ::new ( format! ( " ! {} " , 2 + shift + SHIFT ) ) ) )
2020-04-16 11:52:11 -07:00
) ;
#[ test ]
fn runtime_core_new_api ( ) {
runtime_core_new_api_works ( get_backend ( ) )
}
2020-04-06 14:13:54 -07:00
}