commit
273eba2c45
|
@ -1,7 +1,6 @@
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
|
||||||
use parity_wasm::elements::{Local, Opcodes};
|
use parity_wasm::elements::{Local, Opcodes};
|
||||||
use {Error, Signature};
|
use {Error, Signature};
|
||||||
use host::Externals;
|
use host::Externals;
|
||||||
|
@ -99,8 +98,8 @@ impl FuncInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn invoke<E: Externals>(
|
pub(crate) fn invoke<E: Externals>(
|
||||||
func: FuncRef,
|
func: &FuncRef,
|
||||||
args: Cow<[RuntimeValue]>,
|
args: &[RuntimeValue],
|
||||||
externals: &mut E,
|
externals: &mut E,
|
||||||
) -> Result<Option<RuntimeValue>, Error> {
|
) -> Result<Option<RuntimeValue>, Error> {
|
||||||
enum InvokeKind<'a> {
|
enum InvokeKind<'a> {
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl MemoryInstance {
|
||||||
None => u32::MAX,
|
None => u32::MAX,
|
||||||
};
|
};
|
||||||
let initial_size = calculate_memory_size(0, limits.initial(), maximum_size)
|
let initial_size = calculate_memory_size(0, limits.initial(), maximum_size)
|
||||||
.ok_or(Error::Memory(format!("initial memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES)))?;
|
.ok_or_else(|| Error::Memory(format!("initial memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES)))?;
|
||||||
|
|
||||||
let memory = MemoryInstance {
|
let memory = MemoryInstance {
|
||||||
limits: limits,
|
limits: limits,
|
||||||
|
@ -165,7 +165,7 @@ impl MemoryInstance {
|
||||||
where B: ::std::ops::Deref<Target=Vec<u8>>
|
where B: ::std::ops::Deref<Target=Vec<u8>>
|
||||||
{
|
{
|
||||||
let end = offset.checked_add(size)
|
let end = offset.checked_add(size)
|
||||||
.ok_or(Error::Memory(format!("trying to access memory block of size {} from offset {}", size, offset)))?;
|
.ok_or_else(|| Error::Memory(format!("trying to access memory block of size {} from offset {}", size, offset)))?;
|
||||||
|
|
||||||
if end > buffer.len() {
|
if end > buffer.len() {
|
||||||
return Err(Error::Memory(format!("trying to access region [{}..{}] in memory [0..{}]", offset, end, buffer.len())));
|
return Err(Error::Memory(format!("trying to access region [{}..{}] in memory [0..{}]", offset, end, buffer.len())));
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
|
||||||
use parity_wasm::elements::{External, InitExpr, Internal, Opcode, ResizableLimits, Type};
|
use parity_wasm::elements::{External, InitExpr, Internal, Opcode, ResizableLimits, Type};
|
||||||
use {LoadedModule, Error, Signature, MemoryInstance, RuntimeValue, TableInstance};
|
use {LoadedModule, Error, Signature, MemoryInstance, RuntimeValue, TableInstance};
|
||||||
use imports::ImportResolver;
|
use imports::ImportResolver;
|
||||||
|
@ -165,7 +164,7 @@ impl ModuleInstance {
|
||||||
let instance = ModuleRef(Rc::new(ModuleInstance::default()));
|
let instance = ModuleRef(Rc::new(ModuleInstance::default()));
|
||||||
|
|
||||||
for &Type::Function(ref ty) in module.type_section().map(|ts| ts.types()).unwrap_or(&[]) {
|
for &Type::Function(ref ty) in module.type_section().map(|ts| ts.types()).unwrap_or(&[]) {
|
||||||
let signature = Rc::new(Signature::from_elements(ty.clone()));
|
let signature = Rc::new(Signature::from_elements(ty));
|
||||||
instance.push_signature(signature);
|
instance.push_signature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +173,9 @@ impl ModuleInstance {
|
||||||
&[],
|
&[],
|
||||||
);
|
);
|
||||||
if imports.len() != extern_vals.len() {
|
if imports.len() != extern_vals.len() {
|
||||||
return Err(Error::Instantiation(format!(
|
return Err(Error::Instantiation(
|
||||||
"extern_vals length is not equal to import section entries"
|
"extern_vals length is not equal to import section entries".to_owned()
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (import, extern_val) in
|
for (import, extern_val) in
|
||||||
|
@ -386,7 +385,7 @@ impl ModuleInstance {
|
||||||
let &Type::Function(ref func_type) = types
|
let &Type::Function(ref func_type) = types
|
||||||
.get(fn_ty_idx as usize)
|
.get(fn_ty_idx as usize)
|
||||||
.expect("Due to validation functions should have valid types");
|
.expect("Due to validation functions should have valid types");
|
||||||
let signature = Signature::from_elements(func_type.clone());
|
let signature = Signature::from_elements(func_type);
|
||||||
let func = imports.resolve_func(module_name, field_name, &signature)?;
|
let func = imports.resolve_func(module_name, field_name, &signature)?;
|
||||||
ExternVal::Func(func)
|
ExternVal::Func(func)
|
||||||
}
|
}
|
||||||
|
@ -437,7 +436,7 @@ impl ModuleInstance {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FuncInstance::invoke(func_instance.clone(), Cow::Borrowed(args), externals)
|
FuncInstance::invoke(&func_instance, args, externals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,12 +450,12 @@ impl<'a> NotStartedModuleRef<'a> {
|
||||||
&self.instance
|
&self.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_start<'b, E: Externals>(self, state: &'b mut E) -> Result<ModuleRef, Error> {
|
pub fn run_start<E: Externals>(self, state: &mut E) -> Result<ModuleRef, Error> {
|
||||||
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",
|
||||||
);
|
);
|
||||||
FuncInstance::invoke(start_func, Cow::Borrowed(&[]), state)?;
|
FuncInstance::invoke(&start_func, &[], state)?;
|
||||||
}
|
}
|
||||||
Ok(self.instance)
|
Ok(self.instance)
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
},
|
},
|
||||||
FuncInstanceInternal::Host { ref signature, .. } => {
|
FuncInstanceInternal::Host { ref signature, .. } => {
|
||||||
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.clone(), args.into(), 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)?;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_br_table(&mut self, context: &mut FunctionContext, table: &Vec<u32>, default: u32) -> Result<InstructionOutcome, Error> {
|
fn run_br_table(&mut self, context: &mut FunctionContext, table: &[u32], default: u32) -> Result<InstructionOutcome, Error> {
|
||||||
let index: u32 = context.value_stack_mut().pop_as()?;
|
let index: u32 = context.value_stack_mut().pop_as()?;
|
||||||
Ok(InstructionOutcome::Branch(table.get(index as usize).cloned().unwrap_or(default) as usize))
|
Ok(InstructionOutcome::Branch(table.get(index as usize).cloned().unwrap_or(default) as usize))
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionContext {
|
impl FunctionContext {
|
||||||
pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec<RuntimeValue>) -> Self {
|
pub fn new(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec<RuntimeValue>) -> Self {
|
||||||
let module = match *function.as_internal() {
|
let module = match *function.as_internal() {
|
||||||
FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"),
|
FuncInstanceInternal::Internal { ref module, .. } => module.upgrade().expect("module deallocated"),
|
||||||
FuncInstanceInternal::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
FuncInstanceInternal::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
||||||
|
@ -1029,7 +1029,7 @@ impl FunctionContext {
|
||||||
};
|
};
|
||||||
let function_type = function.signature();
|
let function_type = function.signature();
|
||||||
let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult);
|
let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult);
|
||||||
let function_locals = prepare_function_args(&function_type, &mut self.value_stack)?;
|
let function_locals = prepare_function_args(function_type, &mut self.value_stack)?;
|
||||||
(function_locals, module, function_return_type)
|
(function_locals, module, function_return_type)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1055,7 +1055,7 @@ impl FunctionContext {
|
||||||
|
|
||||||
let locals = locals.iter()
|
let locals = locals.iter()
|
||||||
.flat_map(|l| repeat(l.value_type()).take(l.count() as usize))
|
.flat_map(|l| repeat(l.value_type()).take(l.count() as usize))
|
||||||
.map(|vt| RuntimeValue::default(vt))
|
.map(RuntimeValue::default)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
self.locals.extend(locals);
|
self.locals.extend(locals);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ impl TableInstance {
|
||||||
buffer_len
|
buffer_len
|
||||||
)),
|
)),
|
||||||
)?;
|
)?;
|
||||||
Ok(table_elem.ok_or(Error::Table(format!(
|
Ok(table_elem.ok_or_else(|| Error::Table(format!(
|
||||||
"trying to read uninitialized element on index {}",
|
"trying to read uninitialized element on index {}",
|
||||||
offset
|
offset
|
||||||
)))?)
|
)))?)
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl Signature {
|
||||||
self.return_type
|
self.return_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_elements(func_type: FunctionType) -> Signature {
|
pub(crate) fn from_elements(func_type: &FunctionType) -> Signature {
|
||||||
Signature {
|
Signature {
|
||||||
params: func_type.params().iter().cloned().map(ValueType::from_elements).collect(),
|
params: func_type.params().iter().cloned().map(ValueType::from_elements).collect(),
|
||||||
return_type: func_type.return_type().map(ValueType::from_elements),
|
return_type: func_type.return_type().map(ValueType::from_elements),
|
||||||
|
@ -122,5 +122,5 @@ impl MemoryDescriptor {
|
||||||
|
|
||||||
pub fn maximum(&self) -> Option<u32> {
|
pub fn maximum(&self) -> Option<u32> {
|
||||||
self.maximum
|
self.maximum
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/value.rs
18
src/value.rs
|
@ -180,7 +180,7 @@ impl TryInto<bool, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<bool, Error> {
|
fn try_into(self) -> Result<bool, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val != 0),
|
RuntimeValue::I32(val) => Ok(val != 0),
|
||||||
_ => Err(Error::Value(format!("32-bit int value expected"))),
|
_ => Err(Error::Value("32-bit int value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ impl TryInto<i32, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<i32, Error> {
|
fn try_into(self) -> Result<i32, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val),
|
RuntimeValue::I32(val) => Ok(val),
|
||||||
_ => Err(Error::Value(format!("32-bit int value expected"))),
|
_ => Err(Error::Value("32-bit int value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ impl TryInto<i64, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<i64, Error> {
|
fn try_into(self) -> Result<i64, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I64(val) => Ok(val),
|
RuntimeValue::I64(val) => Ok(val),
|
||||||
_ => Err(Error::Value(format!("64-bit int value expected"))),
|
_ => Err(Error::Value("64-bit int value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ impl TryInto<f32, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<f32, Error> {
|
fn try_into(self) -> Result<f32, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::F32(val) => Ok(val),
|
RuntimeValue::F32(val) => Ok(val),
|
||||||
_ => Err(Error::Value(format!("32-bit float value expected"))),
|
_ => Err(Error::Value("32-bit float value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ impl TryInto<f64, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<f64, Error> {
|
fn try_into(self) -> Result<f64, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::F64(val) => Ok(val),
|
RuntimeValue::F64(val) => Ok(val),
|
||||||
_ => Err(Error::Value(format!("64-bit float value expected"))),
|
_ => Err(Error::Value("64-bit float value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ impl TryInto<u32, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<u32, Error> {
|
fn try_into(self) -> Result<u32, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I32(val) => Ok(val as u32),
|
RuntimeValue::I32(val) => Ok(val as u32),
|
||||||
_ => Err(Error::Value(format!("32-bit int value expected"))),
|
_ => Err(Error::Value("32-bit int value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ impl TryInto<u64, Error> for RuntimeValue {
|
||||||
fn try_into(self) -> Result<u64, Error> {
|
fn try_into(self) -> Result<u64, Error> {
|
||||||
match self {
|
match self {
|
||||||
RuntimeValue::I64(val) => Ok(val as u64),
|
RuntimeValue::I64(val) => Ok(val as u64),
|
||||||
_ => Err(Error::Value(format!("64-bit int value expected"))),
|
_ => Err(Error::Value("64-bit int value expected".to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ impl LittleEndianConvert for i8 {
|
||||||
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
|
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
|
||||||
buffer.get(0)
|
buffer.get(0)
|
||||||
.map(|v| *v as i8)
|
.map(|v| *v as i8)
|
||||||
.ok_or(Error::Value("invalid little endian buffer".into()))
|
.ok_or_else(|| Error::Value("invalid little endian buffer".into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ impl LittleEndianConvert for u8 {
|
||||||
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
|
fn from_little_endian(buffer: Vec<u8>) -> Result<Self, Error> {
|
||||||
buffer.get(0)
|
buffer.get(0)
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(Error::Value("invalid little endian buffer".into()))
|
.ok_or_else(|| Error::Value("invalid little endian buffer".into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue