mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-11 05:51:48 +00:00
Replace all func_ids to Rcs.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::rc::Rc;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use elements::{FunctionType, ValueType, GlobalType, MemoryType, TableType};
|
use elements::{FunctionType, ValueType, GlobalType, MemoryType, TableType};
|
||||||
@ -11,7 +11,7 @@ enum HostItem {
|
|||||||
Func {
|
Func {
|
||||||
name: String,
|
name: String,
|
||||||
func_type: FunctionType,
|
func_type: FunctionType,
|
||||||
host_func: Arc<AnyFunc>,
|
host_func: Rc<AnyFunc>,
|
||||||
},
|
},
|
||||||
Global {
|
Global {
|
||||||
name: String,
|
name: String,
|
||||||
@ -56,7 +56,7 @@ impl<St: 'static> HostModuleBuilder<St> {
|
|||||||
f: F,
|
f: F,
|
||||||
) {
|
) {
|
||||||
let func_type = Func0::<Cl, St, Ret>::derive_func_type();
|
let func_type = Func0::<Cl, St, Ret>::derive_func_type();
|
||||||
let host_func = Arc::new(f.into()) as Arc<AnyFunc>;
|
let host_func = Rc::new(f.into()) as Rc<AnyFunc>;
|
||||||
|
|
||||||
self.items.push(HostItem::Func {
|
self.items.push(HostItem::Func {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
@ -77,7 +77,7 @@ impl<St: 'static> HostModuleBuilder<St> {
|
|||||||
f: F,
|
f: F,
|
||||||
) {
|
) {
|
||||||
let func_type = Func1::<Cl, St, Ret, P1>::derive_func_type();
|
let func_type = Func1::<Cl, St, Ret, P1>::derive_func_type();
|
||||||
let host_func = Arc::new(f.into()) as Arc<AnyFunc>;
|
let host_func = Rc::new(f.into()) as Rc<AnyFunc>;
|
||||||
|
|
||||||
self.items.push(HostItem::Func {
|
self.items.push(HostItem::Func {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
@ -99,7 +99,7 @@ impl<St: 'static> HostModuleBuilder<St> {
|
|||||||
f: F,
|
f: F,
|
||||||
) {
|
) {
|
||||||
let func_type = Func2::<Cl, St, Ret, P1, P2>::derive_func_type();
|
let func_type = Func2::<Cl, St, Ret, P1, P2>::derive_func_type();
|
||||||
let host_func = Arc::new(f.into()) as Arc<AnyFunc>;
|
let host_func = Rc::new(f.into()) as Rc<AnyFunc>;
|
||||||
|
|
||||||
self.items.push(HostItem::Func {
|
self.items.push(HostItem::Func {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use elements::Module;
|
use elements::Module;
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::store::{ModuleId, FuncId, Store, ExternVal};
|
use interpreter::store::{ModuleId, Store, ExternVal, FuncInstance};
|
||||||
use interpreter::host::HostModule;
|
use interpreter::host::HostModule;
|
||||||
use interpreter::value::RuntimeValue;
|
use interpreter::value::RuntimeValue;
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ impl ProgramInstance {
|
|||||||
|
|
||||||
pub fn invoke_func<St: 'static>(
|
pub fn invoke_func<St: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: FuncId,
|
func: Rc<FuncInstance>,
|
||||||
args: Vec<RuntimeValue>,
|
args: Vec<RuntimeValue>,
|
||||||
state: &mut St,
|
state: &mut St,
|
||||||
) -> Result<Option<RuntimeValue>, Error> {
|
) -> Result<Option<RuntimeValue>, Error> {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::{u32, usize};
|
use std::{u32, usize};
|
||||||
use std::fmt::{self, Display};
|
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, FunctionType};
|
use elements::{Opcode, BlockType, Local, FunctionType};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::store::{Store, FuncId, ModuleId, FuncInstance};
|
use interpreter::store::{Store, ModuleId, FuncInstance};
|
||||||
use interpreter::value::{
|
use interpreter::value::{
|
||||||
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
|
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
|
||||||
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,
|
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,
|
||||||
@ -25,7 +26,7 @@ pub struct FunctionContext {
|
|||||||
/// Is context initialized.
|
/// Is context initialized.
|
||||||
pub is_initialized: bool,
|
pub is_initialized: bool,
|
||||||
/// Internal function reference.
|
/// Internal function reference.
|
||||||
pub function: FuncId,
|
pub function: Rc<FuncInstance>,
|
||||||
pub module: ModuleId,
|
pub module: ModuleId,
|
||||||
/// Function return type.
|
/// Function return type.
|
||||||
pub return_type: BlockType,
|
pub return_type: BlockType,
|
||||||
@ -47,7 +48,7 @@ pub enum InstructionOutcome {
|
|||||||
/// Branch to given frame.
|
/// Branch to given frame.
|
||||||
Branch(usize),
|
Branch(usize),
|
||||||
/// Execute function call.
|
/// Execute function call.
|
||||||
ExecuteCall(FuncId),
|
ExecuteCall(Rc<FuncInstance>),
|
||||||
/// End current frame.
|
/// End current frame.
|
||||||
End,
|
End,
|
||||||
/// Return from current function block.
|
/// Return from current function block.
|
||||||
@ -59,7 +60,7 @@ enum RunResult {
|
|||||||
/// 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(FuncId),
|
NestedCall(Rc<FuncInstance>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, St: 'static> Interpreter<'a, St> {
|
impl<'a, St: 'static> Interpreter<'a, St> {
|
||||||
@ -76,11 +77,9 @@ impl<'a, St: 'static> Interpreter<'a, St> {
|
|||||||
|
|
||||||
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 = function_context.function;
|
let function_ref = Rc::clone(&function_context.function);
|
||||||
let function_return = {
|
let function_return = {
|
||||||
let func_body = function_ref.resolve(self.store).body();
|
match function_ref.body() {
|
||||||
|
|
||||||
match func_body {
|
|
||||||
Some(function_body) => {
|
Some(function_body) => {
|
||||||
if !function_context.is_initialized() {
|
if !function_context.is_initialized() {
|
||||||
let return_type = function_context.return_type;
|
let return_type = function_context.return_type;
|
||||||
@ -108,8 +107,8 @@ impl<'a, St: 'static> Interpreter<'a, St> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
RunResult::NestedCall(nested_func) => {
|
RunResult::NestedCall(nested_func) => {
|
||||||
let func = nested_func.resolve(self.store).clone();
|
// TODO: check this
|
||||||
match func {
|
match *nested_func {
|
||||||
FuncInstance::Internal { .. } => {
|
FuncInstance::Internal { .. } => {
|
||||||
let nested_context = function_context.nested(self.store, nested_func)?;
|
let nested_context = function_context.nested(self.store, nested_func)?;
|
||||||
function_stack.push_back(function_context);
|
function_stack.push_back(function_context);
|
||||||
@ -452,7 +451,7 @@ impl<'a, St: 'static> Interpreter<'a, St> {
|
|||||||
.resolve(self.store);
|
.resolve(self.store);
|
||||||
let func_ref = table.get(table_func_idx)?;
|
let func_ref = table.get(table_func_idx)?;
|
||||||
|
|
||||||
let actual_function_type = func_ref.resolve(self.store).func_type().resolve(self.store);
|
let actual_function_type = func_ref.func_type().resolve(self.store);
|
||||||
let required_function_type = context
|
let required_function_type = context
|
||||||
.module()
|
.module()
|
||||||
.type_by_index(self.store, type_idx)
|
.type_by_index(self.store, type_idx)
|
||||||
@ -1019,9 +1018,8 @@ impl<'a, St: 'static> Interpreter<'a, St> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionContext {
|
impl FunctionContext {
|
||||||
pub fn new<'store>(store: &'store Store, function: FuncId, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionType, args: Vec<RuntimeValue>) -> Self {
|
pub fn new<'store>(store: &'store Store, function: Rc<FuncInstance>, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionType, args: Vec<RuntimeValue>) -> Self {
|
||||||
let func_instance = function.resolve(store);
|
let module = match *function {
|
||||||
let module = match *func_instance {
|
|
||||||
FuncInstance::Internal { module, .. } => module,
|
FuncInstance::Internal { module, .. } => module,
|
||||||
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"),
|
||||||
};
|
};
|
||||||
@ -1037,14 +1035,13 @@ impl FunctionContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nested(&mut self, store: &Store, function: FuncId) -> Result<Self, Error> {
|
pub fn nested(&mut self, store: &Store, function: Rc<FuncInstance>) -> Result<Self, Error> {
|
||||||
let (function_locals, module, function_return_type) = {
|
let (function_locals, module, function_return_type) = {
|
||||||
let func_instance = function.resolve(store);
|
let module = match *function {
|
||||||
let module = match *func_instance {
|
|
||||||
FuncInstance::Internal { module, .. } => module,
|
FuncInstance::Internal { module, .. } => module,
|
||||||
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 = func_instance.func_type().resolve(store);
|
let function_type = function.func_type().resolve(store);
|
||||||
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)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// TODO: remove this
|
// TODO: remove this
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::rc::Rc;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -52,7 +52,7 @@ impl ModuleId {
|
|||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn func_by_index(&self, store: &Store, idx: u32) -> Option<FuncId> {
|
pub fn func_by_index(&self, store: &Store, idx: u32) -> Option<Rc<FuncInstance>> {
|
||||||
store.resolve_module(*self)
|
store.resolve_module(*self)
|
||||||
.funcs
|
.funcs
|
||||||
.get(idx as usize)
|
.get(idx as usize)
|
||||||
@ -77,17 +77,6 @@ impl ModuleId {
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct HostFuncId(u32);
|
pub struct HostFuncId(u32);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct FuncId(u32);
|
|
||||||
|
|
||||||
impl FuncId {
|
|
||||||
pub fn resolve<'s>(&self, store: &'s Store) -> &'s FuncInstance {
|
|
||||||
store
|
|
||||||
.funcs
|
|
||||||
.get(self.0 as usize)
|
|
||||||
.expect("ID should be always valid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct TableId(u32);
|
pub struct TableId(u32);
|
||||||
@ -116,18 +105,18 @@ impl MemoryId {
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct GlobalId(u32);
|
pub struct GlobalId(u32);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ExternVal {
|
pub enum ExternVal {
|
||||||
Func(FuncId),
|
Func(Rc<FuncInstance>),
|
||||||
Table(TableId),
|
Table(TableId),
|
||||||
Memory(MemoryId),
|
Memory(MemoryId),
|
||||||
Global(GlobalId),
|
Global(GlobalId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternVal {
|
impl ExternVal {
|
||||||
pub fn as_func(&self) -> Option<FuncId> {
|
pub fn as_func(&self) -> Option<Rc<FuncInstance>> {
|
||||||
match *self {
|
match *self {
|
||||||
ExternVal::Func(func) => Some(func),
|
ExternVal::Func(ref func) => Some(Rc::clone(func)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,11 +148,11 @@ pub enum FuncInstance {
|
|||||||
Internal {
|
Internal {
|
||||||
func_type: TypeId,
|
func_type: TypeId,
|
||||||
module: ModuleId,
|
module: ModuleId,
|
||||||
body: Arc<FuncBody>,
|
body: Rc<FuncBody>,
|
||||||
},
|
},
|
||||||
Host {
|
Host {
|
||||||
func_type: TypeId,
|
func_type: TypeId,
|
||||||
host_func: Arc<AnyFunc>,
|
host_func: Rc<AnyFunc>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,9 +178,9 @@ impl FuncInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body(&self) -> Option<Arc<FuncBody>> {
|
pub fn body(&self) -> Option<Rc<FuncBody>> {
|
||||||
match *self {
|
match *self {
|
||||||
FuncInstance::Internal { ref body, .. } => Some(Arc::clone(body)),
|
FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)),
|
||||||
FuncInstance::Host { .. } => None,
|
FuncInstance::Host { .. } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,8 +213,8 @@ pub struct ExportInstance {
|
|||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct ModuleInstance {
|
pub struct ModuleInstance {
|
||||||
types: Vec<TypeId>,
|
types: Vec<TypeId>,
|
||||||
funcs: Vec<FuncId>,
|
|
||||||
tables: Vec<TableId>,
|
tables: Vec<TableId>,
|
||||||
|
funcs: Vec<Rc<FuncInstance>>,
|
||||||
memories: Vec<MemoryId>,
|
memories: Vec<MemoryId>,
|
||||||
globals: Vec<GlobalId>,
|
globals: Vec<GlobalId>,
|
||||||
exports: HashMap<String, ExternVal>,
|
exports: HashMap<String, ExternVal>,
|
||||||
@ -274,25 +263,21 @@ impl Store {
|
|||||||
TypeId(type_id as u32)
|
TypeId(type_id as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_func(&mut self, module: ModuleId, func_type: TypeId, body: FuncBody) -> FuncId {
|
pub fn alloc_func(&mut self, module: ModuleId, func_type: TypeId, body: FuncBody) -> Rc<FuncInstance> {
|
||||||
let func = FuncInstance::Internal {
|
let func = FuncInstance::Internal {
|
||||||
func_type,
|
func_type,
|
||||||
module,
|
module,
|
||||||
body: Arc::new(body),
|
body: Rc::new(body),
|
||||||
};
|
};
|
||||||
self.funcs.push(func);
|
Rc::new(func)
|
||||||
let func_id = self.funcs.len() - 1;
|
|
||||||
FuncId(func_id as u32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_host_func(&mut self, func_type: TypeId, host_func: Arc<AnyFunc>) -> FuncId {
|
pub fn alloc_host_func(&mut self, func_type: TypeId, host_func: Rc<AnyFunc>) -> Rc<FuncInstance> {
|
||||||
let func = FuncInstance::Host {
|
let func = FuncInstance::Host {
|
||||||
func_type,
|
func_type,
|
||||||
host_func,
|
host_func,
|
||||||
};
|
};
|
||||||
self.funcs.push(func);
|
Rc::new(func)
|
||||||
let func_id = self.funcs.len() - 1;
|
|
||||||
FuncId(func_id as u32)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_table(&mut self, table_type: &TableType) -> Result<TableId, Error> {
|
pub fn alloc_table(&mut self, table_type: &TableType) -> Result<TableId, Error> {
|
||||||
@ -342,10 +327,10 @@ impl Store {
|
|||||||
|
|
||||||
for (import, extern_val) in Iterator::zip(imports.into_iter(), extern_vals.into_iter())
|
for (import, extern_val) in Iterator::zip(imports.into_iter(), extern_vals.into_iter())
|
||||||
{
|
{
|
||||||
match (import.external(), *extern_val) {
|
match (import.external(), extern_val) {
|
||||||
(&External::Function(fn_type_idx), ExternVal::Func(func)) => {
|
(&External::Function(fn_type_idx), &ExternVal::Func(ref func)) => {
|
||||||
let expected_fn_type = instance.types.get(fn_type_idx as usize).expect("Due to validation function type should exists").resolve(self);
|
let expected_fn_type = instance.types.get(fn_type_idx as usize).expect("Due to validation function type should exists").resolve(self);
|
||||||
let actual_fn_type = func.resolve(self).func_type().resolve(self);
|
let actual_fn_type = func.func_type().resolve(self);
|
||||||
if expected_fn_type != actual_fn_type {
|
if expected_fn_type != actual_fn_type {
|
||||||
return Err(Error::Initialization(format!(
|
return Err(Error::Initialization(format!(
|
||||||
"Expected function with type {:?}, but actual type is {:?} for entry {}",
|
"Expected function with type {:?}, but actual type is {:?} for entry {}",
|
||||||
@ -354,17 +339,17 @@ impl Store {
|
|||||||
import.field(),
|
import.field(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
instance.funcs.push(func)
|
instance.funcs.push(Rc::clone(func))
|
||||||
}
|
}
|
||||||
(&External::Table(ref tt), ExternVal::Table(table)) => {
|
(&External::Table(ref tt), &ExternVal::Table(table)) => {
|
||||||
match_limits(table.resolve(self).limits(), tt.limits())?;
|
match_limits(table.resolve(self).limits(), tt.limits())?;
|
||||||
instance.tables.push(table);
|
instance.tables.push(table);
|
||||||
}
|
}
|
||||||
(&External::Memory(ref mt), ExternVal::Memory(memory)) => {
|
(&External::Memory(ref mt), &ExternVal::Memory(memory)) => {
|
||||||
match_limits(memory.resolve(self).limits(), mt.limits())?;
|
match_limits(memory.resolve(self).limits(), mt.limits())?;
|
||||||
instance.memories.push(memory);
|
instance.memories.push(memory);
|
||||||
}
|
}
|
||||||
(&External::Global(ref gl), ExternVal::Global(global)) => {
|
(&External::Global(ref gl), &ExternVal::Global(global)) => {
|
||||||
// TODO: check globals
|
// TODO: check globals
|
||||||
instance.globals.push(global)
|
instance.globals.push(global)
|
||||||
}
|
}
|
||||||
@ -439,11 +424,11 @@ impl Store {
|
|||||||
let field = export.field();
|
let field = export.field();
|
||||||
let extern_val: ExternVal = match *export.internal() {
|
let extern_val: ExternVal = match *export.internal() {
|
||||||
Internal::Function(idx) => {
|
Internal::Function(idx) => {
|
||||||
let func_id = instance
|
let func = instance
|
||||||
.funcs
|
.funcs
|
||||||
.get(idx as usize)
|
.get(idx as usize)
|
||||||
.expect("Due to validation func should exists");
|
.expect("Due to validation func should exists");
|
||||||
ExternVal::Func(*func_id)
|
ExternVal::Func(Rc::clone(func))
|
||||||
}
|
}
|
||||||
Internal::Global(idx) => {
|
Internal::Global(idx) => {
|
||||||
let global_id = instance
|
let global_id = instance
|
||||||
@ -504,12 +489,12 @@ impl Store {
|
|||||||
.expect("ID should be always valid");
|
.expect("ID should be always valid");
|
||||||
|
|
||||||
for (j, func_idx) in element_segment.members().into_iter().enumerate() {
|
for (j, func_idx) in element_segment.members().into_iter().enumerate() {
|
||||||
let func_id = instance
|
let func = instance
|
||||||
.funcs
|
.funcs
|
||||||
.get(*func_idx as usize)
|
.get(*func_idx as usize)
|
||||||
.expect("Due to validation funcs from element segments should exists");
|
.expect("Due to validation funcs from element segments should exists");
|
||||||
|
|
||||||
table_inst.set(offset_val + j as u32, *func_id);
|
table_inst.set(offset_val + j as u32, Rc::clone(func));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,9 +522,10 @@ impl Store {
|
|||||||
if let Some(start_fn_idx) = module.start_section() {
|
if let Some(start_fn_idx) = module.start_section() {
|
||||||
let start_func = {
|
let start_func = {
|
||||||
let instance = self.resolve_module(module_id);
|
let instance = self.resolve_module(module_id);
|
||||||
*instance
|
instance
|
||||||
.funcs
|
.funcs
|
||||||
.get(start_fn_idx as usize)
|
.get(start_fn_idx as usize)
|
||||||
|
.cloned()
|
||||||
.expect("Due to validation start function should exists")
|
.expect("Due to validation start function should exists")
|
||||||
};
|
};
|
||||||
self.invoke(start_func, vec![], state)?;
|
self.invoke(start_func, vec![], state)?;
|
||||||
@ -556,23 +542,23 @@ impl Store {
|
|||||||
|
|
||||||
pub fn invoke<St: 'static>(
|
pub fn invoke<St: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: FuncId,
|
func: Rc<FuncInstance>,
|
||||||
args: Vec<RuntimeValue>,
|
args: Vec<RuntimeValue>,
|
||||||
state: &mut St,
|
state: &mut St,
|
||||||
) -> Result<Option<RuntimeValue>, Error> {
|
) -> Result<Option<RuntimeValue>, Error> {
|
||||||
enum InvokeKind {
|
enum InvokeKind {
|
||||||
Internal(FunctionContext),
|
Internal(FunctionContext),
|
||||||
Host(Arc<AnyFunc>, Vec<RuntimeValue>),
|
Host(Rc<AnyFunc>, Vec<RuntimeValue>),
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = match *func.resolve(self) {
|
let result = match *func {
|
||||||
FuncInstance::Internal { func_type, .. } => {
|
FuncInstance::Internal { func_type, .. } => {
|
||||||
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
|
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
|
||||||
let func_signature = func_type.resolve(self);
|
let func_signature = func_type.resolve(self);
|
||||||
let args = prepare_function_args(&func_signature, &mut args)?;
|
let args = prepare_function_args(&func_signature, &mut args)?;
|
||||||
let context = FunctionContext::new(
|
let context = FunctionContext::new(
|
||||||
self,
|
self,
|
||||||
func,
|
Rc::clone(&func),
|
||||||
DEFAULT_VALUE_STACK_LIMIT,
|
DEFAULT_VALUE_STACK_LIMIT,
|
||||||
DEFAULT_FRAME_STACK_LIMIT,
|
DEFAULT_FRAME_STACK_LIMIT,
|
||||||
&func_signature,
|
&func_signature,
|
||||||
@ -580,7 +566,7 @@ impl Store {
|
|||||||
);
|
);
|
||||||
InvokeKind::Internal(context)
|
InvokeKind::Internal(context)
|
||||||
}
|
}
|
||||||
FuncInstance::Host { ref host_func, .. } => InvokeKind::Host(Arc::clone(host_func), args),
|
FuncInstance::Host { ref host_func, .. } => InvokeKind::Host(Rc::clone(host_func), args),
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use std::u32;
|
use std::u32;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::rc::Rc;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use elements::{TableType, ResizableLimits};
|
use elements::{TableType, ResizableLimits};
|
||||||
use interpreter::Error;
|
use interpreter::Error;
|
||||||
use interpreter::module::check_limits;
|
use interpreter::module::check_limits;
|
||||||
use interpreter::variable::VariableType;
|
use interpreter::variable::VariableType;
|
||||||
use interpreter::store::FuncId;
|
use interpreter::store::FuncInstance;
|
||||||
|
|
||||||
/// Table instance.
|
/// Table instance.
|
||||||
pub struct TableInstance {
|
pub struct TableInstance {
|
||||||
/// Table limits.
|
/// Table limits.
|
||||||
limits: ResizableLimits,
|
limits: ResizableLimits,
|
||||||
/// Table memory buffer.
|
/// Table memory buffer.
|
||||||
buffer: RwLock<Vec<Option<FuncId>>>,
|
buffer: RwLock<Vec<Option<Rc<FuncInstance>>>>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +49,10 @@ impl TableInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the specific value in the table
|
/// Get the specific value in the table
|
||||||
pub fn get(&self, offset: u32) -> Result<FuncId, Error> {
|
pub fn get(&self, offset: u32) -> Result<Rc<FuncInstance>, Error> {
|
||||||
let buffer = self.buffer.read();
|
let buffer = self.buffer.read();
|
||||||
let buffer_len = buffer.len();
|
let buffer_len = buffer.len();
|
||||||
let table_elem = buffer.get(offset as usize).ok_or(Error::Table(format!(
|
let table_elem = buffer.get(offset as usize).cloned().ok_or(Error::Table(format!(
|
||||||
"trying to read table item with index {} when there are only {} items",
|
"trying to read table item with index {} when there are only {} items",
|
||||||
offset,
|
offset,
|
||||||
buffer_len
|
buffer_len
|
||||||
@ -63,7 +64,7 @@ impl TableInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the table element to the specified function.
|
/// Set the table element to the specified function.
|
||||||
pub fn set(&self, offset: u32, value: FuncId) -> Result<(), Error> {
|
pub fn set(&self, offset: u32, value: Rc<FuncInstance>) -> Result<(), Error> {
|
||||||
let mut buffer = self.buffer.write();
|
let mut buffer = self.buffer.write();
|
||||||
let buffer_len = buffer.len();
|
let buffer_len = buffer.len();
|
||||||
let table_elem = buffer.get_mut(offset as usize).ok_or(Error::Table(format!(
|
let table_elem = buffer.get_mut(offset as usize).ok_or(Error::Table(format!(
|
||||||
|
Reference in New Issue
Block a user