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

Commit 4faaf5b

Browse files
reduce instruction enum size even more
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 83a768d commit 4faaf5b

File tree

8 files changed

+296
-180
lines changed

8 files changed

+296
-180
lines changed

crates/benchmarks/benches/selfhosted.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ fn criterion_benchmark(c: &mut Criterion) {
6161
{
6262
let twasm = util::wasm_to_twasm(TINYWASM);
6363
let mut group = c.benchmark_group("selfhosted");
64-
// group.bench_function("native", |b| b.iter(run_native));
64+
group.bench_function("native", |b| b.iter(run_native));
6565
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm)));
66-
// group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
67-
// group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
66+
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
67+
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
6868
}
6969
}
7070

crates/parser/src/visit.rs

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{conversion::convert_blocktype, Result};
33
use crate::conversion::{convert_heaptype, convert_memarg, convert_valtype};
44
use alloc::string::ToString;
55
use alloc::{boxed::Box, format, vec::Vec};
6-
use tinywasm_types::Instruction;
6+
use tinywasm_types::{BlockArgsPacked, Instruction};
77
use wasmparser::{FuncValidator, FunctionBody, VisitOperator, WasmModuleResources};
88

99
struct ValidateThenVisit<'a, T, U>(T, &'a mut U);
@@ -74,12 +74,14 @@ macro_rules! define_primitive_operands {
7474
}
7575

