removed panics && lifetimes

This commit is contained in:
Svyatoslav Nikolsky 2017-06-23 14:11:09 +03:00
parent ca001e21df
commit a8e13030ec
4 changed files with 35 additions and 38 deletions

View File

@ -377,7 +377,7 @@ impl ModuleInstance {
} }
fn self_ref<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> { fn self_ref<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>>) -> Result<Arc<ModuleInstanceInterface + 'a>, Error> {
self.imports.module(externals, &self.name).map_err(|_| panic!("xxx")) self.imports.module(externals, &self.name)
} }
fn require_function(&self, index: ItemIndex) -> Result<u32, Error> { fn require_function(&self, index: ItemIndex) -> Result<u32, Error> {

View File

@ -156,7 +156,7 @@ impl Interpreter {
})) }))
} }
fn run_instruction<'a, 'b>(context: &'b mut FunctionContext<'a>, opcode: &Opcode) -> Result<InstructionOutcome<'a>, Error> { fn run_instruction<'a>(context: &mut FunctionContext<'a>, opcode: &Opcode) -> Result<InstructionOutcome<'a>, Error> {
match opcode { match opcode {
&Opcode::Unreachable => Interpreter::run_unreachable(context), &Opcode::Unreachable => Interpreter::run_unreachable(context),
&Opcode::Nop => Interpreter::run_nop(context), &Opcode::Nop => Interpreter::run_nop(context),
@ -358,17 +358,17 @@ impl Interpreter {
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_block<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> { fn run_block<'a>(context: &mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> {
context.push_frame(BlockFrameType::Block, block_type)?; context.push_frame(BlockFrameType::Block, block_type)?;
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_loop<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> { fn run_loop<'a>(context: &mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> {
context.push_frame(BlockFrameType::Loop, block_type)?; context.push_frame(BlockFrameType::Loop, block_type)?;
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
fn run_if<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> { fn run_if<'a>(context: &mut FunctionContext<'a>, block_type: BlockType) -> Result<InstructionOutcome<'a>, Error> {
let branch = context.value_stack_mut().pop_as()?; let branch = context.value_stack_mut().pop_as()?;
let block_frame_type = if branch { BlockFrameType::IfTrue } else { let block_frame_type = if branch { BlockFrameType::IfTrue } else {
let else_pos = context.function_labels[&context.position]; let else_pos = context.function_labels[&context.position];
@ -416,11 +416,11 @@ impl Interpreter {
Ok(InstructionOutcome::Return) Ok(InstructionOutcome::Return)
} }
fn run_call<'a, 'b>(context: &'b mut FunctionContext<'a>, func_idx: u32) -> Result<InstructionOutcome<'a>, Error> where 'a: 'b { fn run_call<'a>(context: &mut FunctionContext<'a>, func_idx: u32) -> Result<InstructionOutcome<'a>, Error> {
Ok(InstructionOutcome::ExecuteCall(context.module().function_reference(ItemIndex::IndexSpace(func_idx), Some(context.externals))?)) Ok(InstructionOutcome::ExecuteCall(context.module().function_reference(ItemIndex::IndexSpace(func_idx), Some(context.externals))?))
} }
fn run_call_indirect<'a, 'b>(context: &'b mut FunctionContext<'a>, type_idx: u32) -> Result<InstructionOutcome<'a>, Error> { fn run_call_indirect<'a>(context: &mut FunctionContext<'a>, type_idx: u32) -> Result<InstructionOutcome<'a>, Error> {
let table_func_idx: u32 = context.value_stack_mut().pop_as()?; let table_func_idx: u32 = context.value_stack_mut().pop_as()?;
let function_reference = context.module().function_reference_indirect(DEFAULT_TABLE_INDEX, type_idx, table_func_idx, Some(context.externals))?; let function_reference = context.module().function_reference_indirect(DEFAULT_TABLE_INDEX, type_idx, table_func_idx, Some(context.externals))?;
let required_function_type = context.module().function_type_by_index(type_idx)?; let required_function_type = context.module().function_type_by_index(type_idx)?;

View File

@ -46,14 +46,12 @@ impl<T> StackWithLimit<T> where T: Clone {
self.values self.values
.back() .back()
.ok_or(Error::Stack("non-empty stack expected".into())) .ok_or(Error::Stack("non-empty stack expected".into()))
.map_err(|_| panic!("1"))
} }
pub fn top_mut(&mut self) -> Result<&mut T, Error> { pub fn top_mut(&mut self) -> Result<&mut T, Error> {
self.values self.values
.back_mut() .back_mut()
.ok_or(Error::Stack("non-empty stack expected".into())) .ok_or(Error::Stack("non-empty stack expected".into()))
.map_err(|_| panic!("2"))
} }
pub fn get(&self, index: usize) -> Result<&T, Error> { pub fn get(&self, index: usize) -> Result<&T, Error> {
@ -90,7 +88,6 @@ impl<T> StackWithLimit<T> where T: Clone {
self.values self.values
.pop_back() .pop_back()
.ok_or(Error::Stack("non-empty stack expected".into())) .ok_or(Error::Stack("non-empty stack expected".into()))
.map_err(|_| panic!("3"))
} }
pub fn resize(&mut self, new_size: usize, dummy: T) { pub fn resize(&mut self, new_size: usize, dummy: T) {

View File

@ -94,7 +94,7 @@ impl Validator {
Ok(()) Ok(())
} }
fn validate_function_block<'a>(context: &mut FunctionValidationContext, body: &[Opcode]) -> Result<(), Error> { fn validate_function_block(context: &mut FunctionValidationContext, body: &[Opcode]) -> Result<(), Error> {
let body_len = body.len(); let body_len = body.len();
if body_len == 0 { if body_len == 0 {
return Err(Error::Validation("Non-empty function body expected".into())); return Err(Error::Validation("Non-empty function body expected".into()));
@ -114,7 +114,7 @@ impl Validator {
} }
} }
fn validate_instruction<'a>(context: &mut FunctionValidationContext, opcode: &'a Opcode) -> Result<InstructionOutcome, Error> { fn validate_instruction(context: &mut FunctionValidationContext, opcode: &Opcode) -> Result<InstructionOutcome, Error> {
debug!(target: "validator", "validating {:?}", opcode); debug!(target: "validator", "validating {:?}", opcode);
match opcode { match opcode {
&Opcode::Unreachable => Ok(InstructionOutcome::Unreachable), &Opcode::Unreachable => Ok(InstructionOutcome::Unreachable),
@ -309,49 +309,49 @@ impl Validator {
} }
} }
fn validate_const<'a>(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_const(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
context.push_value(value_type)?; context.push_value(value_type)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_unop<'a>(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_unop(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.push_value(value_type)?; context.push_value(value_type)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_binop<'a>(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_binop(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.push_value(value_type)?; context.push_value(value_type)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_testop<'a>(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_testop(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.push_value(ValueType::I32.into())?; context.push_value(ValueType::I32.into())?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_relop<'a>(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_relop(context: &mut FunctionValidationContext, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.pop_value(value_type)?; context.pop_value(value_type)?;
context.push_value(ValueType::I32.into())?; context.push_value(ValueType::I32.into())?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_cvtop<'a>(context: &mut FunctionValidationContext, value_type1: StackValueType, value_type2: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_cvtop(context: &mut FunctionValidationContext, value_type1: StackValueType, value_type2: StackValueType) -> Result<InstructionOutcome, Error> {
context.pop_value(value_type1)?; context.pop_value(value_type1)?;
context.push_value(value_type2)?; context.push_value(value_type2)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_drop<'a>(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> { fn validate_drop(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {
context.pop_any_value().map(|_| ())?; context.pop_any_value().map(|_| ())?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_select<'a>(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> { fn validate_select(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {
context.pop_value(ValueType::I32.into())?; context.pop_value(ValueType::I32.into())?;
let select_type = context.pop_any_value()?; let select_type = context.pop_any_value()?;
context.pop_value(select_type)?; context.pop_value(select_type)?;
@ -359,13 +359,13 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_get_local<'a>(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> { fn validate_get_local(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {
let local_type = context.require_local(index)?; let local_type = context.require_local(index)?;
context.push_value(local_type)?; context.push_value(local_type)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_set_local<'a>(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> { fn validate_set_local(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {
let local_type = context.require_local(index)?; let local_type = context.require_local(index)?;
let value_type = context.pop_any_value()?; let value_type = context.pop_any_value()?;
if local_type != value_type { if local_type != value_type {
@ -374,7 +374,7 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_tee_local<'a>(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> { fn validate_tee_local(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {
let local_type = context.require_local(index)?; let local_type = context.require_local(index)?;
let value_type = context.tee_any_value()?; let value_type = context.tee_any_value()?;
if local_type != value_type { if local_type != value_type {
@ -383,13 +383,13 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_get_global<'a>(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> { fn validate_get_global(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {
let global_type = context.require_global(index, None)?; let global_type = context.require_global(index, None)?;
context.push_value(global_type)?; context.push_value(global_type)?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_set_global<'a>(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> { fn validate_set_global(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {
let global_type = context.require_global(index, Some(true))?; let global_type = context.require_global(index, Some(true))?;
let value_type = context.pop_any_value()?; let value_type = context.pop_any_value()?;
if global_type != value_type { if global_type != value_type {
@ -398,7 +398,7 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_load<'a>(context: &mut FunctionValidationContext, align: u32, max_align: u32, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_load(context: &mut FunctionValidationContext, align: u32, max_align: u32, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
if align != NATURAL_ALIGNMENT { if align != NATURAL_ALIGNMENT {
if 1u32.checked_shl(align).unwrap_or(u32::MAX) > max_align { if 1u32.checked_shl(align).unwrap_or(u32::MAX) > max_align {
return Err(Error::Validation(format!("Too large memory alignment 2^{} (expected at most {})", align, max_align))); return Err(Error::Validation(format!("Too large memory alignment 2^{} (expected at most {})", align, max_align)));
@ -411,7 +411,7 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_store<'a>(context: &mut FunctionValidationContext, align: u32, max_align: u32, value_type: StackValueType) -> Result<InstructionOutcome, Error> { fn validate_store(context: &mut FunctionValidationContext, align: u32, max_align: u32, value_type: StackValueType) -> Result<InstructionOutcome, Error> {
if align != NATURAL_ALIGNMENT { if align != NATURAL_ALIGNMENT {
if 1u32.checked_shl(align).unwrap_or(u32::MAX) > max_align { if 1u32.checked_shl(align).unwrap_or(u32::MAX) > max_align {
return Err(Error::Validation(format!("Too large memory alignment 2^{} (expected at most {})", align, max_align))); return Err(Error::Validation(format!("Too large memory alignment 2^{} (expected at most {})", align, max_align)));
@ -424,15 +424,15 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_block<'a>(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn validate_block(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> {
context.push_label(BlockFrameType::Block, block_type).map(|_| InstructionOutcome::ValidateNextInstruction) context.push_label(BlockFrameType::Block, block_type).map(|_| InstructionOutcome::ValidateNextInstruction)
} }
fn validate_loop<'a>(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn validate_loop(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> {
context.push_label(BlockFrameType::Loop, block_type).map(|_| InstructionOutcome::ValidateNextInstruction) context.push_label(BlockFrameType::Loop, block_type).map(|_| InstructionOutcome::ValidateNextInstruction)
} }
fn validate_if<'a>(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> { fn validate_if(context: &mut FunctionValidationContext, block_type: BlockType) -> Result<InstructionOutcome, Error> {
context.pop_value(ValueType::I32.into())?; context.pop_value(ValueType::I32.into())?;
context.push_label(BlockFrameType::IfTrue, block_type).map(|_| InstructionOutcome::ValidateNextInstruction) context.push_label(BlockFrameType::IfTrue, block_type).map(|_| InstructionOutcome::ValidateNextInstruction)
} }
@ -466,7 +466,7 @@ impl Validator {
context.pop_label().map(|_| InstructionOutcome::ValidateNextInstruction) context.pop_label().map(|_| InstructionOutcome::ValidateNextInstruction)
} }
fn validate_br<'a>(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> { fn validate_br(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> {
let (frame_type, frame_block_type) = { let (frame_type, frame_block_type) = {
let frame = context.require_label(idx)?; let frame = context.require_label(idx)?;
(frame.frame_type, frame.block_type) (frame.frame_type, frame.block_type)
@ -480,7 +480,7 @@ impl Validator {
Ok(InstructionOutcome::Unreachable) Ok(InstructionOutcome::Unreachable)
} }
fn validate_br_if<'a>(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> { fn validate_br_if(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> {
context.pop_value(ValueType::I32.into())?; context.pop_value(ValueType::I32.into())?;
if let BlockType::Value(value_type) = context.require_label(idx)?.block_type { if let BlockType::Value(value_type) = context.require_label(idx)?.block_type {
context.tee_value(value_type.into())?; context.tee_value(value_type.into())?;
@ -488,7 +488,7 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_br_table<'a>(context: &mut FunctionValidationContext, table: &Vec<u32>, default: u32) -> Result<InstructionOutcome, Error> { fn validate_br_table(context: &mut FunctionValidationContext, table: &Vec<u32>, default: u32) -> Result<InstructionOutcome, Error> {
let mut required_block_type = None; let mut required_block_type = None;
{ {
@ -520,14 +520,14 @@ impl Validator {
Ok(InstructionOutcome::Unreachable) Ok(InstructionOutcome::Unreachable)
} }
fn validate_return<'a>(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> { fn validate_return(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {
if let BlockType::Value(value_type) = context.return_type()? { if let BlockType::Value(value_type) = context.return_type()? {
context.tee_value(value_type.into())?; context.tee_value(value_type.into())?;
} }
Ok(InstructionOutcome::Unreachable) Ok(InstructionOutcome::Unreachable)
} }
fn validate_call<'a>(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> { fn validate_call(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> {
let (argument_types, return_type) = context.require_function(idx)?; let (argument_types, return_type) = context.require_function(idx)?;
for argument_type in argument_types.iter().rev() { for argument_type in argument_types.iter().rev() {
context.pop_value((*argument_type).into())?; context.pop_value((*argument_type).into())?;
@ -538,7 +538,7 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_call_indirect<'a>(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> { fn validate_call_indirect(context: &mut FunctionValidationContext, idx: u32) -> Result<InstructionOutcome, Error> {
context.require_table(DEFAULT_TABLE_INDEX, VariableType::AnyFunc)?; context.require_table(DEFAULT_TABLE_INDEX, VariableType::AnyFunc)?;
context.pop_value(ValueType::I32.into())?; context.pop_value(ValueType::I32.into())?;
@ -552,13 +552,13 @@ impl Validator {
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_current_memory<'a>(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> { fn validate_current_memory(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {
context.require_memory(DEFAULT_MEMORY_INDEX)?; context.require_memory(DEFAULT_MEMORY_INDEX)?;
context.push_value(ValueType::I32.into())?; context.push_value(ValueType::I32.into())?;
Ok(InstructionOutcome::ValidateNextInstruction) Ok(InstructionOutcome::ValidateNextInstruction)
} }
fn validate_grow_memory<'a>(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> { fn validate_grow_memory(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {
context.require_memory(DEFAULT_MEMORY_INDEX)?; context.require_memory(DEFAULT_MEMORY_INDEX)?;
context.pop_value(ValueType::I32.into())?; context.pop_value(ValueType::I32.into())?;
context.push_value(ValueType::I32.into())?; context.push_value(ValueType::I32.into())?;