Collect all linking errors

This commit is contained in:
Lachlan Sneff
2019-01-18 13:44:44 -08:00
parent 019f02e481
commit 4f8e567d91
2 changed files with 105 additions and 47 deletions

View File

@ -307,13 +307,39 @@ impl ImportBacking {
imports: &mut Imports, imports: &mut Imports,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<Self> { ) -> LinkResult<Self> {
let mut link_errors = vec![];
let functions = import_functions(module, imports, vmctx).unwrap_or_else(|le| {
link_errors.extend(le);
Map::new().into_boxed_map()
});
let memories = import_memories(module, imports, vmctx).unwrap_or_else(|le| {
link_errors.extend(le);
Map::new().into_boxed_map()
});
let tables = import_tables(module, imports, vmctx).unwrap_or_else(|le| {
link_errors.extend(le);
Map::new().into_boxed_map()
});
let globals = import_globals(module, imports).unwrap_or_else(|le| {
link_errors.extend(le);
Map::new().into_boxed_map()
});
if link_errors.len() > 0 {
Err(link_errors)
} else {
Ok(ImportBacking { Ok(ImportBacking {
functions: import_functions(module, imports, vmctx)?, functions,
memories: import_memories(module, imports, vmctx)?, memories,
tables: import_tables(module, imports, vmctx)?, tables,
globals: import_globals(module, imports)?, globals,
}) })
} }
}
pub fn imported_memory(&self, memory_index: ImportedMemoryIndex) -> vm::ImportedMemory { pub fn imported_memory(&self, memory_index: ImportedMemoryIndex) -> vm::ImportedMemory {
self.memories[memory_index].clone() self.memories[memory_index].clone()
@ -325,6 +351,7 @@ fn import_functions(
imports: &mut Imports, imports: &mut Imports,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedFuncIndex, vm::ImportedFunc>> { ) -> LinkResult<BoxedMap<ImportedFuncIndex, vm::ImportedFunc>> {
let mut link_errors = vec![];
let mut functions = Map::with_capacity(module.imported_functions.len()); let mut functions = Map::with_capacity(module.imported_functions.len());
for (index, ImportName { namespace, name }) in &module.imported_functions { for (index, ImportName { namespace, name }) in &module.imported_functions {
let sig_index = module.func_assoc[index.convert_up(module)]; let sig_index = module.func_assoc[index.convert_up(module)];
@ -347,12 +374,12 @@ fn import_functions(
}, },
}); });
} else { } else {
Err(LinkError::IncorrectImportSignature { link_errors.push(LinkError::IncorrectImportSignature {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: expected_sig.clone(), expected: expected_sig.clone(),
found: signature.clone(), found: signature.clone(),
})? });
} }
} }
Some(export_type) => { Some(export_type) => {
@ -363,27 +390,35 @@ fn import_functions(
Export::Global { .. } => "global", Export::Global { .. } => "global",
} }
.to_string(); .to_string();
Err(LinkError::IncorrectImportType { link_errors.push(LinkError::IncorrectImportType {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: "function".to_string(), expected: "function".to_string(),
found: export_type_name, found: export_type_name,
})? });
} }
None => Err(LinkError::ImportNotFound { None => {
link_errors.push(LinkError::ImportNotFound {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
})?, });
} }
} }
}
if link_errors.len() > 0 {
Err(link_errors)
} else {
Ok(functions.into_boxed_map()) Ok(functions.into_boxed_map())
} }
}
fn import_memories( fn import_memories(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut Imports,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>> { ) -> LinkResult<BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>> {
let mut link_errors = vec![];
let mut memories = Map::with_capacity(module.imported_memories.len()); let mut memories = Map::with_capacity(module.imported_memories.len());
for (_index, (ImportName { namespace, name }, expected_memory_desc)) in for (_index, (ImportName { namespace, name }, expected_memory_desc)) in
&module.imported_memories &module.imported_memories
@ -406,12 +441,12 @@ fn import_memories(
}, },
}); });
} else { } else {
Err(LinkError::IncorrectMemoryDescription { link_errors.push(LinkError::IncorrectMemoryDescription {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: expected_memory_desc.clone(), expected: expected_memory_desc.clone(),
found: memory_desc.clone(), found: memory_desc.clone(),
})? });
} }
} }
Some(export_type) => { Some(export_type) => {
@ -422,27 +457,35 @@ fn import_memories(
Export::Global { .. } => "global", Export::Global { .. } => "global",
} }
.to_string(); .to_string();
Err(LinkError::IncorrectImportType { link_errors.push(LinkError::IncorrectImportType {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: "memory".to_string(), expected: "memory".to_string(),
found: export_type_name, found: export_type_name,
})? });
} }
None => Err(LinkError::ImportNotFound { None => {
link_errors.push(LinkError::ImportNotFound {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
})?, });
} }
} }
}
if link_errors.len() > 0 {
Err(link_errors)
} else {
Ok(memories.into_boxed_map()) Ok(memories.into_boxed_map())
} }
}
fn import_tables( fn import_tables(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut Imports,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<BoxedMap<ImportedTableIndex, vm::ImportedTable>> { ) -> LinkResult<BoxedMap<ImportedTableIndex, vm::ImportedTable>> {
let mut link_errors = vec![];
let mut tables = Map::with_capacity(module.imported_tables.len()); let mut tables = Map::with_capacity(module.imported_tables.len());
for (_index, (ImportName { namespace, name }, expected_table_desc)) in &module.imported_tables { for (_index, (ImportName { namespace, name }, expected_table_desc)) in &module.imported_tables {
let table_import = imports let table_import = imports
@ -463,12 +506,12 @@ fn import_tables(
}, },
}); });
} else { } else {
Err(LinkError::IncorrectTableDescription { link_errors.push(LinkError::IncorrectTableDescription {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: expected_table_desc.clone(), expected: expected_table_desc.clone(),
found: table_desc.clone(), found: table_desc.clone(),
})? });
} }
} }
Some(export_type) => { Some(export_type) => {
@ -479,26 +522,34 @@ fn import_tables(
Export::Global { .. } => "global", Export::Global { .. } => "global",
} }
.to_string(); .to_string();
Err(LinkError::IncorrectImportType { link_errors.push(LinkError::IncorrectImportType {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: "table".to_string(), expected: "table".to_string(),
found: export_type_name, found: export_type_name,
})? });
} }
None => Err(LinkError::ImportNotFound { None => {
link_errors.push(LinkError::ImportNotFound {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
})?, });
} }
} }
}
if link_errors.len() > 0 {
Err(link_errors)
} else {
Ok(tables.into_boxed_map()) Ok(tables.into_boxed_map())
} }
}
fn import_globals( fn import_globals(
module: &ModuleInner, module: &ModuleInner,
imports: &mut Imports, imports: &mut Imports,
) -> LinkResult<BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>> { ) -> LinkResult<BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>> {
let mut link_errors = vec![];
let mut globals = Map::with_capacity(module.imported_globals.len()); let mut globals = Map::with_capacity(module.imported_globals.len());
for (_, (ImportName { namespace, name }, imported_global_desc)) in &module.imported_globals { for (_, (ImportName { namespace, name }, imported_global_desc)) in &module.imported_globals {
let import = imports let import = imports
@ -511,12 +562,12 @@ fn import_globals(
global: local.inner(), global: local.inner(),
}); });
} else { } else {
Err(LinkError::IncorrectGlobalDescription { link_errors.push(LinkError::IncorrectGlobalDescription {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: imported_global_desc.clone(), expected: imported_global_desc.clone(),
found: global.clone(), found: global.clone(),
})? });
} }
} }
Some(export_type) => { Some(export_type) => {
@ -527,18 +578,25 @@ fn import_globals(
Export::Global { .. } => "global", Export::Global { .. } => "global",
} }
.to_string(); .to_string();
Err(LinkError::IncorrectImportType { link_errors.push(LinkError::IncorrectImportType {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
expected: "global".to_string(), expected: "global".to_string(),
found: export_type_name, found: export_type_name,
})? });
} }
None => Err(LinkError::ImportNotFound { None => {
link_errors.push(LinkError::ImportNotFound {
namespace: namespace.clone(), namespace: namespace.clone(),
name: name.clone(), name: name.clone(),
})?, });
} }
} }
}
if link_errors.len() > 0 {
Err(link_errors)
} else {
Ok(globals.into_boxed_map()) Ok(globals.into_boxed_map())
} }
}

View File

@ -2,7 +2,7 @@ use crate::types::{FuncSig, GlobalDesc, Memory, MemoryIndex, Table, TableIndex,
pub type Result<T> = std::result::Result<T, Box<Error>>; pub type Result<T> = std::result::Result<T, Box<Error>>;
pub type CompileResult<T> = std::result::Result<T, Box<CompileError>>; pub type CompileResult<T> = std::result::Result<T, Box<CompileError>>;
pub type LinkResult<T> = std::result::Result<T, Box<LinkError>>; pub type LinkResult<T> = std::result::Result<T, Vec<LinkError>>;
pub type RuntimeResult<T> = std::result::Result<T, Box<RuntimeError>>; pub type RuntimeResult<T> = std::result::Result<T, Box<RuntimeError>>;
pub type CallResult<T> = std::result::Result<T, Box<CallError>>; pub type CallResult<T> = std::result::Result<T, Box<CallError>>;
@ -120,7 +120,7 @@ impl PartialEq for CallError {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Error { pub enum Error {
CompileError(CompileError), CompileError(CompileError),
LinkError(LinkError), LinkError(Vec<LinkError>),
RuntimeError(RuntimeError), RuntimeError(RuntimeError),
CallError(CallError), CallError(CallError),
} }
@ -137,9 +137,9 @@ impl From<Box<CompileError>> for Box<Error> {
} }
} }
impl From<Box<LinkError>> for Box<Error> { impl From<Vec<LinkError>> for Box<Error> {
fn from(link_err: Box<LinkError>) -> Self { fn from(link_err: Vec<LinkError>) -> Self {
Box::new(Error::LinkError(*link_err)) Box::new(Error::LinkError(link_err))
} }
} }