Add a concept of "global exports".
This adds a feature which allows one to look up an export by name without knowing what module it's in -- `lookup_global_export` on an `InstanceContents`. The main expected use for this is to support APIs where module A imports a function from module B, and module B needs to access module A's memory. B can't import it from A in the normal way, because that would create a dependency cycle. So for now, allow B to look up A's exported memory dynamically with `lookup_global_export`. In the future, with reference types and possibly host bindings, we'll be able to pass references to memory as arguments, which will obviate the need for this mechanism.
This commit is contained in:
@@ -16,8 +16,8 @@ cranelift-codegen = "0.26.0"
|
||||
cranelift-entity = "0.26.0"
|
||||
cranelift-wasm = "0.26.0"
|
||||
cranelift-frontend = "0.26.0"
|
||||
wasmtime-environ = { path = "../environ" }
|
||||
wasmtime-runtime = { path = "../runtime" }
|
||||
wasmtime-environ = { path = "../environ", default-features = false }
|
||||
wasmtime-runtime = { path = "../runtime", default-features = false }
|
||||
region = "1.0.0"
|
||||
failure = { version = "0.1.3", default-features = false }
|
||||
failure_derive = { version = "0.1.3", default-features = false }
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
//! `CompiledModule` to allow compiling and instantiating to be done as separate
|
||||
//! steps.
|
||||
|
||||
use super::HashMap;
|
||||
use crate::compiler::Compiler;
|
||||
use crate::link::link_module;
|
||||
use crate::resolver::Resolver;
|
||||
use core::cell::RefCell;
|
||||
use cranelift_entity::{BoxedSlice, PrimaryMap};
|
||||
use cranelift_wasm::{DefinedFuncIndex, SignatureIndex};
|
||||
use std::boxed::Box;
|
||||
@@ -16,7 +18,7 @@ use wasmtime_environ::{
|
||||
CompileError, DataInitializer, DataInitializerLocation, Module, ModuleEnvironment,
|
||||
};
|
||||
use wasmtime_runtime::{
|
||||
Imports, Instance, InstantiationError, VMFunctionBody, VMSharedSignatureIndex,
|
||||
Export, Imports, Instance, InstantiationError, VMFunctionBody, VMSharedSignatureIndex,
|
||||
};
|
||||
|
||||
/// An error condition while setting up a wasm instance, be it validation,
|
||||
@@ -112,6 +114,7 @@ pub struct CompiledModule {
|
||||
imports: Imports,
|
||||
data_initializers: Box<[OwnedDataInitializer]>,
|
||||
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
}
|
||||
|
||||
impl CompiledModule {
|
||||
@@ -120,26 +123,28 @@ impl CompiledModule {
|
||||
compiler: &mut Compiler,
|
||||
data: &'data [u8],
|
||||
resolver: &mut dyn Resolver,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
) -> Result<Self, SetupError> {
|
||||
let raw = RawCompiledModule::<'data>::new(compiler, data, resolver)?;
|
||||
|
||||
Ok(Self {
|
||||
module: Rc::new(raw.module),
|
||||
finished_functions: raw.finished_functions,
|
||||
imports: raw.imports,
|
||||
data_initializers: raw
|
||||
.data_initializers
|
||||
Ok(Self::from_parts(
|
||||
raw.module,
|
||||
global_exports,
|
||||
raw.finished_functions,
|
||||
raw.imports,
|
||||
raw.data_initializers
|
||||
.iter()
|
||||
.map(OwnedDataInitializer::new)
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice(),
|
||||
signatures: raw.signatures.clone(),
|
||||
})
|
||||
raw.signatures.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Construct a `CompiledModule` from component parts.
|
||||
pub fn from_parts(
|
||||
module: Module,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
finished_functions: BoxedSlice<DefinedFuncIndex, *const VMFunctionBody>,
|
||||
imports: Imports,
|
||||
data_initializers: Box<[OwnedDataInitializer]>,
|
||||
@@ -147,6 +152,7 @@ impl CompiledModule {
|
||||
) -> Self {
|
||||
Self {
|
||||
module: Rc::new(module),
|
||||
global_exports: Rc::clone(&global_exports),
|
||||
finished_functions,
|
||||
imports,
|
||||
data_initializers,
|
||||
@@ -170,6 +176,7 @@ impl CompiledModule {
|
||||
.collect::<Vec<_>>();
|
||||
Instance::new(
|
||||
Rc::clone(&self.module),
|
||||
Rc::clone(&self.global_exports),
|
||||
self.finished_functions.clone(),
|
||||
self.imports.clone(),
|
||||
&data_initializers,
|
||||
@@ -206,11 +213,13 @@ pub fn instantiate(
|
||||
compiler: &mut Compiler,
|
||||
data: &[u8],
|
||||
resolver: &mut dyn Resolver,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
) -> Result<Instance, SetupError> {
|
||||
let raw = RawCompiledModule::new(compiler, data, resolver)?;
|
||||
|
||||
Instance::new(
|
||||
Rc::new(raw.module),
|
||||
global_exports,
|
||||
raw.finished_functions,
|
||||
raw.imports,
|
||||
&*raw.data_initializers,
|
||||
|
||||
@@ -32,7 +32,7 @@ extern crate alloc as std;
|
||||
extern crate std;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use hashbrown::{map as hash_map, HashMap};
|
||||
use hashbrown::{hash_map, HashMap};
|
||||
#[cfg(feature = "std")]
|
||||
use std::collections::{hash_map, HashMap};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user