Don't require Store in Instance constructor (#810)
* Don't require `Store` in `Instance` constructor This can be inferred from the `Module` argument. Additionally add a `store` accessor to an `Instance` in case it's needed to instantiate another `Module`. cc #708 * Update more constructors * Fix a doctest * Don't ignore store in `wasm_instance_new` * Run rustfmt
This commit is contained in:
@@ -50,7 +50,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
.0;
|
.0;
|
||||||
|
|
||||||
// Instantiate the module.
|
// Instantiate the module.
|
||||||
let instance = Instance::new(&store, &module, &[])?;
|
let instance = Instance::new(&module, &[])?;
|
||||||
|
|
||||||
// Invoke `gcd` export
|
// Invoke `gcd` export
|
||||||
let gcd = instance.exports()[gcd_index].func().expect("gcd");
|
let gcd = instance.exports()[gcd_index].func().expect("gcd");
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ fn main() -> Result<()> {
|
|||||||
// Note that this is where the wasm `start` function, if any, would run.
|
// Note that this is where the wasm `start` function, if any, would run.
|
||||||
println!("Instantiating module...");
|
println!("Instantiating module...");
|
||||||
let imports = vec![hello_func.into()];
|
let imports = vec![hello_func.into()];
|
||||||
let instance =
|
let instance = Instance::new(&module, &imports).context("> Error instantiating module!")?;
|
||||||
Instance::new(&store, &module, &imports).context("> Error instantiating module!")?;
|
|
||||||
|
|
||||||
// Next we poke around a bit to extract the `run` function from the module.
|
// Next we poke around a bit to extract the `run` function from the module.
|
||||||
println!("Extracting export...");
|
println!("Extracting export...");
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ fn main() -> Result<(), Error> {
|
|||||||
|
|
||||||
// Instantiate.
|
// Instantiate.
|
||||||
println!("Instantiating module...");
|
println!("Instantiating module...");
|
||||||
let instance = Instance::new(&store, &module, &[]).context("> Error instantiating module!")?;
|
let instance = Instance::new(&module, &[]).context("> Error instantiating module!")?;
|
||||||
|
|
||||||
// Extract export.
|
// Extract export.
|
||||||
println!("Extracting export...");
|
println!("Extracting export...");
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ fn main() -> Result<()> {
|
|||||||
// Instantiate.
|
// Instantiate.
|
||||||
println!("Instantiating module...");
|
println!("Instantiating module...");
|
||||||
let imports = vec![callback_func.into()];
|
let imports = vec![callback_func.into()];
|
||||||
let instance = Instance::new(&store, &module, imports.as_slice())
|
let instance =
|
||||||
.context("Error instantiating module!")?;
|
Instance::new(&module, imports.as_slice()).context("Error instantiating module!")?;
|
||||||
|
|
||||||
// Extract exports.
|
// Extract exports.
|
||||||
println!("Extracting export...");
|
println!("Extracting export...");
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ use wasmtime_runtime::Export;
|
|||||||
///
|
///
|
||||||
/// // Create module instance that imports our function
|
/// // Create module instance that imports our function
|
||||||
/// let instance = wasmtime::Instance::new(
|
/// let instance = wasmtime::Instance::new(
|
||||||
/// &store,
|
|
||||||
/// &module,
|
/// &module,
|
||||||
/// &[times_two_function.into()]
|
/// &[times_two_function.into()]
|
||||||
/// )?;
|
/// )?;
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ pub struct Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
pub fn new(store: &Store, module: &Module, externs: &[Extern]) -> Result<Instance, Error> {
|
pub fn new(module: &Module, externs: &[Extern]) -> Result<Instance, Error> {
|
||||||
|
let store = module.store();
|
||||||
let context = store.context().clone();
|
let context = store.context().clone();
|
||||||
let exports = store.global_exports().clone();
|
let exports = store.global_exports().clone();
|
||||||
let (mut instance_handle, contexts) = instantiate_in_context(
|
let (mut instance_handle, contexts) = instantiate_in_context(
|
||||||
@@ -100,14 +101,27 @@ impl Instance {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exports(&self) -> &[Extern] {
|
/// Returns the associated [`Store`] that this `Instance` is compiled into.
|
||||||
&self.exports
|
///
|
||||||
|
/// This is the [`Store`] that generally serves as a sort of global cache
|
||||||
|
/// for various instance-related things.
|
||||||
|
pub fn store(&self) -> &Store {
|
||||||
|
self.module.store()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the associated [`Module`] that this `Instance` instantiated.
|
||||||
|
///
|
||||||
|
/// The corresponding [`Module`] here is a static version of this `Instance`
|
||||||
|
/// which can be used to learn information such as naming information about
|
||||||
|
/// various functions.
|
||||||
pub fn module(&self) -> &Module {
|
pub fn module(&self) -> &Module {
|
||||||
&self.module
|
&self.module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn exports(&self) -> &[Extern] {
|
||||||
|
&self.exports
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_export_by_name(&self, name: &str) -> Option<&Extern> {
|
pub fn find_export_by_name(&self, name: &str) -> Option<&Extern> {
|
||||||
let (i, _) = self
|
let (i, _) = self
|
||||||
.module
|
.module
|
||||||
|
|||||||
@@ -397,6 +397,10 @@ impl Store {
|
|||||||
.get(&type_index)
|
.get(&type_index)
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ptr_eq(a: &Store, b: &Store) -> bool {
|
||||||
|
Rc::ptr_eq(&a.inner, &b.inner)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Store {
|
impl Default for Store {
|
||||||
|
|||||||
@@ -686,7 +686,6 @@ pub unsafe extern "C" fn wasm_instance_new(
|
|||||||
imports: *const *const wasm_extern_t,
|
imports: *const *const wasm_extern_t,
|
||||||
result: *mut *mut wasm_trap_t,
|
result: *mut *mut wasm_trap_t,
|
||||||
) -> *mut wasm_instance_t {
|
) -> *mut wasm_instance_t {
|
||||||
let store = &(*store).store.borrow();
|
|
||||||
let mut externs: Vec<Extern> = Vec::with_capacity((*module).imports.len());
|
let mut externs: Vec<Extern> = Vec::with_capacity((*module).imports.len());
|
||||||
for i in 0..(*module).imports.len() {
|
for i in 0..(*module).imports.len() {
|
||||||
let import = *imports.add(i);
|
let import = *imports.add(i);
|
||||||
@@ -697,8 +696,21 @@ pub unsafe extern "C" fn wasm_instance_new(
|
|||||||
ExternHost::Memory(e) => Extern::Memory(e.borrow().clone()),
|
ExternHost::Memory(e) => Extern::Memory(e.borrow().clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let store = &(*store).store.borrow();
|
||||||
let module = &(*module).module.borrow();
|
let module = &(*module).module.borrow();
|
||||||
match Instance::new(store, module, &externs) {
|
// FIXME(WebAssembly/wasm-c-api#126) what else can we do with the `store`
|
||||||
|
// argument?
|
||||||
|
if !Store::ptr_eq(&store, module.store()) {
|
||||||
|
if !result.is_null() {
|
||||||
|
let trap = Trap::new("wasm_store_t must match store in wasm_module_t");
|
||||||
|
let trap = Box::new(wasm_trap_t {
|
||||||
|
trap: HostRef::new(trap),
|
||||||
|
});
|
||||||
|
(*result) = Box::into_raw(trap);
|
||||||
|
}
|
||||||
|
return ptr::null_mut();
|
||||||
|
}
|
||||||
|
match Instance::new(module, &externs) {
|
||||||
Ok(instance) => {
|
Ok(instance) => {
|
||||||
let instance = Box::new(wasm_instance_t {
|
let instance = Box::new(wasm_instance_t {
|
||||||
instance: HostRef::new(instance),
|
instance: HostRef::new(instance),
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> {
|
|||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
];
|
];
|
||||||
let instance = Instance::new(&store, &module, &imports)?;
|
let instance = Instance::new(&module, &imports)?;
|
||||||
|
|
||||||
let func = instance.find_export_by_name("foo").unwrap().func().unwrap();
|
let func = instance.find_export_by_name("foo").unwrap().func().unwrap();
|
||||||
let results = func.call(&[])?;
|
let results = func.call(&[])?;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ fn test_import_calling_export() {
|
|||||||
|
|
||||||
let imports = vec![callback_func.into()];
|
let imports = vec![callback_func.into()];
|
||||||
let instance =
|
let instance =
|
||||||
Instance::new(&store, &module, imports.as_slice()).expect("failed to instantiate module");
|
Instance::new(&module, imports.as_slice()).expect("failed to instantiate module");
|
||||||
|
|
||||||
let exports = instance.exports();
|
let exports = instance.exports();
|
||||||
assert!(!exports.is_empty());
|
assert!(!exports.is_empty());
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ fn test_trap_return() -> Result<(), String> {
|
|||||||
let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback));
|
let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback));
|
||||||
|
|
||||||
let imports = vec![hello_func.into()];
|
let imports = vec![hello_func.into()];
|
||||||
let instance = Instance::new(&store, &module, &imports)
|
let instance = Instance::new(&module, &imports)
|
||||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||||
let run_func = instance.exports()[0]
|
let run_func = instance.exports()[0]
|
||||||
.func()
|
.func()
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ pub fn instantiate(wasm: &[u8], strategy: Strategy) {
|
|||||||
// aren't caught during validation or compilation. For example, an imported
|
// aren't caught during validation or compilation. For example, an imported
|
||||||
// table might not have room for an element segment that we want to
|
// table might not have room for an element segment that we want to
|
||||||
// initialize into it.
|
// initialize into it.
|
||||||
let _result = Instance::new(&store, &module, &imports);
|
let _result = Instance::new(&module, &imports);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the Wasm buffer, and implicitly fail if we have an unexpected
|
/// Compile the Wasm buffer, and implicitly fail if we have an unexpected
|
||||||
@@ -152,7 +152,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
|
|||||||
// aren't caught during validation or compilation. For example, an imported
|
// aren't caught during validation or compilation. For example, an imported
|
||||||
// table might not have room for an element segment that we want to
|
// table might not have room for an element segment that we want to
|
||||||
// initialize into it.
|
// initialize into it.
|
||||||
if let Ok(instance) = Instance::new(store.as_ref().unwrap(), &module, &imports) {
|
if let Ok(instance) = Instance::new(&module, &imports) {
|
||||||
instances.insert(id, instance);
|
instances.insert(id, instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ pub fn instantiate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance = wasmtime::Instance::new(&store, &module, &imports)
|
let instance = wasmtime::Instance::new(&module, &imports)
|
||||||
.map_err(|t| PyErr::new::<Exception, _>(format!("instantiated with trap {:?}", t)))?;
|
.map_err(|t| PyErr::new::<Exception, _>(format!("instantiated with trap {:?}", t)))?;
|
||||||
|
|
||||||
let module = Py::new(py, Module { module })?;
|
let module = Py::new(py, Module { module })?;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let instance =
|
let instance =
|
||||||
Instance::new(&store, &module, &imports).map_err(|t| format_err!("instantiation trap: {:?}", t))?;
|
Instance::new(&module, &imports).map_err(|t| format_err!("instantiation trap: {:?}", t))?;
|
||||||
|
|
||||||
Ok(#name { instance, data })
|
Ok(#name { instance, data })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
let instance = Instance::new(&store, &module, &imports).context(format!(
|
let instance = Instance::new(&module, &imports).context(format!(
|
||||||
"error while instantiating Wasm module '{}'",
|
"error while instantiating Wasm module '{}'",
|
||||||
bin_name,
|
bin_name,
|
||||||
))?;
|
))?;
|
||||||
|
|||||||
2
crates/test-programs/wasi-tests/Cargo.lock
generated
2
crates/test-programs/wasi-tests/Cargo.lock
generated
@@ -17,7 +17,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi-tests"
|
name = "wasi-tests"
|
||||||
version = "0.7.0"
|
version = "0.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ impl WastContext {
|
|||||||
.clone();
|
.clone();
|
||||||
imports.push(export);
|
imports.push(export);
|
||||||
}
|
}
|
||||||
let instance = match Instance::new(&self.store, &module, &imports) {
|
let instance = match Instance::new(&module, &imports) {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(e) => return e.downcast::<Trap>().map(Outcome::Trap),
|
Err(e) => return e.downcast::<Trap>().map(Outcome::Trap),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ impl RunCommand {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
let instance = Instance::new(store, &module, &imports)
|
let instance = Instance::new(&module, &imports)
|
||||||
.context(format!("failed to instantiate {:?}", path))?;
|
.context(format!("failed to instantiate {:?}", path))?;
|
||||||
|
|
||||||
Ok((instance, module, data))
|
Ok((instance, module, data))
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ mod tests {
|
|||||||
let store = Store::new(&engine);
|
let store = Store::new(&engine);
|
||||||
let data = wat::parse_str(WAT1)?;
|
let data = wat::parse_str(WAT1)?;
|
||||||
let module = Module::new(&store, &data)?;
|
let module = Module::new(&store, &data)?;
|
||||||
let instance = Instance::new(&store, &module, &[])?;
|
let instance = Instance::new(&module, &[])?;
|
||||||
|
|
||||||
let (base, length) = set_up_memory(&instance);
|
let (base, length) = set_up_memory(&instance);
|
||||||
instance.set_signal_handler(move |signum, siginfo, _| {
|
instance.set_signal_handler(move |signum, siginfo, _| {
|
||||||
@@ -165,7 +165,7 @@ mod tests {
|
|||||||
|
|
||||||
// Set up multiple instances
|
// Set up multiple instances
|
||||||
|
|
||||||
let instance1 = Instance::new(&store, &module, &[])?;
|
let instance1 = Instance::new(&module, &[])?;
|
||||||
let instance1_handler_triggered = Rc::new(AtomicBool::new(false));
|
let instance1_handler_triggered = Rc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -192,7 +192,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance2 = Instance::new(&store, &module, &[]).expect("failed to instantiate module");
|
let instance2 = Instance::new(&module, &[]).expect("failed to instantiate module");
|
||||||
let instance2_handler_triggered = Rc::new(AtomicBool::new(false));
|
let instance2_handler_triggered = Rc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -261,7 +261,7 @@ mod tests {
|
|||||||
// instance1 which defines 'read'
|
// instance1 which defines 'read'
|
||||||
let data1 = wat::parse_str(WAT1)?;
|
let data1 = wat::parse_str(WAT1)?;
|
||||||
let module1 = Module::new(&store, &data1)?;
|
let module1 = Module::new(&store, &data1)?;
|
||||||
let instance1 = Instance::new(&store, &module1, &[])?;
|
let instance1 = Instance::new(&module1, &[])?;
|
||||||
let (base1, length1) = set_up_memory(&instance1);
|
let (base1, length1) = set_up_memory(&instance1);
|
||||||
instance1.set_signal_handler(move |signum, siginfo, _| {
|
instance1.set_signal_handler(move |signum, siginfo, _| {
|
||||||
println!("instance1");
|
println!("instance1");
|
||||||
@@ -275,7 +275,7 @@ mod tests {
|
|||||||
// instance2 wich calls 'instance1.read'
|
// instance2 wich calls 'instance1.read'
|
||||||
let data2 = wat::parse_str(WAT2)?;
|
let data2 = wat::parse_str(WAT2)?;
|
||||||
let module2 = Module::new(&store, &data2)?;
|
let module2 = Module::new(&store, &data2)?;
|
||||||
let instance2 = Instance::new(&store, &module2, &[instance1_read])?;
|
let instance2 = Instance::new(&module2, &[instance1_read])?;
|
||||||
// since 'instance2.run' calls 'instance1.read' we need to set up the signal handler to handle
|
// since 'instance2.run' calls 'instance1.read' we need to set up the signal handler to handle
|
||||||
// SIGSEGV originating from within the memory of instance1
|
// SIGSEGV originating from within the memory of instance1
|
||||||
instance2.set_signal_handler(move |signum, siginfo, _| {
|
instance2.set_signal_handler(move |signum, siginfo, _| {
|
||||||
|
|||||||
Reference in New Issue
Block a user