Fix borrow scope for store in WrappedCallable impl for WasmtimeFn.
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.
This commit is contained in:
@@ -52,6 +52,7 @@ banner "Rust unit tests"
|
||||
#RUST_BACKTRACE=1 cargo test --all
|
||||
RUST_BACKTRACE=1 cargo test \
|
||||
--package wasmtime \
|
||||
--package wasmtime-api \
|
||||
--package wasmtime-wasi \
|
||||
--package wasmtime-wast \
|
||||
--package wasmtime-debug \
|
||||
|
||||
@@ -56,9 +56,6 @@ impl WrappedCallable for WasmtimeFn {
|
||||
_ => panic!("unexpected export type in Callable"),
|
||||
};
|
||||
|
||||
let mut store = self.store.borrow_mut();
|
||||
|
||||
let context = store.context();
|
||||
let value_size = mem::size_of::<u64>();
|
||||
let mut values_vec: Vec<u64> = vec![0; max(params.len(), results.len())];
|
||||
|
||||
@@ -78,7 +75,10 @@ impl WrappedCallable for WasmtimeFn {
|
||||
}
|
||||
|
||||
// Get the trampoline to call for this function.
|
||||
let exec_code_buf = context
|
||||
let exec_code_buf = self
|
||||
.store
|
||||
.borrow_mut()
|
||||
.context()
|
||||
.compiler()
|
||||
.get_published_trampoline(body, &signature, value_size)
|
||||
.map_err(|_| HostRef::new(Trap::fake()))?; //was ActionError::Setup)?;
|
||||
|
||||
69
wasmtime-api/tests/import_calling_export.rs
Normal file
69
wasmtime-api/tests/import_calling_export.rs
Normal file
@@ -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");
|
||||
}
|
||||
BIN
wasmtime-api/tests/import_calling_export.wasm
Normal file
BIN
wasmtime-api/tests/import_calling_export.wasm
Normal file
Binary file not shown.
8
wasmtime-api/tests/import_calling_export.wat
Normal file
8
wasmtime-api/tests/import_calling_export.wat
Normal file
@@ -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))
|
||||
)
|
||||
Reference in New Issue
Block a user