Get rid of Stack error
This commit is contained in:
parent
106ac7afdb
commit
30bc275a7a
13
src/lib.rs
13
src/lib.rs
|
@ -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;
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue