Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Contracts: Memory and Module instance teardowns #171

Merged
merged 2 commits into from
May 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
45 changes: 37 additions & 8 deletions substrate/executor/src/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl SandboxInstance {

fn decode_environment_definition(
raw_env_def: &[u8],
memories: &[MemoryRef],
memories: &[Option<MemoryRef>],
) -> Result<(Imports, GuestToSupervisorFunctionMapping), DummyUserError> {
let env_def = sandbox_primitives::EnvironmentDefinition::decode(&mut &raw_env_def[..]).ok_or_else(|| DummyUserError)?;

Expand All @@ -351,8 +351,10 @@ fn decode_environment_definition(
sandbox_primitives::ExternEntity::Memory(memory_idx) => {
let memory_ref = memories
.get(memory_idx as usize)
.cloned()
.ok_or_else(|| DummyUserError)?
.ok_or_else(|| DummyUserError)?;
memories_map.insert((module, field), memory_ref.clone());
memories_map.insert((module, field), memory_ref);
}
}
}
Expand Down Expand Up @@ -422,8 +424,9 @@ pub fn instantiate<FE: SandboxCapabilities + Externals>(

/// This struct keeps track of all sandboxed components.
pub struct Store {
instances: Vec<Rc<SandboxInstance>>,
memories: Vec<MemoryRef>,
// Memories and instances are `Some` untill torndown.
instances: Vec<Option<Rc<SandboxInstance>>>,
memories: Vec<Option<MemoryRef>>,
}

impl Store {
Expand All @@ -450,37 +453,63 @@ impl Store {
let mem =
MemoryInstance::alloc(Pages(initial as usize), maximum).map_err(|_| DummyUserError)?;
let mem_idx = self.memories.len();
self.memories.push(mem);
self.memories.push(Some(mem));
Ok(mem_idx as u32)
}

/// Returns `SandboxInstance` by `instance_idx`.
///
/// # Errors
///
/// Returns `Err` If `instance_idx` isn't a valid index of an instance.
/// Returns `Err` If `instance_idx` isn't a valid index of an instance or
/// instance is already torndown.
pub fn instance(&self, instance_idx: u32) -> Result<Rc<SandboxInstance>, DummyUserError> {
self.instances
.get(instance_idx as usize)
.cloned()
.ok_or_else(|| DummyUserError)?
.ok_or_else(|| DummyUserError)
}

/// Returns reference to a memory instance by `memory_idx`.
///
/// # Errors
///
/// Returns `Err` If `memory_idx` isn't a valid index of an instance.
/// Returns `Err` If `memory_idx` isn't a valid index of an memory or
/// memory is already torndown.
pub fn memory(&self, memory_idx: u32) -> Result<MemoryRef, DummyUserError> {
self.memories
.get(memory_idx as usize)
.cloned()
.ok_or_else(|| DummyUserError)?
.ok_or_else(|| DummyUserError)
}

/// Teardown the memory at the specified index.
///
/// # Errors
///
/// Returns `Err` if `memory_idx` isn't a valid index of an memory.
pub fn memory_teardown(&mut self, memory_idx: u32) -> Result<(), DummyUserError> {
if memory_idx as usize >= self.memories.len() {
return Err(DummyUserError);
}
self.memories[memory_idx as usize] = None;
Ok(())
}

/// Teardown the instance at the specified index.
pub fn instance_teardown(&mut self, instance_idx: u32) -> Result<(), DummyUserError> {
if instance_idx as usize >= self.instances.len() {
return Err(DummyUserError);
}
self.instances[instance_idx as usize] = None;
Ok(())
}

fn register_sandbox_instance(&mut self, sandbox_instance: Rc<SandboxInstance>) -> u32 {
let instance_idx = self.instances.len();
self.instances.push(sandbox_instance);
self.instances.push(Some(sandbox_instance));
instance_idx as u32
}
}
Expand Down
8 changes: 8 additions & 0 deletions substrate/executor/src/wasm_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,

Ok(instance_idx as u32)
},
ext_sandbox_instance_teardown(instance_idx: u32) => {
this.sandbox_store.instance_teardown(instance_idx)?;
Ok(())
},
ext_sandbox_invoke(instance_idx: u32, export_ptr: *const u8, export_len: usize, state: usize) -> u32 => {
trace!(target: "runtime-sandbox", "invoke, instance_idx={}", instance_idx);
let export = this.memory.get(export_ptr, export_len as usize)
Expand Down Expand Up @@ -406,6 +410,10 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,

Ok(sandbox_primitives::ERR_OK)
},
ext_sandbox_memory_teardown(memory_idx: u32) => {
this.sandbox_store.memory_teardown(memory_idx)?;
Ok(())
},
=> <'e, E: Externalities + 'e>
);

Expand Down
Binary file not shown.
Binary file not shown.
25 changes: 22 additions & 3 deletions substrate/runtime-sandbox/without_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,12 @@ mod ffi {
val_ptr: *const u8,
val_len: usize,
) -> u32;

// TODO: ext_instance_teardown
// TODO: ext_memory_teardown
pub fn ext_sandbox_memory_teardown(
memory_idx: u32,
);
pub fn ext_sandbox_instance_teardown(
instance_idx: u32,
);
}
}

Expand Down Expand Up @@ -122,6 +125,14 @@ impl Memory {
}
}

impl Drop for Memory {
fn drop(&mut self) {
unsafe {
ffi::ext_sandbox_memory_teardown(self.memory_idx);
}
}
}

pub struct EnvironmentDefinitionBuilder<T> {
env_def: sandbox_primitives::EnvironmentDefinition,
_marker: marker::PhantomData<T>,
Expand Down Expand Up @@ -265,3 +276,11 @@ impl<T> Instance<T> {
}
}
}

impl<T> Drop for Instance<T> {
fn drop(&mut self) {
unsafe {
ffi::ext_sandbox_instance_teardown(self.instance_idx);
}
}
}