Make module info store FuncSig, not Arc<FuncSig>

This commit is contained in:
Lachlan Sneff
2019-02-08 14:19:58 -08:00
parent 1886b3d3c1
commit aa90a33501
9 changed files with 55 additions and 47 deletions

View File

@ -62,10 +62,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
/// Declares a function signature to the environment. /// Declares a function signature to the environment.
fn declare_signature(&mut self, sig: &ir::Signature) { fn declare_signature(&mut self, sig: &ir::Signature) {
self.signatures.push(sig.clone()); self.signatures.push(sig.clone());
self.module self.module.info.signatures.push(Converter(sig).into());
.info
.signatures
.push(Arc::new(Converter(sig).into()));
} }
/// Return the signature with the given index. /// Return the signature with the given index.

View File

@ -201,7 +201,7 @@ impl FuncResolverBuilder {
pub fn finalize( pub fn finalize(
mut self, mut self,
signatures: &SliceMap<SigIndex, Arc<FuncSig>>, signatures: &SliceMap<SigIndex, FuncSig>,
) -> CompileResult<FuncResolver> { ) -> CompileResult<FuncResolver> {
for (index, relocs) in self.external_relocs.iter() { for (index, relocs) in self.external_relocs.iter() {
for ref reloc in relocs.iter() { for ref reloc in relocs.iter() {
@ -263,8 +263,8 @@ impl FuncResolverBuilder {
}, },
}, },
RelocationType::Signature(sig_index) => { RelocationType::Signature(sig_index) => {
let sig_index = let signature = SigRegistry.lookup_signature_ref(&signatures[sig_index]);
SigRegistry.lookup_sig_index(Arc::clone(&signatures[sig_index])); let sig_index = SigRegistry.lookup_sig_index(signature);
sig_index.index() as _ sig_index.index() as _
} }
}; };

View File

@ -137,11 +137,11 @@ impl ProtectedCaller for Caller {
} }
} }
fn get_func_from_index( fn get_func_from_index<'a>(
module: &ModuleInner, module: &'a ModuleInner,
import_backing: &ImportBacking, import_backing: &ImportBacking,
func_index: FuncIndex, func_index: FuncIndex,
) -> (*const vm::Func, Context, Arc<FuncSig>, SigIndex) { ) -> (*const vm::Func, Context, &'a FuncSig, SigIndex) {
let sig_index = *module let sig_index = *module
.info .info
.func_assoc .func_assoc
@ -167,7 +167,7 @@ fn get_func_from_index(
} }
}; };
let signature = Arc::clone(&module.info.signatures[sig_index]); let signature = &module.info.signatures[sig_index];
(func_ptr, ctx, signature, sig_index) (func_ptr, ctx, signature, sig_index)
} }

View File

@ -23,6 +23,7 @@ pub use crate::sig_registry::SigRegistry;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Backend { pub enum Backend {
Cranelift, Cranelift,
LLVM,
} }
/// This type cannot be constructed from /// This type cannot be constructed from

View File

