Skip to content

Commit

Permalink
Check type when resuming function (bytecodealliance#152)
Browse files Browse the repository at this point in the history
* Check type when resuming function

* Remove pub(crate)

* Update lib.rs
  • Loading branch information
eira-fransham authored and pepyakin committed Jan 2, 2019
1 parent 899cc32 commit 617be01
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,16 +293,23 @@ impl<'args> FuncInvocation<'args> {
return_val: Option<RuntimeValue>,
externals: &'externals mut E,
) -> Result<Option<RuntimeValue>, ResumableError> {
match self.kind {
FuncInvocationKind::Internal(ref mut interpreter) => {
if !interpreter.state().is_resumable() {
return Err(ResumableError::AlreadyStarted);
use crate::TrapKind;

if return_val.map(|v| v.value_type()) != self.resumable_value_type() {
return Err(ResumableError::Trap(Trap::new(
TrapKind::UnexpectedSignature,
)));
}

match &mut self.kind {
FuncInvocationKind::Internal(interpreter) => {
if interpreter.state().is_resumable() {
Ok(interpreter.resume_execution(return_val, externals)?)
} else {
Err(ResumableError::AlreadyStarted)
}
Ok(interpreter.resume_execution(return_val, externals)?)
}
FuncInvocationKind::Host { .. } => {
return Err(ResumableError::NotResumable);
}
FuncInvocationKind::Host { .. } => Err(ResumableError::NotResumable),
}
}
}
Expand Down
60 changes: 60 additions & 0 deletions src/tests/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,66 @@ fn resume_call_host_func() {
);
}

#[test]
fn resume_call_host_func_type_mismatch() {
fn resume_with_val(val: Option<RuntimeValue>) {
let module = parse_wat(
r#"
(module
(import "env" "trap_sub" (func $trap_sub (param i32 i32) (result i32)))
(func (export "test") (result i32)
(call $trap_sub
(i32.const 5)
(i32.const 7)
)
)
)
"#,
);

let mut env = TestHost::new();

let instance =
ModuleInstance::new(&module, &ImportsBuilder::new().with_resolver("env", &env))
.expect("Failed to instantiate module")
.assert_no_start();

let export = instance.export_by_name("test").unwrap();
let func_instance = export.as_func().unwrap();

let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[]).unwrap();
let result = invocation.start_execution(&mut env);
match result {
Err(ResumableError::Trap(_)) => {}
_ => panic!(),
}

assert!(invocation.is_resumable());
let err = invocation.resume_execution(val, &mut env).unwrap_err();

match &err {
ResumableError::Trap(trap) => {
if let TrapKind::UnexpectedSignature = trap.kind() {
return;
}
}
_ => {}
}

// If didn't return in the previous `match`...

panic!(
"Expected `ResumableError::Trap(Trap {{ kind: \
TrapKind::UnexpectedSignature, }})`, got `{:?}`",
err
)
}

resume_with_val(None);
resume_with_val(Some((-1i64).into()));
}

#[test]
fn host_err() {
let module = parse_wat(
Expand Down

0 comments on commit 617be01

Please sign in to comment.