Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit 489abcd

Browse files
chore: add all instances
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent af3caca commit 489abcd

File tree

4 files changed

+233
-77
lines changed

4 files changed

+233
-77
lines changed

crates/tinywasm/src/instance.rs

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use alloc::{boxed::Box, string::ToString, sync::Arc, vec::Vec};
2-
use tinywasm_types::{Export, ExternalKind, FuncAddr, FuncType, ModuleInstanceAddr};
2+
use tinywasm_types::{
3+
DataAddr, ElmAddr, Export, ExternalKind, FuncAddr, FuncType, GlobalAddr, Import, MemAddr, ModuleInstanceAddr,
4+
TableAddr,
5+
};
36

47
use crate::{
58
func::{FromWasmValueTuple, IntoWasmValueTuple},
@@ -15,19 +18,21 @@ use crate::{
1518
pub struct ModuleInstance(Arc<ModuleInstanceInner>);
1619

1720
#[derive(Debug)]
18-
struct ModuleInstanceInner {
21+
pub(crate) struct ModuleInstanceInner {
1922
pub(crate) store_id: usize,
20-
pub(crate) _idx: ModuleInstanceAddr,
21-
pub(crate) func_start: Option<FuncAddr>,
22-
pub(crate) types: Box<[FuncType]>,
23-
pub(crate) exports: ExportInstance,
23+
pub(crate) idx: ModuleInstanceAddr,
2424

25+
pub(crate) types: Box<[FuncType]>,
2526
pub(crate) func_addrs: Vec<FuncAddr>,
26-
// pub table_addrs: Vec<TableAddr>,
27-
// pub mem_addrs: Vec<MemAddr>,
28-
// pub global_addrs: Vec<GlobalAddr>,
29-
// pub elem_addrs: Vec<ElmAddr>,
30-
// pub data_addrs: Vec<DataAddr>,
27+
pub(crate) table_addrs: Vec<TableAddr>,
28+
pub(crate) mem_addrs: Vec<MemAddr>,
29+
pub(crate) global_addrs: Vec<GlobalAddr>,
30+
pub(crate) elem_addrs: Vec<ElmAddr>,
31+
pub(crate) data_addrs: Vec<DataAddr>,
32+
33+
pub(crate) func_start: Option<FuncAddr>,
34+
pub(crate) imports: Box<[Import]>,
35+
pub(crate) exports: ExportInstance,
3136
}
3237

3338
impl ModuleInstance {
@@ -44,22 +49,8 @@ impl ModuleInstance {
4449
&self.0.types
4550
}
4651

47-
pub(crate) fn new(
48-
types: Box<[FuncType]>,
49-
func_start: Option<FuncAddr>,
50-
exports: Box<[Export]>,
51-
func_addrs: Vec<FuncAddr>,
52-
idx: ModuleInstanceAddr,
53-
store_id: usize,
54-
) -> Self {
55-
Self(Arc::new(ModuleInstanceInner {
56-
store_id,
57-
_idx: idx,
58-
types,
59-
func_start,
60-
func_addrs,
61-
exports: ExportInstance(exports),
62-
}))
52+
pub(crate) fn new(inner: ModuleInstanceInner) -> Self {
53+
Self(Arc::new(inner))
6354
}
6455

6556
pub(crate) fn func_ty(&self, addr: FuncAddr) -> &FuncType {

crates/tinywasm/src/module.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use alloc::vec::Vec;
12
use tinywasm_types::TinyWasmModule;
23

3-
use crate::{ModuleInstance, Result, Store};
4+
use crate::{instance::ModuleInstanceInner, ModuleInstance, Result, Store};
45

56
#[derive(Debug)]
67
/// A WebAssembly Module
@@ -49,8 +50,8 @@ impl Module {
4950

5051
/// Instantiate the module in the given store
5152
///
52-
/// Runs the start function if it exists
53-
/// If you want to run the start function yourself, use `ModuleInstance::new`
53+
// TODO: /// Runs the start function if it exists
54+
// /// If you want to run the start function yourself, use `ModuleInstance::new`
5455
///
5556
/// See <https://webassembly.github.io/spec/core/exec/modules.html#exec-instantiation>
5657
pub fn instantiate(
@@ -59,18 +60,35 @@ impl Module {
5960
// imports: Option<()>,
6061
) -> Result<ModuleInstance> {
6162
let idx = store.next_module_instance_idx();
63+
6264
let func_addrs = store.add_funcs(self.data.funcs.into(), idx);
65+
let table_addrs = store.add_tables(self.data.table_types.into(), idx);
66+
let mem_addrs = store.add_mems(self.data.memory_types.into(), idx);
67+
let global_addrs = store.add_globals(self.data.globals.into(), idx);
68+
let elem_addrs = store.add_elems(self.data.elements.into(), idx);
69+
let data_addrs = store.add_datas(self.data.data.into(), idx);
6370

64-
let instance = ModuleInstance::new(
65-
self.data.func_types,
66-
self.data.start_func,
67-
self.data.exports,
68-
func_addrs,
71+
let instance = ModuleInstanceInner {
72+
store_id: store.id(),
6973
idx,
70-
store.id(),
71-
);
7274

75+
types: self.data.func_types,
76+
func_addrs,
77+
table_addrs,
78+
mem_addrs,
79+
global_addrs,
80+
elem_addrs,
81+
data_addrs,
82+
83+
func_start: self.data.start_func,
84+
imports: self.data.imports,
85+
exports: crate::ExportInstance(self.data.exports),
86+
};
87+
88+
let instance = ModuleInstance::new(instance);
7389
store.add_instance(instance.clone())?;
90+
91+
// TODO: Auto-run start function?
7492
// let _ = instance.start(store)?;
7593
Ok(instance)
7694
}

crates/tinywasm/src/store.rs

Lines changed: 184 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use core::sync::atomic::{AtomicUsize, Ordering};
22

33
use alloc::{format, rc::Rc, vec::Vec};
4-
use tinywasm_types::{FuncAddr, Function, Instruction, ModuleInstanceAddr, TypeAddr, ValType};
4+
use tinywasm_types::{
5+
Addr, Data, Element, ElementKind, FuncAddr, Function, Global, GlobalType, Instruction, MemAddr, MemoryType,
6+
ModuleInstanceAddr, TableAddr, TableType, TypeAddr, ValType,
7+
};
58

69
use crate::{
710
runtime::{self, DefaultRuntime},
@@ -69,42 +72,19 @@ impl Default for Store {
6972
}
7073
}
7174

72-
#[derive(Debug)]
73-
/// A WebAssembly Function Instance
74-
///
75-
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
76-
pub struct FunctionInstance {
77-
pub(crate) func: Function,
78-
pub(crate) _module_instance: ModuleInstanceAddr, // index into store.module_instances
79-
}
80-
81-
impl FunctionInstance {
82-
pub(crate) fn _module_instance_addr(&self) -> ModuleInstanceAddr {
83-
self._module_instance
84-
}
85-
86-
pub(crate) fn locals(&self) -> &[ValType] {
87-
&self.func.locals
88-
}
89-
90-
pub(crate) fn instructions(&self) -> &[Instruction] {
91-
&self.func.instructions
92-
}
93-
94-
pub(crate) fn ty_addr(&self) -> TypeAddr {
95-
self.func.ty
96-
}
97-
}
98-
9975
#[derive(Debug, Default)]
10076
/// Global state that can be manipulated by WebAssembly programs
77+
///
78+
/// Data should only be addressable by the module that owns it
79+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#store>
80+
// TODO: Arena allocate these?
10181
pub(crate) struct StoreData {
10282
pub(crate) funcs: Vec<Rc<FunctionInstance>>,
103-
// pub tables: Vec<TableAddr>,
104-
// pub mems: Vec<MemAddr>,
105-
// pub globals: Vec<GlobalAddr>,
106-
// pub elems: Vec<ElmAddr>,
107-
// pub datas: Vec<DataAddr>,
83+
pub(crate) tables: Vec<TableInstance>,
84+
pub(crate) mems: Vec<Rc<MemoryInstance>>,
85+
pub(crate) globals: Vec<Rc<GlobalInstance>>,
86+
pub(crate) elems: Vec<ElemInstance>,
87+
pub(crate) datas: Vec<DataInstance>,
10888
}
10989

11090
impl Store {
@@ -129,15 +109,69 @@ impl Store {
129109
let func_count = self.data.funcs.len();
130110
let mut func_addrs = Vec::with_capacity(func_count);
131111
for (i, func) in funcs.into_iter().enumerate() {
132-
self.data.funcs.push(Rc::new(FunctionInstance {
133-
func,
134-
_module_instance: idx,
135-
}));
112+
self.data.funcs.push(Rc::new(FunctionInstance { func, owner: idx }));
136113
func_addrs.push((i + func_count) as FuncAddr);
137114
}
138115
func_addrs
139116
}
140117

118+
/// Add tables to the store, returning their addresses in the store
119+
pub(crate) fn add_tables(&mut self, tables: Vec<TableType>, idx: ModuleInstanceAddr) -> Vec<TableAddr> {
120+
let table_count = self.data.tables.len();
121+
let mut table_addrs = Vec::with_capacity(table_count);
122+
for (i, table) in tables.into_iter().enumerate() {
123+
self.data.tables.push(TableInstance::new(table, idx));
124+
table_addrs.push((i + table_count) as TableAddr);
125+
}
126+
table_addrs
127+
}
128+
129+
/// Add memories to the store, returning their addresses in the store
130+
pub(crate) fn add_mems(&mut self, mems: Vec<MemoryType>, idx: ModuleInstanceAddr) -> Vec<MemAddr> {
131+
let mem_count = self.data.mems.len();
132+
let mut mem_addrs = Vec::with_capacity(mem_count);
133+
for (i, mem) in mems.into_iter().enumerate() {
134+
self.data.mems.push(Rc::new(MemoryInstance::new(mem, idx)));
135+
mem_addrs.push((i + mem_count) as MemAddr);
136+
}
137+
mem_addrs
138+
}
139+
140+
/// Add globals to the store, returning their addresses in the store
141+
pub(crate) fn add_globals(&mut self, globals: Vec<Global>, idx: ModuleInstanceAddr) -> Vec<Addr> {
142+
let global_count = self.data.globals.len();
143+
let mut global_addrs = Vec::with_capacity(global_count);
144+
for (i, global) in globals.into_iter().enumerate() {
145+
// TODO: initialize globals
146+
// Don't fail here yet - we'll fail when we try to use the global
147+
self.data.globals.push(Rc::new(GlobalInstance::new(global.ty, 0, idx)));
148+
global_addrs.push((i + global_count) as Addr);
149+
}
150+
global_addrs
151+
}
152+
153+
/// Add elements to the store, returning their addresses in the store
154+
pub(crate) fn add_elems(&mut self, elems: Vec<Element>, idx: ModuleInstanceAddr) -> Vec<Addr> {
155+
let elem_count = self.data.elems.len();
156+
let mut elem_addrs = Vec::with_capacity(elem_count);
157+
for (i, elem) in elems.into_iter().enumerate() {
158+
self.data.elems.push(ElemInstance::new(elem.kind, idx));
159+
elem_addrs.push((i + elem_count) as Addr);
160+
}
161+
elem_addrs
162+
}
163+
164+
/// Add data to the store, returning their addresses in the store
165+
pub(crate) fn add_datas(&mut self, datas: Vec<Data>, idx: ModuleInstanceAddr) -> Vec<Addr> {
166+
let data_count = self.data.datas.len();
167+
let mut data_addrs = Vec::with_capacity(data_count);
168+
for (i, data) in datas.into_iter().enumerate() {
169+
self.data.datas.push(DataInstance::new(data.data.to_vec(), idx));
170+
data_addrs.push((i + data_count) as Addr);
171+
}
172+
data_addrs
173+
}
174+
141175
/// Get the function at the actual index in the store
142176
pub(crate) fn get_func(&self, addr: usize) -> Result<&Rc<FunctionInstance>> {
143177
self.data
@@ -146,3 +180,116 @@ impl Store {
146180
.ok_or_else(|| Error::Other(format!("function {} not found", addr)))
147181
}
148182
}
183+
184+
#[derive(Debug)]
185+
/// A WebAssembly Function Instance
186+
///
187+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances>
188+
pub struct FunctionInstance {
189+
pub(crate) func: Function,
190+
pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances
191+
}
192+
193+
impl FunctionInstance {
194+
pub(crate) fn _module_instance_addr(&self) -> ModuleInstanceAddr {
195+
self.owner
196+
}
197+
198+
pub(crate) fn locals(&self) -> &[ValType] {
199+
&self.func.locals
200+
}
201+
202+
pub(crate) fn instructions(&self) -> &[Instruction] {
203+
&self.func.instructions
204+
}
205+
206+
pub(crate) fn ty_addr(&self) -> TypeAddr {
207+
self.func.ty
208+
}
209+
}
210+
211+
/// A WebAssembly Table Instance
212+
///
213+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
214+
#[derive(Debug)]
215+
pub(crate) struct TableInstance {
216+
pub(crate) kind: TableType,
217+
pub(crate) elements: Vec<Addr>,
218+
pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances
219+
}
220+
221+
impl TableInstance {
222+
pub(crate) fn new(kind: TableType, owner: ModuleInstanceAddr) -> Self {
223+
Self {
224+
kind,
225+
elements: Vec::new(),
226+
owner,
227+
}
228+
}
229+
}
230+
231+
/// A WebAssembly Memory Instance
232+
///
233+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
234+
#[derive(Debug)]
235+
pub(crate) struct MemoryInstance {
236+
pub(crate) kind: MemoryType,
237+
pub(crate) data: Vec<u8>,
238+
pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances
239+
}
240+
241+
impl MemoryInstance {
242+
pub(crate) fn new(kind: MemoryType, owner: ModuleInstanceAddr) -> Self {
243+
Self {
244+
kind,
245+
data: Vec::new(),
246+
owner,
247+
}
248+
}
249+
}
250+
251+
/// A WebAssembly Global Instance
252+
///
253+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
254+
#[derive(Debug)]
255+
pub(crate) struct GlobalInstance {
256+
pub(crate) ty: GlobalType,
257+
pub(crate) value: Addr,
258+
owner: ModuleInstanceAddr, // index into store.module_instances
259+
}
260+
261+
impl GlobalInstance {
262+
pub(crate) fn new(ty: GlobalType, value: Addr, owner: ModuleInstanceAddr) -> Self {
263+
Self { ty, value, owner }
264+
}
265+
}
266+
267+
/// A WebAssembly Element Instance
268+
///
269+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#element-instances>
270+
#[derive(Debug)]
271+
pub(crate) struct ElemInstance {
272+
kind: ElementKind,
273+
owner: ModuleInstanceAddr, // index into store.module_instances
274+
}
275+
276+
impl ElemInstance {
277+
pub(crate) fn new(kind: ElementKind, owner: ModuleInstanceAddr) -> Self {
278+
Self { kind, owner }
279+
}
280+
}
281+
282+
/// A WebAssembly Data Instance
283+
///
284+
/// See <https://webassembly.github.io/spec/core/exec/runtime.html#data-instances>
285+
#[derive(Debug)]
286+
pub(crate) struct DataInstance {
287+
pub(crate) data: Vec<u8>,
288+
owner: ModuleInstanceAddr, // index into store.module_instances
289+
}
290+
291+
impl DataInstance {
292+
pub(crate) fn new(data: Vec<u8>, owner: ModuleInstanceAddr) -> Self {
293+
Self { data, owner }
294+
}
295+
}

0 commit comments

Comments
 (0)