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

Commit 34dedd5

Browse files
feat: initial global support
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent 405564c commit 34dedd5

File tree

6 files changed

+69
-25
lines changed

6 files changed

+69
-25
lines changed

crates/tinywasm/src/instance.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ impl ModuleInstance {
7676
&self.0.func_addrs
7777
}
7878

79+
pub(crate) fn global_addrs(&self) -> &[GlobalAddr] {
80+
&self.0.global_addrs
81+
}
82+
7983
pub(crate) fn func_ty_addrs(&self) -> &[FuncType] {
8084
&self.0.types
8185
}
@@ -93,6 +97,11 @@ impl ModuleInstance {
9397
self.0.func_addrs[addr as usize]
9498
}
9599

100+
// resolve a global address to the global store address
101+
pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr {
102+
self.0.global_addrs[addr as usize]
103+
}
104+
96105
/// Get an exported function by name
97106
pub fn exported_func_by_name(&self, store: &Store, name: &str) -> Result<FuncHandle> {
98107
if self.0.store_id != store.id() {

crates/tinywasm/src/runtime/executor/mod.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,6 @@ enum ExecResult {
7575
Trap(crate::Trap),
7676
}
7777

78-
/// Execute a const instruction
79-
pub(crate) fn exec_const(instr: ConstInstruction) -> RawWasmValue {
80-
match instr {
81-
ConstInstruction::F32Const(val) => val.into(),
82-
ConstInstruction::F64Const(val) => val.into(),
83-
ConstInstruction::I32Const(val) => val.into(),
84-
ConstInstruction::I64Const(val) => val.into(),
85-
ConstInstruction::GlobalGet(_) => unimplemented!("global get"),
86-
ConstInstruction::RefFunc(_) => unimplemented!("ref func"),
87-
ConstInstruction::RefNull(_) => unimplemented!("ref null"),
88-
}
89-
}
90-
9178
/// Run a single step of the interpreter
9279
/// A seperate function is used so later, we can more easily implement
9380
/// a step-by-step debugger (using generators once they're stable?)
@@ -269,6 +256,17 @@ fn exec_one(
269256
LocalSet(local_index) => cf.set_local(*local_index as usize, stack.values.pop()?),
270257
LocalTee(local_index) => cf.set_local(*local_index as usize, *stack.values.last()?),
271258

259+
GlobalGet(global_index) => {
260+
let idx = module.resolve_global_addr(*global_index);
261+
let global = store.get_global_val(idx as usize)?;
262+
stack.values.push(global);
263+
}
264+
265+
GlobalSet(global_index) => {
266+
let idx = module.resolve_global_addr(*global_index);
267+
store.set_global_val(idx as usize, stack.values.pop()?)?;
268+
}
269+
272270
I32Const(val) => stack.values.push((*val).into()),
273271
I64Const(val) => stack.values.push((*val).into()),
274272
F32Const(val) => stack.values.push((*val).into()),

crates/tinywasm/src/runtime/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::fmt::Debug;
22

3-
use tinywasm_types::{ValType, WasmValue};
3+
use tinywasm_types::{ConstInstruction, ValType, WasmValue};
44

55
/// A raw wasm value.
66
///

crates/tinywasm/src/store.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use core::sync::atomic::{AtomicUsize, Ordering};
1+
use core::{
2+
cell::RefCell,
3+
sync::atomic::{AtomicUsize, Ordering},
4+
};
25

36
use alloc::{format, rc::Rc, vec::Vec};
47
use tinywasm_types::{
@@ -8,7 +11,7 @@ use tinywasm_types::{
811

912
use crate::{
1013
runtime::{self, DefaultRuntime},
11-
Error, ModuleInstance, Result,
14+
Error, ModuleInstance, RawWasmValue, Result,
1215
};
1316

1417
// global store id counter
@@ -82,7 +85,7 @@ pub(crate) struct StoreData {
8285
pub(crate) funcs: Vec<Rc<FunctionInstance>>,
8386
pub(crate) tables: Vec<TableInstance>,
8487
pub(crate) mems: Vec<Rc<MemoryInstance>>,
85-
pub(crate) globals: Vec<Rc<GlobalInstance>>,
88+
pub(crate) globals: Vec<Rc<RefCell<GlobalInstance>>>,
8689
pub(crate) elems: Vec<ElemInstance>,
8790
pub(crate) datas: Vec<DataInstance>,
8891
}
@@ -143,8 +146,26 @@ impl Store {
143146
let mut global_addrs = Vec::with_capacity(global_count);
144147
for (i, global) in globals.into_iter().enumerate() {
145148
// 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)));
149+
use tinywasm_types::ConstInstruction::*;
150+
let val = match global.init {
151+
F32Const(f) => RawWasmValue::from(f),
152+
F64Const(f) => RawWasmValue::from(f),
153+
I32Const(i) => RawWasmValue::from(i),
154+
I64Const(i) => RawWasmValue::from(i),
155+
GlobalGet(addr) => {
156+
let addr = global_addrs[addr as usize];
157+
let global = self.data.globals[addr as usize].clone();
158+
let val = global.borrow().value;
159+
val
160+
}
161+
RefNull(_) => RawWasmValue::default(),
162+
RefFunc(idx) => RawWasmValue::from(idx as i64),
163+
};
164+
165+
self.data
166+
.globals
167+
.push(Rc::new(RefCell::new(GlobalInstance::new(global.ty, val, idx))));
168+
148169
global_addrs.push((i + global_count) as Addr);
149170
}
150171
global_addrs
@@ -179,6 +200,22 @@ impl Store {
179200
.get(addr)
180201
.ok_or_else(|| Error::Other(format!("function {} not found", addr)))
181202
}
203+
204+
pub(crate) fn get_global_val(&self, addr: usize) -> Result<RawWasmValue> {
205+
self.data
206+
.globals
207+
.get(addr)
208+
.ok_or_else(|| Error::Other(format!("global {} not found", addr)))
209+
.map(|global| global.borrow().value)
210+
}
211+
212+
pub(crate) fn set_global_val(&mut self, addr: usize, value: RawWasmValue) -> Result<()> {
213+
self.data
214+
.globals
215+
.get(addr)
216+
.ok_or_else(|| Error::Other(format!("global {} not found", addr)))
217+
.map(|global| global.borrow_mut().value = value)
218+
}
182219
}
183220

184221
#[derive(Debug)]
@@ -254,12 +291,12 @@ impl MemoryInstance {
254291
#[derive(Debug)]
255292
pub(crate) struct GlobalInstance {
256293
pub(crate) ty: GlobalType,
257-
pub(crate) value: Addr,
294+
pub(crate) value: RawWasmValue,
258295
owner: ModuleInstanceAddr, // index into store.module_instances
259296
}
260297

261298
impl GlobalInstance {
262-
pub(crate) fn new(ty: GlobalType, value: Addr, owner: ModuleInstanceAddr) -> Self {
299+
pub(crate) fn new(ty: GlobalType, value: RawWasmValue, owner: ModuleInstanceAddr) -> Self {
263300
Self { ty, value, owner }
264301
}
265302
}

0 commit comments

Comments
 (0)