mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-09 04:51:35 +00:00
Convert *Ref types to a newtype.
This commit is contained in:
parent
9b11d1c96c
commit
8c7dc1b529
@ -3,7 +3,6 @@ use std::fmt;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use elements::{FunctionType, Local, Opcodes};
|
use elements::{FunctionType, Local, Opcodes};
|
||||||
use interpreter::module::FuncRef;
|
|
||||||
use interpreter::{Error, ModuleInstance};
|
use interpreter::{Error, ModuleInstance};
|
||||||
use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter};
|
use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter};
|
||||||
use interpreter::host::HostFunc;
|
use interpreter::host::HostFunc;
|
||||||
@ -12,6 +11,16 @@ use interpreter::state::HostState;
|
|||||||
use common::stack::StackWithLimit;
|
use common::stack::StackWithLimit;
|
||||||
use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT};
|
use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct FuncRef(Rc<FuncInstance>);
|
||||||
|
|
||||||
|
impl ::std::ops::Deref for FuncRef {
|
||||||
|
type Target = FuncInstance;
|
||||||
|
fn deref(&self) -> &FuncInstance {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum FuncInstance {
|
pub enum FuncInstance {
|
||||||
Internal {
|
Internal {
|
||||||
@ -52,21 +61,21 @@ impl FuncInstance {
|
|||||||
module: Rc<ModuleInstance>,
|
module: Rc<ModuleInstance>,
|
||||||
func_type: Rc<FunctionType>,
|
func_type: Rc<FunctionType>,
|
||||||
body: FuncBody,
|
body: FuncBody,
|
||||||
) -> Rc<Self> {
|
) -> FuncRef {
|
||||||
let func = FuncInstance::Internal {
|
let func = FuncInstance::Internal {
|
||||||
func_type,
|
func_type,
|
||||||
module: module,
|
module: module,
|
||||||
body: Rc::new(body),
|
body: Rc::new(body),
|
||||||
};
|
};
|
||||||
Rc::new(func)
|
FuncRef(Rc::new(func))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_host(func_type: Rc<FunctionType>, host_func: Rc<HostFunc>) -> Rc<Self> {
|
pub fn alloc_host(func_type: Rc<FunctionType>, host_func: Rc<HostFunc>) -> FuncRef {
|
||||||
let func = FuncInstance::Host {
|
let func = FuncInstance::Host {
|
||||||
func_type,
|
func_type,
|
||||||
host_func,
|
host_func,
|
||||||
};
|
};
|
||||||
Rc::new(func)
|
FuncRef(Rc::new(func))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn func_type(&self) -> Rc<FunctionType> {
|
pub fn func_type(&self) -> Rc<FunctionType> {
|
||||||
@ -99,7 +108,7 @@ impl FuncInstance {
|
|||||||
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(func_type, &mut stack)?;
|
||||||
let context = FunctionContext::new(
|
let context = FunctionContext::new(
|
||||||
Rc::clone(&func),
|
func.clone(),
|
||||||
DEFAULT_VALUE_STACK_LIMIT,
|
DEFAULT_VALUE_STACK_LIMIT,
|
||||||
DEFAULT_FRAME_STACK_LIMIT,
|
DEFAULT_FRAME_STACK_LIMIT,
|
||||||
func_type,
|
func_type,
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use elements::ValueType;
|
use elements::{ValueType, GlobalType};
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct GlobalRef(Rc<GlobalInstance>);
|
||||||
|
|
||||||
|
impl ::std::ops::Deref for GlobalRef {
|
||||||
|
type Target = GlobalInstance;
|
||||||
|
fn deref(&self) -> &GlobalInstance {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GlobalInstance {
|
pub struct GlobalInstance {
|
||||||
val: Cell<RuntimeValue>,
|
val: Cell<RuntimeValue>,
|
||||||
@ -17,6 +28,11 @@ impl GlobalInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn alloc(global_type: &GlobalType, val: RuntimeValue) -> GlobalRef {
|
||||||
|
let global = GlobalInstance::new(val, global_type.is_mutable());
|
||||||
|
GlobalRef(Rc::new(global))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&self, val: RuntimeValue) -> Result<(), Error> {
|
pub fn set(&self, val: RuntimeValue) -> Result<(), Error> {
|
||||||
assert!(self.mutable, "Attempt to change an immutable variable");
|
assert!(self.mutable, "Attempt to change an immutable variable");
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use interpreter::module::GlobalRef;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use elements::{FunctionType, GlobalType, MemoryType, TableType, ValueType};
|
use elements::{FunctionType, GlobalType, MemoryType, TableType, ValueType};
|
||||||
use interpreter::module::{ExternVal, ModuleInstance, FuncRef};
|
use interpreter::module::{ExternVal, ModuleInstance};
|
||||||
use interpreter::module::MemoryRef;
|
use interpreter::func::FuncRef;
|
||||||
use interpreter::module::TableRef;
|
use interpreter::global::GlobalRef;
|
||||||
|
use interpreter::memory::MemoryRef;
|
||||||
|
use interpreter::table::TableRef;
|
||||||
use interpreter::func::FuncInstance;
|
use interpreter::func::FuncInstance;
|
||||||
use interpreter::global::GlobalInstance;
|
use interpreter::global::GlobalInstance;
|
||||||
use interpreter::memory::MemoryInstance;
|
use interpreter::memory::MemoryInstance;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use interpreter::module::GlobalRef;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use elements::{FunctionType, GlobalType, MemoryType, TableType};
|
use elements::{FunctionType, GlobalType, MemoryType, TableType};
|
||||||
use interpreter::module::MemoryRef;
|
use interpreter::global::GlobalRef;
|
||||||
use interpreter::module::FuncRef;
|
use interpreter::memory::MemoryRef;
|
||||||
use interpreter::module::TableRef;
|
use interpreter::func::FuncRef;
|
||||||
|
use interpreter::table::TableRef;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
|
|
||||||
pub struct Imports<'a> {
|
pub struct Imports<'a> {
|
||||||
|
@ -2,6 +2,7 @@ use std::u32;
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use elements::{MemoryType, ResizableLimits};
|
use elements::{MemoryType, ResizableLimits};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
@ -12,6 +13,16 @@ pub const LINEAR_MEMORY_PAGE_SIZE: u32 = 65536;
|
|||||||
/// Maximal number of pages.
|
/// Maximal number of pages.
|
||||||
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;
|
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct MemoryRef(Rc<MemoryInstance>);
|
||||||
|
|
||||||
|
impl ::std::ops::Deref for MemoryRef {
|
||||||
|
type Target = MemoryInstance;
|
||||||
|
fn deref(&self) -> &MemoryInstance {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Linear memory instance.
|
/// Linear memory instance.
|
||||||
pub struct MemoryInstance {
|
pub struct MemoryInstance {
|
||||||
/// Memofy limits.
|
/// Memofy limits.
|
||||||
@ -78,6 +89,11 @@ impl MemoryInstance {
|
|||||||
Ok(memory)
|
Ok(memory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn alloc(mem_type: &MemoryType) -> Result<MemoryRef, Error> {
|
||||||
|
let memory = MemoryInstance::new(&mem_type)?;
|
||||||
|
Ok(MemoryRef(Rc::new(memory)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Return linear memory limits.
|
/// Return linear memory limits.
|
||||||
pub fn limits(&self) -> &ResizableLimits {
|
pub fn limits(&self) -> &ResizableLimits {
|
||||||
&self.limits
|
&self.limits
|
||||||
|
@ -151,13 +151,13 @@ mod state;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub use self::memory::MemoryInstance;
|
pub use self::memory::{MemoryInstance, MemoryRef};
|
||||||
pub use self::table::TableInstance;
|
pub use self::table::{TableInstance, TableRef};
|
||||||
pub use self::program::ProgramInstance;
|
pub use self::program::ProgramInstance;
|
||||||
pub use self::value::RuntimeValue;
|
pub use self::value::RuntimeValue;
|
||||||
pub use self::host::{HostModule, HostModuleBuilder, HostFunc, IntoReturnVal, FromArg};
|
pub use self::host::{HostModule, HostModuleBuilder, HostFunc, IntoReturnVal, FromArg};
|
||||||
pub use self::imports::{ImportResolver, Imports};
|
pub use self::imports::{ImportResolver, Imports};
|
||||||
pub use self::module::{ModuleInstance, FuncRef, MemoryRef, GlobalRef, TableRef};
|
pub use self::module::ModuleInstance;
|
||||||
pub use self::global::GlobalInstance;
|
pub use self::global::{GlobalInstance, GlobalRef};
|
||||||
pub use self::func::FuncInstance;
|
pub use self::func::{FuncInstance, FuncRef};
|
||||||
pub use self::state::{HostState, StateKey};
|
pub use self::state::{HostState, StateKey};
|
||||||
|
@ -7,17 +7,14 @@ use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryTyp
|
|||||||
ResizableLimits, TableType, Type};
|
ResizableLimits, TableType, Type};
|
||||||
use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance};
|
use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance};
|
||||||
use interpreter::imports::{ImportResolver, Imports};
|
use interpreter::imports::{ImportResolver, Imports};
|
||||||
use interpreter::global::GlobalInstance;
|
use interpreter::global::{GlobalInstance, GlobalRef};
|
||||||
use interpreter::func::{FuncBody, FuncInstance};
|
use interpreter::func::{FuncRef, FuncBody, FuncInstance};
|
||||||
|
use interpreter::table::TableRef;
|
||||||
use interpreter::state::HostState;
|
use interpreter::state::HostState;
|
||||||
|
use interpreter::memory::MemoryRef;
|
||||||
use validation::validate_module;
|
use validation::validate_module;
|
||||||
use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
|
use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
|
||||||
|
|
||||||
pub type FuncRef = Rc<FuncInstance>;
|
|
||||||
pub type TableRef = Rc<TableInstance>;
|
|
||||||
pub type MemoryRef = Rc<MemoryInstance>;
|
|
||||||
pub type GlobalRef = Rc<GlobalInstance>;
|
|
||||||
|
|
||||||
pub enum ExternVal {
|
pub enum ExternVal {
|
||||||
Func(FuncRef),
|
Func(FuncRef),
|
||||||
Table(TableRef),
|
Table(TableRef),
|
||||||
@ -28,10 +25,10 @@ pub enum ExternVal {
|
|||||||
impl Clone for ExternVal {
|
impl Clone for ExternVal {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Func(ref func) => ExternVal::Func(Rc::clone(func)),
|
ExternVal::Func(ref func) => ExternVal::Func(func.clone()),
|
||||||
ExternVal::Table(ref table) => ExternVal::Table(Rc::clone(table)),
|
ExternVal::Table(ref table) => ExternVal::Table(table.clone()),
|
||||||
ExternVal::Memory(ref memory) => ExternVal::Memory(Rc::clone(memory)),
|
ExternVal::Memory(ref memory) => ExternVal::Memory(memory.clone()),
|
||||||
ExternVal::Global(ref global) => ExternVal::Global(Rc::clone(global)),
|
ExternVal::Global(ref global) => ExternVal::Global(global.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,28 +51,28 @@ impl fmt::Debug for ExternVal {
|
|||||||
impl ExternVal {
|
impl ExternVal {
|
||||||
pub fn as_func(&self) -> Option<FuncRef> {
|
pub fn as_func(&self) -> Option<FuncRef> {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Func(ref func) => Some(Rc::clone(func)),
|
ExternVal::Func(ref func) => Some(func.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_table(&self) -> Option<TableRef> {
|
pub fn as_table(&self) -> Option<TableRef> {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Table(ref table) => Some(Rc::clone(table)),
|
ExternVal::Table(ref table) => Some(table.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_memory(&self) -> Option<MemoryRef> {
|
pub fn as_memory(&self) -> Option<MemoryRef> {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Memory(ref memory) => Some(Rc::clone(memory)),
|
ExternVal::Memory(ref memory) => Some(memory.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_global(&self) -> Option<GlobalRef> {
|
pub fn as_global(&self) -> Option<GlobalRef> {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Global(ref global) => Some(Rc::clone(global)),
|
ExternVal::Global(ref global) => Some(global.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,15 +195,15 @@ impl ModuleInstance {
|
|||||||
import.field(),
|
import.field(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
instance.push_func(Rc::clone(func))
|
instance.push_func(func.clone())
|
||||||
}
|
}
|
||||||
(&External::Table(ref tt), &ExternVal::Table(ref table)) => {
|
(&External::Table(ref tt), &ExternVal::Table(ref table)) => {
|
||||||
match_limits(table.limits(), tt.limits())?;
|
match_limits(table.limits(), tt.limits())?;
|
||||||
instance.push_table(Rc::clone(table));
|
instance.push_table(table.clone());
|
||||||
}
|
}
|
||||||
(&External::Memory(ref mt), &ExternVal::Memory(ref memory)) => {
|
(&External::Memory(ref mt), &ExternVal::Memory(ref memory)) => {
|
||||||
match_limits(memory.limits(), mt.limits())?;
|
match_limits(memory.limits(), mt.limits())?;
|
||||||
instance.push_memory(Rc::clone(memory));
|
instance.push_memory(memory.clone());
|
||||||
}
|
}
|
||||||
(&External::Global(ref gl), &ExternVal::Global(ref global)) => {
|
(&External::Global(ref gl), &ExternVal::Global(ref global)) => {
|
||||||
if gl.content_type() != global.value_type() {
|
if gl.content_type() != global.value_type() {
|
||||||
@ -216,7 +213,7 @@ impl ModuleInstance {
|
|||||||
global.value_type(),
|
global.value_type(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
instance.push_global(Rc::clone(global))
|
instance.push_global(global.clone());
|
||||||
}
|
}
|
||||||
(expected_import, actual_extern_val) => {
|
(expected_import, actual_extern_val) => {
|
||||||
return Err(Error::Instantiation(format!(
|
return Err(Error::Instantiation(format!(
|
||||||
@ -260,7 +257,7 @@ impl ModuleInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for table_type in module.table_section().map(|ts| ts.entries()).unwrap_or(&[]) {
|
for table_type in module.table_section().map(|ts| ts.entries()).unwrap_or(&[]) {
|
||||||
let table = alloc_table(table_type)?;
|
let table = TableInstance::alloc(table_type)?;
|
||||||
instance.push_table(table);
|
instance.push_table(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +265,7 @@ impl ModuleInstance {
|
|||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let memory = alloc_memory(memory_type)?;
|
let memory = MemoryInstance::alloc(memory_type)?;
|
||||||
instance.push_memory(memory);
|
instance.push_memory(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +274,7 @@ impl ModuleInstance {
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
let init_val = eval_init_expr(global_entry.init_expr(), &*instance);
|
let init_val = eval_init_expr(global_entry.init_expr(), &*instance);
|
||||||
let global = alloc_global(global_entry.global_type().clone(), init_val);
|
let global = GlobalInstance::alloc(global_entry.global_type(), init_val);
|
||||||
instance.push_global(global);
|
instance.push_global(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +441,7 @@ impl ModuleInstance {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FuncInstance::invoke(Rc::clone(&func_instance), Cow::Borrowed(args), state)
|
FuncInstance::invoke(func_instance.clone(), Cow::Borrowed(args), state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,21 +561,6 @@ fn alloc_func_type(func_type: FunctionType) -> Rc<FunctionType> {
|
|||||||
Rc::new(func_type)
|
Rc::new(func_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_table(table_type: &TableType) -> Result<TableRef, Error> {
|
|
||||||
let table = TableInstance::new(table_type)?;
|
|
||||||
Ok(Rc::new(table))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc_memory(mem_type: &MemoryType) -> Result<MemoryRef, Error> {
|
|
||||||
let memory = MemoryInstance::new(&mem_type)?;
|
|
||||||
Ok(Rc::new(memory))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc_global(global_type: GlobalType, val: RuntimeValue) -> GlobalRef {
|
|
||||||
let global = GlobalInstance::new(val, global_type.is_mutable());
|
|
||||||
Rc::new(global)
|
|
||||||
}
|
|
||||||
|
|
||||||
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!(
|
||||||
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use elements::Module;
|
use elements::Module;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::{ModuleInstance, FuncRef};
|
use interpreter::module::{ModuleInstance};
|
||||||
use interpreter::func::FuncInstance;
|
use interpreter::func::{FuncInstance, FuncRef};
|
||||||
use interpreter::host::HostModule;
|
use interpreter::host::HostModule;
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
use interpreter::imports::{Imports, ImportResolver};
|
use interpreter::imports::{Imports, ImportResolver};
|
||||||
@ -102,7 +102,7 @@ impl ProgramInstance {
|
|||||||
args: &[RuntimeValue],
|
args: &[RuntimeValue],
|
||||||
state: &'a mut HostState<'a>,
|
state: &'a mut HostState<'a>,
|
||||||
) -> Result<Option<RuntimeValue>, Error> {
|
) -> Result<Option<RuntimeValue>, Error> {
|
||||||
FuncInstance::invoke(Rc::clone(&func_instance), Cow::Borrowed(args), state)
|
FuncInstance::invoke(func_instance.clone(), Cow::Borrowed(args), state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolver(&self, name: &str) -> Option<&ImportResolver> {
|
pub fn resolver(&self, name: &str) -> Option<&ImportResolver> {
|
||||||
|
@ -8,7 +8,7 @@ use std::collections::{HashMap, VecDeque};
|
|||||||
use elements::{Opcode, BlockType, Local, FunctionType};
|
use elements::{Opcode, BlockType, Local, FunctionType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::ModuleInstance;
|
use interpreter::module::ModuleInstance;
|
||||||
use interpreter::module::FuncRef;
|
use interpreter::func::FuncRef;
|
||||||
use interpreter::func::FuncInstance;
|
use interpreter::func::FuncInstance;
|
||||||
use interpreter::value::{
|
use interpreter::value::{
|
||||||
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
|
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
|
||||||
@ -77,7 +77,7 @@ impl<'a, 'b: 'a> Interpreter<'a, 'b> {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
let mut function_context = function_stack.pop_back().expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
|
||||||
let function_ref = Rc::clone(&function_context.function);
|
let function_ref = function_context.function.clone();
|
||||||
let function_body = function_ref.body().expect("Host functions checked in function_return below; Internal functions always have a body; qed");
|
let function_body = function_ref.body().expect("Host functions checked in function_return below; Internal functions always have a body; qed");
|
||||||
if !function_context.is_initialized() {
|
if !function_context.is_initialized() {
|
||||||
let return_type = function_context.return_type;
|
let return_type = function_context.return_type;
|
||||||
@ -99,13 +99,13 @@ impl<'a, 'b: 'a> Interpreter<'a, 'b> {
|
|||||||
RunResult::NestedCall(nested_func) => {
|
RunResult::NestedCall(nested_func) => {
|
||||||
match *nested_func {
|
match *nested_func {
|
||||||
FuncInstance::Internal { .. } => {
|
FuncInstance::Internal { .. } => {
|
||||||
let nested_context = function_context.nested(Rc::clone(&nested_func))?;
|
let nested_context = function_context.nested(nested_func.clone())?;
|
||||||
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 func_type, .. } => {
|
||||||
let args = prepare_function_args(func_type, &mut function_context.value_stack)?;
|
let args = prepare_function_args(func_type, &mut function_context.value_stack)?;
|
||||||
let return_val = FuncInstance::invoke(Rc::clone(&nested_func), args.into(), self.state)?;
|
let return_val = FuncInstance::invoke(nested_func.clone(), args.into(), self.state)?;
|
||||||
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)?;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
use std::u32;
|
use std::u32;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
use elements::{ResizableLimits, TableType};
|
use elements::{ResizableLimits, TableType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::FuncRef;
|
use interpreter::func::FuncRef;
|
||||||
use interpreter::module::check_limits;
|
use interpreter::module::check_limits;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct TableRef(Rc<TableInstance>);
|
||||||
|
|
||||||
|
impl ::std::ops::Deref for TableRef {
|
||||||
|
type Target = TableInstance;
|
||||||
|
fn deref(&self) -> &TableInstance {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Table instance.
|
/// Table instance.
|
||||||
pub struct TableInstance {
|
pub struct TableInstance {
|
||||||
/// Table limits.
|
/// Table limits.
|
||||||
@ -24,8 +35,13 @@ impl fmt::Debug for TableInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TableInstance {
|
impl TableInstance {
|
||||||
/// New instance of the table
|
|
||||||
pub fn new(table_type: &TableType) -> Result<Self, Error> {
|
pub fn alloc(table_type: &TableType) -> Result<TableRef, Error> {
|
||||||
|
let table = TableInstance::new(table_type)?;
|
||||||
|
Ok(TableRef(Rc::new(table)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(table_type: &TableType) -> Result<TableInstance, Error> {
|
||||||
check_limits(table_type.limits())?;
|
check_limits(table_type.limits())?;
|
||||||
Ok(TableInstance {
|
Ok(TableInstance {
|
||||||
limits: table_type.limits().clone(),
|
limits: table_type.limits().clone(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user