diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index edeee6f23c..2e59b39e12 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -127,15 +127,32 @@ impl WrappedCallable for WasmtimeFn { } => (*vmctx, *address, signature.clone()), _ => panic!("unexpected export type in Callable"), }; + if signature.params.len() - 2 != params.len() { + return Err(Trap::new(format!( + "expected {} arguments, got {}", + signature.params.len() - 2, + params.len() + ))); + } + if signature.returns.len() != results.len() { + return Err(Trap::new(format!( + "expected {} results, got {}", + signature.returns.len(), + results.len() + ))); + } let value_size = mem::size_of::(); let mut values_vec = vec![0; max(params.len(), results.len())]; // Store the argument values into `values_vec`. - for (index, arg) in params.iter().enumerate() { + let param_tys = signature.params.iter().skip(2); + for ((arg, slot), ty) in params.iter().zip(&mut values_vec).zip(param_tys) { + if arg.ty().get_wasmtime_type() != Some(ty.value_type) { + return Err(Trap::new("argument type mismatch")); + } unsafe { - let ptr = values_vec.as_mut_ptr().add(index); - arg.write_value_to(ptr); + arg.write_value_to(slot); } } diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs index c5b221ff28..a5dbbadf48 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -308,3 +308,34 @@ fn rust_panic_start_function() -> Result<()> { assert_eq!(err.downcast_ref::<&'static str>(), Some(&"this is a panic")); Ok(()) } + +#[test] +fn mismatched_arguments() -> Result<()> { + let store = Store::default(); + let binary = wat::parse_str( + r#" + (module $a + (func (export "foo") (param i32)) + ) + "#, + )?; + + let module = Module::new(&store, &binary)?; + let instance = Instance::new(&module, &[])?; + let func = instance.exports()[0].func().unwrap().clone(); + assert_eq!( + func.call(&[]).unwrap_err().message(), + "expected 1 arguments, got 0" + ); + assert_eq!( + func.call(&[Val::F32(0)]).unwrap_err().message(), + "argument type mismatch", + ); + assert_eq!( + func.call(&[Val::I32(0), Val::I32(1)]) + .unwrap_err() + .message(), + "expected 1 arguments, got 2" + ); + Ok(()) +}