Browse Source
This PR fixes the borrow scope of store in the `WrappedCallable` impl of `WasmTimeFn` such that it does not remain borrowed across the call to `wasmtime_call_trampoline`. By limiting the scope of the borrow, the implementation can be reentered if an exported function calls an imported function, which in turn calls another exported function. Fixes #365.pull/392/head
Peter Huene
5 years ago
committed by
Dan Gohman
5 changed files with 82 additions and 4 deletions
@ -0,0 +1,69 @@ |
|||
use std::cell::{Ref, RefCell}; |
|||
use std::fs::read; |
|||
use std::rc::Rc; |
|||
use wasmtime_api::*; |
|||
|
|||
#[test] |
|||
fn test_import_calling_export() { |
|||
struct Callback { |
|||
pub other: RefCell<Option<HostRef<Func>>>, |
|||
} |
|||
|
|||
impl Callable for Callback { |
|||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef<Trap>> { |
|||
self.other |
|||
.borrow() |
|||
.as_ref() |
|||
.expect("expected a function ref") |
|||
.borrow() |
|||
.call(&[]) |
|||
.expect("expected function not to trap"); |
|||
Ok(()) |
|||
} |
|||
} |
|||
|
|||
let engine = HostRef::new(Engine::new(Config::default())); |
|||
let store = HostRef::new(Store::new(engine)); |
|||
let module = HostRef::new( |
|||
Module::new( |
|||
store.clone(), |
|||
&read("tests/import_calling_export.wasm").expect("failed to read wasm file"), |
|||
) |
|||
.expect("failed to create module"), |
|||
); |
|||
|
|||
let callback = Rc::new(Callback { |
|||
other: RefCell::new(None), |
|||
}); |
|||
|
|||
let callback_func = HostRef::new(Func::new( |
|||
store.clone(), |
|||
FuncType::new(Box::new([]), Box::new([])), |
|||
callback.clone(), |
|||
)); |
|||
|
|||
let imports = vec![callback_func.into()]; |
|||
let instance = HostRef::new( |
|||
Instance::new(store.clone(), module, imports.as_slice()) |
|||
.expect("failed to instantiate module"), |
|||
); |
|||
|
|||
let exports = Ref::map(instance.borrow(), |instance| instance.exports()); |
|||
assert!(!exports.is_empty()); |
|||
|
|||
let run_func = exports[0] |
|||
.func() |
|||
.expect("expected a run func in the module"); |
|||
|
|||
*callback.other.borrow_mut() = Some( |
|||
exports[1] |
|||
.func() |
|||
.expect("expected an other func in the module") |
|||
.clone(), |
|||
); |
|||
|
|||
run_func |
|||
.borrow() |
|||
.call(&[]) |
|||
.expect("expected function not to trap"); |
|||
} |
Binary file not shown.
@ -0,0 +1,8 @@ |
|||
(module |
|||
(type $t0 (func)) |
|||
(import "" "imp" (func $.imp (type $t0))) |
|||
(func $run call $.imp) |
|||
(func $other) |
|||
(export "run" (func $run)) |
|||
(export "other" (func $other)) |
|||
) |
Loading…
Reference in new issue