@ -14,7 +14,7 @@ use crate::{
}, },
vm, vm,
}; };
use std::{slice, sync::Arc}; use std::slice;
#[derive(Debug)] #[derive(Debug)]
pub struct LocalBacking { pub struct LocalBacking {
@ -172,10 +172,11 @@ impl LocalBacking {
table.anyfunc_direct_access_mut(|elements| { table.anyfunc_direct_access_mut(|elements| {
for (i, &func_index) in init.elements.iter().enumerate() { for (i, &func_index) in init.elements.iter().enumerate() {
let sig_index = module.info.func_assoc[func_index]; let sig_index = module.info.func_assoc[func_index];
let signature = &module.info.signatures[sig_index]; // let signature = &module.info.signatures[sig_index];
let sig_id = vm::SigId( let signature = SigRegistry
SigRegistry.lookup_sig_index(Arc::clone(&signature)).index() as u32, .lookup_signature_ref(&module.info.signatures[sig_index]);
); let sig_id =
vm::SigId(SigRegistry.lookup_sig_index(signature).index() as u32);
let (func, ctx) = match func_index.local_or_import(module) { let (func, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => ( LocalOrImport::Local(local_func_index) => (
@ -210,10 +211,11 @@ impl LocalBacking {
table.anyfunc_direct_access_mut(|elements| { table.anyfunc_direct_access_mut(|elements| {
for (i, &func_index) in init.elements.iter().enumerate() { for (i, &func_index) in init.elements.iter().enumerate() {
let sig_index = module.info.func_assoc[func_index]; let sig_index = module.info.func_assoc[func_index];
let signature = &module.info.signatures[sig_index]; let signature = SigRegistry
let sig_id = vm::SigId( .lookup_signature_ref(&module.info.signatures[sig_index]);
SigRegistry.lookup_sig_index(Arc::clone(&signature)).index() as u32, // let signature = &module.info.signatures[sig_index];
); let sig_id =
vm::SigId(SigRegistry.lookup_sig_index(signature).index() as u32);
let (func, ctx) = match func_index.local_or_import(module) { let (func, ctx) = match func_index.local_or_import(module) {
LocalOrImport::Local(local_func_index) => ( LocalOrImport::Local(local_func_index) => (
@ -379,7 +381,7 @@ fn import_functions(
ctx, ctx,
signature, signature,
}) => { }) => {
if *expected_sig == signature { if *expected_sig == *signature {
functions.push(vm::ImportedFunc { functions.push(vm::ImportedFunc {
func: func.inner(), func: func.inner(),
vmctx: match ctx { vmctx: match ctx {
@ -391,8 +393,8 @@ fn import_functions(
link_errors.push(LinkError::IncorrectImportSignature { link_errors.push(LinkError::IncorrectImportSignature {
namespace: namespace.to_string(), namespace: namespace.to_string(),
name: name.to_string(), name: name.to_string(),
expected: expected_sig.clone(), expected: (*expected_sig).clone(),
found: signature.clone(), found: (*signature).clone(),
}); });
} }
} }

View File

@ -1,7 +1,6 @@
use crate::types::{ use crate::types::{
FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type, FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type,
}; };
use std::sync::Arc;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
pub type CompileResult<T> = std::result::Result<T, CompileError>; pub type CompileResult<T> = std::result::Result<T, CompileError>;
@ -42,8 +41,8 @@ pub enum LinkError {
IncorrectImportSignature { IncorrectImportSignature {
namespace: String, namespace: String,
name: String, name: String,
expected: Arc<FuncSig>, expected: FuncSig,
found: Arc<FuncSig>, found: FuncSig,
}, },
ImportNotFound { ImportNotFound {
namespace: String, namespace: String,
@ -117,16 +116,9 @@ impl PartialEq for RuntimeError {
/// Comparing two `ResolveError`s always evaluates to false. /// Comparing two `ResolveError`s always evaluates to false.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ResolveError { pub enum ResolveError {
Signature { Signature { expected: FuncSig, found: Vec<Type> },
expected: Arc<FuncSig>, ExportNotFound { name: String },
found: Vec<Type>, ExportWrongType { name: String },
},
ExportNotFound {
name: String,
},
ExportWrongType {
name: String,
},
} }
impl PartialEq for ResolveError { impl PartialEq for ResolveError {

View File

@ -7,6 +7,7 @@ use crate::{
import::{ImportObject, LikeNamespace}, import::{ImportObject, LikeNamespace},
memory::Memory, memory::Memory,
module::{ExportIndex, Module, ModuleInner}, module::{ExportIndex, Module, ModuleInner},
sig_registry::SigRegistry,
table::Table, table::Table,
typed_func::{Func, Safe, WasmTypeList}, typed_func::{Func, Safe, WasmTypeList},
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value}, types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
@ -112,11 +113,12 @@ impl Instance {
.func_assoc .func_assoc
.get(*func_index) .get(*func_index)
.expect("broken invariant, incorrect func index"); .expect("broken invariant, incorrect func index");
let signature = &self.module.info.signatures[sig_index]; let signature =
SigRegistry.lookup_signature_ref(&self.module.info.signatures[sig_index]);
if signature.params() != Args::types() || signature.returns() != Rets::types() { if signature.params() != Args::types() || signature.returns() != Rets::types() {
Err(ResolveError::Signature { Err(ResolveError::Signature {
expected: Arc::clone(&signature), expected: (*signature).clone(),
found: Args::types().to_vec(), found: Args::types().to_vec(),
})?; })?;
} }
@ -183,7 +185,8 @@ impl Instance {
.func_assoc .func_assoc
.get(*func_index) .get(*func_index)
.expect("broken invariant, incorrect func index"); .expect("broken invariant, incorrect func index");
let signature = Arc::clone(&self.module.info.signatures[sig_index]); let signature =
SigRegistry.lookup_signature_ref(&self.module.info.signatures[sig_index]);
Ok(DynFunc { Ok(DynFunc {
signature, signature,
@ -374,13 +377,10 @@ impl InstanceInner {
} }
}; };
let signature = &module.info.signatures[sig_index]; let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]);
// let signature = &module.info.signatures[sig_index];
( (unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
unsafe { FuncPointer::new(func_ptr) },
ctx,
Arc::clone(signature),
)
} }
fn get_memory_from_index(&self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory { fn get_memory_from_index(&self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory {
@ -457,7 +457,7 @@ impl<'a> DynFunc<'a> {
pub fn call(&mut self, params: &[Value]) -> CallResult<Vec<Value>> { pub fn call(&mut self, params: &[Value]) -> CallResult<Vec<Value>> {
if !self.signature.check_param_value_types(params) { if !self.signature.check_param_value_types(params) {
Err(ResolveError::Signature { Err(ResolveError::Signature {
expected: self.signature.clone(), expected: (*self.signature).clone(),
found: params.iter().map(|val| val.ty()).collect(), found: params.iter().map(|val| val.ty()).collect(),
})? })?
} }

View File

@ -46,7 +46,7 @@ pub struct ModuleInfo {
pub start_func: Option<FuncIndex>, pub start_func: Option<FuncIndex>,
pub func_assoc: Map<FuncIndex, SigIndex>, pub func_assoc: Map<FuncIndex, SigIndex>,
pub signatures: Map<SigIndex, Arc<FuncSig>>, pub signatures: Map<SigIndex, FuncSig>,
pub backend: Backend, pub backend: Backend,
pub namespace_table: StringTable<NamespaceIndex>, pub namespace_table: StringTable<NamespaceIndex>,

View File

@ -49,4 +49,20 @@ impl SigRegistry {
let global = (*GLOBAL_SIG_REGISTRY).read(); let global = (*GLOBAL_SIG_REGISTRY).read();
Arc::clone(&global.sig_assoc[sig_index]) Arc::clone(&global.sig_assoc[sig_index])
} }
pub fn lookup_signature_ref(&self, func_sig: &FuncSig) -> Arc<FuncSig> {
let mut global = (*GLOBAL_SIG_REGISTRY).write();
let global = &mut *global;
let func_table = &mut global.func_table;
let sig_assoc = &mut global.sig_assoc;
if func_table.contains_key(func_sig) {
Arc::clone(&sig_assoc[func_table[func_sig]])
} else {
let arc = Arc::new(func_sig.clone());
func_table.insert(Arc::clone(&arc), sig_assoc.push(Arc::clone(&arc)));
arc
}
}
} }