7676
macro_rules! define_mem_operands {
77-
($($name:ident, $instr:expr),*) => {
77+
($($name:ident, $instr:ident),*) => {
7878
$(
7979
fn $name(&mut self, mem_arg: wasmparser::MemArg) -> Self::Output {
80-
self.instructions.push($instr(
81-
convert_memarg(mem_arg)
82-
));
80+
let arg = convert_memarg(mem_arg);
81+
self.instructions.push(Instruction::$instr {
82+
offset: arg.offset,
83+
mem_addr: arg.mem_addr,
84+
});
8385
Ok(())
8486
}
8587
)*
@@ -149,29 +151,29 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
149151
}
150152

151153
define_mem_operands! {
152-
visit_i32_load, Instruction::I32Load,
153-
visit_i64_load, Instruction::I64Load,
154-
visit_f32_load, Instruction::F32Load,
155-
visit_f64_load, Instruction::F64Load,
156-
visit_i32_load8_s, Instruction::I32Load8S,
157-
visit_i32_load8_u, Instruction::I32Load8U,
158-
visit_i32_load16_s, Instruction::I32Load16S,
159-
visit_i32_load16_u, Instruction::I32Load16U,
160-
visit_i64_load8_s, Instruction::I64Load8S,
161-
visit_i64_load8_u, Instruction::I64Load8U,
162-
visit_i64_load16_s, Instruction::I64Load16S,
163-
visit_i64_load16_u, Instruction::I64Load16U,
164-
visit_i64_load32_s, Instruction::I64Load32S,
165-
visit_i64_load32_u, Instruction::I64Load32U,
166-
visit_i32_store, Instruction::I32Store,
167-
visit_i64_store, Instruction::I64Store,
168-
visit_f32_store, Instruction::F32Store,
169-
visit_f64_store, Instruction::F64Store,
170-
visit_i32_store8, Instruction::I32Store8,
171-
visit_i32_store16, Instruction::I32Store16,
172-
visit_i64_store8, Instruction::I64Store8,
173-
visit_i64_store16, Instruction::I64Store16,
174-
visit_i64_store32, Instruction::I64Store32
154+
visit_i32_load, I32Load,
155+
visit_i64_load, I64Load,
156+
visit_f32_load, F32Load,
157+
visit_f64_load, F64Load,
158+
visit_i32_load8_s, I32Load8S,
159+
visit_i32_load8_u, I32Load8U,
160+
visit_i32_load16_s, I32Load16S,
161+
visit_i32_load16_u, I32Load16U,
162+
visit_i64_load8_s, I64Load8S,
163+
visit_i64_load8_u, I64Load8U,
164+
visit_i64_load16_s, I64Load16S,
165+
visit_i64_load16_u, I64Load16U,
166+
visit_i64_load32_s, I64Load32S,
167+
visit_i64_load32_u, I64Load32U,
168+
visit_i32_store, I32Store,
169+
visit_i64_store, I64Store,
170+
visit_f32_store, F32Store,
171+
visit_f64_store, F64Store,
172+
visit_i32_store8, I32Store8,
173+
visit_i32_store16, I32Store16,
174+
visit_i64_store8, I64Store8,
175+
visit_i64_store16, I64Store16,
176+
visit_i64_store32, I64Store32
175177
}
176178

177179
define_operands! {
@@ -327,7 +329,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
327329
match instruction {
328330
Instruction::LocalGet(a) => *instruction = Instruction::LocalGet2(*a, idx),
329331
Instruction::LocalGet2(a, b) => *instruction = Instruction::LocalGet3(*a, *b, idx),
330-
Instruction::LocalGet3(a, b, c) => *instruction = Instruction::LocalGet4(*a, *b, *c, idx),
332+
// Instruction::LocalGet3(a, b, c) => *instruction = Instruction::LocalGet4(*a, *b, *c, idx),
331333
Instruction::LocalTee(a) => *instruction = Instruction::LocalTeeGet(*a, idx),
332334
_ => return self.visit(Instruction::LocalGet(idx)),
333335
};
@@ -396,7 +398,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
396398

397399
fn visit_if(&mut self, ty: wasmparser::BlockType) -> Self::Output {
398400
self.label_ptrs.push(self.instructions.len());
399-
self.visit(Instruction::If(convert_blocktype(ty), None, 0))
401+
self.visit(Instruction::If(BlockArgsPacked::new(convert_blocktype(ty)), 0, 0))
400402
}
401403

402404
fn visit_else(&mut self) -> Self::Output {
@@ -414,7 +416,9 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
414416

415417
match self.instructions[label_pointer] {
416418
Instruction::Else(ref mut else_instr_end_offset) => {
417-
*else_instr_end_offset = (current_instr_ptr - label_pointer as usize) as u32;
419+
*else_instr_end_offset = (current_instr_ptr - label_pointer as usize)
420+
.try_into()
421+
.expect("else_instr_end_offset is too large, tinywasm does not support if blocks that large");
418422

419423
#[cold]
420424
fn error() -> crate::ParseError {
@@ -431,13 +435,20 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
431435
return Err(error());
432436
};
433437

434-
*else_offset = Some((label_pointer - if_label_pointer) as u32);
435-
*end_offset = (current_instr_ptr - if_label_pointer) as u32;
438+
*else_offset = (label_pointer - if_label_pointer)
439+
.try_into()
440+
.expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
441+
442+
*end_offset = (current_instr_ptr - if_label_pointer)
443+
.try_into()
444+
.expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
436445
}
437446
Instruction::Block(_, ref mut end_offset)
438447
| Instruction::Loop(_, ref mut end_offset)
439448
| Instruction::If(_, _, ref mut end_offset) => {
440-
*end_offset = (current_instr_ptr - label_pointer) as u32;
449+
*end_offset = (current_instr_ptr - label_pointer)
450+
.try_into()
451+
.expect("else_instr_end_offset is too large, tinywasm does not support blocks that large");
441452
}
442453
_ => {
443454
return Err(crate::ParseError::UnsupportedOperator(

crates/tinywasm/src/runtime/interpreter/macros.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// from a function, so we need to check if the label stack is empty
1212
macro_rules! break_to {
1313
($cf:ident, $stack:ident, $break_to_relative:ident) => {{
14-
if $cf.break_to($break_to_relative, &mut $stack.values, &mut $stack.blocks).is_none() {
14+
if $cf.break_to(*$break_to_relative, &mut $stack.values, &mut $stack.blocks).is_none() {
1515
if $stack.call_stack.is_empty() {
1616
return Ok(ExecResult::Return);
1717
} else {
@@ -23,20 +23,22 @@ macro_rules! break_to {
2323

2424
/// Load a value from memory
2525
macro_rules! mem_load {
26-
($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
26+
($type:ty, $arg:expr, $stack:ident, $store:ident, $module:ident) => {{
2727
mem_load!($type, $type, $arg, $stack, $store, $module)
2828
}};
2929

30-
($load_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
31-
let mem_idx = $module.resolve_mem_addr($arg.mem_addr);
30+
($load_type:ty, $target_type:ty, $arg:expr, $stack:ident, $store:ident, $module:ident) => {{
31+
let (mem_addr, offset) = $arg;
32+
33+
let mem_idx = $module.resolve_mem_addr(*mem_addr);
3234
let mem = $store.get_mem(mem_idx as usize)?;
3335
let mem_ref = mem.borrow_mut();
3436

3537
let addr: u64 = $stack.values.pop()?.into();
36-
let addr = $arg.offset.checked_add(addr).ok_or_else(|| {
38+
let addr = offset.checked_add(addr).ok_or_else(|| {
3739
cold();
3840
Error::Trap(crate::Trap::MemoryOutOfBounds {
39-
offset: $arg.offset as usize,
41+
offset: *offset as usize,
4042
len: core::mem::size_of::<$load_type>(),
4143
max: mem_ref.max_pages(),
4244
})
@@ -45,7 +47,7 @@ macro_rules! mem_load {
4547
let addr: usize = addr.try_into().ok().ok_or_else(|| {
4648
cold();
4749
Error::Trap(crate::Trap::MemoryOutOfBounds {
48-
offset: $arg.offset as usize,
50+
offset: *offset as usize,
4951
len: core::mem::size_of::<$load_type>(),
5052
max: mem_ref.max_pages(),
5153
})
@@ -59,15 +61,14 @@ macro_rules! mem_load {
5961

6062
/// Store a value to memory
6163
macro_rules! mem_store {
62-
($type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
64+
($type:ty, $arg:expr, $stack:ident, $store:ident, $module:ident) => {{
6365
log::debug!("mem_store!({}, {:?})", stringify!($type), $arg);
64-
6566
mem_store!($type, $type, $arg, $stack, $store, $module)
6667
}};
6768

68-
($store_type:ty, $target_type:ty, $arg:ident, $stack:ident, $store:ident, $module:ident) => {{
69-
// likewise, there could be a lot of performance improvements here
70-
let mem_idx = $module.resolve_mem_addr($arg.mem_addr);
69+
($store_type:ty, $target_type:ty, $arg:expr, $stack:ident, $store:ident, $module:ident) => {{
70+
let (mem_addr, offset) = $arg;
71+
let mem_idx = $module.resolve_mem_addr(*mem_addr);
7172
let mem = $store.get_mem(mem_idx as usize)?;
7273

7374
let val = $stack.values.pop_t::<$store_type>()?;
@@ -76,7 +77,7 @@ macro_rules! mem_store {
7677
let val = val as $store_type;
7778
let val = val.to_le_bytes();
7879

79-
mem.borrow_mut().store(($arg.offset + addr) as usize, val.len(), &val)?;
80+
mem.borrow_mut().store((*offset + addr) as usize, val.len(), &val)?;
8081
}};
8182
}
8283

0 commit comments

Comments
 (0)