Skip to content

Commit

Permalink
refactor: module instantiation
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Jan 5, 2024
1 parent 489abcd commit 405564c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 89 deletions.
88 changes: 44 additions & 44 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 36 additions & 5 deletions crates/tinywasm/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use alloc::{boxed::Box, string::ToString, sync::Arc, vec::Vec};
use tinywasm_types::{
DataAddr, ElmAddr, Export, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr,
TableAddr,
DataAddr, ElmAddr, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr, TableAddr,
};

use crate::{
func::{FromWasmValueTuple, IntoWasmValueTuple},
Error, ExportInstance, FuncHandle, Result, Store, TypedFuncHandle,
Error, ExportInstance, FuncHandle, Module, Result, Store, TypedFuncHandle,
};

/// A WebAssembly Module Instance
Expand Down Expand Up @@ -36,6 +35,38 @@ pub(crate) struct ModuleInstanceInner {
}

impl ModuleInstance {
/// Instantiate the module in the given store
pub fn instantiate(store: &mut Store, module: Module) -> Result<Self> {
let idx = store.next_module_instance_idx();

let func_addrs = store.add_funcs(module.data.funcs.into(), idx);
let table_addrs = store.add_tables(module.data.table_types.into(), idx);
let mem_addrs = store.add_mems(module.data.memory_types.into(), idx);
let global_addrs = store.add_globals(module.data.globals.into(), idx);
let elem_addrs = store.add_elems(module.data.elements.into(), idx);
let data_addrs = store.add_datas(module.data.data.into(), idx);

let instance = ModuleInstanceInner {
store_id: store.id(),
idx,

types: module.data.func_types,
func_addrs,
table_addrs,
mem_addrs,
global_addrs,
elem_addrs,
data_addrs,

func_start: module.data.start_func,
imports: module.data.imports,
exports: crate::ExportInstance(module.data.exports),
};
let instance = ModuleInstance::new(instance);
store.add_instance(instance.clone())?;
Ok(instance)
}

/// Get the module's exports
pub fn exports(&self) -> &ExportInstance {
&self.0.exports
Expand Down Expand Up @@ -101,7 +132,7 @@ impl ModuleInstance {
/// (which is not part of the spec, but used by llvm)
///
/// See <https://webassembly.github.io/spec/core/syntax/modules.html#start-function>
pub fn start_func(&mut self, store: &Store) -> Result<Option<FuncHandle>> {
pub fn start_func(&self, store: &Store) -> Result<Option<FuncHandle>> {
if self.0.store_id != store.id() {
return Err(Error::InvalidStore);
}
Expand Down Expand Up @@ -135,7 +166,7 @@ impl ModuleInstance {
/// Returns None if the module has no start function
///
/// See <https://webassembly.github.io/spec/core/syntax/modules.html#syntax-start>
pub fn start(&mut self, store: &mut Store) -> Result<Option<()>> {
pub fn start(&self, store: &mut Store) -> Result<Option<()>> {
let Some(func) = self.start_func(store)? else {
return Ok(None);
};
Expand Down
42 changes: 6 additions & 36 deletions crates/tinywasm/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use alloc::vec::Vec;
use tinywasm_types::TinyWasmModule;

use crate::{instance::ModuleInstanceInner, ModuleInstance, Result, Store};
use crate::{ModuleInstance, Result, Store};

#[derive(Debug)]
/// A WebAssembly Module
///
/// See <https://webassembly.github.io/spec/core/syntax/modules.html#syntax-module>
pub struct Module {
data: TinyWasmModule,
pub(crate) data: TinyWasmModule,
}

impl From<&TinyWasmModule> for Module {
Expand Down Expand Up @@ -50,46 +49,17 @@ impl Module {

/// Instantiate the module in the given store
///
// TODO: /// Runs the start function if it exists
// /// If you want to run the start function yourself, use `ModuleInstance::new`
/// Runs the start function if it exists
/// If you want to run the start function yourself, use `ModuleInstance::instantiate`
///
/// See <https://webassembly.github.io/spec/core/exec/modules.html#exec-instantiation>
pub fn instantiate(
self,
store: &mut Store,
// imports: Option<()>,
) -> Result<ModuleInstance> {
let idx = store.next_module_instance_idx();

let func_addrs = store.add_funcs(self.data.funcs.into(), idx);
let table_addrs = store.add_tables(self.data.table_types.into(), idx);
let mem_addrs = store.add_mems(self.data.memory_types.into(), idx);
let global_addrs = store.add_globals(self.data.globals.into(), idx);
let elem_addrs = store.add_elems(self.data.elements.into(), idx);
let data_addrs = store.add_datas(self.data.data.into(), idx);

let instance = ModuleInstanceInner {
store_id: store.id(),
idx,

types: self.data.func_types,
func_addrs,
table_addrs,
mem_addrs,
global_addrs,
elem_addrs,
data_addrs,

func_start: self.data.start_func,
imports: self.data.imports,
exports: crate::ExportInstance(self.data.exports),
};

let instance = ModuleInstance::new(instance);
store.add_instance(instance.clone())?;

// TODO: Auto-run start function?
// let _ = instance.start(store)?;
let instance = ModuleInstance::instantiate(store, self)?;
let _ = instance.start(store)?;
Ok(instance)
}
}
Loading

0 comments on commit 405564c

Please sign in to comment.