wasmtime: Expand Func::{wrap,get} tests to cover {func,extern}ref args/returns

This commit is contained in:
Nick Fitzgerald
2020-07-07 11:06:29 -07:00
parent 3e63774e99
commit c2fc371e58

View File

@@ -13,12 +13,16 @@ fn func_constructors() {
Func::wrap(&store, || -> i64 { 0 }); Func::wrap(&store, || -> i64 { 0 });
Func::wrap(&store, || -> f32 { 0.0 }); Func::wrap(&store, || -> f32 { 0.0 });
Func::wrap(&store, || -> f64 { 0.0 }); Func::wrap(&store, || -> f64 { 0.0 });
Func::wrap(&store, || -> Option<ExternRef> { None });
Func::wrap(&store, || -> Option<Func> { None });
Func::wrap(&store, || -> Result<(), Trap> { loop {} }); Func::wrap(&store, || -> Result<(), Trap> { loop {} });
Func::wrap(&store, || -> Result<i32, Trap> { loop {} }); Func::wrap(&store, || -> Result<i32, Trap> { loop {} });
Func::wrap(&store, || -> Result<i64, Trap> { loop {} }); Func::wrap(&store, || -> Result<i64, Trap> { loop {} });
Func::wrap(&store, || -> Result<f32, Trap> { loop {} }); Func::wrap(&store, || -> Result<f32, Trap> { loop {} });
Func::wrap(&store, || -> Result<f64, Trap> { loop {} }); Func::wrap(&store, || -> Result<f64, Trap> { loop {} });
Func::wrap(&store, || -> Result<Option<ExternRef>, Trap> { loop {} });
Func::wrap(&store, || -> Result<Option<Func>, Trap> { loop {} });
} }
#[test] #[test]
@@ -95,9 +99,12 @@ fn signatures_match() {
assert_eq!(f.ty().params(), &[]); assert_eq!(f.ty().params(), &[]);
assert_eq!(f.ty().results(), &[ValType::F64]); assert_eq!(f.ty().results(), &[ValType::F64]);
let f = Func::wrap(&store, |_: f32, _: f64, _: i32, _: i64, _: i32| -> f64 { let f = Func::wrap(
loop {} &store,
}); |_: f32, _: f64, _: i32, _: i64, _: i32, _: Option<ExternRef>, _: Option<Func>| -> f64 {
loop {}
},
);
assert_eq!( assert_eq!(
f.ty().params(), f.ty().params(),
&[ &[
@@ -105,13 +112,18 @@ fn signatures_match() {
ValType::F64, ValType::F64,
ValType::I32, ValType::I32,
ValType::I64, ValType::I64,
ValType::I32 ValType::I32,
ValType::ExternRef,
ValType::FuncRef,
] ]
); );
assert_eq!(f.ty().results(), &[ValType::F64]); assert_eq!(f.ty().results(), &[ValType::F64]);
} }
#[test] #[test]
// Note: Cranelift only supports refrerence types (used in the wasm in this
// test) on x64.
#[cfg(target_arch = "x86_64")]
fn import_works() -> Result<()> { fn import_works() -> Result<()> {
static HITS: AtomicUsize = AtomicUsize::new(0); static HITS: AtomicUsize = AtomicUsize::new(0);
@@ -120,9 +132,9 @@ fn import_works() -> Result<()> {
(import "" "" (func)) (import "" "" (func))
(import "" "" (func (param i32) (result i32))) (import "" "" (func (param i32) (result i32)))
(import "" "" (func (param i32) (param i64))) (import "" "" (func (param i32) (param i64)))
(import "" "" (func (param i32 i64 i32 f32 f64))) (import "" "" (func (param i32 i64 i32 f32 f64 externref funcref)))
(func $foo (func (export "run") (param externref funcref)
call 0 call 0
i32.const 0 i32.const 0
call 1 call 1
@@ -136,14 +148,18 @@ fn import_works() -> Result<()> {
i32.const 300 i32.const 300
f32.const 400 f32.const 400
f64.const 500 f64.const 500
local.get 0
local.get 1
call 3 call 3
) )
(start $foo)
"#, "#,
)?; )?;
let store = Store::default(); let mut config = Config::new();
let module = Module::new(store.engine(), &wasm)?; config.wasm_reference_types(true);
Instance::new( let engine = Engine::new(&config);
let store = Store::new(&engine);
let module = Module::new(&engine, &wasm)?;
let instance = Instance::new(
&store, &store,
&module, &module,
&[ &[
@@ -163,17 +179,31 @@ fn import_works() -> Result<()> {
assert_eq!(HITS.fetch_add(1, SeqCst), 2); assert_eq!(HITS.fetch_add(1, SeqCst), 2);
}) })
.into(), .into(),
Func::wrap(&store, |a: i32, b: i64, c: i32, d: f32, e: f64| { Func::wrap(
assert_eq!(a, 100); &store,
assert_eq!(b, 200); |a: i32, b: i64, c: i32, d: f32, e: f64, f: Option<ExternRef>, g: Option<Func>| {
assert_eq!(c, 300); assert_eq!(a, 100);
assert_eq!(d, 400.0); assert_eq!(b, 200);
assert_eq!(e, 500.0); assert_eq!(c, 300);
assert_eq!(HITS.fetch_add(1, SeqCst), 3); assert_eq!(d, 400.0);
}) assert_eq!(e, 500.0);
assert_eq!(
f.as_ref().unwrap().data().downcast_ref::<String>().unwrap(),
"hello"
);
assert_eq!(g.as_ref().unwrap().call(&[]).unwrap()[0].unwrap_i32(), 42);
assert_eq!(HITS.fetch_add(1, SeqCst), 3);
},
)
.into(), .into(),
], ],
)?; )?;
let run = instance.get_func("run").unwrap();
run.call(&[
Val::ExternRef(Some(ExternRef::new("hello".to_string()))),
Val::FuncRef(Some(Func::wrap(&store, || -> i32 { 42 }))),
])?;
assert_eq!(HITS.load(SeqCst), 4);
Ok(()) Ok(())
} }
@@ -228,6 +258,10 @@ fn get_from_wrapper() {
assert!(f.get0::<f32>().is_ok()); assert!(f.get0::<f32>().is_ok());
let f = Func::wrap(&store, || -> f64 { loop {} }); let f = Func::wrap(&store, || -> f64 { loop {} });
assert!(f.get0::<f64>().is_ok()); assert!(f.get0::<f64>().is_ok());
let f = Func::wrap(&store, || -> Option<ExternRef> { loop {} });
assert!(f.get0::<Option<ExternRef>>().is_ok());
let f = Func::wrap(&store, || -> Option<Func> { loop {} });
assert!(f.get0::<Option<Func>>().is_ok());
let f = Func::wrap(&store, |_: i32| {}); let f = Func::wrap(&store, |_: i32| {});
assert!(f.get1::<i32, ()>().is_ok()); assert!(f.get1::<i32, ()>().is_ok());
@@ -240,6 +274,10 @@ fn get_from_wrapper() {
assert!(f.get1::<f32, ()>().is_ok()); assert!(f.get1::<f32, ()>().is_ok());
let f = Func::wrap(&store, |_: f64| {}); let f = Func::wrap(&store, |_: f64| {});
assert!(f.get1::<f64, ()>().is_ok()); assert!(f.get1::<f64, ()>().is_ok());
let f = Func::wrap(&store, |_: Option<ExternRef>| {});
assert!(f.get1::<Option<ExternRef>, ()>().is_ok());
let f = Func::wrap(&store, |_: Option<Func>| {});
assert!(f.get1::<Option<Func>, ()>().is_ok());
} }
#[test] #[test]