mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-05 19:11: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::borrow::Cow;
|
||||
use elements::{FunctionType, Local, Opcodes};
|
||||
use interpreter::module::FuncRef;
|
||||
use interpreter::{Error, ModuleInstance};
|
||||
use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter};
|
||||
use interpreter::host::HostFunc;
|
||||
@ -12,6 +11,16 @@ use interpreter::state::HostState;
|
||||
use common::stack::StackWithLimit;
|
||||
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)]
|
||||
pub enum FuncInstance {
|
||||
Internal {
|
||||
@ -52,21 +61,21 @@ impl FuncInstance {
|
||||
module: Rc<ModuleInstance>,
|
||||
func_type: Rc<FunctionType>,
|
||||
body: FuncBody,
|
||||
) -> Rc<Self> {
|
||||
) -> FuncRef {
|
||||
let func = FuncInstance::Internal {
|
||||
func_type,
|
||||
module: module,
|
||||
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 {
|
||||
func_type,
|
||||
host_func,
|
||||
};
|
||||
Rc::new(func)
|
||||
FuncRef(Rc::new(func))
|
||||
}
|
||||
|
||||
pub fn func_type(&self) -> Rc<FunctionType> {
|
||||
@ -99,7 +108,7 @@ impl FuncInstance {
|
||||
StackWithLimit::with_data(args.into_iter().cloned(), DEFAULT_VALUE_STACK_LIMIT);
|
||||
let args = prepare_function_args(func_type, &mut stack)?;
|
||||
let context = FunctionContext::new(
|
||||
Rc::clone(&func),
|
||||
func.clone(),
|
||||
DEFAULT_VALUE_STACK_LIMIT,
|
||||
DEFAULT_FRAME_STACK_LIMIT,
|
||||
func_type,
|
||||
|
@ -1,8 +1,19 @@
|
||||
use std::rc::Rc;
|
||||
use std::cell::Cell;
|
||||
use elements::ValueType;
|
||||
use elements::{ValueType, GlobalType};
|
||||
use interpreter::value::RuntimeValue;
|
||||
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)]
|
||||
pub struct GlobalInstance {
|
||||
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> {
|
||||
assert!(self.mutable, "Attempt to change an immutable variable");
|
||||
assert!(
|
||||
|
@ -1,11 +1,12 @@
|
||||
use interpreter::module::GlobalRef;
|
||||
use std::rc::Rc;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry;
|
||||
use elements::{FunctionType, GlobalType, MemoryType, TableType, ValueType};
|
||||
use interpreter::module::{ExternVal, ModuleInstance, FuncRef};
|
||||
use interpreter::module::MemoryRef;
|
||||
use interpreter::module::TableRef;
|
||||
use interpreter::module::{ExternVal, ModuleInstance};
|
||||
use interpreter::func::FuncRef;
|
||||
use interpreter::global::GlobalRef;
|
||||
use interpreter::memory::MemoryRef;
|
||||
use interpreter::table::TableRef;
|
||||
use interpreter::func::FuncInstance;
|
||||
use interpreter::global::GlobalInstance;
|
||||
use interpreter::memory::MemoryInstance;
|
||||
|
@ -1,9 +1,9 @@
|
||||
use interpreter::module::GlobalRef;
|
||||
use std::collections::HashMap;
|
||||
use elements::{FunctionType, GlobalType, MemoryType, TableType};
|
||||
use interpreter::module::MemoryRef;
|
||||
use interpreter::module::FuncRef;
|
||||
use interpreter::module::TableRef;
|
||||
use interpreter::global::GlobalRef;
|
||||
use interpreter::memory::MemoryRef;
|
||||
use interpreter::func::FuncRef;
|
||||
use interpreter::table::TableRef;
|
||||
use interpreter::Error;
|
||||
|
||||
pub struct Imports<'a> {
|
||||
|
@ -2,6 +2,7 @@ use std::u32;
|
||||
use std::ops::Range;
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use elements::{MemoryType, ResizableLimits};
|
||||
use interpreter::Error;
|
||||
@ -12,6 +13,16 @@ pub const LINEAR_MEMORY_PAGE_SIZE: u32 = 65536;
|
||||
/// Maximal number of pages.
|
||||
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.
|
||||
pub struct MemoryInstance {
|
||||
/// Memofy limits.
|
||||
@ -78,6 +89,11 @@ impl MemoryInstance {
|
||||
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.
|
||||
pub fn limits(&self) -> &ResizableLimits {
|
||||
&self.limits
|
||||
|
@ -151,13 +151,13 @@ mod state;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use self::memory::MemoryInstance;
|
||||
pub use self::table::TableInstance;
|
||||
pub use self::memory::{MemoryInstance, MemoryRef};
|
||||
pub use self::table::{TableInstance, TableRef};
|
||||
pub use self::program::ProgramInstance;
|
||||
pub use self::value::RuntimeValue;
|
||||
pub use self::host::{HostModule, HostModuleBuilder, HostFunc, IntoReturnVal, FromArg};
|
||||
pub use self::imports::{ImportResolver, Imports};
|
||||
pub use self::module::{ModuleInstance, FuncRef, MemoryRef, GlobalRef, TableRef};
|
||||
pub use self::global::GlobalInstance;
|
||||
pub use self::func::FuncInstance;
|
||||
pub use self::module::ModuleInstance;
|
||||
pub use self::global::{GlobalInstance, GlobalRef};
|
||||
pub use self::func::{FuncInstance, FuncRef};
|
||||
pub use self::state::{HostState, StateKey};
|
||||
|
@ -7,17 +7,14 @@ use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryTyp
|
||||
ResizableLimits, TableType, Type};
|
||||
use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance};
|
||||
use interpreter::imports::{ImportResolver, Imports};
|
||||
use interpreter::global::GlobalInstance;
|
||||
use interpreter::func::{FuncBody, FuncInstance};
|
||||
use interpreter::global::{GlobalInstance, GlobalRef};
|
||||
use interpreter::func::{FuncRef, FuncBody, FuncInstance};
|
||||
use interpreter::table::TableRef;
|
||||
use interpreter::state::HostState;
|
||||
use interpreter::memory::MemoryRef;
|
||||
use validation::validate_module;
|
||||
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 {
|
||||
Func(FuncRef),
|
||||
Table(TableRef),
|
||||
@ -28,10 +25,10 @@ pub enum ExternVal {
|
||||
impl Clone for ExternVal {
|
||||
fn clone(&self) -> Self {
|
||||
match *self {
|
||||
ExternVal::Func(ref func) => ExternVal::Func(Rc::clone(func)),
|
||||
ExternVal::Table(ref table) => ExternVal::Table(Rc::clone(table)),
|
||||
ExternVal::Memory(ref memory) => ExternVal::Memory(Rc::clone(memory)),
|
||||
ExternVal::Global(ref global) => ExternVal::Global(Rc::clone(global)),
|
||||
ExternVal::Func(ref func) => ExternVal::Func(func.clone()),
|
||||
ExternVal::Table(ref table) => ExternVal::Table(table.clone()),
|
||||
ExternVal::Memory(ref memory) => ExternVal::Memory(memory.clone()),
|
||||
ExternVal::Global(ref global) => ExternVal::Global(global.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,28 +51,28 @@ impl fmt::Debug for ExternVal {
|
||||
impl ExternVal {
|
||||
pub fn as_func(&self) -> Option<FuncRef> {
|
||||
match *self {
|
||||
ExternVal::Func(ref func) => Some(Rc::clone(func)),
|
||||
ExternVal::Func(ref func) => Some(func.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_table(&self) -> Option<TableRef> {
|
||||
match *self {
|
||||
ExternVal::Table(ref table) => Some(Rc::clone(table)),
|
||||
ExternVal::Table(ref table) => Some(table.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_memory(&self) -> Option<MemoryRef> {
|
||||
match *self {
|
||||
ExternVal::Memory(ref memory) => Some(Rc::clone(memory)),
|
||||
ExternVal::Memory(ref memory) => Some(memory.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_global(&self) -> Option<GlobalRef> {
|
||||
match *self {
|
||||
ExternVal::Global(ref global) => Some(Rc::clone(global)),
|
||||
ExternVal::Global(ref global) => Some(global.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -198,15 +195,15 @@ impl ModuleInstance {
|
||||
import.field(),
|
||||
)));
|
||||
}
|
||||
instance.push_func(Rc::clone(func))
|
||||
instance.push_func(func.clone())
|
||||
}
|
||||
(&External::Table(ref tt), &ExternVal::Table(ref table)) => {
|
||||
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)) => {
|
||||
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)) => {
|
||||
if gl.content_type() != global.value_type() {
|
||||
@ -216,7 +213,7 @@ impl ModuleInstance {
|
||||
global.value_type(),
|
||||
)));
|
||||
}
|
||||
instance.push_global(Rc::clone(global))
|
||||
instance.push_global(global.clone());
|
||||
}
|
||||
(expected_import, actual_extern_val) => {
|
||||
return Err(Error::Instantiation(format!(
|
||||
@ -260,7 +257,7 @@ impl ModuleInstance {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -268,7 +265,7 @@ impl ModuleInstance {
|
||||
&[],
|
||||
)
|
||||
{
|
||||
let memory = alloc_memory(memory_type)?;
|
||||
let memory = MemoryInstance::alloc(memory_type)?;
|
||||
instance.push_memory(memory);
|
||||
}
|
||||
|
||||
@ -277,7 +274,7 @@ impl ModuleInstance {
|
||||
)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
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 {
|
||||
let code = init_expr.code();
|
||||
debug_assert!(
|
||||
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||
use std::borrow::Cow;
|
||||
use elements::Module;
|
||||
use interpreter::Error;
|
||||
use interpreter::module::{ModuleInstance, FuncRef};
|
||||
use interpreter::func::FuncInstance;
|
||||
use interpreter::module::{ModuleInstance};
|
||||
use interpreter::func::{FuncInstance, FuncRef};
|
||||
use interpreter::host::HostModule;
|
||||
use interpreter::value::RuntimeValue;
|
||||
use interpreter::imports::{Imports, ImportResolver};
|
||||
@ -102,7 +102,7 @@ impl ProgramInstance {
|
||||
args: &[RuntimeValue],
|
||||
state: &'a mut HostState<'a>,
|
||||
) -> 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> {
|
||||
|
@ -8,7 +8,7 @@ use std::collections::{HashMap, VecDeque};
|
||||
use elements::{Opcode, BlockType, Local, FunctionType};
|
||||
use interpreter::Error;
|
||||
use interpreter::module::ModuleInstance;
|
||||
use interpreter::module::FuncRef;
|
||||
use interpreter::func::FuncRef;
|
||||
use interpreter::func::FuncInstance;
|
||||
use interpreter::value::{
|
||||
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
|
||||
@ -77,7 +77,7 @@ impl<'a, 'b: 'a> Interpreter<'a, 'b> {
|
||||
|
||||
loop {
|
||||
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");
|
||||
if !function_context.is_initialized() {
|
||||
let return_type = function_context.return_type;
|
||||
@ -99,13 +99,13 @@ impl<'a, 'b: 'a> Interpreter<'a, 'b> {
|
||||
RunResult::NestedCall(nested_func) => {
|
||||
match *nested_func {
|
||||
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(nested_context);
|
||||
},
|
||||
FuncInstance::Host { ref func_type, .. } => {
|
||||
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 {
|
||||
function_context.value_stack_mut().push(return_val)?;
|
||||
}
|
||||
|
@ -1,11 +1,22 @@
|
||||
use std::u32;
|
||||
use std::fmt;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use elements::{ResizableLimits, TableType};
|
||||
use interpreter::Error;
|
||||
use interpreter::module::FuncRef;
|
||||
use interpreter::func::FuncRef;
|
||||
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.
|
||||
pub struct TableInstance {
|
||||
/// Table limits.
|
||||
@ -24,8 +35,13 @@ impl fmt::Debug for 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())?;
|
||||
Ok(TableInstance {
|
||||
limits: table_type.limits().clone(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user