Skip to content

Commit 617be01

Browse files
eira-franshampepyakin
authored andcommitted
Check type when resuming function (#152)
* Check type when resuming function * Remove pub(crate) * Update lib.rs
1 parent 899cc32 commit 617be01

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed

src/func.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -293,16 +293,23 @@ impl<'args> FuncInvocation<'args> {
293293
return_val: Option<RuntimeValue>,
294294
externals: &'externals mut E,
295295
) -> Result<Option<RuntimeValue>, ResumableError> {
296-
match self.kind {
297-
FuncInvocationKind::Internal(ref mut interpreter) => {
298-
if !interpreter.state().is_resumable() {
299-
return Err(ResumableError::AlreadyStarted);
296+
use crate::TrapKind;
297+
298+
if return_val.map(|v| v.value_type()) != self.resumable_value_type() {
299+
return Err(ResumableError::Trap(Trap::new(
300+
TrapKind::UnexpectedSignature,
301+
)));
302+
}
303+
304+
match &mut self.kind {
305+
FuncInvocationKind::Internal(interpreter) => {
306+
if interpreter.state().is_resumable() {
307+
Ok(interpreter.resume_execution(return_val, externals)?)
308+
} else {
309+
Err(ResumableError::AlreadyStarted)
300310
}
301-
Ok(interpreter.resume_execution(return_val, externals)?)
302-
}
303-
FuncInvocationKind::Host { .. } => {
304-
return Err(ResumableError::NotResumable);
305311
}
312+
FuncInvocationKind::Host { .. } => Err(ResumableError::NotResumable),
306313
}
307314
}
308315
}

src/tests/host.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,66 @@ fn resume_call_host_func() {
302302
);
303303
}
304304

305+
#[test]
306+
fn resume_call_host_func_type_mismatch() {
307+
fn resume_with_val(val: Option<RuntimeValue>) {
308+
let module = parse_wat(
309+
r#"
310+
(module
311+
(import "env" "trap_sub" (func $trap_sub (param i32 i32) (result i32)))
312+
313+
(func (export "test") (result i32)
314+
(call $trap_sub
315+
(i32.const 5)
316+
(i32.const 7)
317+
)
318+
)
319+
)
320+
"#,
321+
);
322+
323+
let mut env = TestHost::new();
324+
325+
let instance =
326+
ModuleInstance::new(&module, &ImportsBuilder::new().with_resolver("env", &env))
327+
.expect("Failed to instantiate module")
328+
.assert_no_start();
329+
330+
let export = instance.export_by_name("test").unwrap();
331+
let func_instance = export.as_func().unwrap();
332+
333+
let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[]).unwrap();
334+
let result = invocation.start_execution(&mut env);
335+
match result {
336+
Err(ResumableError::Trap(_)) => {}
337+
_ => panic!(),
338+
}
339+
340+
assert!(invocation.is_resumable());
341+
let err = invocation.resume_execution(val, &mut env).unwrap_err();
342+
343+
match &err {
344+
ResumableError::Trap(trap) => {
345+
if let TrapKind::UnexpectedSignature = trap.kind() {
346+
return;
347+
}
348+
}
349+
_ => {}
350+
}
351+
352+
// If didn't return in the previous `match`...
353+
354+
panic!(
355+
"Expected `ResumableError::Trap(Trap {{ kind: \
356+
TrapKind::UnexpectedSignature, }})`, got `{:?}`",
357+
err
358+
)
359+
}
360+
361+
resume_with_val(None);
362+
resume_with_val(Some((-1i64).into()));
363+
}
364+
305365
#[test]
306366
fn host_err() {
307367
let module = parse_wat(

0 commit comments

Comments
 (0)