diff --git a/src/func.rs b/src/func.rs index 3b382e8..5cfc8fb 100644 --- a/src/func.rs +++ b/src/func.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +use std::rc::{Rc, Weak}; use std::fmt; use std::collections::HashMap; use std::borrow::Cow; @@ -7,7 +7,7 @@ use {Error, Signature}; use host::Externals; use runner::{prepare_function_args, FunctionContext, Interpreter}; use value::RuntimeValue; -use module::ModuleRef; +use module::ModuleInstance; use common::stack::StackWithLimit; use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT}; @@ -36,7 +36,7 @@ impl FuncRef { pub(crate) enum FuncInstance { Internal { signature: Rc, - module: ModuleRef, + module: Weak, body: Rc, }, Host { @@ -69,7 +69,7 @@ impl fmt::Debug for FuncInstance { impl FuncInstance { pub(crate) fn alloc_internal( - module: ModuleRef, + module: Weak, signature: Rc, body: FuncBody, ) -> FuncRef { diff --git a/src/module.rs b/src/module.rs index fb0b5c5..c536ed9 100644 --- a/src/module.rs +++ b/src/module.rs @@ -15,7 +15,7 @@ use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; use types::{GlobalDescriptor, TableDescriptor, MemoryDescriptor}; #[derive(Clone, Debug)] -pub struct ModuleRef(Rc); +pub struct ModuleRef(pub(crate) Rc); impl ::std::ops::Deref for ModuleRef { type Target = ModuleInstance; @@ -253,7 +253,7 @@ impl ModuleInstance { labels: labels, }; let func_instance = - FuncInstance::alloc_internal(instance.clone(), signature, func_body); + FuncInstance::alloc_internal(Rc::downgrade(&instance.0), signature, func_body); instance.push_func(func_instance); } } diff --git a/src/runner.rs b/src/runner.rs index 63f740b..cb89262 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1008,13 +1008,13 @@ impl<'a, E: Externals> Interpreter<'a, E> { impl FunctionContext { pub fn new<'store>(function: FuncRef, value_stack_limit: usize, frame_stack_limit: usize, signature: &Signature, args: Vec) -> Self { let module = match *function.as_instance() { - FuncInstance::Internal { ref module, .. } => module.clone(), + FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), }; FunctionContext { is_initialized: false, function: function, - module: module, + module: ModuleRef(module), return_type: signature.return_type().map(|vt| BlockType::Value(vt.into_elements())).unwrap_or(BlockType::NoResult), value_stack: StackWithLimit::with_limit(value_stack_limit), frame_stack: StackWithLimit::with_limit(frame_stack_limit), @@ -1026,7 +1026,7 @@ impl FunctionContext { pub fn nested(&mut self, function: FuncRef) -> Result { let (function_locals, module, function_return_type) = { let module = match *function.as_instance() { - FuncInstance::Internal { ref module, .. } => module.clone(), + FuncInstance::Internal { ref module, .. } => module.upgrade().expect("module deallocated"), 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.signature(); @@ -1038,7 +1038,7 @@ impl FunctionContext { Ok(FunctionContext { is_initialized: false, function: function, - module: module, + module: ModuleRef(module), return_type: function_return_type, value_stack: StackWithLimit::with_limit(self.value_stack.limit() - self.value_stack.len()), frame_stack: StackWithLimit::with_limit(self.frame_stack.limit() - self.frame_stack.len()),