Get rid of Stack error

This commit is contained in:
Sergey Pepyakin 2018-02-05 17:19:20 +03:00
parent 106ac7afdb
commit 30bc275a7a
2 changed files with 28 additions and 38 deletions

View File

@ -193,8 +193,6 @@ pub enum Error {
Memory(String), Memory(String),
/// Global-level error. /// Global-level error.
Global(String), Global(String),
/// Stack-level error.
Stack(String),
/// Value-level error. /// Value-level error.
Value(String), Value(String),
/// Trap. /// Trap.
@ -212,7 +210,6 @@ impl Into<String> for Error {
Error::Table(s) => s, Error::Table(s) => s,
Error::Memory(s) => s, Error::Memory(s) => s,
Error::Global(s) => s, Error::Global(s) => s,
Error::Stack(s) => s,
Error::Value(s) => s, Error::Value(s) => s,
Error::Trap(s) => format!("trap: {:?}", s), Error::Trap(s) => format!("trap: {:?}", s),
Error::Host(e) => format!("user: {}", e), Error::Host(e) => format!("user: {}", e),
@ -229,7 +226,6 @@ impl fmt::Display for Error {
Error::Table(ref s) => write!(f, "Table: {}", s), Error::Table(ref s) => write!(f, "Table: {}", s),
Error::Memory(ref s) => write!(f, "Memory: {}", s), Error::Memory(ref s) => write!(f, "Memory: {}", s),
Error::Global(ref s) => write!(f, "Global: {}", s), Error::Global(ref s) => write!(f, "Global: {}", s),
Error::Stack(ref s) => write!(f, "Stack: {}", s),
Error::Value(ref s) => write!(f, "Value: {}", s), Error::Value(ref s) => write!(f, "Value: {}", s),
Error::Trap(ref s) => write!(f, "Trap: {:?}", s), Error::Trap(ref s) => write!(f, "Trap: {:?}", s),
Error::Host(ref e) => write!(f, "User: {}", e), Error::Host(ref e) => write!(f, "User: {}", e),
@ -237,8 +233,6 @@ impl fmt::Display for Error {
} }
} }
impl error::Error for Error { impl error::Error for Error {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
@ -248,7 +242,6 @@ impl error::Error for Error {
Error::Table(ref s) => s, Error::Table(ref s) => s,
Error::Memory(ref s) => s, Error::Memory(ref s) => s,
Error::Global(ref s) => s, Error::Global(ref s) => s,
Error::Stack(ref s) => s,
Error::Value(ref s) => s, Error::Value(ref s) => s,
Error::Trap(_) => "Trap", Error::Trap(_) => "Trap",
Error::Host(_) => "Host error", Error::Host(_) => "Host error",
@ -281,12 +274,6 @@ impl From<validation::Error> for Error {
} }
} }
impl From<::common::stack::Error> for Error {
fn from(e: ::common::stack::Error) -> Self {
Error::Stack(e.to_string())
}
}
mod validation; mod validation;
mod common; mod common;
mod memory; mod memory;

View File

@ -148,8 +148,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
BlockType::Value(_) => { BlockType::Value(_) => {
let result = function_context let result = function_context
.value_stack_mut() .value_stack_mut()
.pop() .pop();
.expect("Due to validation stack shouldn't be empty");
Some(result) Some(result)
}, },
BlockType::NoResult => None, BlockType::NoResult => None,
@ -480,8 +479,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
fn run_select(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> { fn run_select(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
let (left, mid, right) = context let (left, mid, right) = context
.value_stack_mut() .value_stack_mut()
.pop_triple() .pop_triple();
.expect("Due to validation there should be 3 values on stack");
let condition = right let condition = right
.try_into() .try_into()
@ -500,8 +498,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
fn run_set_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, Trap> { fn run_set_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, Trap> {
let arg = context let arg = context
.value_stack_mut() .value_stack_mut()
.pop() .pop();
.expect("Due to vaidation stack should contain value");
context.set_local(index as usize, arg); context.set_local(index as usize, arg);
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
} }
@ -510,7 +507,6 @@ impl<'a, E: Externals> Interpreter<'a, E> {
let arg = context let arg = context
.value_stack() .value_stack()
.top() .top()
.expect("Due to vaidation stack should contain value")
.clone(); .clone();
context.set_local(index as usize, arg); context.set_local(index as usize, arg);
Ok(InstructionOutcome::RunNextInstruction) Ok(InstructionOutcome::RunNextInstruction)
@ -537,8 +533,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
) -> Result<InstructionOutcome, Trap> { ) -> Result<InstructionOutcome, Trap> {
let val = context let val = context
.value_stack_mut() .value_stack_mut()
.pop() .pop();
.expect("Due to vaidation stack should contain value");
let global = context let global = context
.module() .module()
.global_by_index(index) .global_by_index(index)
@ -634,7 +629,6 @@ impl<'a, E: Externals> Interpreter<'a, E> {
let stack_value: T = context let stack_value: T = context
.value_stack_mut() .value_stack_mut()
.pop() .pop()
.expect("Due to vaidation stack should contain value")
.try_into() .try_into()
.expect("Due to validation value should be of proper type"); .expect("Due to validation value should be of proper type");
let stack_value = stack_value.wrap_into().into_little_endian(); let stack_value = stack_value.wrap_into().into_little_endian();
@ -1192,7 +1186,7 @@ impl FunctionContext {
let frame_value = match frame.block_type { let frame_value = match frame.block_type {
BlockType::Value(_) if frame.frame_type != BlockFrameType::Loop || !is_branch => BlockType::Value(_) if frame.frame_type != BlockFrameType::Loop || !is_branch =>
Some(self.value_stack.pop().expect("Due to validation, stack shouldn't be empty")), Some(self.value_stack.pop()),
_ => None, _ => None,
}; };
self.value_stack.resize(frame.value_stack_len); self.value_stack.resize(frame.value_stack_len);
@ -1218,10 +1212,17 @@ fn effective_address(address: u32, offset: u32) -> Result<u32, Trap> {
} }
} }
fn prepare_function_args(signature: &Signature, caller_stack: &mut ValueStack) -> Vec<RuntimeValue> { fn prepare_function_args(
let mut args = signature.params().iter().cloned().rev().map(|_| { signature: &Signature,
caller_stack.pop().expect("Due to validation stack shouldn't be empty") caller_stack: &mut ValueStack,
}).collect::<Vec<RuntimeValue>>(); ) -> Vec<RuntimeValue> {
let mut args = signature
.params()
.iter()
.cloned()
.rev()
.map(|_| caller_stack.pop())
.collect::<Vec<RuntimeValue>>();
args.reverse(); args.reverse();
check_function_args(signature, &args).expect("Due to validation arguments should match"); check_function_args(signature, &args).expect("Due to validation arguments should match");
args args
@ -1266,7 +1267,9 @@ impl ValueStack {
where where
RuntimeValue: TryInto<T, Error>, RuntimeValue: TryInto<T, Error>,
{ {
let value = self.stack_with_limit.pop()?; let value = self.stack_with_limit
.pop()
.expect("Due to validation stack shouldn't be empty");
TryInto::try_into(value) TryInto::try_into(value)
} }
@ -1279,15 +1282,15 @@ impl ValueStack {
Ok((left, right)) Ok((left, right))
} }
fn pop_triple(&mut self) -> Result<(RuntimeValue, RuntimeValue, RuntimeValue), Error> { fn pop_triple(&mut self) -> (RuntimeValue, RuntimeValue, RuntimeValue) {
let right = self.stack_with_limit.pop()?; let right = self.stack_with_limit.pop().expect("Due to validation stack shouldn't be empty");
let mid = self.stack_with_limit.pop()?; let mid = self.stack_with_limit.pop().expect("Due to validation stack shouldn't be empty");
let left = self.stack_with_limit.pop()?; let left = self.stack_with_limit.pop().expect("Due to validation stack shouldn't be empty");
Ok((left, mid, right)) (left, mid, right)
} }
fn pop(&mut self) -> Result<RuntimeValue, Error> { fn pop(&mut self) -> RuntimeValue {
self.stack_with_limit.pop().map_err(|e| Error::Stack(e.to_string())) self.stack_with_limit.pop().expect("Due to validation stack shouldn't be empty")
} }
fn push(&mut self, value: RuntimeValue) -> Result<(), Trap> { fn push(&mut self, value: RuntimeValue) -> Result<(), Trap> {
@ -1307,7 +1310,7 @@ impl ValueStack {
self.stack_with_limit.limit() self.stack_with_limit.limit()
} }
fn top(&self) -> Result<&RuntimeValue, Error> { fn top(&self) -> &RuntimeValue {
self.stack_with_limit.top().map_err(|e| Error::Stack(e.to_string())) self.stack_with_limit.top().expect("Due to validation stack shouldn't be empty")
} }
} }