Rename Trap to TrapKind
This commit is contained in:
parent
0e355684a2
commit
daf7d95a65
|
@ -8,7 +8,7 @@ use wasmi::{
|
||||||
Error as InterpreterError, ModuleInstance, ModuleRef,
|
Error as InterpreterError, ModuleInstance, ModuleRef,
|
||||||
Externals, RuntimeValue, FuncRef, ModuleImportResolver,
|
Externals, RuntimeValue, FuncRef, ModuleImportResolver,
|
||||||
FuncInstance, HostError, ImportsBuilder, Signature, ValueType,
|
FuncInstance, HostError, ImportsBuilder, Signature, ValueType,
|
||||||
RuntimeArgs, Trap,
|
RuntimeArgs, TrapKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -149,7 +149,7 @@ impl<'a> Externals for Runtime<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
SET_FUNC_INDEX => {
|
SET_FUNC_INDEX => {
|
||||||
let idx: i32 = args.nth(0);
|
let idx: i32 = args.nth(0);
|
||||||
|
|
|
@ -13,14 +13,14 @@ use wasmi::{
|
||||||
GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder,
|
GlobalInstance, GlobalRef, ImportResolver, ImportsBuilder,
|
||||||
MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance,
|
MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance,
|
||||||
ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType,
|
ModuleRef, RuntimeValue, TableInstance, TableRef, ValueType,
|
||||||
Module, Signature, MemoryDescriptor, Trap,
|
Module, Signature, MemoryDescriptor, TrapKind,
|
||||||
TableDescriptor, GlobalDescriptor, FuncInstance, RuntimeArgs,
|
TableDescriptor, GlobalDescriptor, FuncInstance, RuntimeArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
Load(String),
|
Load(String),
|
||||||
Start(Trap),
|
Start(TrapKind),
|
||||||
Interpreter(InterpreterError),
|
Interpreter(InterpreterError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ impl Externals for SpecModule {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
PRINT_FUNC_INDEX => {
|
PRINT_FUNC_INDEX => {
|
||||||
println!("print: {:?}", args);
|
println!("print: {:?}", args);
|
||||||
|
@ -495,7 +495,7 @@ pub fn spec(name: &str) {
|
||||||
Err(e) => println!("assert_exhaustion at line {} - success ({:?})", line, e),
|
Err(e) => println!("assert_exhaustion at line {} - success ({:?})", line, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&test::Command::AssertTrap {
|
&test::Command::AssertTrapKind {
|
||||||
line, ref action, ..
|
line, ref action, ..
|
||||||
} => {
|
} => {
|
||||||
let result = run_action(&mut spec_driver, action);
|
let result = run_action(&mut spec_driver, action);
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub enum Command {
|
||||||
action: Action,
|
action: Action,
|
||||||
},
|
},
|
||||||
#[serde(rename = "assert_trap")]
|
#[serde(rename = "assert_trap")]
|
||||||
AssertTrap {
|
AssertTrapKind {
|
||||||
line: u64,
|
line: u64,
|
||||||
action: Action,
|
action: Action,
|
||||||
text: String,
|
text: String,
|
||||||
|
|
10
src/func.rs
10
src/func.rs
|
@ -2,7 +2,7 @@ use std::rc::{Rc, Weak};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use parity_wasm::elements::{Local, Opcodes};
|
use parity_wasm::elements::{Local, Opcodes};
|
||||||
use {Trap, Signature};
|
use {TrapKind, Signature};
|
||||||
use host::Externals;
|
use host::Externals;
|
||||||
use runner::{check_function_args, Interpreter};
|
use runner::{check_function_args, Interpreter};
|
||||||
use value::RuntimeValue;
|
use value::RuntimeValue;
|
||||||
|
@ -132,16 +132,16 @@ impl FuncInstance {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns `Err` if `args` types is not match function [`signature`] or
|
/// Returns `Err` if `args` types is not match function [`signature`] or
|
||||||
/// if [`Trap`] at execution time occured.
|
/// if [`TrapKind`] at execution time occured.
|
||||||
///
|
///
|
||||||
/// [`signature`]: #method.signature
|
/// [`signature`]: #method.signature
|
||||||
/// [`Trap`]: #enum.Trap.html
|
/// [`TrapKind`]: #enum.TrapKind.html
|
||||||
pub fn invoke<E: Externals>(
|
pub fn invoke<E: Externals>(
|
||||||
func: &FuncRef,
|
func: &FuncRef,
|
||||||
args: &[RuntimeValue],
|
args: &[RuntimeValue],
|
||||||
externals: &mut E,
|
externals: &mut E,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
check_function_args(func.signature(), &args).map_err(|_| Trap::UnexpectedSignature)?;
|
check_function_args(func.signature(), &args).map_err(|_| TrapKind::UnexpectedSignature)?;
|
||||||
match *func.as_internal() {
|
match *func.as_internal() {
|
||||||
FuncInstanceInternal::Internal { .. } => {
|
FuncInstanceInternal::Internal { .. } => {
|
||||||
let mut interpreter = Interpreter::new(externals);
|
let mut interpreter = Interpreter::new(externals);
|
||||||
|
|
20
src/host.rs
20
src/host.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use value::{RuntimeValue, TryInto};
|
use value::{RuntimeValue, TryInto};
|
||||||
use Trap;
|
use TrapKind;
|
||||||
|
|
||||||
/// Safe wrapper for list of arguments.
|
/// Safe wrapper for list of arguments.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -18,8 +18,8 @@ impl<'a> RuntimeArgs<'a> {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns `Err` if cast is invalid or not enough arguments.
|
/// Returns `Err` if cast is invalid or not enough arguments.
|
||||||
pub fn nth_checked<T>(&self, idx: usize) -> Result<T, Trap> where RuntimeValue: TryInto<T, ::value::Error> {
|
pub fn nth_checked<T>(&self, idx: usize) -> Result<T, TrapKind> where RuntimeValue: TryInto<T, ::value::Error> {
|
||||||
Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| Trap::UnexpectedSignature)?)
|
Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| TrapKind::UnexpectedSignature)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract argument as a [`RuntimeValue`] by index `idx`.
|
/// Extract argument as a [`RuntimeValue`] by index `idx`.
|
||||||
|
@ -27,9 +27,9 @@ impl<'a> RuntimeArgs<'a> {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns `Err` if this list has not enough arguments.
|
/// Returns `Err` if this list has not enough arguments.
|
||||||
pub fn nth_value_checked(&self, idx: usize) -> Result<RuntimeValue, Trap> {
|
pub fn nth_value_checked(&self, idx: usize) -> Result<RuntimeValue, TrapKind> {
|
||||||
if self.0.len() <= idx {
|
if self.0.len() <= idx {
|
||||||
return Err(Trap::UnexpectedSignature);
|
return Err(TrapKind::UnexpectedSignature);
|
||||||
}
|
}
|
||||||
Ok(self.0[idx])
|
Ok(self.0[idx])
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ impl HostError {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use wasmi::{
|
/// use wasmi::{
|
||||||
/// Externals, RuntimeValue, RuntimeArgs, Error, ModuleImportResolver,
|
/// Externals, RuntimeValue, RuntimeArgs, Error, ModuleImportResolver,
|
||||||
/// FuncRef, ValueType, Signature, FuncInstance, Trap,
|
/// FuncRef, ValueType, Signature, FuncInstance, TrapKind,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// struct HostExternals {
|
/// struct HostExternals {
|
||||||
|
@ -136,7 +136,7 @@ impl HostError {
|
||||||
/// &mut self,
|
/// &mut self,
|
||||||
/// index: usize,
|
/// index: usize,
|
||||||
/// args: RuntimeArgs,
|
/// args: RuntimeArgs,
|
||||||
/// ) -> Result<Option<RuntimeValue>, Trap> {
|
/// ) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
/// match index {
|
/// match index {
|
||||||
/// ADD_FUNC_INDEX => {
|
/// ADD_FUNC_INDEX => {
|
||||||
/// let a: u32 = args.nth(0);
|
/// let a: u32 = args.nth(0);
|
||||||
|
@ -192,7 +192,7 @@ pub trait Externals {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap>;
|
) -> Result<Option<RuntimeValue>, TrapKind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of [`Externals`] that just traps on [`invoke_index`].
|
/// Implementation of [`Externals`] that just traps on [`invoke_index`].
|
||||||
|
@ -206,8 +206,8 @@ impl Externals for NopExternals {
|
||||||
&mut self,
|
&mut self,
|
||||||
_index: usize,
|
_index: usize,
|
||||||
_args: RuntimeArgs,
|
_args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
Err(Trap::Unreachable)
|
Err(TrapKind::Unreachable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
src/lib.rs
26
src/lib.rs
|
@ -107,10 +107,10 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
/// Error type which can thrown by wasm code or by host environment.
|
/// Error type which can thrown by wasm code or by host environment.
|
||||||
///
|
///
|
||||||
/// Under some conditions, wasm execution may produce a `Trap`, which immediately aborts execution.
|
/// Under some conditions, wasm execution may produce a `TrapKind`, which immediately aborts execution.
|
||||||
/// Traps can't be handled by WebAssembly code, but are reported to the embedder.
|
/// TrapKinds can't be handled by WebAssembly code, but are reported to the embedder.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Trap {
|
pub enum TrapKind {
|
||||||
/// Wasm code executed `unreachable` opcode.
|
/// Wasm code executed `unreachable` opcode.
|
||||||
///
|
///
|
||||||
/// `unreachable` is a special opcode which always traps upon execution.
|
/// `unreachable` is a special opcode which always traps upon execution.
|
||||||
|
@ -201,8 +201,8 @@ pub enum Error {
|
||||||
Global(String),
|
Global(String),
|
||||||
/// Value-level error.
|
/// Value-level error.
|
||||||
Value(String),
|
Value(String),
|
||||||
/// Trap.
|
/// TrapKind.
|
||||||
Trap(Trap),
|
TrapKind(TrapKind),
|
||||||
/// Custom embedder error.
|
/// Custom embedder error.
|
||||||
Host(Box<host::HostError>),
|
Host(Box<host::HostError>),
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ impl Into<String> for Error {
|
||||||
Error::Memory(s) => s,
|
Error::Memory(s) => s,
|
||||||
Error::Global(s) => s,
|
Error::Global(s) => s,
|
||||||
Error::Value(s) => s,
|
Error::Value(s) => s,
|
||||||
Error::Trap(s) => format!("trap: {:?}", s),
|
Error::TrapKind(s) => format!("trap: {:?}", s),
|
||||||
Error::Host(e) => format!("user: {}", e),
|
Error::Host(e) => format!("user: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ impl fmt::Display for Error {
|
||||||
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::Value(ref s) => write!(f, "Value: {}", s),
|
Error::Value(ref s) => write!(f, "Value: {}", s),
|
||||||
Error::Trap(ref s) => write!(f, "Trap: {:?}", s),
|
Error::TrapKind(ref s) => write!(f, "TrapKind: {:?}", s),
|
||||||
Error::Host(ref e) => write!(f, "User: {}", e),
|
Error::Host(ref e) => write!(f, "User: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ impl error::Error for Error {
|
||||||
Error::Memory(ref s) => s,
|
Error::Memory(ref s) => s,
|
||||||
Error::Global(ref s) => s,
|
Error::Global(ref s) => s,
|
||||||
Error::Value(ref s) => s,
|
Error::Value(ref s) => s,
|
||||||
Error::Trap(_) => "Trap",
|
Error::TrapKind(_) => "TrapKind",
|
||||||
Error::Host(_) => "Host error",
|
Error::Host(_) => "Host error",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,15 +262,15 @@ impl<U> From<U> for Error where U: host::HostError + Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> From<U> for Trap where U: host::HostError + Sized {
|
impl<U> From<U> for TrapKind where U: host::HostError + Sized {
|
||||||
fn from(e: U) -> Self {
|
fn from(e: U) -> Self {
|
||||||
Trap::Host(Box::new(e))
|
TrapKind::Host(Box::new(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Trap> for Error {
|
impl From<TrapKind> for Error {
|
||||||
fn from(e: Trap) -> Error {
|
fn from(e: TrapKind) -> Error {
|
||||||
Error::Trap(e)
|
Error::TrapKind(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use runner::check_function_args;
|
use runner::check_function_args;
|
||||||
use Trap;
|
use TrapKind;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -594,7 +594,7 @@ impl ModuleInstance {
|
||||||
|
|
||||||
check_function_args(func_instance.signature(), &args)?;
|
check_function_args(func_instance.signature(), &args)?;
|
||||||
FuncInstance::invoke(&func_instance, args, externals)
|
FuncInstance::invoke(&func_instance, args, externals)
|
||||||
.map_err(|t| Error::Trap(t))
|
.map_err(|t| Error::TrapKind(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find export by a name.
|
/// Find export by a name.
|
||||||
|
@ -647,7 +647,7 @@ impl<'a> NotStartedModuleRef<'a> {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns `Err` if start function traps.
|
/// Returns `Err` if start function traps.
|
||||||
pub fn run_start<E: Externals>(self, state: &mut E) -> Result<ModuleRef, Trap> {
|
pub fn run_start<E: Externals>(self, state: &mut E) -> Result<ModuleRef, TrapKind> {
|
||||||
if let Some(start_fn_idx) = self.loaded_module.module().start_section() {
|
if let Some(start_fn_idx) = self.loaded_module.module().start_section() {
|
||||||
let start_func = self.instance.func_by_index(start_fn_idx).expect(
|
let start_func = self.instance.func_by_index(start_fn_idx).expect(
|
||||||
"Due to validation start function should exists",
|
"Due to validation start function should exists",
|
||||||
|
|
174
src/runner.rs
174
src/runner.rs
|
@ -5,7 +5,7 @@ use std::fmt::{self, Display};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use parity_wasm::elements::{Opcode, BlockType, Local};
|
use parity_wasm::elements::{Opcode, BlockType, Local};
|
||||||
use {Error, Trap, Signature};
|
use {Error, TrapKind, Signature};
|
||||||
use module::ModuleRef;
|
use module::ModuleRef;
|
||||||
use func::{FuncRef, FuncInstance, FuncInstanceInternal};
|
use func::{FuncRef, FuncInstance, FuncInstanceInternal};
|
||||||
use value::{
|
use value::{
|
||||||
|
@ -51,7 +51,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_execution(&mut self, func: &FuncRef, args: &[RuntimeValue]) -> Result<Option<RuntimeValue>, Trap> {
|
pub fn start_execution(&mut self, func: &FuncRef, args: &[RuntimeValue]) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
let context = FunctionContext::new(
|
let context = FunctionContext::new(
|
||||||
func.clone(),
|
func.clone(),
|
||||||
DEFAULT_VALUE_STACK_LIMIT,
|
DEFAULT_VALUE_STACK_LIMIT,
|
||||||
|
@ -66,7 +66,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
self.run_interpreter_loop(&mut function_stack)
|
self.run_interpreter_loop(&mut function_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_interpreter_loop(&mut self, function_stack: &mut VecDeque<FunctionContext>) -> Result<Option<RuntimeValue>, Trap> {
|
fn run_interpreter_loop(&mut self, function_stack: &mut VecDeque<FunctionContext>) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
loop {
|
loop {
|
||||||
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
||||||
let function_ref = function_context.function.clone();
|
let function_ref = function_context.function.clone();
|
||||||
|
@ -113,7 +113,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_run_function(&mut self, function_context: &mut FunctionContext, function_body: &[Opcode], function_labels: &HashMap<usize, usize>) -> Result<RunResult, Trap> {
|
fn do_run_function(&mut self, function_context: &mut FunctionContext, function_body: &[Opcode], function_labels: &HashMap<usize, usize>) -> Result<RunResult, TrapKind> {
|
||||||
loop {
|
loop {
|
||||||
let instruction = &function_body[function_context.position];
|
let instruction = &function_body[function_context.position];
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_instruction(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, opcode: &Opcode) -> Result<InstructionOutcome, Trap> {
|
fn run_instruction(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, opcode: &Opcode) -> Result<InstructionOutcome, TrapKind> {
|
||||||
match opcode {
|
match opcode {
|
||||||
&Opcode::Unreachable => self.run_unreachable(context),
|
&Opcode::Unreachable => self.run_unreachable(context),
|
||||||
&Opcode::Nop => self.run_nop(context),
|
&Opcode::Nop => self.run_nop(context),
|
||||||
|
@ -349,25 +349,25 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_unreachable(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_unreachable(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
Err(Trap::Unreachable)
|
Err(TrapKind::Unreachable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_nop(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_nop(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_block(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Trap> {
|
fn run_block(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, TrapKind> {
|
||||||
context.push_frame(labels, BlockFrameType::Block, block_type)?;
|
context.push_frame(labels, BlockFrameType::Block, block_type)?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_loop(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Trap> {
|
fn run_loop(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, TrapKind> {
|
||||||
context.push_frame(labels, BlockFrameType::Loop, block_type)?;
|
context.push_frame(labels, BlockFrameType::Loop, block_type)?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_if(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, Trap> {
|
fn run_if(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>, block_type: BlockType) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let condition: bool = context
|
let condition: bool = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop_as();
|
.pop_as();
|
||||||
|
@ -386,23 +386,23 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_else(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>) -> Result<InstructionOutcome, Trap> {
|
fn run_else(&mut self, context: &mut FunctionContext, labels: &HashMap<usize, usize>) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let end_pos = labels[&context.position];
|
let end_pos = labels[&context.position];
|
||||||
context.pop_frame(false)?;
|
context.pop_frame(false)?;
|
||||||
context.position = end_pos;
|
context.position = end_pos;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_end(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_end(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
context.pop_frame(false)?;
|
context.pop_frame(false)?;
|
||||||
Ok(InstructionOutcome::End)
|
Ok(InstructionOutcome::End)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_br(&mut self, _context: &mut FunctionContext, label_idx: u32) -> Result<InstructionOutcome, Trap> {
|
fn run_br(&mut self, _context: &mut FunctionContext, label_idx: u32) -> Result<InstructionOutcome, TrapKind> {
|
||||||
Ok(InstructionOutcome::Branch(label_idx as usize))
|
Ok(InstructionOutcome::Branch(label_idx as usize))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_br_if(&mut self, context: &mut FunctionContext, label_idx: u32) -> Result<InstructionOutcome, Trap> {
|
fn run_br_if(&mut self, context: &mut FunctionContext, label_idx: u32) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let condition = context.value_stack_mut().pop_as();
|
let condition = context.value_stack_mut().pop_as();
|
||||||
if condition {
|
if condition {
|
||||||
Ok(InstructionOutcome::Branch(label_idx as usize))
|
Ok(InstructionOutcome::Branch(label_idx as usize))
|
||||||
|
@ -411,13 +411,13 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_br_table(&mut self, context: &mut FunctionContext, table: &[u32], default: u32) -> Result<InstructionOutcome, Trap> {
|
fn run_br_table(&mut self, context: &mut FunctionContext, table: &[u32], default: u32) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let index: u32 = context.value_stack_mut()
|
let index: u32 = context.value_stack_mut()
|
||||||
.pop_as();
|
.pop_as();
|
||||||
Ok(InstructionOutcome::Branch(table.get(index as usize).cloned().unwrap_or(default) as usize))
|
Ok(InstructionOutcome::Branch(table.get(index as usize).cloned().unwrap_or(default) as usize))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_return(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_return(&mut self, _context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
Ok(InstructionOutcome::Return)
|
Ok(InstructionOutcome::Return)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
func_idx: u32,
|
func_idx: u32,
|
||||||
) -> Result<InstructionOutcome, Trap> {
|
) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let func = context
|
let func = context
|
||||||
.module()
|
.module()
|
||||||
.func_by_index(func_idx)
|
.func_by_index(func_idx)
|
||||||
|
@ -437,7 +437,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
signature_idx: u32,
|
signature_idx: u32,
|
||||||
) -> Result<InstructionOutcome, Trap> {
|
) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let table_func_idx: u32 = context
|
let table_func_idx: u32 = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop_as();
|
.pop_as();
|
||||||
|
@ -446,8 +446,8 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.table_by_index(DEFAULT_TABLE_INDEX)
|
.table_by_index(DEFAULT_TABLE_INDEX)
|
||||||
.expect("Due to validation table should exists");
|
.expect("Due to validation table should exists");
|
||||||
let func_ref = table.get(table_func_idx)
|
let func_ref = table.get(table_func_idx)
|
||||||
.map_err(|_| Trap::TableAccessOutOfBounds)?
|
.map_err(|_| TrapKind::TableAccessOutOfBounds)?
|
||||||
.ok_or_else(|| Trap::ElemUninitialized)?;
|
.ok_or_else(|| TrapKind::ElemUninitialized)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let actual_function_type = func_ref.signature();
|
let actual_function_type = func_ref.signature();
|
||||||
|
@ -457,21 +457,21 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.expect("Due to validation type should exists");
|
.expect("Due to validation type should exists");
|
||||||
|
|
||||||
if &*required_function_type != actual_function_type {
|
if &*required_function_type != actual_function_type {
|
||||||
return Err(Trap::ElemSignatureMismatch);
|
return Err(TrapKind::ElemSignatureMismatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(InstructionOutcome::ExecuteCall(func_ref))
|
Ok(InstructionOutcome::ExecuteCall(func_ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_drop(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_drop(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let _ = context
|
let _ = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop();
|
.pop();
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_select(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_select(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let (left, mid, right) = context
|
let (left, mid, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop_triple();
|
.pop_triple();
|
||||||
|
@ -484,13 +484,13 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_get_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, Trap> {
|
fn run_get_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let val = context.get_local(index as usize);
|
let val = context.get_local(index as usize);
|
||||||
context.value_stack_mut().push(val)?;
|
context.value_stack_mut().push(val)?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
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, TrapKind> {
|
||||||
let arg = context
|
let arg = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop();
|
.pop();
|
||||||
|
@ -498,7 +498,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_tee_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, Trap> {
|
fn run_tee_local(&mut self, context: &mut FunctionContext, index: u32) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let arg = context
|
let arg = context
|
||||||
.value_stack()
|
.value_stack()
|
||||||
.top()
|
.top()
|
||||||
|
@ -511,7 +511,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Result<InstructionOutcome, Trap> {
|
) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let global = context
|
let global = context
|
||||||
.module()
|
.module()
|
||||||
.global_by_index(index)
|
.global_by_index(index)
|
||||||
|
@ -525,7 +525,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Result<InstructionOutcome, Trap> {
|
) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let val = context
|
let val = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop();
|
.pop();
|
||||||
|
@ -537,7 +537,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_load<T>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, Trap>
|
fn run_load<T>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T>, T: LittleEndianConvert {
|
where RuntimeValue: From<T>, T: LittleEndianConvert {
|
||||||
let raw_address = context
|
let raw_address = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -551,14 +551,14 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
||||||
.expect("Due to validation memory should exists");
|
.expect("Due to validation memory should exists");
|
||||||
let b = m.get(address, mem::size_of::<T>())
|
let b = m.get(address, mem::size_of::<T>())
|
||||||
.map_err(|_| Trap::MemoryAccessOutOfBounds)?;
|
.map_err(|_| TrapKind::MemoryAccessOutOfBounds)?;
|
||||||
let n = T::from_little_endian(&b)
|
let n = T::from_little_endian(&b)
|
||||||
.expect("Can't fail since buffer length should be size_of::<T>");
|
.expect("Can't fail since buffer length should be size_of::<T>");
|
||||||
context.value_stack_mut().push(n.into())?;
|
context.value_stack_mut().push(n.into())?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_load_extend<T, U>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, Trap>
|
fn run_load_extend<T, U>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, TrapKind>
|
||||||
where T: ExtendInto<U>, RuntimeValue: From<U>, T: LittleEndianConvert {
|
where T: ExtendInto<U>, RuntimeValue: From<U>, T: LittleEndianConvert {
|
||||||
let raw_address = context
|
let raw_address = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -572,7 +572,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
||||||
.expect("Due to validation memory should exists");
|
.expect("Due to validation memory should exists");
|
||||||
let b = m.get(address, mem::size_of::<T>())
|
let b = m.get(address, mem::size_of::<T>())
|
||||||
.map_err(|_| Trap::MemoryAccessOutOfBounds)?;
|
.map_err(|_| TrapKind::MemoryAccessOutOfBounds)?;
|
||||||
let v = T::from_little_endian(&b)
|
let v = T::from_little_endian(&b)
|
||||||
.expect("Can't fail since buffer length should be size_of::<T>");
|
.expect("Can't fail since buffer length should be size_of::<T>");
|
||||||
let stack_value: U = v.extend_into();
|
let stack_value: U = v.extend_into();
|
||||||
|
@ -583,7 +583,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.map(|_| InstructionOutcome::RunNextInstruction)
|
.map(|_| InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_store<T>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, Trap>
|
fn run_store<T>(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: LittleEndianConvert {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: LittleEndianConvert {
|
||||||
let stack_value = context
|
let stack_value = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -602,7 +602,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
||||||
.expect("Due to validation memory should exists");
|
.expect("Due to validation memory should exists");
|
||||||
m.set(address, &stack_value)
|
m.set(address, &stack_value)
|
||||||
.map_err(|_| Trap::MemoryAccessOutOfBounds)?;
|
.map_err(|_| TrapKind::MemoryAccessOutOfBounds)?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +611,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
_align: u32,
|
_align: u32,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
) -> Result<InstructionOutcome, Trap>
|
) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
RuntimeValue: TryInto<T, ::value::Error>,
|
RuntimeValue: TryInto<T, ::value::Error>,
|
||||||
T: WrapInto<U>,
|
T: WrapInto<U>,
|
||||||
|
@ -635,11 +635,11 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
||||||
.expect("Due to validation memory should exists");
|
.expect("Due to validation memory should exists");
|
||||||
m.set(address, &stack_value)
|
m.set(address, &stack_value)
|
||||||
.map_err(|_| Trap::MemoryAccessOutOfBounds)?;
|
.map_err(|_| TrapKind::MemoryAccessOutOfBounds)?;
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_current_memory(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_current_memory(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let m = context.module()
|
let m = context.module()
|
||||||
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
.memory_by_index(DEFAULT_MEMORY_INDEX)
|
||||||
.expect("Due to validation memory should exists");
|
.expect("Due to validation memory should exists");
|
||||||
|
@ -650,7 +650,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_grow_memory(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap> {
|
fn run_grow_memory(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind> {
|
||||||
let pages: u32 = context
|
let pages: u32 = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop_as();
|
.pop_as();
|
||||||
|
@ -666,7 +666,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_const(&mut self, context: &mut FunctionContext, val: RuntimeValue) -> Result<InstructionOutcome, Trap> {
|
fn run_const(&mut self, context: &mut FunctionContext, val: RuntimeValue) -> Result<InstructionOutcome, TrapKind> {
|
||||||
context
|
context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.push(val)
|
.push(val)
|
||||||
|
@ -674,7 +674,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.map(|_| InstructionOutcome::RunNextInstruction)
|
.map(|_| InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_relop<T, F>(&mut self, context: &mut FunctionContext, f: F) -> Result<InstructionOutcome, Trap>
|
fn run_relop<T, F>(&mut self, context: &mut FunctionContext, f: F) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
RuntimeValue: TryInto<T, ::value::Error>,
|
RuntimeValue: TryInto<T, ::value::Error>,
|
||||||
F: FnOnce(T, T) -> bool,
|
F: FnOnce(T, T) -> bool,
|
||||||
|
@ -692,7 +692,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_eqz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_eqz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T> + Default {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T> + Default {
|
||||||
let v = context
|
let v = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -702,38 +702,38 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_eq<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_eq<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T>
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T>
|
||||||
{
|
{
|
||||||
self.run_relop(context, |left, right| left == right)
|
self.run_relop(context, |left, right| left == right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ne<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_ne<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T> {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialEq<T> {
|
||||||
self.run_relop(context, |left, right| left != right)
|
self.run_relop(context, |left, right| left != right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_lt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_lt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> + Display {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> + Display {
|
||||||
self.run_relop(context, |left, right| left < right)
|
self.run_relop(context, |left, right| left < right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_gt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_gt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
||||||
self.run_relop(context, |left, right| left > right)
|
self.run_relop(context, |left, right| left > right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_lte<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_lte<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
||||||
self.run_relop(context, |left, right| left <= right)
|
self.run_relop(context, |left, right| left <= right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_gte<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_gte<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
where RuntimeValue: TryInto<T, ::value::Error>, T: PartialOrd<T> {
|
||||||
self.run_relop(context, |left, right| left >= right)
|
self.run_relop(context, |left, right| left >= right)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_unop<T, U, F>(&mut self, context: &mut FunctionContext, f: F) -> Result<InstructionOutcome, Trap>
|
fn run_unop<T, U, F>(&mut self, context: &mut FunctionContext, f: F) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
F: FnOnce(T) -> U,
|
F: FnOnce(T) -> U,
|
||||||
RuntimeValue: From<U> + TryInto<T, ::value::Error>
|
RuntimeValue: From<U> + TryInto<T, ::value::Error>
|
||||||
|
@ -746,22 +746,22 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_clz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_clz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
||||||
self.run_unop(context, |v| v.leading_zeros())
|
self.run_unop(context, |v| v.leading_zeros())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ctz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_ctz<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
||||||
self.run_unop(context, |v| v.trailing_zeros())
|
self.run_unop(context, |v| v.trailing_zeros())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_popcnt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_popcnt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
||||||
self.run_unop(context, |v| v.count_ones())
|
self.run_unop(context, |v| v.count_ones())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_add<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_add<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -772,7 +772,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_sub<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_sub<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -783,7 +783,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_mul<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_mul<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: ArithmeticOps<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -794,7 +794,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_div<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_div<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U> + Display, U: ArithmeticOps<U> + TransmuteInto<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U> + Display, U: ArithmeticOps<U> + TransmuteInto<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -807,7 +807,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_rem<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_rem<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U>, U: Integer<U> + TransmuteInto<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U>, U: Integer<U> + TransmuteInto<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -820,7 +820,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_and<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_and<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<<T as ops::BitAnd>::Output> + TryInto<T, ::value::Error>, T: ops::BitAnd<T> {
|
where RuntimeValue: From<<T as ops::BitAnd>::Output> + TryInto<T, ::value::Error>, T: ops::BitAnd<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -831,7 +831,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_or<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_or<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<<T as ops::BitOr>::Output> + TryInto<T, ::value::Error>, T: ops::BitOr<T> {
|
where RuntimeValue: From<<T as ops::BitOr>::Output> + TryInto<T, ::value::Error>, T: ops::BitOr<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -842,7 +842,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_xor<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_xor<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<<T as ops::BitXor>::Output> + TryInto<T, ::value::Error>, T: ops::BitXor<T> {
|
where RuntimeValue: From<<T as ops::BitXor>::Output> + TryInto<T, ::value::Error>, T: ops::BitXor<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -853,7 +853,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_shl<T>(&mut self, context: &mut FunctionContext, mask: T) -> Result<InstructionOutcome, Trap>
|
fn run_shl<T>(&mut self, context: &mut FunctionContext, mask: T) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<<T as ops::Shl<T>>::Output> + TryInto<T, ::value::Error>, T: ops::Shl<T> + ops::BitAnd<T, Output=T> {
|
where RuntimeValue: From<<T as ops::Shl<T>>::Output> + TryInto<T, ::value::Error>, T: ops::Shl<T> + ops::BitAnd<T, Output=T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -864,7 +864,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_shr<T, U>(&mut self, context: &mut FunctionContext, mask: U) -> Result<InstructionOutcome, Trap>
|
fn run_shr<T, U>(&mut self, context: &mut FunctionContext, mask: U) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U>, U: ops::Shr<U> + ops::BitAnd<U, Output=U>, <U as ops::Shr<U>>::Output: TransmuteInto<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: TransmuteInto<U>, U: ops::Shr<U> + ops::BitAnd<U, Output=U>, <U as ops::Shr<U>>::Output: TransmuteInto<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -877,7 +877,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_rotl<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_rotl<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -888,7 +888,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_rotr<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_rotr<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Integer<T>
|
||||||
{
|
{
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
|
@ -900,13 +900,13 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_abs<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_abs<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.abs())
|
self.run_unop(context, |v| v.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_neg<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_neg<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
RuntimeValue: From<<T as ops::Neg>::Output> + TryInto<T, ::value::Error>,
|
RuntimeValue: From<<T as ops::Neg>::Output> + TryInto<T, ::value::Error>,
|
||||||
T: ops::Neg
|
T: ops::Neg
|
||||||
|
@ -914,37 +914,37 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
self.run_unop(context, |v| v.neg())
|
self.run_unop(context, |v| v.neg())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ceil<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_ceil<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.ceil())
|
self.run_unop(context, |v| v.ceil())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_floor<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_floor<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.floor())
|
self.run_unop(context, |v| v.floor())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_trunc<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_trunc<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.trunc())
|
self.run_unop(context, |v| v.trunc())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_nearest<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_nearest<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.nearest())
|
self.run_unop(context, |v| v.nearest())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_sqrt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_sqrt<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
self.run_unop(context, |v| v.sqrt())
|
self.run_unop(context, |v| v.sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_min<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_min<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T>
|
||||||
{
|
{
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
|
@ -956,7 +956,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_max<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_max<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -967,7 +967,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_copysign<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_copysign<T>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T> {
|
where RuntimeValue: From<T> + TryInto<T, ::value::Error>, T: Float<T> {
|
||||||
let (left, right) = context
|
let (left, right) = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
|
@ -978,13 +978,13 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_wrap<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_wrap<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<U> + TryInto<T, ::value::Error>, T: WrapInto<U> {
|
where RuntimeValue: From<U> + TryInto<T, ::value::Error>, T: WrapInto<U> {
|
||||||
self.run_unop(context, |v| v.wrap_into())
|
self.run_unop(context, |v| v.wrap_into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_trunc_to_int<T, U, V>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_trunc_to_int<T, U, V>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where RuntimeValue: From<V> + TryInto<T, ::value::Error>, T: TryTruncateInto<U, Trap>, U: TransmuteInto<V>, {
|
where RuntimeValue: From<V> + TryInto<T, ::value::Error>, T: TryTruncateInto<U, TrapKind>, U: TransmuteInto<V>, {
|
||||||
let v = context
|
let v = context
|
||||||
.value_stack_mut()
|
.value_stack_mut()
|
||||||
.pop_as::<T>();
|
.pop_as::<T>();
|
||||||
|
@ -995,7 +995,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
.map(|_| InstructionOutcome::RunNextInstruction)
|
.map(|_| InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_extend<T, U, V>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_extend<T, U, V>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
RuntimeValue: From<V> + TryInto<T, ::value::Error>, T: ExtendInto<U>, U: TransmuteInto<V>
|
RuntimeValue: From<V> + TryInto<T, ::value::Error>, T: ExtendInto<U>, U: TransmuteInto<V>
|
||||||
{
|
{
|
||||||
|
@ -1009,7 +1009,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
Ok(InstructionOutcome::RunNextInstruction)
|
Ok(InstructionOutcome::RunNextInstruction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_reinterpret<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, Trap>
|
fn run_reinterpret<T, U>(&mut self, context: &mut FunctionContext) -> Result<InstructionOutcome, TrapKind>
|
||||||
where
|
where
|
||||||
RuntimeValue: From<U>, RuntimeValue: TryInto<T, ::value::Error>, T: TransmuteInto<U>
|
RuntimeValue: From<U>, RuntimeValue: TryInto<T, ::value::Error>, T: TransmuteInto<U>
|
||||||
{
|
{
|
||||||
|
@ -1061,7 +1061,7 @@ impl FunctionContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nested(&mut self, function: FuncRef) -> Result<Self, Trap> {
|
pub fn nested(&mut self, function: FuncRef) -> Result<Self, TrapKind> {
|
||||||
let (function_locals, module, function_return_type) = {
|
let (function_locals, module, function_return_type) = {
|
||||||
let module = match *function.as_internal() {
|
let module = match *function.as_internal() {
|
||||||
FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"),
|
FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"),
|
||||||
|
@ -1127,7 +1127,7 @@ impl FunctionContext {
|
||||||
&self.frame_stack
|
&self.frame_stack
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_frame(&mut self, labels: &HashMap<usize, usize>, frame_type: BlockFrameType, block_type: BlockType) -> Result<(), Trap> {
|
pub fn push_frame(&mut self, labels: &HashMap<usize, usize>, frame_type: BlockFrameType, block_type: BlockType) -> Result<(), TrapKind> {
|
||||||
let begin_position = self.position;
|
let begin_position = self.position;
|
||||||
let branch_position = match frame_type {
|
let branch_position = match frame_type {
|
||||||
BlockFrameType::Function => usize::MAX,
|
BlockFrameType::Function => usize::MAX,
|
||||||
|
@ -1153,7 +1153,7 @@ impl FunctionContext {
|
||||||
branch_position: branch_position,
|
branch_position: branch_position,
|
||||||
end_position: end_position,
|
end_position: end_position,
|
||||||
value_stack_len: self.value_stack.len(),
|
value_stack_len: self.value_stack.len(),
|
||||||
}).map_err(|_| Trap::StackOverflow)?;
|
}).map_err(|_| TrapKind::StackOverflow)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1162,7 @@ impl FunctionContext {
|
||||||
let _ = self.frame_stack.pop().expect("Due to validation frame stack shouldn't be empty");
|
let _ = self.frame_stack.pop().expect("Due to validation frame stack shouldn't be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_frame(&mut self, is_branch: bool) -> Result<(), Trap> {
|
pub fn pop_frame(&mut self, is_branch: bool) -> Result<(), TrapKind> {
|
||||||
let frame = self.frame_stack
|
let frame = self.frame_stack
|
||||||
.pop()
|
.pop()
|
||||||
.expect("Due to validation frame stack shouldn't be empty");
|
.expect("Due to validation frame stack shouldn't be empty");
|
||||||
|
@ -1189,9 +1189,9 @@ impl fmt::Debug for FunctionContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effective_address(address: u32, offset: u32) -> Result<u32, Trap> {
|
fn effective_address(address: u32, offset: u32) -> Result<u32, TrapKind> {
|
||||||
match offset.checked_add(address) {
|
match offset.checked_add(address) {
|
||||||
None => Err(Trap::MemoryAccessOutOfBounds),
|
None => Err(TrapKind::MemoryAccessOutOfBounds),
|
||||||
Some(address) => Ok(address),
|
Some(address) => Ok(address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1277,9 +1277,9 @@ impl ValueStack {
|
||||||
self.stack_with_limit.pop().expect("Due to validation stack shouldn't be empty")
|
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<(), TrapKind> {
|
||||||
self.stack_with_limit.push(value)
|
self.stack_with_limit.push(value)
|
||||||
.map_err(|_| Trap::StackOverflow)
|
.map_err(|_| TrapKind::StackOverflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, new_len: usize) {
|
fn resize(&mut self, new_len: usize) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
|
Error, Signature, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder,
|
||||||
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
|
MemoryInstance, MemoryRef, TableInstance, TableRef, ModuleImportResolver, ModuleInstance, ModuleRef,
|
||||||
RuntimeValue, RuntimeArgs, TableDescriptor, MemoryDescriptor, Trap,
|
RuntimeValue, RuntimeArgs, TableDescriptor, MemoryDescriptor, TrapKind,
|
||||||
};
|
};
|
||||||
use types::ValueType;
|
use types::ValueType;
|
||||||
use super::parse_wat;
|
use super::parse_wat;
|
||||||
|
@ -79,7 +79,7 @@ impl Externals for TestHost {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
SUB_FUNC_INDEX => {
|
SUB_FUNC_INDEX => {
|
||||||
let a: i32 = args.nth(0);
|
let a: i32 = args.nth(0);
|
||||||
|
@ -92,7 +92,7 @@ impl Externals for TestHost {
|
||||||
ERR_FUNC_INDEX => {
|
ERR_FUNC_INDEX => {
|
||||||
let error_code: u32 = args.nth(0);
|
let error_code: u32 = args.nth(0);
|
||||||
let error = HostErrorWithCode { error_code };
|
let error = HostErrorWithCode { error_code };
|
||||||
Err(Trap::Host(Box::new(error)))
|
Err(TrapKind::Host(Box::new(error)))
|
||||||
}
|
}
|
||||||
INC_MEM_FUNC_INDEX => {
|
INC_MEM_FUNC_INDEX => {
|
||||||
let ptr: u32 = args.nth(0);
|
let ptr: u32 = args.nth(0);
|
||||||
|
@ -131,7 +131,7 @@ impl Externals for TestHost {
|
||||||
.expect("expected to be Some");
|
.expect("expected to be Some");
|
||||||
|
|
||||||
if val.value_type() != result.value_type() {
|
if val.value_type() != result.value_type() {
|
||||||
return Err(Trap::Host(Box::new(HostErrorWithCode { error_code: 123 })));
|
return Err(TrapKind::Host(Box::new(HostErrorWithCode { error_code: 123 })));
|
||||||
}
|
}
|
||||||
Ok(Some(result))
|
Ok(Some(result))
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ fn host_err() {
|
||||||
);
|
);
|
||||||
|
|
||||||
let host_error: Box<HostError> = match error {
|
let host_error: Box<HostError> = match error {
|
||||||
Error::Trap(Trap::Host(err)) => err,
|
Error::TrapKind(TrapKind::Host(err)) => err,
|
||||||
err => panic!("Unexpected error {:?}", err),
|
err => panic!("Unexpected error {:?}", err),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ fn defer_providing_externals() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
INC_FUNC_INDEX => {
|
INC_FUNC_INDEX => {
|
||||||
let a = args.nth::<u32>(0);
|
let a = args.nth::<u32>(0);
|
||||||
|
@ -523,7 +523,7 @@ fn two_envs_one_externals() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
_args: RuntimeArgs,
|
_args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
PRIVILEGED_FUNC_INDEX => {
|
PRIVILEGED_FUNC_INDEX => {
|
||||||
println!("privileged!");
|
println!("privileged!");
|
||||||
|
@ -643,7 +643,7 @@ fn dynamically_add_host_func() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
_args: RuntimeArgs,
|
_args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, Trap> {
|
) -> Result<Option<RuntimeValue>, TrapKind> {
|
||||||
match index {
|
match index {
|
||||||
ADD_FUNC_FUNC_INDEX => {
|
ADD_FUNC_FUNC_INDEX => {
|
||||||
// Allocate indicies for the new function.
|
// Allocate indicies for the new function.
|
||||||
|
@ -657,7 +657,7 @@ fn dynamically_add_host_func() {
|
||||||
host_func_index as usize,
|
host_func_index as usize,
|
||||||
);
|
);
|
||||||
self.table.set(table_index, Some(added_func))
|
self.table.set(table_index, Some(added_func))
|
||||||
.map_err(|_| Trap::TableAccessOutOfBounds)?;
|
.map_err(|_| TrapKind::TableAccessOutOfBounds)?;
|
||||||
|
|
||||||
Ok(Some(RuntimeValue::I32(table_index as i32)))
|
Ok(Some(RuntimeValue::I32(table_index as i32)))
|
||||||
}
|
}
|
||||||
|
|
26
src/value.rs
26
src/value.rs
|
@ -1,7 +1,7 @@
|
||||||
use std::{i32, i64, u32, u64, f32};
|
use std::{i32, i64, u32, u64, f32};
|
||||||
use std::io;
|
use std::io;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use {Trap};
|
use {TrapKind};
|
||||||
use parity_wasm::elements::ValueType;
|
use parity_wasm::elements::ValueType;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -72,7 +72,7 @@ pub trait ArithmeticOps<T> {
|
||||||
/// Multiply two values.
|
/// Multiply two values.
|
||||||
fn mul(self, other: T) -> T;
|
fn mul(self, other: T) -> T;
|
||||||
/// Divide two values.
|
/// Divide two values.
|
||||||
fn div(self, other: T) -> Result<T, Trap>;
|
fn div(self, other: T) -> Result<T, TrapKind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Integer value.
|
/// Integer value.
|
||||||
|
@ -88,7 +88,7 @@ pub trait Integer<T>: ArithmeticOps<T> {
|
||||||
/// Get right bit rotation result.
|
/// Get right bit rotation result.
|
||||||
fn rotr(self, other: T) -> T;
|
fn rotr(self, other: T) -> T;
|
||||||
/// Get division remainder.
|
/// Get division remainder.
|
||||||
fn rem(self, other: T) -> Result<T, Trap>;
|
fn rem(self, other: T) -> Result<T, TrapKind>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float-point value.
|
/// Float-point value.
|
||||||
|
@ -270,19 +270,19 @@ impl_wrap_into!(f64, f32);
|
||||||
|
|
||||||
macro_rules! impl_try_truncate_into {
|
macro_rules! impl_try_truncate_into {
|
||||||
($from: ident, $into: ident) => {
|
($from: ident, $into: ident) => {
|
||||||
impl TryTruncateInto<$into, Trap> for $from {
|
impl TryTruncateInto<$into, TrapKind> for $from {
|
||||||
fn try_truncate_into(self) -> Result<$into, Trap> {
|
fn try_truncate_into(self) -> Result<$into, TrapKind> {
|
||||||
// Casting from a float to an integer will round the float towards zero
|
// Casting from a float to an integer will round the float towards zero
|
||||||
// NOTE: currently this will cause Undefined Behavior if the rounded value cannot be represented by the
|
// NOTE: currently this will cause Undefined Behavior if the rounded value cannot be represented by the
|
||||||
// target integer type. This includes Inf and NaN. This is a bug and will be fixed.
|
// target integer type. This includes Inf and NaN. This is a bug and will be fixed.
|
||||||
if self.is_nan() || self.is_infinite() {
|
if self.is_nan() || self.is_infinite() {
|
||||||
return Err(Trap::InvalidConversionToInt);
|
return Err(TrapKind::InvalidConversionToInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// range check
|
// range check
|
||||||
let result = self as $into;
|
let result = self as $into;
|
||||||
if result as $from != self.trunc() {
|
if result as $from != self.trunc() {
|
||||||
return Err(Trap::InvalidConversionToInt);
|
return Err(TrapKind::InvalidConversionToInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self as $into)
|
Ok(self as $into)
|
||||||
|
@ -544,14 +544,14 @@ macro_rules! impl_integer_arithmetic_ops {
|
||||||
fn add(self, other: $type) -> $type { self.wrapping_add(other) }
|
fn add(self, other: $type) -> $type { self.wrapping_add(other) }
|
||||||
fn sub(self, other: $type) -> $type { self.wrapping_sub(other) }
|
fn sub(self, other: $type) -> $type { self.wrapping_sub(other) }
|
||||||
fn mul(self, other: $type) -> $type { self.wrapping_mul(other) }
|
fn mul(self, other: $type) -> $type { self.wrapping_mul(other) }
|
||||||
fn div(self, other: $type) -> Result<$type, Trap> {
|
fn div(self, other: $type) -> Result<$type, TrapKind> {
|
||||||
if other == 0 {
|
if other == 0 {
|
||||||
Err(Trap::DivisionByZero)
|
Err(TrapKind::DivisionByZero)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let (result, overflow) = self.overflowing_div(other);
|
let (result, overflow) = self.overflowing_div(other);
|
||||||
if overflow {
|
if overflow {
|
||||||
Err(Trap::InvalidConversionToInt)
|
Err(TrapKind::InvalidConversionToInt)
|
||||||
} else {
|
} else {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
@ -572,7 +572,7 @@ macro_rules! impl_float_arithmetic_ops {
|
||||||
fn add(self, other: $type) -> $type { self + other }
|
fn add(self, other: $type) -> $type { self + other }
|
||||||
fn sub(self, other: $type) -> $type { self - other }
|
fn sub(self, other: $type) -> $type { self - other }
|
||||||
fn mul(self, other: $type) -> $type { self * other }
|
fn mul(self, other: $type) -> $type { self * other }
|
||||||
fn div(self, other: $type) -> Result<$type, Trap> { Ok(self / other) }
|
fn div(self, other: $type) -> Result<$type, TrapKind> { Ok(self / other) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,8 +588,8 @@ macro_rules! impl_integer {
|
||||||
fn count_ones(self) -> $type { self.count_ones() as $type }
|
fn count_ones(self) -> $type { self.count_ones() as $type }
|
||||||
fn rotl(self, other: $type) -> $type { self.rotate_left(other as u32) }
|
fn rotl(self, other: $type) -> $type { self.rotate_left(other as u32) }
|
||||||
fn rotr(self, other: $type) -> $type { self.rotate_right(other as u32) }
|
fn rotr(self, other: $type) -> $type { self.rotate_right(other as u32) }
|
||||||
fn rem(self, other: $type) -> Result<$type, Trap> {
|
fn rem(self, other: $type) -> Result<$type, TrapKind> {
|
||||||
if other == 0 { Err(Trap::DivisionByZero) }
|
if other == 0 { Err(TrapKind::DivisionByZero) }
|
||||||
else { Ok(self.wrapping_rem(other)) }
|
else { Ok(self.wrapping_rem(other)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue