Files
wasmtime/lib/jit/src/namespace.rs
Dan Gohman 7592c99f3b Refactor the compilation and instantiation pipeline.
wasmtime-execute is now wasmtime-jit. Move `JITCode` and the TargetIsa
into a new `Compiler` type. `InstancePlus` is no more, with trampoline
functionality now handled by `Compiler`.
2019-01-03 11:47:55 -08:00

102 lines
3.2 KiB
Rust

//! The core WebAssembly spec does not specify how imports are to be resolved
//! to exports. This file provides one possible way to manage multiple instances
//! and resolve imports to exports among them.
use action::{get, inspect_memory, invoke};
use action::{ActionError, ActionOutcome, RuntimeValue};
use compiler::Compiler;
use cranelift_entity::PrimaryMap;
use resolver::Resolver;
use std::boxed::Box;
use std::collections::HashMap;
use std::string::String;
use wasmtime_runtime::{Export, Instance};
/// An opaque reference to an `Instance`.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct InstanceIndex(u32);
entity_impl!(InstanceIndex, "instance");
/// A namespace containing instances keyed by name.
///
/// Note that `Namespace` implements the `Resolver` trait, so it can resolve
/// imports using defined exports.
pub struct Namespace {
/// Mapping from identifiers to indices in `self.instances`.
names: HashMap<String, InstanceIndex>,
/// The instances, available by index.
instances: PrimaryMap<InstanceIndex, Box<Instance>>,
}
impl Namespace {
/// Construct a new `Namespace`.
pub fn new() -> Self {
Self {
names: HashMap::new(),
instances: PrimaryMap::new(),
}
}
/// Install a new `Instance` in this `Namespace`, optionally with the
/// given name, and return its index.
pub fn instance(
&mut self,
instance_name: Option<&str>,
instance: Box<Instance>,
) -> InstanceIndex {
let index = self.instances.push(instance);
if let Some(instance_name) = instance_name {
self.names.insert(instance_name.into(), index);
}
index
}
/// Get the instance index registered with the given `instance_name`.
pub fn get_instance_index(&mut self, instance_name: &str) -> Option<&mut InstanceIndex> {
self.names.get_mut(instance_name)
}
/// Register an instance with a given name.
pub fn register(&mut self, name: String, index: InstanceIndex) {
self.names.insert(name, index);
}
/// Invoke an exported function from an instance.
pub fn invoke(
&mut self,
compiler: &mut Compiler,
index: InstanceIndex,
field_name: &str,
args: &[RuntimeValue],
) -> Result<ActionOutcome, ActionError> {
invoke(compiler, &mut self.instances[index], &field_name, &args)
}
/// Get a slice of memory from an instance.
pub fn inspect_memory(
&self,
index: InstanceIndex,
field_name: &str,
start: usize,
len: usize,
) -> Result<&[u8], ActionError> {
inspect_memory(&self.instances[index], &field_name, start, len)
}
/// Get the value of an exported global from an instance.
pub fn get(&self, index: InstanceIndex, field_name: &str) -> Result<RuntimeValue, ActionError> {
get(&self.instances[index], &field_name)
}
}
impl Resolver for Namespace {
fn resolve(&mut self, instance: &str, field: &str) -> Option<Export> {
if let Some(index) = self.names.get(instance) {
self.instances[*index].lookup(field)
} else {
None
}
}
}