Migrate on Signature type.
This commit is contained in:
parent
fa1cba92c9
commit
e9470373f7
40
src/func.rs
40
src/func.rs
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use parity_wasm::elements::{FunctionType, Local, Opcodes};
|
use parity_wasm::elements::{FunctionType, Local, Opcodes};
|
||||||
use Error;
|
use {Error, Signature};
|
||||||
use host::Externals;
|
use host::Externals;
|
||||||
use runner::{prepare_function_args, FunctionContext, Interpreter};
|
use runner::{prepare_function_args, FunctionContext, Interpreter};
|
||||||
use value::RuntimeValue;
|
use value::RuntimeValue;
|
||||||
|
@ -24,12 +24,12 @@ impl ::std::ops::Deref for FuncRef {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum FuncInstance {
|
pub enum FuncInstance {
|
||||||
Internal {
|
Internal {
|
||||||
func_type: Rc<FunctionType>,
|
signature: Rc<Signature>,
|
||||||
module: ModuleRef,
|
module: ModuleRef,
|
||||||
body: Rc<FuncBody>,
|
body: Rc<FuncBody>,
|
||||||
},
|
},
|
||||||
Host {
|
Host {
|
||||||
func_type: FunctionType,
|
signature: Signature,
|
||||||
host_func_index: usize,
|
host_func_index: usize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -38,19 +38,19 @@ impl fmt::Debug for FuncInstance {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&FuncInstance::Internal {
|
&FuncInstance::Internal {
|
||||||
ref func_type,
|
ref signature,
|
||||||
ref module,
|
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
// We can't write description of self.module here, because it generate
|
||||||
|
// debug string for function instances and this will lead to infinite loop.
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Internal {{ type={:?}, module={:?} }}",
|
"Internal {{ signature={:?} }}",
|
||||||
func_type,
|
signature,
|
||||||
module
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&FuncInstance::Host { ref func_type, .. } => {
|
&FuncInstance::Host { ref signature, .. } => {
|
||||||
write!(f, "Host {{ type={:?} }}", func_type)
|
write!(f, "Host {{ signature={:?} }}", signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,29 +59,29 @@ impl fmt::Debug for FuncInstance {
|
||||||
impl FuncInstance {
|
impl FuncInstance {
|
||||||
pub(crate) fn alloc_internal(
|
pub(crate) fn alloc_internal(
|
||||||
module: ModuleRef,
|
module: ModuleRef,
|
||||||
func_type: Rc<FunctionType>,
|
signature: Rc<Signature>,
|
||||||
body: FuncBody,
|
body: FuncBody,
|
||||||
) -> FuncRef {
|
) -> FuncRef {
|
||||||
let func = FuncInstance::Internal {
|
let func = FuncInstance::Internal {
|
||||||
func_type,
|
signature,
|
||||||
module: module,
|
module: module,
|
||||||
body: Rc::new(body),
|
body: Rc::new(body),
|
||||||
};
|
};
|
||||||
FuncRef(Rc::new(func))
|
FuncRef(Rc::new(func))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_host(func_type: FunctionType, host_func_index: usize) -> FuncRef {
|
pub fn alloc_host(signature: Signature, host_func_index: usize) -> FuncRef {
|
||||||
let func = FuncInstance::Host {
|
let func = FuncInstance::Host {
|
||||||
func_type,
|
signature,
|
||||||
host_func_index,
|
host_func_index,
|
||||||
};
|
};
|
||||||
FuncRef(Rc::new(func))
|
FuncRef(Rc::new(func))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn func_type(&self) -> &FunctionType {
|
pub fn signature(&self) -> &Signature {
|
||||||
match *self {
|
match *self {
|
||||||
FuncInstance::Internal { ref func_type, .. } => func_type,
|
FuncInstance::Internal { ref signature, .. } => signature,
|
||||||
FuncInstance::Host { ref func_type, .. } => func_type,
|
FuncInstance::Host { ref signature, .. } => signature,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,15 +103,15 @@ impl FuncInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = match *func {
|
let result = match *func {
|
||||||
FuncInstance::Internal { ref func_type, .. } => {
|
FuncInstance::Internal { ref signature, .. } => {
|
||||||
let mut stack =
|
let mut stack =
|
||||||
StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT);
|
StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT);
|
||||||
let args = prepare_function_args(func_type, &mut stack)?;
|
let args = prepare_function_args(signature, &mut stack)?;
|
||||||
let context = FunctionContext::new(
|
let context = FunctionContext::new(
|
||||||
func.clone(),
|
func.clone(),
|
||||||
DEFAULT_VALUE_STACK_LIMIT,
|
DEFAULT_VALUE_STACK_LIMIT,
|
||||||
DEFAULT_FRAME_STACK_LIMIT,
|
DEFAULT_FRAME_STACK_LIMIT,
|
||||||
func_type,
|
signature,
|
||||||
args,
|
args,
|
||||||
);
|
);
|
||||||
InvokeKind::Internal(context)
|
InvokeKind::Internal(context)
|
||||||
|
|
|
@ -5,14 +5,14 @@ use memory::MemoryRef;
|
||||||
use func::FuncRef;
|
use func::FuncRef;
|
||||||
use table::TableRef;
|
use table::TableRef;
|
||||||
use module::ModuleRef;
|
use module::ModuleRef;
|
||||||
use Error;
|
use {Error, Signature};
|
||||||
|
|
||||||
pub trait ImportResolver {
|
pub trait ImportResolver {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
func_type: &Signature,
|
||||||
) -> Result<FuncRef, Error>;
|
) -> Result<FuncRef, Error>;
|
||||||
|
|
||||||
fn resolve_global(
|
fn resolve_global(
|
||||||
|
@ -75,11 +75,11 @@ impl<'a> ImportResolver for ImportsBuilder<'a> {
|
||||||
&self,
|
&self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
self.resolver(module_name).ok_or_else(||
|
self.resolver(module_name).ok_or_else(||
|
||||||
Error::Instantiation(format!("Module {} not found", module_name))
|
Error::Instantiation(format!("Module {} not found", module_name))
|
||||||
)?.resolve_func(field_name, func_type)
|
)?.resolve_func(field_name, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_global(
|
fn resolve_global(
|
||||||
|
@ -120,7 +120,7 @@ pub trait ModuleImportResolver {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
_func_type: &FunctionType,
|
_signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
Err(Error::Instantiation(
|
Err(Error::Instantiation(
|
||||||
format!("Export {} not found", field_name),
|
format!("Export {} not found", field_name),
|
||||||
|
@ -162,7 +162,7 @@ impl ModuleImportResolver for ModuleRef {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
_func_type: &FunctionType,
|
_signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
Ok(self.export_by_name(field_name)
|
Ok(self.export_by_name(field_name)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
|
|
28
src/lib.rs
28
src/lib.rs
|
@ -10,6 +10,7 @@ extern crate byteorder;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::error;
|
use std::error;
|
||||||
|
use parity_wasm::elements::{FunctionType, ValueType};
|
||||||
|
|
||||||
/// Internal interpreter error.
|
/// Internal interpreter error.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -97,6 +98,33 @@ impl From<::common::stack::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Signature {
|
||||||
|
func_type: FunctionType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Signature {
|
||||||
|
pub fn new(params: &[ValueType], return_type: Option<ValueType>) -> Signature {
|
||||||
|
Signature {
|
||||||
|
func_type: FunctionType::new(params.to_vec(), return_type),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn params(&self) -> &[ValueType] {
|
||||||
|
self.func_type.params()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn return_type(&self) -> Option<ValueType> {
|
||||||
|
self.func_type.return_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FunctionType> for Signature {
|
||||||
|
fn from(func_type: FunctionType) -> Signature {
|
||||||
|
Signature { func_type }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod validation;
|
mod validation;
|
||||||
mod common;
|
mod common;
|
||||||
mod memory;
|
mod memory;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use parity_wasm::elements::{External, FunctionType, InitExpr, Internal, Opcode, ResizableLimits, Type};
|
use parity_wasm::elements::{External, FunctionType, InitExpr, Internal, Opcode, ResizableLimits, Type};
|
||||||
use {Error, MemoryInstance, RuntimeValue, TableInstance};
|
use {Error, Signature, MemoryInstance, RuntimeValue, TableInstance};
|
||||||
use imports::ImportResolver;
|
use imports::ImportResolver;
|
||||||
use global::{GlobalInstance, GlobalRef};
|
use global::{GlobalInstance, GlobalRef};
|
||||||
use func::{FuncRef, FuncBody, FuncInstance};
|
use func::{FuncRef, FuncBody, FuncInstance};
|
||||||
|
@ -89,7 +89,7 @@ impl ExternVal {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ModuleInstance {
|
pub struct ModuleInstance {
|
||||||
types: RefCell<Vec<Rc<FunctionType>>>,
|
signatures: RefCell<Vec<Rc<Signature>>>,
|
||||||
tables: RefCell<Vec<TableRef>>,
|
tables: RefCell<Vec<TableRef>>,
|
||||||
funcs: RefCell<Vec<FuncRef>>,
|
funcs: RefCell<Vec<FuncRef>>,
|
||||||
memories: RefCell<Vec<MemoryRef>>,
|
memories: RefCell<Vec<MemoryRef>>,
|
||||||
|
@ -101,7 +101,7 @@ impl ModuleInstance {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ModuleInstance {
|
ModuleInstance {
|
||||||
funcs: RefCell::new(Vec::new()),
|
funcs: RefCell::new(Vec::new()),
|
||||||
types: RefCell::new(Vec::new()),
|
signatures: RefCell::new(Vec::new()),
|
||||||
tables: RefCell::new(Vec::new()),
|
tables: RefCell::new(Vec::new()),
|
||||||
memories: RefCell::new(Vec::new()),
|
memories: RefCell::new(Vec::new()),
|
||||||
globals: RefCell::new(Vec::new()),
|
globals: RefCell::new(Vec::new()),
|
||||||
|
@ -129,16 +129,16 @@ impl ModuleInstance {
|
||||||
self.exports.borrow().get(name).cloned()
|
self.exports.borrow().get(name).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn type_by_index(&self, idx: u32) -> Option<Rc<FunctionType>> {
|
pub(crate) fn signature_by_index(&self, idx: u32) -> Option<Rc<Signature>> {
|
||||||
self.types.borrow().get(idx as usize).cloned()
|
self.signatures.borrow().get(idx as usize).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_func(&self, func: FuncRef) {
|
fn push_func(&self, func: FuncRef) {
|
||||||
self.funcs.borrow_mut().push(func);
|
self.funcs.borrow_mut().push(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_type(&self, func_type: Rc<FunctionType>) {
|
fn push_signature(&self, signature: Rc<Signature>) {
|
||||||
self.types.borrow_mut().push(func_type)
|
self.signatures.borrow_mut().push(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_memory(&self, memory: MemoryRef) {
|
fn push_memory(&self, memory: MemoryRef) {
|
||||||
|
@ -165,8 +165,8 @@ 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 type_id = alloc_func_type(ty.clone());
|
let signature = Rc::new(ty.clone().into());
|
||||||
instance.push_type(type_id);
|
instance.push_signature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -184,10 +184,10 @@ impl ModuleInstance {
|
||||||
{
|
{
|
||||||
match (import.external(), extern_val) {
|
match (import.external(), extern_val) {
|
||||||
(&External::Function(fn_type_idx), &ExternVal::Func(ref func)) => {
|
(&External::Function(fn_type_idx), &ExternVal::Func(ref func)) => {
|
||||||
let expected_fn_type = instance.type_by_index(fn_type_idx).expect(
|
let expected_fn_type = instance.signature_by_index(fn_type_idx).expect(
|
||||||
"Due to validation function type should exists",
|
"Due to validation function type should exists",
|
||||||
);
|
);
|
||||||
let actual_fn_type = func.func_type();
|
let actual_fn_type = func.signature();
|
||||||
if &*expected_fn_type != actual_fn_type {
|
if &*expected_fn_type != actual_fn_type {
|
||||||
return Err(Error::Instantiation(format!(
|
return Err(Error::Instantiation(format!(
|
||||||
"Expected function with type {:?}, but actual type is {:?} for entry {}",
|
"Expected function with type {:?}, but actual type is {:?} for entry {}",
|
||||||
|
@ -241,7 +241,7 @@ impl ModuleInstance {
|
||||||
for (index, (ty, body)) in
|
for (index, (ty, body)) in
|
||||||
Iterator::zip(funcs.into_iter(), bodies.into_iter()).enumerate()
|
Iterator::zip(funcs.into_iter(), bodies.into_iter()).enumerate()
|
||||||
{
|
{
|
||||||
let func_type = instance.type_by_index(ty.type_ref()).expect(
|
let signature = instance.signature_by_index(ty.type_ref()).expect(
|
||||||
"Due to validation type should exists",
|
"Due to validation type should exists",
|
||||||
);
|
);
|
||||||
let labels = labels.get(&index).expect(
|
let labels = labels.get(&index).expect(
|
||||||
|
@ -253,7 +253,7 @@ impl ModuleInstance {
|
||||||
labels: labels,
|
labels: labels,
|
||||||
};
|
};
|
||||||
let func_instance =
|
let func_instance =
|
||||||
FuncInstance::alloc_internal(instance.clone(), func_type, func_body);
|
FuncInstance::alloc_internal(instance.clone(), signature, func_body);
|
||||||
instance.push_func(func_instance);
|
instance.push_func(func_instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,8 @@ 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 func = imports.resolve_func(module_name, field_name, func_type)?;
|
let signature = func_type.clone().into();
|
||||||
|
let func = imports.resolve_func(module_name, field_name, &signature)?;
|
||||||
ExternVal::Func(func)
|
ExternVal::Func(func)
|
||||||
}
|
}
|
||||||
External::Table(ref table_type) => {
|
External::Table(ref table_type) => {
|
||||||
|
@ -478,10 +479,6 @@ impl<'a> NotStartedModuleRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_func_type(func_type: FunctionType) -> Rc<FunctionType> {
|
|
||||||
Rc::new(func_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_init_expr(init_expr: &InitExpr, module: &ModuleInstance) -> RuntimeValue {
|
fn eval_init_expr(init_expr: &InitExpr, module: &ModuleInstance) -> RuntimeValue {
|
||||||
let code = init_expr.code();
|
let code = init_expr.code();
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
|
|
|
@ -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, FunctionType};
|
use parity_wasm::elements::{Opcode, BlockType, Local, FunctionType};
|
||||||
use Error;
|
use {Error, Signature};
|
||||||
use module::ModuleRef;
|
use module::ModuleRef;
|
||||||
use func::FuncRef;
|
use func::FuncRef;
|
||||||
use func::FuncInstance;
|
use func::FuncInstance;
|
||||||
|
@ -102,8 +102,8 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
function_stack.push_back(function_context);
|
function_stack.push_back(function_context);
|
||||||
function_stack.push_back(nested_context);
|
function_stack.push_back(nested_context);
|
||||||
},
|
},
|
||||||
FuncInstance::Host { ref func_type, .. } => {
|
FuncInstance::Host { ref signature, .. } => {
|
||||||
let args = prepare_function_args(func_type, &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.clone(), args.into(), 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)?;
|
||||||
|
@ -428,7 +428,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
fn run_call_indirect(
|
fn run_call_indirect(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &mut FunctionContext,
|
context: &mut FunctionContext,
|
||||||
type_idx: u32,
|
signature_idx: u32,
|
||||||
) -> Result<InstructionOutcome, Error> {
|
) -> Result<InstructionOutcome, Error> {
|
||||||
let table_func_idx: u32 = context.value_stack_mut().pop_as()?;
|
let table_func_idx: u32 = context.value_stack_mut().pop_as()?;
|
||||||
let table = context
|
let table = context
|
||||||
|
@ -438,10 +438,10 @@ impl<'a, E: Externals> Interpreter<'a, E> {
|
||||||
let func_ref = table.get(table_func_idx)?;
|
let func_ref = table.get(table_func_idx)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let actual_function_type = func_ref.func_type();
|
let actual_function_type = func_ref.signature();
|
||||||
let required_function_type = context
|
let required_function_type = context
|
||||||
.module()
|
.module()
|
||||||
.type_by_index(type_idx)
|
.signature_by_index(signature_idx)
|
||||||
.expect("Due to validation type should exists");
|
.expect("Due to validation type should exists");
|
||||||
|
|
||||||
if &*required_function_type != actual_function_type {
|
if &*required_function_type != actual_function_type {
|
||||||
|
@ -1001,7 +1001,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, function_type: &FunctionType, args: Vec<RuntimeValue>) -> Self {
|
pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec<RuntimeValue>) -> Self {
|
||||||
let module = match *function {
|
let module = match *function {
|
||||||
FuncInstance::Internal { ref module, .. } => module.clone(),
|
FuncInstance::Internal { ref module, .. } => module.clone(),
|
||||||
FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
||||||
|
@ -1010,7 +1010,7 @@ impl FunctionContext {
|
||||||
is_initialized: false,
|
is_initialized: false,
|
||||||
function: function,
|
function: function,
|
||||||
module: module,
|
module: module,
|
||||||
return_type: function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
|
return_type: signature.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
|
||||||
value_stack: StackWithLimit::with_limit(value_stack_limit),
|
value_stack: StackWithLimit::with_limit(value_stack_limit),
|
||||||
frame_stack: StackWithLimit::with_limit(frame_stack_limit),
|
frame_stack: StackWithLimit::with_limit(frame_stack_limit),
|
||||||
locals: args,
|
locals: args,
|
||||||
|
@ -1024,7 +1024,7 @@ impl FunctionContext {
|
||||||
FuncInstance::Internal { ref module, .. } => module.clone(),
|
FuncInstance::Internal { ref module, .. } => module.clone(),
|
||||||
FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"),
|
||||||
};
|
};
|
||||||
let function_type = function.func_type();
|
let function_type = function.signature();
|
||||||
let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult);
|
let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt)).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)
|
||||||
|
@ -1151,8 +1151,8 @@ fn effective_address(address: u32, offset: u32) -> Result<u32, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_function_args(function_type: &FunctionType, caller_stack: &mut StackWithLimit<RuntimeValue>) -> Result<Vec<RuntimeValue>, Error> {
|
pub fn prepare_function_args(signature: &Signature, caller_stack: &mut StackWithLimit<RuntimeValue>) -> Result<Vec<RuntimeValue>, Error> {
|
||||||
let mut args = function_type.params().iter().cloned().rev().map(|expected_type| {
|
let mut args = signature.params().iter().cloned().rev().map(|expected_type| {
|
||||||
let param_value = caller_stack.pop()?;
|
let param_value = caller_stack.pop()?;
|
||||||
let actual_type = param_value.value_type();
|
let actual_type = param_value.value_type();
|
||||||
if actual_type != expected_type {
|
if actual_type != expected_type {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use parity_wasm::elements::{deserialize_buffer, FunctionType, MemoryType, TableType, ValueType};
|
use parity_wasm::elements::{deserialize_buffer, FunctionType, MemoryType, TableType, ValueType};
|
||||||
use validation::{validate_module, ValidatedModule};
|
use validation::{validate_module, ValidatedModule};
|
||||||
use {
|
use {
|
||||||
Error, 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, TryInto,
|
RuntimeValue, TryInto,
|
||||||
};
|
};
|
||||||
|
@ -144,14 +144,14 @@ impl Externals for TestHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestHost {
|
impl TestHost {
|
||||||
fn check_signature(&self, index: usize, func_type: &FunctionType) -> bool {
|
fn check_signature(&self, index: usize, signature: &Signature) -> bool {
|
||||||
if index == RECURSE_FUNC_INDEX {
|
if index == RECURSE_FUNC_INDEX {
|
||||||
// This function requires special handling because it is polymorphic.
|
// This function requires special handling because it is polymorphic.
|
||||||
if func_type.params().len() != 1 {
|
if signature.params().len() != 1 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let param_type = func_type.params()[0];
|
let param_type = signature.params()[0];
|
||||||
return func_type.return_type() == Some(param_type);
|
return signature.return_type() == Some(param_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index {
|
let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index {
|
||||||
|
@ -162,12 +162,12 @@ impl TestHost {
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
func_type.params() == params && func_type.return_type() == ret_ty
|
signature.params() == params && signature.return_type() == ret_ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleImportResolver for TestHost {
|
impl ModuleImportResolver for TestHost {
|
||||||
fn resolve_func(&self, field_name: &str, func_type: &FunctionType) -> Result<FuncRef, Error> {
|
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
|
||||||
let index = match field_name {
|
let index = match field_name {
|
||||||
"sub" => SUB_FUNC_INDEX,
|
"sub" => SUB_FUNC_INDEX,
|
||||||
"err" => ERR_FUNC_INDEX,
|
"err" => ERR_FUNC_INDEX,
|
||||||
|
@ -181,15 +181,15 @@ impl ModuleImportResolver for TestHost {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.check_signature(index, func_type) {
|
if !self.check_signature(index, signature) {
|
||||||
return Err(Error::Instantiation(format!(
|
return Err(Error::Instantiation(format!(
|
||||||
"Export `{}` doesnt match expected type {:?}",
|
"Export `{}` doesnt match expected type {:?}",
|
||||||
field_name,
|
field_name,
|
||||||
func_type
|
signature
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FuncInstance::alloc_host(func_type.clone(), index))
|
Ok(FuncInstance::alloc_host(signature.clone(), index))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_memory(
|
fn resolve_memory(
|
||||||
|
@ -424,22 +424,22 @@ fn defer_providing_externals() {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
if field_name != "inc" {
|
if field_name != "inc" {
|
||||||
return Err(Error::Instantiation(
|
return Err(Error::Instantiation(
|
||||||
format!("Export {} not found", field_name),
|
format!("Export {} not found", field_name),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if func_type.params() != &[ValueType::I32] || func_type.return_type() != None {
|
if signature.params() != &[ValueType::I32] || signature.return_type() != None {
|
||||||
return Err(Error::Instantiation(format!(
|
return Err(Error::Instantiation(format!(
|
||||||
"Export `{}` doesnt match expected type {:?}",
|
"Export `{}` doesnt match expected type {:?}",
|
||||||
field_name,
|
field_name,
|
||||||
func_type
|
signature
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FuncInstance::alloc_host(func_type.clone(), INC_FUNC_INDEX))
|
Ok(FuncInstance::alloc_host(signature.clone(), INC_FUNC_INDEX))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_memory(
|
fn resolve_memory(
|
||||||
|
@ -552,7 +552,7 @@ fn two_envs_one_externals() {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
let index = match field_name {
|
let index = match field_name {
|
||||||
"ordinary" => ORDINARY_FUNC_INDEX,
|
"ordinary" => ORDINARY_FUNC_INDEX,
|
||||||
|
@ -564,7 +564,7 @@ fn two_envs_one_externals() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(FuncInstance::alloc_host(func_type.clone(), index))
|
Ok(FuncInstance::alloc_host(signature.clone(), index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +572,7 @@ fn two_envs_one_externals() {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
let index = match field_name {
|
let index = match field_name {
|
||||||
"ordinary" => ORDINARY_FUNC_INDEX,
|
"ordinary" => ORDINARY_FUNC_INDEX,
|
||||||
|
@ -588,7 +588,7 @@ fn two_envs_one_externals() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(FuncInstance::alloc_host(func_type.clone(), index))
|
Ok(FuncInstance::alloc_host(signature.clone(), index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ fn dynamically_add_host_func() {
|
||||||
self.added_funcs += 1;
|
self.added_funcs += 1;
|
||||||
|
|
||||||
let added_func = FuncInstance::alloc_host(
|
let added_func = FuncInstance::alloc_host(
|
||||||
FunctionType::new(vec![], Some(ValueType::I32)),
|
Signature::new(&[], Some(ValueType::I32)),
|
||||||
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))?;
|
||||||
|
@ -682,7 +682,7 @@ fn dynamically_add_host_func() {
|
||||||
fn resolve_func(
|
fn resolve_func(
|
||||||
&self,
|
&self,
|
||||||
field_name: &str,
|
field_name: &str,
|
||||||
func_type: &FunctionType,
|
signature: &Signature,
|
||||||
) -> Result<FuncRef, Error> {
|
) -> Result<FuncRef, Error> {
|
||||||
let index = match field_name {
|
let index = match field_name {
|
||||||
"add_func" => ADD_FUNC_FUNC_INDEX,
|
"add_func" => ADD_FUNC_FUNC_INDEX,
|
||||||
|
@ -692,7 +692,7 @@ fn dynamically_add_host_func() {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(FuncInstance::alloc_host(func_type.clone(), index))
|
Ok(FuncInstance::alloc_host(signature.clone(), index))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_table(
|
fn resolve_table(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use parity_wasm::elements::deserialize_file;
|
use parity_wasm::elements::deserialize_file;
|
||||||
use parity_wasm::elements::{FunctionType, GlobalType, MemoryType, Module, TableType};
|
use parity_wasm::elements::{FunctionType, GlobalType, MemoryType, Module, TableType};
|
||||||
use {Error, FuncRef, GlobalInstance, GlobalRef, ImportsBuilder, MemoryInstance,
|
use {Error, Signature, FuncRef, GlobalInstance, GlobalRef, ImportsBuilder, MemoryInstance,
|
||||||
MemoryRef, ModuleImportResolver, ModuleInstance, NopExternals, RuntimeValue,
|
MemoryRef, ModuleImportResolver, ModuleInstance, NopExternals, RuntimeValue,
|
||||||
TableInstance, TableRef};
|
TableInstance, TableRef};
|
||||||
use validation::validate_module;
|
use validation::validate_module;
|
||||||
|
@ -24,7 +24,7 @@ impl Env {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleImportResolver for Env {
|
impl ModuleImportResolver for Env {
|
||||||
fn resolve_func(&self, _field_name: &str, _func_type: &FunctionType) -> Result<FuncRef, Error> {
|
fn resolve_func(&self, _field_name: &str, _func_type: &Signature) -> Result<FuncRef, Error> {
|
||||||
Err(Error::Instantiation(
|
Err(Error::Instantiation(
|
||||||
"env module doesn't provide any functions".into(),
|
"env module doesn't provide any functions".into(),
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue