Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(runtime) Add some better runtime docs #269

Merged
merged 4 commits into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
27 changes: 17 additions & 10 deletions lib/runtime-core/src/backing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,31 @@ use crate::{
};
use std::slice;

/// The `LocalBacking` "owns" the memory used by all the local resources.
/// That is, local memories, tables, and globals (as well as some additional
/// data for the virtual call machinery).
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
#[derive(Debug)]
pub struct LocalBacking {
/// This is a map from the local resource index to actual memory,
/// table, and globals.
pub(crate) memories: BoxedMap<LocalMemoryIndex, Memory>,
pub(crate) tables: BoxedMap<LocalTableIndex, Table>,
pub(crate) globals: BoxedMap<LocalGlobalIndex, Global>,

/// This own the memory containing the pointers to the local memories.
/// While simplifying implementation, this adds indirection and may hurt
/// performance, especially on cache-starved systems.
pub(crate) vm_memories: BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory>,
pub(crate) vm_tables: BoxedMap<LocalTableIndex, *mut vm::LocalTable>,
pub(crate) vm_globals: BoxedMap<LocalGlobalIndex, *mut vm::LocalGlobal>,

/// The dynamic sigindices are used to efficiently support caching and
/// the `call_indirect` wasm instruction. This field (and local_functions
/// as well) are subject to change.
pub(crate) dynamic_sigindices: BoxedMap<SigIndex, vm::SigId>,
pub(crate) local_functions: BoxedMap<LocalFuncIndex, *const vm::Func>,
}

// impl LocalBacking {
// pub fn memory(&mut self, local_memory_index: LocalMemoryIndex) -> &mut Memory {
// &mut self.memories[local_memory_index]
// }

// pub fn table(&mut self, local_table_index: LocalTableIndex) -> &mut TableBacking {
// &mut self.tables[local_table_index]
// }
// }

impl LocalBacking {
pub(crate) fn new(module: &ModuleInner, imports: &ImportBacking, vmctx: *mut vm::Ctx) -> Self {
let mut memories = Self::generate_memories(module);
Expand Down Expand Up @@ -102,6 +103,9 @@ impl LocalBacking {
memories.into_boxed_map()
}

/// Initialize each local memory.
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
///
/// This involves copying in the data initializers.
fn finalize_memories(
module: &ModuleInner,
imports: &ImportBacking,
Expand Down Expand Up @@ -174,6 +178,9 @@ impl LocalBacking {
tables.into_boxed_map()
}

/// This initializes all of the local tables, e.g.
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
/// putting all the table elements (function pointers)
/// in the right places.
#[allow(clippy::cast_ptr_alignment)]
fn finalize_tables(
module: &ModuleInner,
Expand Down
12 changes: 12 additions & 0 deletions lib/runtime-core/src/sig_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ struct GlobalSigRegistry {
sig_assoc: Map<SigIndex, Arc<FuncSig>>,
}

/// The `SigRegistry` represents a process-global map of function signatures
/// to signature indexes and vice versa (the map goes both ways).
///
/// This exists for two reasons:
/// 1. The `call_indirect` wasm instruction can compare two signature indices
/// to do signature validation very quickly.
/// 2. To intern function signatures, which may be expensive to create.
#[derive(Debug)]
pub struct SigRegistry;

impl SigRegistry {
/// Map a `FuncSig` to a global `SigIndex`.
pub fn lookup_sig_index<Sig>(&self, func_sig: Sig) -> SigIndex
where
Sig: Into<Arc<FuncSig>>,
Expand All @@ -45,11 +53,15 @@ impl SigRegistry {
sig_index
}

/// Map a global `SigIndex` to an interned `FuncSig`.
pub fn lookup_signature(&self, sig_index: SigIndex) -> Arc<FuncSig> {
let global = (*GLOBAL_SIG_REGISTRY).read();
Arc::clone(&global.sig_assoc[sig_index])
}

/// Register a function signature with the global signature registry.
///
/// This will return an interned `FuncSig`.
pub fn lookup_signature_ref(&self, func_sig: &FuncSig) -> Arc<FuncSig> {
let mut global = (*GLOBAL_SIG_REGISTRY).write();
let global = &mut *global;
Expand Down
23 changes: 23 additions & 0 deletions lib/runtime-core/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ use std::{ffi::c_void, mem, ptr};

/// The context of the currently running WebAssembly instance.
///
/// This is implicitly passed to every webassembly function.
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
/// Since this is per-module, each field has a statically
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
/// (as in after compiling the wasm) known size, so no
/// runtime checks are necessary.
///
/// While the runtime currently just passes this around
/// as the first, implicit parameter of every function,
/// it may someday be pinned to a register (especially
/// on arm, which has a ton of registers) to reduce
/// register shuffling.
#[derive(Debug)]
#[repr(C)]
pub struct Ctx {
Expand Down Expand Up @@ -42,11 +51,25 @@ pub struct Ctx {

pub(crate) local_functions: *const *const Func,

/// These are pointers to things that are known to be owned
/// by the owning `Instance`.
local_backing: *mut LocalBacking,
import_backing: *mut ImportBacking,
module: *const ModuleInner,

//// This is intended to be user-supplied, per-instance
/// contextual data. There are currently some issue with it,
/// notably that it cannot be set before running the `start`
/// function in a webassembly module.
///
/// [#219](https://github.com/wasmerio/wasmer/pull/219) fixes that
/// issue, as well as allowing the user to have *per-function*
/// context, instead of just per-instance.
pub data: *mut c_void,

/// If there's a function set in this field, it gets called
/// when the context is destructed, e.g. when an `Instance`
/// is dropped.
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
}

Expand Down