mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-14 15:31:44 +00:00
CustomUserError -> UserError
This commit is contained in:
@ -14,7 +14,7 @@ use parity_wasm::interpreter::{
|
|||||||
DefaultProgramInstance, DefaultModuleInstance,
|
DefaultProgramInstance, DefaultModuleInstance,
|
||||||
ItemIndex, ExportEntryType,
|
ItemIndex, ExportEntryType,
|
||||||
Error as InterpreterError,
|
Error as InterpreterError,
|
||||||
DummyCustomUserError,
|
DummyUserError,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn spec_test_module() -> elements::Module {
|
fn spec_test_module() -> elements::Module {
|
||||||
@ -58,7 +58,7 @@ fn try_deserialize(base_dir: &str, module_path: &str) -> Result<elements::Module
|
|||||||
parity_wasm::deserialize_file(&wasm_path)
|
parity_wasm::deserialize_file(&wasm_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_load(base_dir: &str, module_path: &str) -> Result<(), parity_wasm::interpreter::Error<DummyCustomUserError>> {
|
fn try_load(base_dir: &str, module_path: &str) -> Result<(), parity_wasm::interpreter::Error<DummyUserError>> {
|
||||||
let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?;
|
let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?;
|
||||||
let program = DefaultProgramInstance::new().expect("Failed creating program");
|
let program = DefaultProgramInstance::new().expect("Failed creating program");
|
||||||
program.add_module("try_load", module, None).map(|_| ())
|
program.add_module("try_load", module, None).map(|_| ())
|
||||||
@ -91,7 +91,7 @@ fn runtime_values(test_vals: &[test::RuntimeValue]) -> Vec<parity_wasm::RuntimeV
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_action(program: &DefaultProgramInstance, action: &test::Action)
|
fn run_action(program: &DefaultProgramInstance, action: &test::Action)
|
||||||
-> Result<Option<parity_wasm::RuntimeValue>, InterpreterError<DummyCustomUserError>>
|
-> Result<Option<parity_wasm::RuntimeValue>, InterpreterError<DummyUserError>>
|
||||||
{
|
{
|
||||||
match *action {
|
match *action {
|
||||||
test::Action::Invoke { ref module, ref field, ref args } => {
|
test::Action::Invoke { ref module, ref field, ref args } => {
|
||||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use builder::module;
|
use builder::module;
|
||||||
use elements::{Module, ExportEntry, Internal, GlobalEntry, GlobalType,
|
use elements::{Module, ExportEntry, Internal, GlobalEntry, GlobalType,
|
||||||
ValueType, InitExpr, Opcode, Opcodes};
|
ValueType, InitExpr, Opcode, Opcodes};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::env_native::NATIVE_INDEX_FUNC_MIN;
|
use interpreter::env_native::NATIVE_INDEX_FUNC_MIN;
|
||||||
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
|
use interpreter::module::{ModuleInstanceInterface, ModuleInstance, ExecutionParams,
|
||||||
ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
||||||
@ -78,12 +78,12 @@ pub struct EnvParams {
|
|||||||
pub allow_memory_growth: bool,
|
pub allow_memory_growth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnvModuleInstance<E: CustomUserError> {
|
pub struct EnvModuleInstance<E: UserError> {
|
||||||
_params: EnvParams,
|
_params: EnvParams,
|
||||||
instance: ModuleInstance<E>,
|
instance: ModuleInstance<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> EnvModuleInstance<E> where E: CustomUserError {
|
impl<E> EnvModuleInstance<E> where E: UserError {
|
||||||
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error<E>> {
|
pub fn new(params: EnvParams, module: Module) -> Result<Self, Error<E>> {
|
||||||
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
|
let mut instance = ModuleInstance::new(Weak::default(), "env".into(), module)?;
|
||||||
instance.instantiate(None)?;
|
instance.instantiate(None)?;
|
||||||
@ -95,7 +95,7 @@ impl<E> EnvModuleInstance<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ModuleInstanceInterface<E> for EnvModuleInstance<E> where E: CustomUserError {
|
impl<E> ModuleInstanceInterface<E> for EnvModuleInstance<E> where E: UserError {
|
||||||
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
||||||
self.instance.execute_index(index, params)
|
self.instance.execute_index(index, params)
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ impl<E> ModuleInstanceInterface<E> for EnvModuleInstance<E> where E: CustomUserE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn env_module<E: CustomUserError>(params: EnvParams) -> Result<EnvModuleInstance<E>, Error<E>> {
|
pub fn env_module<E: UserError>(params: EnvParams) -> Result<EnvModuleInstance<E>, Error<E>> {
|
||||||
debug_assert!(params.total_stack < params.total_memory);
|
debug_assert!(params.total_stack < params.total_memory);
|
||||||
debug_assert!((params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
debug_assert!((params.total_stack % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
||||||
debug_assert!((params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
debug_assert!((params.total_memory % LINEAR_MEMORY_PAGE_SIZE) == 0);
|
||||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::{Internal, ValueType};
|
use elements::{Internal, ValueType};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::module::{ModuleInstanceInterface, ExecutionParams, ItemIndex,
|
use interpreter::module::{ModuleInstanceInterface, ExecutionParams, ItemIndex,
|
||||||
CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction, FunctionSignature};
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
@ -17,7 +17,7 @@ pub const NATIVE_INDEX_FUNC_MIN: u32 = 10001;
|
|||||||
pub const NATIVE_INDEX_GLOBAL_MIN: u32 = 20001;
|
pub const NATIVE_INDEX_GLOBAL_MIN: u32 = 20001;
|
||||||
|
|
||||||
/// User functions executor.
|
/// User functions executor.
|
||||||
pub trait UserFunctionExecutor<E: CustomUserError> {
|
pub trait UserFunctionExecutor<E: UserError> {
|
||||||
/// Execute function with given name.
|
/// Execute function with given name.
|
||||||
fn execute(&mut self, name: &str, context: CallerContext<E>) -> Result<Option<RuntimeValue>, Error<E>>;
|
fn execute(&mut self, name: &str, context: CallerContext<E>) -> Result<Option<RuntimeValue>, Error<E>>;
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ impl UserFunctionDescriptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set of user-defined module elements.
|
/// Set of user-defined module elements.
|
||||||
pub struct UserDefinedElements<'a, E: 'a + CustomUserError> {
|
pub struct UserDefinedElements<'a, E: 'a + UserError> {
|
||||||
/// User globals list.
|
/// User globals list.
|
||||||
pub globals: HashMap<String, Arc<VariableInstance<E>>>,
|
pub globals: HashMap<String, Arc<VariableInstance<E>>>,
|
||||||
/// User functions list.
|
/// User functions list.
|
||||||
@ -78,7 +78,7 @@ pub struct UserDefinedElements<'a, E: 'a + CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Native module instance.
|
/// Native module instance.
|
||||||
pub struct NativeModuleInstance<'a, E: 'a + CustomUserError> {
|
pub struct NativeModuleInstance<'a, E: 'a + UserError> {
|
||||||
/// Underllying module reference.
|
/// Underllying module reference.
|
||||||
env: Arc<ModuleInstanceInterface<E>>,
|
env: Arc<ModuleInstanceInterface<E>>,
|
||||||
/// User function executor.
|
/// User function executor.
|
||||||
@ -93,7 +93,7 @@ pub struct NativeModuleInstance<'a, E: 'a + CustomUserError> {
|
|||||||
globals: Vec<Arc<VariableInstance<E>>>,
|
globals: Vec<Arc<VariableInstance<E>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> NativeModuleInstance<'a, E> where E: CustomUserError {
|
impl<'a, E> NativeModuleInstance<'a, E> where E: UserError {
|
||||||
/// Create new native module
|
/// Create new native module
|
||||||
pub fn new(env: Arc<ModuleInstanceInterface<E>>, elements: UserDefinedElements<'a, E>) -> Result<Self, Error<E>> {
|
pub fn new(env: Arc<ModuleInstanceInterface<E>>, elements: UserDefinedElements<'a, E>) -> Result<Self, Error<E>> {
|
||||||
if !elements.functions.is_empty() && elements.executor.is_none() {
|
if !elements.functions.is_empty() && elements.executor.is_none() {
|
||||||
@ -111,7 +111,7 @@ impl<'a, E> NativeModuleInstance<'a, E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> ModuleInstanceInterface<E> for NativeModuleInstance<'a, E> where E: CustomUserError {
|
impl<'a, E> ModuleInstanceInterface<E> for NativeModuleInstance<'a, E> where E: UserError {
|
||||||
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
||||||
self.env.execute_index(index, params)
|
self.env.execute_index(index, params)
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ impl<'a, E> ModuleInstanceInterface<E> for NativeModuleInstance<'a, E> where E:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create wrapper for env module with given native user functions.
|
/// Create wrapper for env module with given native user functions.
|
||||||
pub fn env_native_module<'a, E: CustomUserError>(env: Arc<ModuleInstanceInterface<E>>, user_elements: UserDefinedElements<'a, E>) -> Result<NativeModuleInstance<E>, Error<E>> {
|
pub fn env_native_module<'a, E: UserError>(env: Arc<ModuleInstanceInterface<E>>, user_elements: UserDefinedElements<'a, E>) -> Result<NativeModuleInstance<E>, Error<E>> {
|
||||||
NativeModuleInstance::new(env, user_elements)
|
NativeModuleInstance::new(env, user_elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use elements::{ImportSection, ImportEntry, External, Internal};
|
use elements::{ImportSection, ImportEntry, External, Internal};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
use interpreter::module::{ModuleInstanceInterface, ItemIndex, ExportEntryType, FunctionSignature};
|
use interpreter::module::{ModuleInstanceInterface, ItemIndex, ExportEntryType, FunctionSignature};
|
||||||
use interpreter::program::ProgramInstanceEssence;
|
use interpreter::program::ProgramInstanceEssence;
|
||||||
@ -9,7 +9,7 @@ use interpreter::table::TableInstance;
|
|||||||
use interpreter::variable::{VariableInstance, VariableType};
|
use interpreter::variable::{VariableInstance, VariableType};
|
||||||
|
|
||||||
/// Module imports.
|
/// Module imports.
|
||||||
pub struct ModuleImports<E: CustomUserError> {
|
pub struct ModuleImports<E: UserError> {
|
||||||
/// Program instance.
|
/// Program instance.
|
||||||
program: Weak<ProgramInstanceEssence<E>>,
|
program: Weak<ProgramInstanceEssence<E>>,
|
||||||
/// External functions.
|
/// External functions.
|
||||||
@ -22,7 +22,7 @@ pub struct ModuleImports<E: CustomUserError> {
|
|||||||
globals: Vec<usize>,
|
globals: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ModuleImports<E> where E: CustomUserError {
|
impl<E> ModuleImports<E> where E: UserError {
|
||||||
/// Create new imports for given import section.
|
/// Create new imports for given import section.
|
||||||
pub fn new(program: Weak<ProgramInstanceEssence<E>>, import_section: Option<&ImportSection>) -> Self {
|
pub fn new(program: Weak<ProgramInstanceEssence<E>>, import_section: Option<&ImportSection>) -> Self {
|
||||||
let mut functions = Vec::new();
|
let mut functions = Vec::new();
|
||||||
|
@ -2,7 +2,7 @@ use std::u32;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::MemoryType;
|
use elements::MemoryType;
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::module::check_limits;
|
use interpreter::module::check_limits;
|
||||||
|
|
||||||
/// Linear memory page size.
|
/// Linear memory page size.
|
||||||
@ -11,7 +11,7 @@ pub const LINEAR_MEMORY_PAGE_SIZE: u32 = 65536;
|
|||||||
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;
|
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;
|
||||||
|
|
||||||
/// Linear memory instance.
|
/// Linear memory instance.
|
||||||
pub struct MemoryInstance<E: CustomUserError> {
|
pub struct MemoryInstance<E: UserError> {
|
||||||
/// Linear memory buffer.
|
/// Linear memory buffer.
|
||||||
buffer: RwLock<Vec<u8>>,
|
buffer: RwLock<Vec<u8>>,
|
||||||
/// Maximum buffer size.
|
/// Maximum buffer size.
|
||||||
@ -36,7 +36,7 @@ impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref<Target=Vec<u8>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> MemoryInstance<E> where E: CustomUserError {
|
impl<E> MemoryInstance<E> where E: UserError {
|
||||||
/// Create new linear memory instance.
|
/// Create new linear memory instance.
|
||||||
pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error<E>> {
|
pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error<E>> {
|
||||||
check_limits(memory_type.limits())?;
|
check_limits(memory_type.limits())?;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
//! WebAssembly interpreter module.
|
//! WebAssembly interpreter module.
|
||||||
|
|
||||||
/// Custom user error.
|
/// Custom user error.
|
||||||
pub trait CustomUserError: 'static + ::std::fmt::Display + ::std::fmt::Debug + Clone + PartialEq {
|
pub trait UserError: 'static + ::std::fmt::Display + ::std::fmt::Debug + Clone + PartialEq {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal interpreter error.
|
/// Internal interpreter error.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Error<E> where E: CustomUserError {
|
pub enum Error<E> where E: UserError {
|
||||||
/// Program-level error.
|
/// Program-level error.
|
||||||
Program(String),
|
Program(String),
|
||||||
/// Validation error.
|
/// Validation error.
|
||||||
@ -41,7 +41,7 @@ pub enum Error<E> where E: CustomUserError {
|
|||||||
User(E),
|
User(E),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Into<String> for Error<E> where E: CustomUserError {
|
impl<E> Into<String> for Error<E> where E: UserError {
|
||||||
fn into(self) -> String {
|
fn into(self) -> String {
|
||||||
match self {
|
match self {
|
||||||
Error::Program(s) => s,
|
Error::Program(s) => s,
|
||||||
@ -66,11 +66,11 @@ impl<E> Into<String> for Error<E> where E: CustomUserError {
|
|||||||
|
|
||||||
/// Dummy user error.
|
/// Dummy user error.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct DummyCustomUserError;
|
pub struct DummyUserError;
|
||||||
|
|
||||||
impl CustomUserError for DummyCustomUserError {}
|
impl UserError for DummyUserError {}
|
||||||
|
|
||||||
impl ::std::fmt::Display for DummyCustomUserError {
|
impl ::std::fmt::Display for DummyUserError {
|
||||||
fn fmt(&self, _f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { Ok(()) }
|
fn fmt(&self, _f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { Ok(()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,12 +102,12 @@ pub use self::env::EnvParams;
|
|||||||
|
|
||||||
/// Default type of ProgramInstance if you do not need any custom user errors.
|
/// Default type of ProgramInstance if you do not need any custom user errors.
|
||||||
/// To work with custom user errors or interpreter internals, use CustomProgramInstance.
|
/// To work with custom user errors or interpreter internals, use CustomProgramInstance.
|
||||||
pub type DefaultProgramInstance = self::program::ProgramInstance<DummyCustomUserError>;
|
pub type DefaultProgramInstance = self::program::ProgramInstance<DummyUserError>;
|
||||||
|
|
||||||
/// Default type of ModuleInstance if you do not need any custom user errors.
|
/// Default type of ModuleInstance if you do not need any custom user errors.
|
||||||
/// To work with custom user errors or interpreter internals, use CustomModuleInstance.
|
/// To work with custom user errors or interpreter internals, use CustomModuleInstance.
|
||||||
pub type DefaultModuleInstance = self::module::ModuleInstance<DummyCustomUserError>;
|
pub type DefaultModuleInstance = self::module::ModuleInstance<DummyUserError>;
|
||||||
|
|
||||||
/// Default type of ModuleInstanceInterface if you do not need any custom user errors.
|
/// Default type of ModuleInstanceInterface if you do not need any custom user errors.
|
||||||
/// To work with custom user errors or interpreter internals, use CustomModuleInstanceInterface.
|
/// To work with custom user errors or interpreter internals, use CustomModuleInstanceInterface.
|
||||||
pub type DefaultModuleInstanceInterface = self::module::ModuleInstanceInterface<DummyCustomUserError>;
|
pub type DefaultModuleInstanceInterface = self::module::ModuleInstanceInterface<DummyUserError>;
|
||||||
|
@ -3,7 +3,7 @@ use std::iter::repeat;
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local, ValueType};
|
use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local, ValueType};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::env_native::UserFunctionDescriptor;
|
use interpreter::env_native::UserFunctionDescriptor;
|
||||||
use interpreter::imports::ModuleImports;
|
use interpreter::imports::ModuleImports;
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
@ -22,7 +22,7 @@ const DEFAULT_FRAME_STACK_LIMIT: usize = 1024;
|
|||||||
|
|
||||||
/// Execution context.
|
/// Execution context.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ExecutionParams<'a, E: CustomUserError> {
|
pub struct ExecutionParams<'a, E: UserError> {
|
||||||
/// Arguments.
|
/// Arguments.
|
||||||
pub args: Vec<RuntimeValue>,
|
pub args: Vec<RuntimeValue>,
|
||||||
/// Execution-local external modules.
|
/// Execution-local external modules.
|
||||||
@ -50,7 +50,7 @@ pub enum FunctionSignature<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Module instance API.
|
/// Module instance API.
|
||||||
pub trait ModuleInstanceInterface<E: CustomUserError> {
|
pub trait ModuleInstanceInterface<E: UserError> {
|
||||||
/// Execute function with the given index.
|
/// Execute function with the given index.
|
||||||
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>>;
|
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>>;
|
||||||
/// Execute function with the given export name.
|
/// Execute function with the given export name.
|
||||||
@ -89,7 +89,7 @@ pub enum ItemIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Module instance.
|
/// Module instance.
|
||||||
pub struct ModuleInstance<E: CustomUserError> {
|
pub struct ModuleInstance<E: UserError> {
|
||||||
/// Module name.
|
/// Module name.
|
||||||
name: String,
|
name: String,
|
||||||
/// Module.
|
/// Module.
|
||||||
@ -109,7 +109,7 @@ pub struct ModuleInstance<E: CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Caller context.
|
/// Caller context.
|
||||||
pub struct CallerContext<'a, E: 'a + CustomUserError> {
|
pub struct CallerContext<'a, E: 'a + UserError> {
|
||||||
/// Value stack limit
|
/// Value stack limit
|
||||||
pub value_stack_limit: usize,
|
pub value_stack_limit: usize,
|
||||||
/// Frame stack limit
|
/// Frame stack limit
|
||||||
@ -122,14 +122,14 @@ pub struct CallerContext<'a, E: 'a + CustomUserError> {
|
|||||||
|
|
||||||
/// Internal function reference.
|
/// Internal function reference.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InternalFunctionReference<'a, E: CustomUserError> {
|
pub struct InternalFunctionReference<'a, E: UserError> {
|
||||||
/// Module reference.
|
/// Module reference.
|
||||||
pub module: Arc<ModuleInstanceInterface<E> + 'a>,
|
pub module: Arc<ModuleInstanceInterface<E> + 'a>,
|
||||||
/// Internal function index.
|
/// Internal function index.
|
||||||
pub internal_index: u32,
|
pub internal_index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> fmt::Debug for InternalFunctionReference<'a, E> where E: CustomUserError {
|
impl<'a, E> fmt::Debug for InternalFunctionReference<'a, E> where E: UserError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "InternalFunctionReference")
|
write!(f, "InternalFunctionReference")
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ pub struct InternalFunction<'a> {
|
|||||||
pub labels: &'a HashMap<usize, usize>,
|
pub labels: &'a HashMap<usize, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> ExecutionParams<'a, E> where E: CustomUserError {
|
impl<'a, E> ExecutionParams<'a, E> where E: UserError {
|
||||||
/// Create new execution params with given externa; module override.
|
/// Create new execution params with given externa; module override.
|
||||||
pub fn with_external(name: String, module: Arc<ModuleInstanceInterface<E> + 'a>) -> Self {
|
pub fn with_external(name: String, module: Arc<ModuleInstanceInterface<E> + 'a>) -> Self {
|
||||||
let mut externals = HashMap::new();
|
let mut externals = HashMap::new();
|
||||||
@ -163,7 +163,7 @@ impl<'a, E> ExecutionParams<'a, E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> Default for ExecutionParams<'a, E> where E: CustomUserError {
|
impl<'a, E> Default for ExecutionParams<'a, E> where E: UserError {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ExecutionParams {
|
ExecutionParams {
|
||||||
args: Vec::default(),
|
args: Vec::default(),
|
||||||
@ -172,7 +172,7 @@ impl<'a, E> Default for ExecutionParams<'a, E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> From<Vec<RuntimeValue>> for ExecutionParams<'a, E> where E: CustomUserError {
|
impl<'a, E> From<Vec<RuntimeValue>> for ExecutionParams<'a, E> where E: UserError {
|
||||||
fn from(args: Vec<RuntimeValue>) -> ExecutionParams<'a, E> {
|
fn from(args: Vec<RuntimeValue>) -> ExecutionParams<'a, E> {
|
||||||
ExecutionParams {
|
ExecutionParams {
|
||||||
args: args,
|
args: args,
|
||||||
@ -181,7 +181,7 @@ impl<'a, E> From<Vec<RuntimeValue>> for ExecutionParams<'a, E> where E: CustomUs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ModuleInstance<E> where E: CustomUserError {
|
impl<E> ModuleInstance<E> where E: UserError {
|
||||||
/// Instantiate given module within program context.
|
/// Instantiate given module within program context.
|
||||||
pub fn new<'a>(program: Weak<ProgramInstanceEssence<E>>, name: String, module: Module) -> Result<Self, Error<E>> {
|
pub fn new<'a>(program: Weak<ProgramInstanceEssence<E>>, name: String, module: Module) -> Result<Self, Error<E>> {
|
||||||
// load entries from import section
|
// load entries from import section
|
||||||
@ -429,7 +429,7 @@ impl<E> ModuleInstance<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserError {
|
impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: UserError {
|
||||||
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
||||||
let ExecutionParams { args, externals } = params;
|
let ExecutionParams { args, externals } = params;
|
||||||
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
|
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
|
||||||
@ -609,7 +609,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> CallerContext<'a, E> where E: CustomUserError {
|
impl<'a, E> CallerContext<'a, E> where E: UserError {
|
||||||
/// Top most args
|
/// Top most args
|
||||||
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue, E>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>) -> Self {
|
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue, E>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>) -> Self {
|
||||||
CallerContext {
|
CallerContext {
|
||||||
@ -631,7 +631,7 @@ impl<'a, E> CallerContext<'a, E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_limits<E: CustomUserError>(limits: &ResizableLimits) -> Result<(), Error<E>> {
|
pub fn check_limits<E: UserError>(limits: &ResizableLimits) -> Result<(), Error<E>> {
|
||||||
if let Some(maximum) = limits.maximum() {
|
if let Some(maximum) = limits.maximum() {
|
||||||
if maximum < limits.initial() {
|
if maximum < limits.initial() {
|
||||||
return Err(Error::Validation(format!("maximum limit {} is lesser than minimum {}", maximum, limits.initial())));
|
return Err(Error::Validation(format!("maximum limit {} is lesser than minimum {}", maximum, limits.initial())));
|
||||||
@ -641,7 +641,7 @@ pub fn check_limits<E: CustomUserError>(limits: &ResizableLimits) -> Result<(),
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_initializer<E: CustomUserError>(expr: &InitExpr, module: &Module, imports: &ModuleImports<E>, expected_type: VariableType) -> Result<RuntimeValue, Error<E>> {
|
fn get_initializer<E: UserError>(expr: &InitExpr, module: &Module, imports: &ModuleImports<E>, expected_type: VariableType) -> Result<RuntimeValue, Error<E>> {
|
||||||
let first_opcode = match expr.code().len() {
|
let first_opcode = match expr.code().len() {
|
||||||
1 => &expr.code()[0],
|
1 => &expr.code()[0],
|
||||||
2 if expr.code().len() == 2 && expr.code()[1] == Opcode::End => &expr.code()[0],
|
2 if expr.code().len() == 2 && expr.code()[1] == Opcode::End => &expr.code()[0],
|
||||||
|
@ -2,23 +2,23 @@ use std::sync::Arc;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::Module;
|
use elements::Module;
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::env::{self, env_module};
|
use interpreter::env::{self, env_module};
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface};
|
||||||
|
|
||||||
/// Program instance. Program is a set of instantiated modules.
|
/// Program instance. Program is a set of instantiated modules.
|
||||||
pub struct ProgramInstance<E: CustomUserError> {
|
pub struct ProgramInstance<E: UserError> {
|
||||||
/// Shared data reference.
|
/// Shared data reference.
|
||||||
essence: Arc<ProgramInstanceEssence<E>>,
|
essence: Arc<ProgramInstanceEssence<E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Program instance essence.
|
/// Program instance essence.
|
||||||
pub struct ProgramInstanceEssence<E: CustomUserError> {
|
pub struct ProgramInstanceEssence<E: UserError> {
|
||||||
/// Loaded modules.
|
/// Loaded modules.
|
||||||
modules: RwLock<HashMap<String, Arc<ModuleInstanceInterface<E>>>>,
|
modules: RwLock<HashMap<String, Arc<ModuleInstanceInterface<E>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ProgramInstance<E> where E: CustomUserError {
|
impl<E> ProgramInstance<E> where E: UserError {
|
||||||
/// Create new program instance.
|
/// Create new program instance.
|
||||||
pub fn new() -> Result<Self, Error<E>> {
|
pub fn new() -> Result<Self, Error<E>> {
|
||||||
ProgramInstance::with_env_params(env::EnvParams::default())
|
ProgramInstance::with_env_params(env::EnvParams::default())
|
||||||
@ -55,7 +55,7 @@ impl<E> ProgramInstance<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> ProgramInstanceEssence<E> where E: CustomUserError {
|
impl<E> ProgramInstanceEssence<E> where E: UserError {
|
||||||
/// Create new program essence.
|
/// Create new program essence.
|
||||||
pub fn new() -> Result<Self, Error<E>> {
|
pub fn new() -> Result<Self, Error<E>> {
|
||||||
ProgramInstanceEssence::with_env_params(env::EnvParams::default())
|
ProgramInstanceEssence::with_env_params(env::EnvParams::default())
|
||||||
|
@ -6,7 +6,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 elements::{Opcode, BlockType, Local};
|
use elements::{Opcode, BlockType, Local};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, InternalFunctionReference, FunctionSignature};
|
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, InternalFunctionReference, FunctionSignature};
|
||||||
use interpreter::stack::StackWithLimit;
|
use interpreter::stack::StackWithLimit;
|
||||||
use interpreter::value::{
|
use interpreter::value::{
|
||||||
@ -22,12 +22,12 @@ pub const DEFAULT_MEMORY_INDEX: u32 = 0;
|
|||||||
pub const DEFAULT_TABLE_INDEX: u32 = 0;
|
pub const DEFAULT_TABLE_INDEX: u32 = 0;
|
||||||
|
|
||||||
/// Function interpreter.
|
/// Function interpreter.
|
||||||
pub struct Interpreter<E: CustomUserError> {
|
pub struct Interpreter<E: UserError> {
|
||||||
_dummy: ::std::marker::PhantomData<E>,
|
_dummy: ::std::marker::PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function execution context.
|
/// Function execution context.
|
||||||
pub struct FunctionContext<'a, E: 'a + CustomUserError> {
|
pub struct FunctionContext<'a, E: 'a + UserError> {
|
||||||
/// Is context initialized.
|
/// Is context initialized.
|
||||||
pub is_initialized: bool,
|
pub is_initialized: bool,
|
||||||
/// Internal function reference.
|
/// Internal function reference.
|
||||||
@ -48,7 +48,7 @@ pub struct FunctionContext<'a, E: 'a + CustomUserError> {
|
|||||||
|
|
||||||
/// Interpreter action to execute after executing instruction.
|
/// Interpreter action to execute after executing instruction.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InstructionOutcome<'a, E: CustomUserError> {
|
pub enum InstructionOutcome<'a, E: UserError> {
|
||||||
/// Continue with next instruction.
|
/// Continue with next instruction.
|
||||||
RunNextInstruction,
|
RunNextInstruction,
|
||||||
/// Branch to given frame.
|
/// Branch to given frame.
|
||||||
@ -62,14 +62,14 @@ pub enum InstructionOutcome<'a, E: CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Function run result.
|
/// Function run result.
|
||||||
enum RunResult<'a, E: 'a + CustomUserError> {
|
enum RunResult<'a, E: 'a + UserError> {
|
||||||
/// Function has returned (optional) value.
|
/// Function has returned (optional) value.
|
||||||
Return(Option<RuntimeValue>),
|
Return(Option<RuntimeValue>),
|
||||||
/// Function is calling other function.
|
/// Function is calling other function.
|
||||||
NestedCall(FunctionContext<'a, E>),
|
NestedCall(FunctionContext<'a, E>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Interpreter<E> where E: CustomUserError {
|
impl<E> Interpreter<E> where E: UserError {
|
||||||
pub fn run_function(function_context: FunctionContext<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
pub fn run_function(function_context: FunctionContext<E>) -> Result<Option<RuntimeValue>, Error<E>> {
|
||||||
let mut function_stack = VecDeque::new();
|
let mut function_stack = VecDeque::new();
|
||||||
function_stack.push_back(function_context);
|
function_stack.push_back(function_context);
|
||||||
@ -935,7 +935,7 @@ impl<E> Interpreter<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> FunctionContext<'a, E> where E: CustomUserError {
|
impl<'a, E> FunctionContext<'a, E> where E: UserError {
|
||||||
pub fn new(function: InternalFunctionReference<'a, E>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionSignature, args: Vec<VariableInstance<E>>) -> Self {
|
pub fn new(function: InternalFunctionReference<'a, E>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionSignature, args: Vec<VariableInstance<E>>) -> Self {
|
||||||
FunctionContext {
|
FunctionContext {
|
||||||
is_initialized: false,
|
is_initialized: false,
|
||||||
@ -1075,20 +1075,20 @@ impl<'a, E> FunctionContext<'a, E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> fmt::Debug for FunctionContext<'a, E> where E: CustomUserError {
|
impl<'a, E> fmt::Debug for FunctionContext<'a, E> where E: UserError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "FunctionContext")
|
write!(f, "FunctionContext")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn effective_address<E: CustomUserError>(address: u32, offset: u32) -> Result<u32, Error<E>> {
|
fn effective_address<E: UserError>(address: u32, offset: u32) -> Result<u32, Error<E>> {
|
||||||
match offset.checked_add(address) {
|
match offset.checked_add(address) {
|
||||||
None => Err(Error::Memory(format!("invalid memory access: {} + {}", offset, address))),
|
None => Err(Error::Memory(format!("invalid memory access: {} + {}", offset, address))),
|
||||||
Some(address) => Ok(address),
|
Some(address) => Ok(address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_function_args<E: CustomUserError>(function_type: &FunctionSignature, caller_stack: &mut StackWithLimit<RuntimeValue, E>) -> Result<Vec<VariableInstance<E>>, Error<E>> {
|
pub fn prepare_function_args<E: UserError>(function_type: &FunctionSignature, caller_stack: &mut StackWithLimit<RuntimeValue, E>) -> Result<Vec<VariableInstance<E>>, Error<E>> {
|
||||||
let mut args = function_type.params().iter().rev().map(|param_type| {
|
let mut args = function_type.params().iter().rev().map(|param_type| {
|
||||||
let param_value = caller_stack.pop()?;
|
let param_value = caller_stack.pop()?;
|
||||||
let actual_type = param_value.variable_type();
|
let actual_type = param_value.variable_type();
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::value::{RuntimeValue, TryInto};
|
use interpreter::value::{RuntimeValue, TryInto};
|
||||||
|
|
||||||
/// Stack with limit.
|
/// Stack with limit.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StackWithLimit<T, E> where T: Clone, E: CustomUserError {
|
pub struct StackWithLimit<T, E> where T: Clone, E: UserError {
|
||||||
/// Stack values.
|
/// Stack values.
|
||||||
values: VecDeque<T>,
|
values: VecDeque<T>,
|
||||||
/// Stack limit (maximal stack len).
|
/// Stack limit (maximal stack len).
|
||||||
@ -13,7 +13,7 @@ pub struct StackWithLimit<T, E> where T: Clone, E: CustomUserError {
|
|||||||
_dummy: ::std::marker::PhantomData<E>,
|
_dummy: ::std::marker::PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E> StackWithLimit<T, E> where T: Clone, E: CustomUserError {
|
impl<T, E> StackWithLimit<T, E> where T: Clone, E: UserError {
|
||||||
pub fn with_data(data: Vec<T>, limit: usize) -> Self {
|
pub fn with_data(data: Vec<T>, limit: usize) -> Self {
|
||||||
StackWithLimit {
|
StackWithLimit {
|
||||||
values: data.into_iter().collect(),
|
values: data.into_iter().collect(),
|
||||||
@ -100,7 +100,7 @@ impl<T, E> StackWithLimit<T, E> where T: Clone, E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> StackWithLimit<RuntimeValue, E> where E: CustomUserError {
|
impl<E> StackWithLimit<RuntimeValue, E> where E: UserError {
|
||||||
pub fn pop_as<T>(&mut self) -> Result<T, Error<E>>
|
pub fn pop_as<T>(&mut self) -> Result<T, Error<E>>
|
||||||
where RuntimeValue: TryInto<T, Error<E>> {
|
where RuntimeValue: TryInto<T, Error<E>> {
|
||||||
self.pop().and_then(TryInto::try_into)
|
self.pop().and_then(TryInto::try_into)
|
||||||
|
@ -2,13 +2,13 @@ use std::u32;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::TableType;
|
use elements::TableType;
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::module::check_limits;
|
use interpreter::module::check_limits;
|
||||||
use interpreter::variable::{VariableInstance, VariableType};
|
use interpreter::variable::{VariableInstance, VariableType};
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
|
|
||||||
/// Table instance.
|
/// Table instance.
|
||||||
pub struct TableInstance<E: CustomUserError> {
|
pub struct TableInstance<E: UserError> {
|
||||||
/// Table variables type.
|
/// Table variables type.
|
||||||
variable_type: VariableType,
|
variable_type: VariableType,
|
||||||
/// Table memory buffer.
|
/// Table memory buffer.
|
||||||
@ -16,11 +16,11 @@ pub struct TableInstance<E: CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Table element. Cloneable wrapper around VariableInstance.
|
/// Table element. Cloneable wrapper around VariableInstance.
|
||||||
struct TableElement<E: CustomUserError> {
|
struct TableElement<E: UserError> {
|
||||||
pub var: VariableInstance<E>,
|
pub var: VariableInstance<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TableInstance<E> where E: CustomUserError {
|
impl<E> TableInstance<E> where E: UserError {
|
||||||
/// New instance of the table
|
/// New instance of the table
|
||||||
pub fn new(table_type: &TableType) -> Result<Arc<Self>, Error<E>> {
|
pub fn new(table_type: &TableType) -> Result<Arc<Self>, Error<E>> {
|
||||||
check_limits(table_type.limits())?;
|
check_limits(table_type.limits())?;
|
||||||
@ -70,7 +70,7 @@ impl<E> TableInstance<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TableElement<E> where E: CustomUserError {
|
impl<E> TableElement<E> where E: UserError {
|
||||||
pub fn new(var: VariableInstance<E>) -> Self {
|
pub fn new(var: VariableInstance<E>) -> Self {
|
||||||
TableElement {
|
TableElement {
|
||||||
var: var,
|
var: var,
|
||||||
@ -78,7 +78,7 @@ impl<E> TableElement<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Clone for TableElement<E> where E: CustomUserError {
|
impl<E> Clone for TableElement<E> where E: UserError {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
TableElement::new(VariableInstance::new(self.var.is_mutable(), self.var.variable_type(), self.var.get())
|
TableElement::new(VariableInstance::new(self.var.is_mutable(), self.var.variable_type(), self.var.get())
|
||||||
.expect("it only fails when variable_type() != passed variable value; both are read from already constructed var; qed"))
|
.expect("it only fails when variable_type() != passed variable value; both are read from already constructed var; qed"))
|
||||||
|
@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||||||
use builder::module;
|
use builder::module;
|
||||||
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
use elements::{ExportEntry, Internal, ImportEntry, External, GlobalEntry, GlobalType,
|
||||||
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType};
|
InitExpr, ValueType, BlockType, Opcodes, Opcode, FunctionType};
|
||||||
use interpreter::{Error, CustomUserError, ProgramInstance, DefaultProgramInstance, DefaultModuleInstance};
|
use interpreter::{Error, UserError, ProgramInstance, DefaultProgramInstance, DefaultModuleInstance};
|
||||||
use interpreter::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
use interpreter::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
|
use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, ExecutionParams, ExportEntryType, FunctionSignature};
|
||||||
@ -128,12 +128,12 @@ struct MeasuredVariable {
|
|||||||
pub val: i32,
|
pub val: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalVariableValue<UserError> for MeasuredVariable {
|
impl ExternalVariableValue<UserErrorWithCode> for MeasuredVariable {
|
||||||
fn get(&self) -> RuntimeValue {
|
fn get(&self) -> RuntimeValue {
|
||||||
RuntimeValue::I32(self.val)
|
RuntimeValue::I32(self.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set(&mut self, val: RuntimeValue) -> Result<(), Error<UserError>> {
|
fn set(&mut self, val: RuntimeValue) -> Result<(), Error<UserErrorWithCode>> {
|
||||||
self.val = val.try_into()?;
|
self.val = val.try_into()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -141,26 +141,26 @@ impl ExternalVariableValue<UserError> for MeasuredVariable {
|
|||||||
|
|
||||||
// custom user error
|
// custom user error
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
struct UserError {
|
struct UserErrorWithCode {
|
||||||
error_code: i32,
|
error_code: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::fmt::Display for UserError {
|
impl ::std::fmt::Display for UserErrorWithCode {
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
|
||||||
write!(f, "{}", self.error_code)
|
write!(f, "{}", self.error_code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CustomUserError for UserError {}
|
impl UserError for UserErrorWithCode {}
|
||||||
|
|
||||||
// user function executor
|
// user function executor
|
||||||
struct FunctionExecutor {
|
struct FunctionExecutor {
|
||||||
pub memory: Arc<MemoryInstance<UserError>>,
|
pub memory: Arc<MemoryInstance<UserErrorWithCode>>,
|
||||||
pub values: Vec<i32>,
|
pub values: Vec<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserFunctionExecutor<UserError> for FunctionExecutor {
|
impl UserFunctionExecutor<UserErrorWithCode> for FunctionExecutor {
|
||||||
fn execute(&mut self, name: &str, context: CallerContext<UserError>) -> Result<Option<RuntimeValue>, Error<UserError>> {
|
fn execute(&mut self, name: &str, context: CallerContext<UserErrorWithCode>) -> Result<Option<RuntimeValue>, Error<UserErrorWithCode>> {
|
||||||
match name {
|
match name {
|
||||||
"add" => {
|
"add" => {
|
||||||
let memory_value = self.memory.get(0, 1).unwrap()[0];
|
let memory_value = self.memory.get(0, 1).unwrap()[0];
|
||||||
@ -185,7 +185,7 @@ impl UserFunctionExecutor<UserError> for FunctionExecutor {
|
|||||||
Ok(Some(RuntimeValue::I32(diff as i32)))
|
Ok(Some(RuntimeValue::I32(diff as i32)))
|
||||||
},
|
},
|
||||||
"err" => {
|
"err" => {
|
||||||
Err(Error::User(UserError { error_code: 777 }))
|
Err(Error::User(UserErrorWithCode { error_code: 777 }))
|
||||||
},
|
},
|
||||||
_ => Err(Error::Trap("not implemented".into()).into()),
|
_ => Err(Error::Trap("not implemented".into()).into()),
|
||||||
}
|
}
|
||||||
@ -332,9 +332,9 @@ fn native_custom_error() {
|
|||||||
|
|
||||||
let module_instance = program.add_module("main", module, Some(¶ms.externals)).unwrap();
|
let module_instance = program.add_module("main", module, Some(¶ms.externals)).unwrap();
|
||||||
assert_eq!(module_instance.execute_index(0, params.clone().add_argument(RuntimeValue::I32(7)).add_argument(RuntimeValue::I32(0))),
|
assert_eq!(module_instance.execute_index(0, params.clone().add_argument(RuntimeValue::I32(7)).add_argument(RuntimeValue::I32(0))),
|
||||||
Err(Error::User(UserError { error_code: 777 })));
|
Err(Error::User(UserErrorWithCode { error_code: 777 })));
|
||||||
assert_eq!(module_instance.execute_index(1, params.clone().add_argument(RuntimeValue::I32(7)).add_argument(RuntimeValue::I32(0))),
|
assert_eq!(module_instance.execute_index(1, params.clone().add_argument(RuntimeValue::I32(7)).add_argument(RuntimeValue::I32(0))),
|
||||||
Err(Error::User(UserError { error_code: 777 })));
|
Err(Error::User(UserErrorWithCode { error_code: 777 })));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use builder::module;
|
use builder::module;
|
||||||
use elements::{ValueType, Opcodes, Opcode, BlockType, Local};
|
use elements::{ValueType, Opcodes, Opcode, BlockType, Local};
|
||||||
use interpreter::{Error, DummyCustomUserError, DefaultProgramInstance, DefaultModuleInstanceInterface, ModuleInstanceInterface, ItemIndex};
|
use interpreter::{Error, DummyUserError, DefaultProgramInstance, DefaultModuleInstanceInterface, ModuleInstanceInterface, ItemIndex};
|
||||||
use interpreter::value::{RuntimeValue, TryInto};
|
use interpreter::value::{RuntimeValue, TryInto};
|
||||||
|
|
||||||
fn make_function_i32(body: Opcodes) -> (DefaultProgramInstance, Arc<DefaultModuleInstanceInterface>) {
|
fn make_function_i32(body: Opcodes) -> (DefaultProgramInstance, Arc<DefaultModuleInstanceInterface>) {
|
||||||
@ -22,7 +22,7 @@ fn make_function_i32(body: Opcodes) -> (DefaultProgramInstance, Arc<DefaultModul
|
|||||||
(program, module)
|
(program, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_function_i32(module: &Arc<DefaultModuleInstanceInterface>, arg: i32) -> Result<i32, Error<DummyCustomUserError>> {
|
fn run_function_i32(module: &Arc<DefaultModuleInstanceInterface>, arg: i32) -> Result<i32, Error<DummyUserError>> {
|
||||||
module
|
module
|
||||||
.execute_index(0, vec![RuntimeValue::I32(arg)].into())
|
.execute_index(0, vec![RuntimeValue::I32(arg)].into())
|
||||||
.and_then(|r| r.unwrap().try_into())
|
.and_then(|r| r.unwrap().try_into())
|
||||||
|
@ -2,7 +2,7 @@ use std::u32;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use elements::{Opcode, BlockType, ValueType};
|
use elements::{Opcode, BlockType, ValueType};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::runner::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
|
use interpreter::runner::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
|
||||||
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, FunctionSignature};
|
use interpreter::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, FunctionSignature};
|
||||||
use interpreter::stack::StackWithLimit;
|
use interpreter::stack::StackWithLimit;
|
||||||
@ -12,7 +12,7 @@ use interpreter::variable::VariableType;
|
|||||||
const NATURAL_ALIGNMENT: u32 = 0xFFFFFFFF;
|
const NATURAL_ALIGNMENT: u32 = 0xFFFFFFFF;
|
||||||
|
|
||||||
/// Function validation context.
|
/// Function validation context.
|
||||||
pub struct FunctionValidationContext<'a, E: 'a + CustomUserError> {
|
pub struct FunctionValidationContext<'a, E: 'a + UserError> {
|
||||||
/// Wasm module instance (in process of instantiation).
|
/// Wasm module instance (in process of instantiation).
|
||||||
module_instance: &'a ModuleInstance<E>,
|
module_instance: &'a ModuleInstance<E>,
|
||||||
/// Native externals.
|
/// Native externals.
|
||||||
@ -75,7 +75,7 @@ pub enum BlockFrameType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Function validator.
|
/// Function validator.
|
||||||
pub struct Validator<E: CustomUserError> {
|
pub struct Validator<E: UserError> {
|
||||||
_dummy: ::std::marker::PhantomData<E>,
|
_dummy: ::std::marker::PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ pub enum InstructionOutcome {
|
|||||||
Unreachable,
|
Unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> Validator<E> where E: CustomUserError {
|
impl<E> Validator<E> where E: UserError {
|
||||||
pub fn validate_function(context: &mut FunctionValidationContext<E>, block_type: BlockType, body: &[Opcode]) -> Result<(), Error<E>> {
|
pub fn validate_function(context: &mut FunctionValidationContext<E>, block_type: BlockType, body: &[Opcode]) -> Result<(), Error<E>> {
|
||||||
context.push_label(BlockFrameType::Function, block_type)?;
|
context.push_label(BlockFrameType::Function, block_type)?;
|
||||||
Validator::validate_function_block(context, body)?;
|
Validator::validate_function_block(context, body)?;
|
||||||
@ -571,7 +571,7 @@ impl<E> Validator<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> FunctionValidationContext<'a, E> where E: CustomUserError {
|
impl<'a, E> FunctionValidationContext<'a, E> where E: UserError {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
module_instance: &'a ModuleInstance<E>,
|
module_instance: &'a ModuleInstance<E>,
|
||||||
externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>,
|
externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>,
|
||||||
|
@ -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 interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::variable::VariableType;
|
use interpreter::variable::VariableType;
|
||||||
|
|
||||||
/// Runtime value.
|
/// Runtime value.
|
||||||
@ -52,7 +52,7 @@ pub trait TransmuteInto<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert from and to little endian.
|
/// Convert from and to little endian.
|
||||||
pub trait LittleEndianConvert<E: CustomUserError> where Self: Sized {
|
pub trait LittleEndianConvert<E: UserError> where Self: Sized {
|
||||||
/// Convert to little endian buffer.
|
/// Convert to little endian buffer.
|
||||||
fn into_little_endian(self) -> Vec<u8>;
|
fn into_little_endian(self) -> Vec<u8>;
|
||||||
/// Convert from little endian buffer.
|
/// Convert from little endian buffer.
|
||||||
@ -60,7 +60,7 @@ pub trait LittleEndianConvert<E: CustomUserError> where Self: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Arithmetic operations.
|
/// Arithmetic operations.
|
||||||
pub trait ArithmeticOps<T, E: CustomUserError> {
|
pub trait ArithmeticOps<T, E: UserError> {
|
||||||
/// Add two values.
|
/// Add two values.
|
||||||
fn add(self, other: T) -> T;
|
fn add(self, other: T) -> T;
|
||||||
/// Subtract two values.
|
/// Subtract two values.
|
||||||
@ -72,7 +72,7 @@ pub trait ArithmeticOps<T, E: CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Integer value.
|
/// Integer value.
|
||||||
pub trait Integer<T, E: CustomUserError>: ArithmeticOps<T, E> {
|
pub trait Integer<T, E: UserError>: ArithmeticOps<T, E> {
|
||||||
/// Counts leading zeros in the bitwise representation of the value.
|
/// Counts leading zeros in the bitwise representation of the value.
|
||||||
fn leading_zeros(self) -> T;
|
fn leading_zeros(self) -> T;
|
||||||
/// Counts trailing zeros in the bitwise representation of the value.
|
/// Counts trailing zeros in the bitwise representation of the value.
|
||||||
@ -88,7 +88,7 @@ pub trait Integer<T, E: CustomUserError>: ArithmeticOps<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Float-point value.
|
/// Float-point value.
|
||||||
pub trait Float<T, E: CustomUserError>: ArithmeticOps<T, E> {
|
pub trait Float<T, E: UserError>: ArithmeticOps<T, E> {
|
||||||
/// Get absolute value.
|
/// Get absolute value.
|
||||||
fn abs(self) -> T;
|
fn abs(self) -> T;
|
||||||
/// Returns the largest integer less than or equal to a number.
|
/// Returns the largest integer less than or equal to a number.
|
||||||
@ -178,7 +178,7 @@ impl From<f64> for RuntimeValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<bool, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<bool, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<bool, Error<E>> {
|
fn try_into(self) -> Result<bool, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val != 0),
|
RuntimeValue::I32(val) => Ok(val != 0),
|
||||||
@ -187,7 +187,7 @@ impl<E> TryInto<bool, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<i32, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<i32, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<i32, Error<E>> {
|
fn try_into(self) -> Result<i32, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val),
|
RuntimeValue::I32(val) => Ok(val),
|
||||||
@ -196,7 +196,7 @@ impl<E> TryInto<i32, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<i64, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<i64, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<i64, Error<E>> {
|
fn try_into(self) -> Result<i64, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I64(val) => Ok(val),
|
RuntimeValue::I64(val) => Ok(val),
|
||||||
@ -205,7 +205,7 @@ impl<E> TryInto<i64, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<f32, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<f32, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<f32, Error<E>> {
|
fn try_into(self) -> Result<f32, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::F32(val) => Ok(val),
|
RuntimeValue::F32(val) => Ok(val),
|
||||||
@ -214,7 +214,7 @@ impl<E> TryInto<f32, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<f64, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<f64, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<f64, Error<E>> {
|
fn try_into(self) -> Result<f64, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::F64(val) => Ok(val),
|
RuntimeValue::F64(val) => Ok(val),
|
||||||
@ -223,7 +223,7 @@ impl<E> TryInto<f64, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<u32, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<u32, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<u32, Error<E>> {
|
fn try_into(self) -> Result<u32, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val as u32),
|
RuntimeValue::I32(val) => Ok(val as u32),
|
||||||
@ -232,7 +232,7 @@ impl<E> TryInto<u32, Error<E>> for RuntimeValue where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> TryInto<u64, Error<E>> for RuntimeValue where E: CustomUserError {
|
impl<E> TryInto<u64, Error<E>> for RuntimeValue where E: UserError {
|
||||||
fn try_into(self) -> Result<u64, Error<E>> {
|
fn try_into(self) -> Result<u64, Error<E>> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I64(val) => Ok(val as u64),
|
RuntimeValue::I64(val) => Ok(val as u64),
|
||||||
@ -265,7 +265,7 @@ 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<E> TryTruncateInto<$into, Error<E>> for $from where E: CustomUserError {
|
impl<E> TryTruncateInto<$into, Error<E>> for $from where E: UserError {
|
||||||
fn try_truncate_into(self) -> Result<$into, Error<E>> {
|
fn try_truncate_into(self) -> Result<$into, Error<E>> {
|
||||||
// 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
|
||||||
@ -373,7 +373,7 @@ impl TransmuteInto<f64> for i64 {
|
|||||||
fn transmute_into(self) -> f64 { f64_from_bits(self as _) }
|
fn transmute_into(self) -> f64 { f64_from_bits(self as _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for i8 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for i8 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
vec![self as u8]
|
vec![self as u8]
|
||||||
}
|
}
|
||||||
@ -385,7 +385,7 @@ impl<E> LittleEndianConvert<E> for i8 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for u8 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for u8 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
vec![self]
|
vec![self]
|
||||||
}
|
}
|
||||||
@ -397,7 +397,7 @@ impl<E> LittleEndianConvert<E> for u8 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for i16 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for i16 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(2);
|
let mut vec = Vec::with_capacity(2);
|
||||||
vec.write_i16::<LittleEndian>(self)
|
vec.write_i16::<LittleEndian>(self)
|
||||||
@ -411,7 +411,7 @@ impl<E> LittleEndianConvert<E> for i16 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for u16 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for u16 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(2);
|
let mut vec = Vec::with_capacity(2);
|
||||||
vec.write_u16::<LittleEndian>(self)
|
vec.write_u16::<LittleEndian>(self)
|
||||||
@ -425,7 +425,7 @@ impl<E> LittleEndianConvert<E> for u16 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for i32 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for i32 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(4);
|
let mut vec = Vec::with_capacity(4);
|
||||||
vec.write_i32::<LittleEndian>(self)
|
vec.write_i32::<LittleEndian>(self)
|
||||||
@ -439,7 +439,7 @@ impl<E> LittleEndianConvert<E> for i32 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for u32 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for u32 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(4);
|
let mut vec = Vec::with_capacity(4);
|
||||||
vec.write_u32::<LittleEndian>(self)
|
vec.write_u32::<LittleEndian>(self)
|
||||||
@ -453,7 +453,7 @@ impl<E> LittleEndianConvert<E> for u32 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for i64 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for i64 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(8);
|
let mut vec = Vec::with_capacity(8);
|
||||||
vec.write_i64::<LittleEndian>(self)
|
vec.write_i64::<LittleEndian>(self)
|
||||||
@ -467,7 +467,7 @@ impl<E> LittleEndianConvert<E> for i64 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for f32 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for f32 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(4);
|
let mut vec = Vec::with_capacity(4);
|
||||||
vec.write_f32::<LittleEndian>(self)
|
vec.write_f32::<LittleEndian>(self)
|
||||||
@ -482,7 +482,7 @@ impl<E> LittleEndianConvert<E> for f32 where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LittleEndianConvert<E> for f64 where E: CustomUserError {
|
impl<E> LittleEndianConvert<E> for f64 where E: UserError {
|
||||||
fn into_little_endian(self) -> Vec<u8> {
|
fn into_little_endian(self) -> Vec<u8> {
|
||||||
let mut vec = Vec::with_capacity(8);
|
let mut vec = Vec::with_capacity(8);
|
||||||
vec.write_f64::<LittleEndian>(self)
|
vec.write_f64::<LittleEndian>(self)
|
||||||
@ -535,7 +535,7 @@ fn f64_from_bits(mut v: u64) -> f64 {
|
|||||||
|
|
||||||
macro_rules! impl_integer_arithmetic_ops {
|
macro_rules! impl_integer_arithmetic_ops {
|
||||||
($type: ident) => {
|
($type: ident) => {
|
||||||
impl<E> ArithmeticOps<$type, E> for $type where E: CustomUserError {
|
impl<E> ArithmeticOps<$type, E> for $type where E: UserError {
|
||||||
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) }
|
||||||
@ -561,7 +561,7 @@ impl_integer_arithmetic_ops!(u64);
|
|||||||
|
|
||||||
macro_rules! impl_float_arithmetic_ops {
|
macro_rules! impl_float_arithmetic_ops {
|
||||||
($type: ident) => {
|
($type: ident) => {
|
||||||
impl<E> ArithmeticOps<$type, E> for $type where E: CustomUserError {
|
impl<E> ArithmeticOps<$type, E> for $type where E: UserError {
|
||||||
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 }
|
||||||
@ -575,7 +575,7 @@ impl_float_arithmetic_ops!(f64);
|
|||||||
|
|
||||||
macro_rules! impl_integer {
|
macro_rules! impl_integer {
|
||||||
($type: ident) => {
|
($type: ident) => {
|
||||||
impl<E> Integer<$type, E> for $type where E: CustomUserError {
|
impl<E> Integer<$type, E> for $type where E: UserError {
|
||||||
fn leading_zeros(self) -> $type { self.leading_zeros() as $type }
|
fn leading_zeros(self) -> $type { self.leading_zeros() as $type }
|
||||||
fn trailing_zeros(self) -> $type { self.trailing_zeros() as $type }
|
fn trailing_zeros(self) -> $type { self.trailing_zeros() as $type }
|
||||||
fn count_ones(self) -> $type { self.count_ones() as $type }
|
fn count_ones(self) -> $type { self.count_ones() as $type }
|
||||||
@ -596,7 +596,7 @@ impl_integer!(u64);
|
|||||||
|
|
||||||
macro_rules! impl_float {
|
macro_rules! impl_float {
|
||||||
($type: ident, $int_type: ident) => {
|
($type: ident, $int_type: ident) => {
|
||||||
impl<E> Float<$type, E> for $type where E: CustomUserError {
|
impl<E> Float<$type, E> for $type where E: UserError {
|
||||||
fn abs(self) -> $type { self.abs() }
|
fn abs(self) -> $type { self.abs() }
|
||||||
fn floor(self) -> $type { self.floor() }
|
fn floor(self) -> $type { self.floor() }
|
||||||
fn ceil(self) -> $type { self.ceil() }
|
fn ceil(self) -> $type { self.ceil() }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::{GlobalType, ValueType, TableElementType};
|
use elements::{GlobalType, ValueType, TableElementType};
|
||||||
use interpreter::{Error, CustomUserError};
|
use interpreter::{Error, UserError};
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
|
|
||||||
/// Variable type.
|
/// Variable type.
|
||||||
@ -20,7 +20,7 @@ pub enum VariableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Externally stored variable value.
|
/// Externally stored variable value.
|
||||||
pub trait ExternalVariableValue<E: CustomUserError> {
|
pub trait ExternalVariableValue<E: UserError> {
|
||||||
/// Get variable value.
|
/// Get variable value.
|
||||||
fn get(&self) -> RuntimeValue;
|
fn get(&self) -> RuntimeValue;
|
||||||
/// Set variable value.
|
/// Set variable value.
|
||||||
@ -29,7 +29,7 @@ pub trait ExternalVariableValue<E: CustomUserError> {
|
|||||||
|
|
||||||
/// Variable instance.
|
/// Variable instance.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VariableInstance<E: CustomUserError> {
|
pub struct VariableInstance<E: UserError> {
|
||||||
/// Is mutable?
|
/// Is mutable?
|
||||||
is_mutable: bool,
|
is_mutable: bool,
|
||||||
/// Variable type.
|
/// Variable type.
|
||||||
@ -39,14 +39,14 @@ pub struct VariableInstance<E: CustomUserError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enum variable value.
|
/// Enum variable value.
|
||||||
enum VariableValue<E: CustomUserError> {
|
enum VariableValue<E: UserError> {
|
||||||
/// Internal value.
|
/// Internal value.
|
||||||
Internal(RuntimeValue),
|
Internal(RuntimeValue),
|
||||||
/// External value.
|
/// External value.
|
||||||
External(Box<ExternalVariableValue<E>>),
|
External(Box<ExternalVariableValue<E>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> VariableInstance<E> where E: CustomUserError {
|
impl<E> VariableInstance<E> where E: UserError {
|
||||||
/// New variable instance
|
/// New variable instance
|
||||||
pub fn new(is_mutable: bool, variable_type: VariableType, value: RuntimeValue) -> Result<Self, Error<E>> {
|
pub fn new(is_mutable: bool, variable_type: VariableType, value: RuntimeValue) -> Result<Self, Error<E>> {
|
||||||
// TODO: there is nothing about null value in specification + there is nothing about initializing missing table elements? => runtime check for nulls
|
// TODO: there is nothing about null value in specification + there is nothing about initializing missing table elements? => runtime check for nulls
|
||||||
@ -109,7 +109,7 @@ impl<E> VariableInstance<E> where E: CustomUserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> VariableValue<E> where E: CustomUserError {
|
impl<E> VariableValue<E> where E: UserError {
|
||||||
fn get(&self) -> RuntimeValue {
|
fn get(&self) -> RuntimeValue {
|
||||||
match *self {
|
match *self {
|
||||||
VariableValue::Internal(ref value) => value.clone(),
|
VariableValue::Internal(ref value) => value.clone(),
|
||||||
@ -147,7 +147,7 @@ impl From<TableElementType> for VariableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E> fmt::Debug for VariableValue<E> where E: CustomUserError {
|
impl<E> fmt::Debug for VariableValue<E> where E: UserError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
VariableValue::Internal(ref value) => write!(f, "Variable.Internal({:?})", value),
|
VariableValue::Internal(ref value) => write!(f, "Variable.Internal({:?})", value),
|
||||||
|
Reference in New Issue
Block a user