From 1482648219ab1cd6a0f8e9ce1e1657effa3d8cd3 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Mon, 15 Oct 2018 13:45:44 +0200 Subject: [PATCH] Added module.info.exports for O(1) retrieval --- src/webassembly/instance.rs | 10 +++++--- src/webassembly/mod.rs | 2 +- src/webassembly/module.rs | 47 +++++++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index a1e89ea8f..0e60d1da1 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -97,8 +97,12 @@ impl Instance { // Compile the functions (from cranelift IR to machine code) for function_body in module.info.function_bodies.values() { let mut func_context = Context::for_function(function_body.to_owned()); - func_context.verify(&*isa).map_err(|e| ErrorKind::CompileError(e.to_string()))?; - func_context.verify_locations(&*isa).map_err(|e| ErrorKind::CompileError(e.to_string()))?; + func_context + .verify(&*isa) + .map_err(|e| ErrorKind::CompileError(e.to_string()))?; + func_context + .verify_locations(&*isa) + .map_err(|e| ErrorKind::CompileError(e.to_string()))?; let code_size_offset = func_context .compile(&*isa) .map_err(|e| ErrorKind::CompileError(e.to_string()))? @@ -223,7 +227,7 @@ impl Instance { pub fn memories(&self) -> Arc> { self.memories.clone() } - + /// Invoke a WebAssembly function given a FuncIndex and the /// arguments that the function should be called with pub fn invoke(&self, func_index: FuncIndex, args: Vec) { diff --git a/src/webassembly/mod.rs b/src/webassembly/mod.rs index 14dd6f4e1..3924b299d 100644 --- a/src/webassembly/mod.rs +++ b/src/webassembly/mod.rs @@ -16,7 +16,7 @@ use wasmparser; pub use self::errors::{Error, ErrorKind}; pub use self::instance::Instance; pub use self::memory::LinearMemory; -pub use self::module::Module; +pub use self::module::{Export, Module, ModuleInfo}; pub struct ResultObject { /// A webassembly::Module object representing the compiled WebAssembly module. diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index fa4d2fcb0..8182353a5 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -1,5 +1,9 @@ //! "" implementations of `ModuleEnvironment` and `FuncEnvironment` for testing //! wasm translation. +use std::collections::HashMap; +use std::string::String; +use std::vec::Vec; +use target_lexicon::{PointerWidth, Triple}; use cranelift_codegen::cursor::FuncCursor; use cranelift_codegen::ir::immediates::{Imm64, Offset32}; @@ -12,8 +16,6 @@ use cranelift_codegen::print_errors::pretty_verifier_error; use cranelift_codegen::{isa, settings, verifier}; use cranelift_entity::{EntityRef, PrimaryMap}; -use super::errors::ErrorKind; -use super::memory::LinearMemory; use cranelift_wasm::{ translate_module, // ReturnMode, DefinedFuncIndex, @@ -31,9 +33,9 @@ use cranelift_wasm::{ TableIndex, WasmResult, }; -use std::string::String; -use std::vec::Vec; -use target_lexicon::{PointerWidth, Triple}; + +use super::errors::ErrorKind; +use super::memory::LinearMemory; /// Compute a `ir::ExternalName` for a given wasm function index. fn get_func_name(func_index: FuncIndex) -> ir::ExternalName { @@ -58,6 +60,19 @@ impl Exportable { } } +/// An entity to export. +#[derive(Clone, Debug)] +pub enum Export { + /// Function export. + Function(FuncIndex), + /// Table export. + Table(TableIndex), + /// Memory export. + Memory(MemoryIndex), + /// Global export. + Global(GlobalIndex), +} + /// The main state belonging to a `Module`. This is split out from /// `Module` to allow it to be borrowed separately from the /// `FuncTranslator` field. @@ -107,6 +122,11 @@ pub struct ModuleInfo { /// The data initializers pub data_initializers: Vec, + + /// Exported entities + /// We use this in order to have a O(1) allocation of the exports + /// rather than iterating through the Exportable elements. + pub exports: HashMap, } impl ModuleInfo { @@ -129,6 +149,7 @@ impl ModuleInfo { data_initializers: Vec::new(), main_memory_base: None, memory_base: None, + exports: HashMap::new(), } } } @@ -668,24 +689,40 @@ impl<'data> ModuleEnvironment<'data> for Module { self.info.functions[func_index] .export_names .push(String::from(name)); + // We add to the exports to have O(1) retrieval + self.info + .exports + .insert(name.to_string(), Export::Function(func_index)); } fn declare_table_export(&mut self, table_index: TableIndex, name: &'data str) { self.info.tables[table_index] .export_names .push(String::from(name)); + // We add to the exports to have O(1) retrieval + self.info + .exports + .insert(name.to_string(), Export::Table(table_index)); } fn declare_memory_export(&mut self, memory_index: MemoryIndex, name: &'data str) { self.info.memories[memory_index] .export_names .push(String::from(name)); + // We add to the exports to have O(1) retrieval + self.info + .exports + .insert(name.to_string(), Export::Memory(memory_index)); } fn declare_global_export(&mut self, global_index: GlobalIndex, name: &'data str) { self.info.globals[global_index] .export_names .push(String::from(name)); + // We add to the exports to have O(1) retrieval + self.info + .exports + .insert(name.to_string(), Export::Global(global_index)); } fn declare_start_func(&mut self, func_index: FuncIndex) {