Replace Trap with struct. Enum is now TrapKind
This commit is contained in:
parent
daf7d95a65
commit
2b80a98b7f
|
@ -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, TrapKind,
|
RuntimeArgs, Trap,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[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>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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, TrapKind,
|
Module, Signature, MemoryDescriptor, Trap,
|
||||||
TableDescriptor, GlobalDescriptor, FuncInstance, RuntimeArgs,
|
TableDescriptor, GlobalDescriptor, FuncInstance, RuntimeArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
Load(String),
|
Load(String),
|
||||||
Start(TrapKind),
|
Start(Trap),
|
||||||
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>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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::AssertTrapKind {
|
&test::Command::AssertTrap {
|
||||||
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")]
|
||||||
AssertTrapKind {
|
AssertTrap {
|
||||||
line: u64,
|
line: u64,
|
||||||
action: Action,
|
action: Action,
|
||||||
text: String,
|
text: String,
|
||||||
|
|
|
@ -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 {TrapKind, Signature};
|
use {Trap, 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;
|
||||||
|
@ -140,8 +140,8 @@ impl FuncInstance {
|
||||||
func: &FuncRef,
|
func: &FuncRef,
|
||||||
args: &[RuntimeValue],
|
args: &[RuntimeValue],
|
||||||
externals: &mut E,
|
externals: &mut E,
|
||||||
) -> Result<Option<RuntimeValue>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
check_function_args(func.signature(), &args).map_err(|_| TrapKind::UnexpectedSignature)?;
|
check_function_args(func.signature(), &args).map_err(|_| Trap::new(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);
|
||||||
|
|
24
src/host.rs
24
src/host.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use value::{RuntimeValue, TryInto};
|
use value::{RuntimeValue, TryInto};
|
||||||
use TrapKind;
|
use {TrapKind, Trap};
|
||||||
|
|
||||||
/// 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, TrapKind> where RuntimeValue: TryInto<T, ::value::Error> {
|
pub fn nth_checked<T>(&self, idx: usize) -> Result<T, Trap> where RuntimeValue: TryInto<T, ::value::Error> {
|
||||||
Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| TrapKind::UnexpectedSignature)?)
|
Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| Trap::new(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, TrapKind> {
|
pub fn nth_value_checked(&self, idx: usize) -> Result<RuntimeValue, Trap> {
|
||||||
if self.0.len() <= idx {
|
if self.0.len() <= idx {
|
||||||
return Err(TrapKind::UnexpectedSignature);
|
return Err(Trap::new(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, TrapKind,
|
/// FuncRef, ValueType, Signature, FuncInstance, Trap,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// struct HostExternals {
|
/// struct HostExternals {
|
||||||
|
@ -136,11 +136,11 @@ impl HostError {
|
||||||
/// &mut self,
|
/// &mut self,
|
||||||
/// index: usize,
|
/// index: usize,
|
||||||
/// args: RuntimeArgs,
|
/// args: RuntimeArgs,
|
||||||
/// ) -> Result<Option<RuntimeValue>, TrapKind> {
|
/// ) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
/// match index {
|
/// match index {
|
||||||
/// ADD_FUNC_INDEX => {
|
/// ADD_FUNC_INDEX => {
|
||||||
/// let a: u32 = args.nth(0);
|
/// let a: u32 = args.nth_checked(0)?;
|
||||||
/// let b: u32 = args.nth(1);
|
/// let b: u32 = args.nth_checked(1)?;
|
||||||
/// let result = a + b;
|
/// let result = a + b;
|
||||||
///
|
///
|
||||||
/// Ok(Some(RuntimeValue::I32(result as i32)))
|
/// Ok(Some(RuntimeValue::I32(result as i32)))
|
||||||
|
@ -192,7 +192,7 @@ pub trait Externals {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, TrapKind>;
|
) -> Result<Option<RuntimeValue>, Trap>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
Err(TrapKind::Unreachable)
|
Err(Trap::new(TrapKind::Unreachable))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
src/lib.rs
63
src/lib.rs
|
@ -105,6 +105,27 @@ use std::fmt;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
/// Traps can't be handled by WebAssembly code, but are reported to the embedder.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Trap {
|
||||||
|
kind: TrapKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trap {
|
||||||
|
/// Create new trap.
|
||||||
|
pub fn new(kind: TrapKind) -> Trap {
|
||||||
|
Trap { kind }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns kind of this trap.
|
||||||
|
pub fn kind(&self) -> &TrapKind {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 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 `TrapKind`, which immediately aborts execution.
|
/// Under some conditions, wasm execution may produce a `TrapKind`, which immediately aborts execution.
|
||||||
|
@ -201,12 +222,33 @@ pub enum Error {
|
||||||
Global(String),
|
Global(String),
|
||||||
/// Value-level error.
|
/// Value-level error.
|
||||||
Value(String),
|
Value(String),
|
||||||
/// TrapKind.
|
/// Trap.
|
||||||
TrapKind(TrapKind),
|
Trap(Trap),
|
||||||
/// Custom embedder error.
|
/// Custom embedder error.
|
||||||
Host(Box<host::HostError>),
|
Host(Box<host::HostError>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
/// Returns [`HostError`] if this `Error` represents some host error.
|
||||||
|
///
|
||||||
|
/// I.e. if this error have variant [`Host`] or [`Trap`][`Trap`] with [host][`TrapKind::Host`] error.
|
||||||
|
///
|
||||||
|
/// [`HostError`]: trait.HostError.html
|
||||||
|
/// [`Host`]: enum.Error.html#variant.Host
|
||||||
|
/// [`Trap`]: enum.Error.html#variant.Trap
|
||||||
|
/// [`TrapKind::Host`]: enum.TrapKind.html#variant.Host
|
||||||
|
pub fn as_host_error(&self) -> Option<&host::HostError> {
|
||||||
|
match *self {
|
||||||
|
Error::Host(ref host_err) => Some(&**host_err),
|
||||||
|
Error::Trap(ref trap) => match *trap.kind() {
|
||||||
|
TrapKind::Host(ref host_err) => Some(&**host_err),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Into<String> for Error {
|
impl Into<String> for Error {
|
||||||
fn into(self) -> String {
|
fn into(self) -> String {
|
||||||
match self {
|
match self {
|
||||||
|
@ -217,7 +259,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::TrapKind(s) => format!("trap: {:?}", s),
|
Error::Trap(s) => format!("trap: {:?}", s),
|
||||||
Error::Host(e) => format!("user: {}", e),
|
Error::Host(e) => format!("user: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +275,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::TrapKind(ref s) => write!(f, "TrapKind: {:?}", s),
|
Error::Trap(ref s) => write!(f, "TrapKind: {:?}", s),
|
||||||
Error::Host(ref e) => write!(f, "User: {}", e),
|
Error::Host(ref e) => write!(f, "User: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,28 +291,27 @@ 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::TrapKind(_) => "TrapKind",
|
Error::Trap(_) => "TrapKind",
|
||||||
Error::Host(_) => "Host error",
|
Error::Host(_) => "Host error",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<U> From<U> for Error where U: host::HostError + Sized {
|
impl<U> From<U> for Error where U: host::HostError + Sized {
|
||||||
fn from(e: U) -> Self {
|
fn from(e: U) -> Self {
|
||||||
Error::Host(Box::new(e))
|
Error::Host(Box::new(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> From<U> for TrapKind where U: host::HostError + Sized {
|
impl<U> From<U> for Trap where U: host::HostError + Sized {
|
||||||
fn from(e: U) -> Self {
|
fn from(e: U) -> Self {
|
||||||
TrapKind::Host(Box::new(e))
|
Trap::new(TrapKind::Host(Box::new(e)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrapKind> for Error {
|
impl From<Trap> for Error {
|
||||||
fn from(e: TrapKind) -> Error {
|
fn from(e: Trap) -> Error {
|
||||||
Error::TrapKind(e)
|
Error::Trap(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use runner::check_function_args;
|
use runner::check_function_args;
|
||||||
use TrapKind;
|
use Trap;
|
||||||
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::TrapKind(t))
|
.map_err(|t| Error::Trap(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, TrapKind> {
|
pub fn run_start<E: Externals>(self, state: &mut E) -> Result<ModuleRef, Trap> {
|
||||||
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",
|
||||||
|
|
|
@ -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, TrapKind, Signature};
|
use {Error, Trap, 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>, TrapKind> {
|
pub fn start_execution(&mut self, func: &FuncRef, args: &[RuntimeValue]) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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>, TrapKind> {
|
fn run_interpreter_loop(&mut self, function_stack: &mut VecDeque<FunctionContext>) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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();
|
||||||
|
@ -78,16 +78,16 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
if !function_context.is_initialized() {
|
if !function_context.is_initialized() {
|
||||||
let return_type = function_context.return_type;
|
let return_type = function_context.return_type;
|
||||||
function_context.initialize(&function_body.locals);
|
function_context.initialize(&function_body.locals);
|
||||||
function_context.push_frame(&function_body.labels, BlockFrameType::Function, return_type)?;
|
function_context.push_frame(&function_body.labels, BlockFrameType::Function, return_type).map_err(Trap::new)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let function_return = self.do_run_function(&mut function_context, function_body.opcodes.elements(), &function_body.labels)?;
|
let function_return = self.do_run_function(&mut function_context, function_body.opcodes.elements(), &function_body.labels).map_err(Trap::new)?;
|
||||||
|
|
||||||
match function_return {
|
match function_return {
|
||||||
RunResult::Return(return_value) => {
|
RunResult::Return(return_value) => {
|
||||||
match function_stack.back_mut() {
|
match function_stack.back_mut() {
|
||||||
Some(caller_context) => if let Some(return_value) = return_value {
|
Some(caller_context) => if let Some(return_value) = return_value {
|
||||||
caller_context.value_stack_mut().push(return_value)?;
|
caller_context.value_stack_mut().push(return_value).map_err(Trap::new)?;
|
||||||
},
|
},
|
||||||
None => return Ok(return_value),
|
None => return Ok(return_value),
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
RunResult::NestedCall(nested_func) => {
|
RunResult::NestedCall(nested_func) => {
|
||||||
match *nested_func.as_internal() {
|
match *nested_func.as_internal() {
|
||||||
FuncInstanceInternal::Internal { .. } => {
|
FuncInstanceInternal::Internal { .. } => {
|
||||||
let nested_context = function_context.nested(nested_func.clone())?;
|
let nested_context = function_context.nested(nested_func.clone()).map_err(Trap::new)?;
|
||||||
function_stack.push_back(function_context);
|
function_stack.push_back(function_context);
|
||||||
function_stack.push_back(nested_context);
|
function_stack.push_back(nested_context);
|
||||||
},
|
},
|
||||||
|
@ -103,7 +103,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
let args = prepare_function_args(signature, &mut function_context.value_stack);
|
let args = prepare_function_args(signature, &mut function_context.value_stack);
|
||||||
let return_val = FuncInstance::invoke(&nested_func, &args, self.externals)?;
|
let return_val = FuncInstance::invoke(&nested_func, &args, self.externals)?;
|
||||||
if let Some(return_val) = return_val {
|
if let Some(return_val) = return_val {
|
||||||
function_context.value_stack_mut().push(return_val)?;
|
function_context.value_stack_mut().push(return_val).map_err(Trap::new)?;
|
||||||
}
|
}
|
||||||
function_stack.push_back(function_context);
|
function_stack.push_back(function_context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, TrapKind,
|
RuntimeValue, RuntimeArgs, TableDescriptor, MemoryDescriptor, Trap, 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>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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(TrapKind::Host(Box::new(error)))
|
Err(Trap::new(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(TrapKind::Host(Box::new(HostErrorWithCode { error_code: 123 })));
|
return Err(Trap::new(TrapKind::Host(Box::new(HostErrorWithCode { error_code: 123 }))));
|
||||||
}
|
}
|
||||||
Ok(Some(result))
|
Ok(Some(result))
|
||||||
}
|
}
|
||||||
|
@ -257,12 +257,7 @@ fn host_err() {
|
||||||
"`test` expected to return error",
|
"`test` expected to return error",
|
||||||
);
|
);
|
||||||
|
|
||||||
let host_error: Box<HostError> = match error {
|
let error_with_code = error.as_host_error().expect("Expected host error").downcast_ref::<HostErrorWithCode>().expect(
|
||||||
Error::TrapKind(TrapKind::Host(err)) => err,
|
|
||||||
err => panic!("Unexpected error {:?}", err),
|
|
||||||
};
|
|
||||||
|
|
||||||
let error_with_code = host_error.downcast_ref::<HostErrorWithCode>().expect(
|
|
||||||
"Failed to downcast to expected error type",
|
"Failed to downcast to expected error type",
|
||||||
);
|
);
|
||||||
assert_eq!(error_with_code.error_code, 228);
|
assert_eq!(error_with_code.error_code, 228);
|
||||||
|
@ -459,7 +454,7 @@ fn defer_providing_externals() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
args: RuntimeArgs,
|
args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
match index {
|
match index {
|
||||||
INC_FUNC_INDEX => {
|
INC_FUNC_INDEX => {
|
||||||
let a = args.nth::<u32>(0);
|
let a = args.nth::<u32>(0);
|
||||||
|
@ -523,7 +518,7 @@ fn two_envs_one_externals() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
_args: RuntimeArgs,
|
_args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
match index {
|
match index {
|
||||||
PRIVILEGED_FUNC_INDEX => {
|
PRIVILEGED_FUNC_INDEX => {
|
||||||
println!("privileged!");
|
println!("privileged!");
|
||||||
|
@ -643,7 +638,7 @@ fn dynamically_add_host_func() {
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
_args: RuntimeArgs,
|
_args: RuntimeArgs,
|
||||||
) -> Result<Option<RuntimeValue>, TrapKind> {
|
) -> Result<Option<RuntimeValue>, Trap> {
|
||||||
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 +652,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(|_| TrapKind::TableAccessOutOfBounds)?;
|
.map_err(|_| Trap::new(TrapKind::TableAccessOutOfBounds))?;
|
||||||
|
|
||||||
Ok(Some(RuntimeValue::I32(table_index as i32)))
|
Ok(Some(RuntimeValue::I32(table_index as i32)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue