fix issue 725, remove panics

This commit is contained in:
Patrick Ventuzelo
2019-09-09 16:58:26 +02:00
parent 30d80c3956
commit ba5c43e09d

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
error::{LinkError, LinkResult}, error::{CreationError, LinkError, LinkResult},
export::{Context, Export}, export::{Context, Export},
global::Global, global::Global,
import::ImportObject, import::ImportObject,
@ -60,7 +60,14 @@ impl LocalBacking {
imports: &ImportBacking, imports: &ImportBacking,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> LinkResult<Self> { ) -> LinkResult<Self> {
let mut memories = Self::generate_memories(module); let mut memories = match Self::generate_memories(module) {
Ok(m) => m,
Err(e) => {
return Err(vec![LinkError::Generic {
message: format!("unable to create memory: {:?}", e),
}]);
}
};
let mut tables = Self::generate_tables(module); let mut tables = Self::generate_tables(module);
let mut globals = Self::generate_globals(module, imports); let mut globals = Self::generate_globals(module, imports);
@ -68,8 +75,8 @@ impl LocalBacking {
Self::validate_memories(module, imports)?; Self::validate_memories(module, imports)?;
Self::validate_tables(module, imports, &mut tables)?; Self::validate_tables(module, imports, &mut tables)?;
let vm_memories = Self::finalize_memories(module, imports, &mut memories); let vm_memories = Self::finalize_memories(module, imports, &mut memories)?;
let vm_tables = Self::finalize_tables(module, imports, &mut tables, vmctx); let vm_tables = Self::finalize_tables(module, imports, &mut tables, vmctx)?;
let vm_globals = Self::finalize_globals(&mut globals); let vm_globals = Self::finalize_globals(&mut globals);
let dynamic_sigindices = Self::generate_sigindices(&module.info); let dynamic_sigindices = Self::generate_sigindices(&module.info);
@ -116,13 +123,16 @@ impl LocalBacking {
.into_boxed_map() .into_boxed_map()
} }
fn generate_memories(module: &ModuleInner) -> BoxedMap<LocalMemoryIndex, Memory> { fn generate_memories(
module: &ModuleInner,
) -> Result<BoxedMap<LocalMemoryIndex, Memory>, CreationError> {
let mut memories = Map::with_capacity(module.info.memories.len()); let mut memories = Map::with_capacity(module.info.memories.len());
for (_, &desc) in &module.info.memories { for (_, &desc) in &module.info.memories {
memories.push(Memory::new(desc).expect("unable to create memory")); let memory = Memory::new(desc)?;
memories.push(memory);
} }
memories.into_boxed_map() Ok(memories.into_boxed_map())
} }
/// Validate each locally-defined memory in the Module. /// Validate each locally-defined memory in the Module.
@ -133,12 +143,18 @@ impl LocalBacking {
for init in module.info.data_initializers.iter() { for init in module.info.data_initializers.iter() {
let init_base = match init.base { let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32, Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"), Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => { Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() { if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32 x as u32
} else { } else {
panic!("unsupported global type for initializer") return Err(vec![LinkError::Generic {
message: "unsupported global type for initializer".to_string(),
}]);
} }
} }
} as usize; } as usize;
@ -177,18 +193,24 @@ impl LocalBacking {
module: &ModuleInner, module: &ModuleInner,
imports: &ImportBacking, imports: &ImportBacking,
memories: &mut SliceMap<LocalMemoryIndex, Memory>, memories: &mut SliceMap<LocalMemoryIndex, Memory>,
) -> BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory> { ) -> LinkResult<BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory>> {
// For each init that has some data... // For each init that has some data...
// Initialize data // Initialize data
for init in module.info.data_initializers.iter() { for init in module.info.data_initializers.iter() {
let init_base = match init.base { let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32, Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"), Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => { Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() { if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32 x as u32
} else { } else {
panic!("unsupported global type for initializer") return Err(vec![LinkError::Generic {
message: "unsupported global type for initializer".to_string(),
}]);
} }
} }
} as usize; } as usize;
@ -217,11 +239,11 @@ impl LocalBacking {
} }
} }
memories Ok(memories
.iter_mut() .iter_mut()
.map(|(_, mem)| mem.vm_local_memory()) .map(|(_, mem)| mem.vm_local_memory())
.collect::<Map<_, _>>() .collect::<Map<_, _>>()
.into_boxed_map() .into_boxed_map())
} }
fn generate_tables(module: &ModuleInner) -> BoxedMap<LocalTableIndex, Table> { fn generate_tables(module: &ModuleInner) -> BoxedMap<LocalTableIndex, Table> {
@ -245,12 +267,18 @@ impl LocalBacking {
for init in &module.info.elem_initializers { for init in &module.info.elem_initializers {
let init_base = match init.base { let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32, Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"), Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => { Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() { if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32 x as u32
} else { } else {
panic!("unsupported global type for initializer") return Err(vec![LinkError::Generic {
message: "unsupported global type for initializer".to_string(),
}]);
} }
} }
} as usize; } as usize;
@ -288,16 +316,22 @@ impl LocalBacking {
imports: &ImportBacking, imports: &ImportBacking,
tables: &mut SliceMap<LocalTableIndex, Table>, tables: &mut SliceMap<LocalTableIndex, Table>,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> BoxedMap<LocalTableIndex, *mut vm::LocalTable> { ) -> LinkResult<BoxedMap<LocalTableIndex, *mut vm::LocalTable>> {
for init in &module.info.elem_initializers { for init in &module.info.elem_initializers {
let init_base = match init.base { let init_base = match init.base {
Initializer::Const(Value::I32(offset)) => offset as u32, Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => panic!("a const initializer must be the i32 type"), Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => { Initializer::GetGlobal(import_global_index) => {
if let Value::I32(x) = imports.globals[import_global_index].get() { if let Value::I32(x) = imports.globals[import_global_index].get() {
x as u32 x as u32
} else { } else {
panic!("unsupported global type for initializer") return Err(vec![LinkError::Generic {
message: "unsupported global type for initializer".to_string(),
}]);
} }
} }
} as usize; } as usize;
@ -371,11 +405,11 @@ impl LocalBacking {
} }
} }
tables Ok(tables
.iter_mut() .iter_mut()
.map(|(_, table)| table.vm_local_table()) .map(|(_, table)| table.vm_local_table())
.collect::<Map<_, _>>() .collect::<Map<_, _>>()
.into_boxed_map() .into_boxed_map())
} }
fn generate_globals( fn generate_globals(