summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-05-10 18:08:00 +0200
committerHenry Gressmann <mail@henrygressmann.de>2024-05-10 19:22:29 +0200
commit868aa006b7f1eabffd4aec3a03555012148a7df1 (patch)
tree164722ac37b3efb0f40bcf53925b7e79dc6493c1
parent2ac04cd653898786caca198726e6b9938185b76a (diff)
chore: slight perf improvements
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--BENCHMARKS.md18
-rw-r--r--benchmarks/benches/argon2id.rs8
-rw-r--r--benchmarks/benches/fibonacci.rs11
-rw-r--r--benchmarks/benches/selfhosted.rs11
-rw-r--r--benchmarks/benches/util/mod.rs22
-rw-r--r--crates/parser/src/visit.rs2
-rw-r--r--crates/tinywasm/src/func.rs2
-rw-r--r--crates/tinywasm/src/imports.rs15
-rw-r--r--crates/tinywasm/src/instance.rs31
-rw-r--r--crates/tinywasm/src/lib.rs16
-rw-r--r--crates/tinywasm/src/runtime/interpreter/macros.rs27
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs179
-rw-r--r--crates/tinywasm/src/runtime/stack.rs4
-rw-r--r--crates/tinywasm/src/runtime/stack/block_stack.rs10
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs15
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs12
-rw-r--r--crates/tinywasm/src/runtime/value.rs53
-rw-r--r--crates/tinywasm/src/store/data.rs10
-rw-r--r--crates/tinywasm/src/store/mod.rs40
-rw-r--r--crates/tinywasm/src/store/table.rs11
-rw-r--r--crates/tinywasm/tests/generated/mvp.csv1
-rw-r--r--crates/tinywasm/tests/testsuite/run.rs2
-rw-r--r--crates/types/src/instructions.rs8
-rw-r--r--examples/rust/analyze.py6
24 files changed, 200 insertions, 314 deletions
diff --git a/BENCHMARKS.md b/BENCHMARKS.md
index 746c585..6433be3 100644
--- a/BENCHMARKS.md
+++ b/BENCHMARKS.md
@@ -26,22 +26,18 @@ All runtimes are compiled with the following settings:
## Versions
-- `tinywasm`: `0.4.1`
+- `tinywasm`: `0.6.2`
- `wasmi`: `0.31.2`
-- `wasmer`: `4.2.5`
+- `wasmer`: `4.2.8`
## Results
-| Benchmark | Native | TinyWasm\* | Wasmi | Wasmer (Single Pass) |
+| Benchmark | Native | TinyWasm | Wasmi | Wasmer (Single Pass) |
| ------------ | -------- | ---------- | --------- | -------------------- |
-| `fib` | \*\* | ` 43.60µs` | `48.27µs` | ` 44.99µs` |
-| `fib-rec` | `0.27ms` | ` 21.13ms` | ` 4.63ms` | ` 0.47ms` |
-| `argon2id` | `0.53ms` | ` 86.16ms` | `45.00ms` | ` 4.59ms` |
-| `selfhosted` | `0.05ms` | ` 1.84ms` | ` 6.51ms` | `446.48ms` |
-
-_\* Uses tinywasm's internal module format instead of `wasm`. It takes ~5.7ms to parse and validate `tinywasm.wasm`._
-
-_\*\* essentially instant as it gets computed at compile time._
+| `fib` | `0ms` | ` 19.09µs` | `18.53µs` | ` 48.09µs` |
+| `fib-rec` | `0.27ms` | ` 22.22ms` | ` 4.96ms` | ` 0.47ms` |
+| `argon2id` | `0.53ms` | ` 86.42ms` | `46.36ms` | ` 4.82ms` |
+| `selfhosted` | `0.05ms` | ` 7.26ms` | ` 6.51ms` | `446.48ms` |
### Fib
diff --git a/benchmarks/benches/argon2id.rs b/benchmarks/benches/argon2id.rs
index 3046dee..0cf5af4 100644
--- a/benchmarks/benches/argon2id.rs
+++ b/benchmarks/benches/argon2id.rs
@@ -1,9 +1,8 @@
mod util;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use util::wasm_to_twasm;
-fn run_tinywasm(twasm: &[u8], params: (i32, i32, i32), name: &str) {
- let (mut store, instance) = util::tinywasm(twasm);
+fn run_tinywasm(wasm: &[u8], params: (i32, i32, i32), name: &str) {
+ let (mut store, instance) = util::tinywasm(wasm);
let argon2 = instance.exported_func::<(i32, i32, i32), i32>(&store, name).expect("exported_func");
argon2.call(&mut store, params).expect("call");
}
@@ -38,7 +37,6 @@ fn run_native(params: (i32, i32, i32)) {
const ARGON2ID: &[u8] = include_bytes!("../../examples/rust/out/argon2id.wasm");
fn criterion_benchmark(c: &mut Criterion) {
- let twasm = wasm_to_twasm(ARGON2ID);
let params = (1000, 2, 1);
let mut group = c.benchmark_group("argon2id");
@@ -46,7 +44,7 @@ fn criterion_benchmark(c: &mut Criterion) {
group.sample_size(10);
group.bench_function("native", |b| b.iter(|| run_native(black_box(params))));
- group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(params), "argon2id")));
+ group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(ARGON2ID, black_box(params), "argon2id")));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(ARGON2ID, black_box(params), "argon2id")));
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(ARGON2ID, black_box(params), "argon2id")));
}
diff --git a/benchmarks/benches/fibonacci.rs b/benchmarks/benches/fibonacci.rs
index b391285..15c09ac 100644
--- a/benchmarks/benches/fibonacci.rs
+++ b/benchmarks/benches/fibonacci.rs
@@ -1,9 +1,8 @@
mod util;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use util::wasm_to_twasm;
-fn run_tinywasm(twasm: &[u8], iterations: i32, name: &str) {
- let (mut store, instance) = util::tinywasm(twasm);
+fn run_tinywasm(wasm: &[u8], iterations: i32, name: &str) {
+ let (mut store, instance) = util::tinywasm(wasm);
let fib = instance.exported_func::<i32, i32>(&store, name).expect("exported_func");
fib.call(&mut store, iterations).expect("call");
}
@@ -47,12 +46,10 @@ fn run_native_recursive(n: i32) -> i32 {
const FIBONACCI: &[u8] = include_bytes!("../../examples/rust/out/fibonacci.wasm");
fn criterion_benchmark(c: &mut Criterion) {
- let twasm = wasm_to_twasm(FIBONACCI);
-
{
let mut group = c.benchmark_group("fibonacci");
group.bench_function("native", |b| b.iter(|| run_native(black_box(60))));
- group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(60), "fibonacci")));
+ group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(FIBONACCI, black_box(60), "fibonacci")));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(FIBONACCI, black_box(60), "fibonacci")));
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(FIBONACCI, black_box(60), "fibonacci")));
}
@@ -61,7 +58,7 @@ fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("fibonacci-recursive");
group.measurement_time(std::time::Duration::from_secs(5));
group.bench_function("native", |b| b.iter(|| run_native_recursive(black_box(26))));
- group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm, black_box(26), "fibonacci_recursive")));
+ group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(FIBONACCI, black_box(26), "fibonacci_recursive")));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(FIBONACCI, black_box(26), "fibonacci_recursive")));
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(FIBONACCI, black_box(26), "fibonacci_recursive")));
}
diff --git a/benchmarks/benches/selfhosted.rs b/benchmarks/benches/selfhosted.rs
index 02d44ac..21ea79f 100644
--- a/benchmarks/benches/selfhosted.rs
+++ b/benchmarks/benches/selfhosted.rs
@@ -1,5 +1,4 @@
mod util;
-use crate::util::twasm_to_module;
use criterion::{criterion_group, criterion_main, Criterion};
fn run_native() {
@@ -15,7 +14,7 @@ fn run_native() {
fn run_tinywasm(twasm: &[u8]) {
use tinywasm::*;
- let module = twasm_to_module(twasm);
+ let module = Module::parse_bytes(twasm).expect("Module::parse_bytes");
let mut store = Store::default();
let mut imports = Imports::default();
imports.define("env", "printi32", Extern::typed_func(|_: FuncContext<'_>, _: i32| Ok(()))).expect("define");
@@ -54,15 +53,9 @@ fn run_wasmer(wasm: &[u8]) {
const TINYWASM: &[u8] = include_bytes!("../../examples/rust/out/tinywasm.wasm");
fn criterion_benchmark(c: &mut Criterion) {
{
- let mut group = c.benchmark_group("selfhosted-parse");
- group.bench_function("tinywasm", |b| b.iter(|| util::parse_wasm(TINYWASM)));
- }
-
- {
- let twasm = util::wasm_to_twasm(TINYWASM);
let mut group = c.benchmark_group("selfhosted");
group.bench_function("native", |b| b.iter(run_native));
- group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(&twasm)));
+ group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(TINYWASM)));
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
}
diff --git a/benchmarks/benches/util/mod.rs b/benchmarks/benches/util/mod.rs
index f75ce66..2961046 100644
--- a/benchmarks/benches/util/mod.rs
+++ b/benchmarks/benches/util/mod.rs
@@ -1,26 +1,8 @@
#![allow(dead_code)]
-use tinywasm::{parser::Parser, types::TinyWasmModule};
-
-pub fn parse_wasm(wasm: &[u8]) -> TinyWasmModule {
- let parser = Parser::new();
- parser.parse_module_bytes(wasm).expect("parse_module_bytes")
-}
-
-pub fn wasm_to_twasm(wasm: &[u8]) -> Vec<u8> {
- let parser = Parser::new();
- let res = parser.parse_module_bytes(wasm).expect("parse_module_bytes");
- res.serialize_twasm().to_vec()
-}
-
-#[inline]
-pub fn twasm_to_module(twasm: &[u8]) -> tinywasm::Module {
- unsafe { TinyWasmModule::from_twasm_unchecked(twasm) }.into()
-}
-
-pub fn tinywasm(twasm: &[u8]) -> (tinywasm::Store, tinywasm::ModuleInstance) {
+pub fn tinywasm(wasm: &[u8]) -> (tinywasm::Store, tinywasm::ModuleInstance) {
use tinywasm::*;
- let module = twasm_to_module(twasm);
+ let module = Module::parse_bytes(wasm).expect("Module::parse_bytes");
let mut store = Store::default();
let imports = Imports::default();
let instance = ModuleInstance::instantiate(&mut store, module, Some(imports)).expect("instantiate");
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index 48eba30..c3afee7 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -343,7 +343,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
self.instructions.pop();
self.visit(Instruction::I32StoreLocal {
local: a,
- consti32: b,
+ const_i32: b,
offset: arg.offset as u32,
mem_addr: arg.mem_addr as u8,
})
diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs
index d7f7ca1..95b7cc0 100644
--- a/crates/tinywasm/src/func.rs
+++ b/crates/tinywasm/src/func.rs
@@ -49,7 +49,7 @@ impl FuncHandle {
return Err(Error::Other("Type mismatch".into()));
}
- let func_inst = store.get_func(self.addr as usize)?;
+ let func_inst = store.get_func(self.addr)?;
let wasm_func = match &func_inst.func {
Function::Host(host_func) => {
let func = &host_func.clone().func;
diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs
index 67ac360..7c9e955 100644
--- a/crates/tinywasm/src/imports.rs
+++ b/crates/tinywasm/src/imports.rs
@@ -226,11 +226,8 @@ pub struct Imports {
}
pub(crate) enum ResolvedExtern<S, V> {
- // already in the store
- Store(S),
-
- // needs to be added to the store, provided value
- Extern(V),
+ Store(S), // already in the store
+ Extern(V), // needs to be added to the store, provided value
}
pub(crate) struct ResolvedImports {
@@ -391,17 +388,17 @@ impl Imports {
match (val, &import.kind) {
(ExternVal::Global(global_addr), ImportKind::Global(ty)) => {
- let global = store.get_global(global_addr as usize)?;
+ let global = store.get_global(global_addr)?;
Self::compare_types(import, &global.borrow().ty, ty)?;
imports.globals.push(global_addr);
}
(ExternVal::Table(table_addr), ImportKind::Table(ty)) => {
- let table = store.get_table(table_addr as usize)?;
+ let table = store.get_table(table_addr)?;
Self::compare_table_types(import, &table.borrow().kind, ty)?;
imports.tables.push(table_addr);
}
(ExternVal::Memory(memory_addr), ImportKind::Memory(ty)) => {
- let mem = store.get_mem(memory_addr as usize)?;
+ let mem = store.get_mem(memory_addr)?;
let (size, kind) = {
let mem = mem.borrow();
(mem.page_count(), mem.kind)
@@ -410,7 +407,7 @@ impl Imports {
imports.memories.push(memory_addr);
}
(ExternVal::Func(func_addr), ImportKind::Function(ty)) => {
- let func = store.get_func(func_addr as usize)?;
+ let func = store.get_func(func_addr)?;
let import_func_type = module
.data
.func_types
diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs
index 3fc4fe0..8a663c4 100644
--- a/crates/tinywasm/src/instance.rs
+++ b/crates/tinywasm/src/instance.rs
@@ -2,7 +2,7 @@ use alloc::{boxed::Box, format, rc::Rc, string::ToString};
use tinywasm_types::*;
use crate::func::{FromWasmValueTuple, IntoWasmValueTuple};
-use crate::{log, Error, FuncHandle, FuncHandleTyped, Imports, MemoryRef, MemoryRefMut, Module, Result, Store};
+use crate::{Error, FuncHandle, FuncHandleTyped, Imports, MemoryRef, MemoryRefMut, Module, Result, Store};
/// An instanciated WebAssembly module
///
@@ -61,13 +61,9 @@ impl ModuleInstance {
// don't need to create a auxiliary frame etc.
let idx = store.next_module_instance_idx();
- log::info!("Instantiating module at index {}", idx);
- let imports = imports.unwrap_or_default();
-
- let mut addrs = imports.link(store, &module, idx)?;
+ let mut addrs = imports.unwrap_or_default().link(store, &module, idx)?;
let data = module.data;
- // TODO: check if the compiler correctly optimizes this to prevent wasted allocations
addrs.funcs.extend(store.init_funcs(data.funcs.into(), idx)?);
addrs.tables.extend(store.init_tables(data.table_types.into(), idx)?);
addrs.memories.extend(store.init_memories(data.memory_types.into(), idx)?);
@@ -110,15 +106,14 @@ impl ModuleInstance {
/// Get a export by name
pub fn export_addr(&self, name: &str) -> Option<ExternVal> {
let exports = self.0.exports.iter().find(|e| e.name == name.into())?;
- let kind = exports.kind.clone();
- let addr = match kind {
+ let addr = match exports.kind {
ExternalKind::Func => self.0.func_addrs.get(exports.index as usize)?,
ExternalKind::Table => self.0.table_addrs.get(exports.index as usize)?,
ExternalKind::Memory => self.0.mem_addrs.get(exports.index as usize)?,
ExternalKind::Global => self.0.global_addrs.get(exports.index as usize)?,
};
- Some(ExternVal::new(kind, *addr))
+ Some(ExternVal::new(exports.kind.clone(), *addr))
}
#[inline]
@@ -183,7 +178,7 @@ impl ModuleInstance {
return Err(Error::Other(format!("Export is not a function: {}", name)));
};
- let func_inst = store.get_func(func_addr as usize)?;
+ let func_inst = store.get_func(func_addr)?;
let ty = func_inst.func.ty();
Ok(FuncHandle { addr: func_addr, module_addr: self.id(), name: Some(name.to_string()), ty: ty.clone() })
@@ -205,8 +200,8 @@ impl ModuleInstance {
let ExternVal::Memory(mem_addr) = export else {
return Err(Error::Other(format!("Export is not a memory: {}", name)));
};
- let mem = self.memory(store, mem_addr)?;
- Ok(mem)
+
+ self.memory(store, mem_addr)
}
/// Get an exported memory by name
@@ -215,21 +210,19 @@ impl ModuleInstance {
let ExternVal::Memory(mem_addr) = export else {
return Err(Error::Other(format!("Export is not a memory: {}", name)));
};
- let mem = self.memory_mut(store, mem_addr)?;
- Ok(mem)
+
+ self.memory_mut(store, mem_addr)
}
/// Get a memory by address
pub fn memory<'a>(&self, store: &'a mut Store, addr: MemAddr) -> Result<MemoryRef<'a>> {
- let addr = self.resolve_mem_addr(addr);
- let mem = store.get_mem(addr as usize)?;
+ let mem = store.get_mem(self.resolve_mem_addr(addr))?;
Ok(MemoryRef { instance: mem.borrow() })
}
/// Get a memory by address (mutable)
pub fn memory_mut<'a>(&self, store: &'a mut Store, addr: MemAddr) -> Result<MemoryRefMut<'a>> {
- let addr = self.resolve_mem_addr(addr);
- let mem = store.get_mem(addr as usize)?;
+ let mem = store.get_mem(self.resolve_mem_addr(addr))?;
Ok(MemoryRefMut { instance: mem.borrow_mut() })
}
@@ -257,7 +250,7 @@ impl ModuleInstance {
};
let func_addr = self.0.func_addrs.get(func_index as usize).expect("No func addr for start func, this is a bug");
- let func_inst = store.get_func(*func_addr as usize)?;
+ let func_inst = store.get_func(*func_addr)?;
let ty = func_inst.func.ty();
Ok(Some(FuncHandle { module_addr: self.id(), addr: *func_addr, ty: ty.clone(), name: None }))
diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs
index e2d57fc..4a644fd 100644
--- a/crates/tinywasm/src/lib.rs
+++ b/crates/tinywasm/src/lib.rs
@@ -93,15 +93,13 @@ pub(crate) mod log {
}
mod error;
-pub use {
- error::*,
- func::{FuncHandle, FuncHandleTyped},
- imports::*,
- instance::ModuleInstance,
- module::Module,
- reference::*,
- store::*,
-};
+pub use error::*;
+pub use func::{FuncHandle, FuncHandleTyped};
+pub use imports::*;
+pub use instance::ModuleInstance;
+pub use module::Module;
+pub use reference::*;
+pub use store::*;
mod func;
mod imports;
diff --git a/crates/tinywasm/src/runtime/interpreter/macros.rs b/crates/tinywasm/src/runtime/interpreter/macros.rs
index 30f34fc..b37dedd 100644
--- a/crates/tinywasm/src/runtime/interpreter/macros.rs
+++ b/crates/tinywasm/src/runtime/interpreter/macros.rs
@@ -30,27 +30,24 @@ macro_rules! mem_load {
let (mem_addr, offset) = $arg;
let mem_idx = $module.resolve_mem_addr(*mem_addr);
- let mem = $store.get_mem(mem_idx as usize)?;
+ let mem = $store.get_mem(mem_idx)?;
let mem_ref = mem.borrow_mut();
- let addr: u64 = $stack.values.pop()?.into();
- let addr = offset.checked_add(addr).ok_or_else(|| {
+ let memory_out_of_bounds = || {
cold();
Error::Trap(crate::Trap::MemoryOutOfBounds {
offset: *offset as usize,
len: core::mem::size_of::<$load_type>(),
max: mem_ref.max_pages(),
})
- })?;
+ };
- let addr: usize = addr.try_into().ok().ok_or_else(|| {
- cold();
- Error::Trap(crate::Trap::MemoryOutOfBounds {
- offset: *offset as usize,
- len: core::mem::size_of::<$load_type>(),
- max: mem_ref.max_pages(),
- })
- })?;
+ let addr: usize = offset
+ .checked_add($stack.values.pop()?.into())
+ .ok_or_else(memory_out_of_bounds)?
+ .try_into()
+ .ok()
+ .ok_or_else(memory_out_of_bounds)?;
const LEN: usize = core::mem::size_of::<$load_type>();
let val = mem_ref.load_as::<LEN, $load_type>(addr)?;
@@ -66,10 +63,11 @@ macro_rules! mem_store {
($store_type:ty, $target_type:ty, $arg:expr, $stack:ident, $store:ident, $module:ident) => {{
let (mem_addr, offset) = $arg;
- let mem = $store.get_mem($module.resolve_mem_addr(*mem_addr) as usize)?;
+ let mem = $store.get_mem($module.resolve_mem_addr(*mem_addr))?;
let val: $store_type = $stack.values.pop()?.into();
let val = val.to_le_bytes();
let addr: u64 = $stack.values.pop()?.into();
+
mem.borrow_mut().store((*offset + addr) as usize, val.len(), &val)?;
}};
}
@@ -163,8 +161,7 @@ macro_rules! arithmetic {
/// Apply an arithmetic method to a single value on the stack
macro_rules! arithmetic_single {
($op:ident, $ty:ty, $stack:ident) => {{
- let a: $ty = $stack.values.pop()?.into();
- $stack.values.push((a.$op() as $ty).into());
+ arithmetic_single!($op, $ty, $ty, $stack)
}};
($op:ident, $from:ty, $to:ty, $stack:ident) => {{
diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs
index 6ff7be1..da37e80 100644
--- a/crates/tinywasm/src/runtime/interpreter/mod.rs
+++ b/crates/tinywasm/src/runtime/interpreter/mod.rs
@@ -22,42 +22,39 @@ use no_std_floats::NoStdFloatExt;
impl InterpreterRuntime {
// #[inline(always)] // a small 2-3% performance improvement in some cases
pub(crate) fn exec(&self, store: &mut Store, stack: &mut Stack) -> Result<()> {
- // The current call frame, gets updated inside of exec_one
- let mut cf = stack.call_stack.pop()?;
-
- // The function to execute, gets updated from ExecResult::Call
- let mut current_module = store.get_module_instance_raw(cf.func_instance.1);
+ let mut call_frame = stack.call_stack.pop()?;
+ let mut current_module = store.get_module_instance_raw(call_frame.func_instance.1);
loop {
- match exec_one(&mut cf, stack, store, &current_module) {
+ match exec_one(&mut call_frame, stack, store, &current_module) {
+ // return from the function
+ Ok(ExecResult::Return) => return Ok(()),
+
+ // continue to the next instruction and increment the instruction pointer
+ Ok(ExecResult::Ok) => call_frame.instr_ptr += 1,
+
// Continue execution at the new top of the call stack
Ok(ExecResult::Call) => {
- let old = cf.block_ptr;
- cf = stack.call_stack.pop()?;
+ let old = call_frame.block_ptr;
+ call_frame = stack.call_stack.pop()?;
- if old > cf.block_ptr {
+ if old > call_frame.block_ptr {
stack.blocks.truncate(old);
}
// keeping the pointer seperate from the call frame is about 2% faster
// than storing it in the call frame
- if cf.func_instance.1 != current_module.id() {
- current_module.swap_with(cf.func_instance.1, store);
+ if call_frame.func_instance.1 != current_module.id() {
+ current_module.swap_with(call_frame.func_instance.1, store);
}
}
- // return from the function
- Ok(ExecResult::Return) => return Ok(()),
-
- // continue to the next instruction and increment the instruction pointer
- Ok(ExecResult::Ok) => cf.instr_ptr += 1,
-
// trap the program
Err(error) => {
- cf.instr_ptr += 1;
+ call_frame.instr_ptr += 1;
// push the call frame back onto the stack so that it can be resumed
// if the trap can be handled
- stack.call_stack.push(cf)?;
+ stack.call_stack.push(call_frame)?;
return Err(error);
}
}
@@ -89,7 +86,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
// unreasonable complexity. This *should* be optimized to a jump table.
// See https://pliniker.github.io/post/dispatchers/
use tinywasm_types::Instruction::*;
- match cf.current_instruction() {
+ match &instrs[cf.instr_ptr as usize] {
Nop => { /* do nothing */ }
Unreachable => {
cold();
@@ -113,8 +110,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
Call(v) => {
// prepare the call frame
- let func_idx = module.resolve_func_addr(*v);
- let func_inst = store.get_func(func_idx as usize)?.clone();
+ let func_inst = store.get_func(module.resolve_func_addr(*v))?.clone();
let wasm_func = match &func_inst.func {
crate::Function::Wasm(wasm_func) => wasm_func.clone(),
@@ -140,17 +136,17 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
}
CallIndirect(type_addr, table_addr) => {
- let table = store.get_table(module.resolve_table_addr(*table_addr) as usize)?;
+ let table = store.get_table(module.resolve_table_addr(*table_addr))?;
let table_idx = stack.values.pop_t::<u32>()?;
// verify that the table is of the right type, this should be validated by the parser already
let func_ref = {
let table = table.borrow();
assert!(table.kind.element_type == ValType::RefFunc, "table is not of type funcref");
- table.get(table_idx as usize)?.addr().ok_or(Trap::UninitializedElement { index: table_idx as usize })?
+ table.get(table_idx)?.addr().ok_or(Trap::UninitializedElement { index: table_idx as usize })?
};
- let func_inst = store.get_func(func_ref as usize)?.clone();
+ let func_inst = store.get_func(func_ref)?.clone();
let call_ty = module.func_ty(*type_addr);
let wasm_func = match func_inst.func {
@@ -315,22 +311,21 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
stack.values.truncate_keep(block.stack_ptr, block.results as u32);
}
- LocalGet(local_index) => stack.values.push(cf.get_local(*local_index as usize)),
- LocalSet(local_index) => cf.set_local(*local_index as usize, stack.values.pop()?),
+ LocalGet(local_index) => stack.values.push(cf.get_local(*local_index)),
+ LocalSet(local_index) => cf.set_local(*local_index, stack.values.pop()?),
LocalTee(local_index) => cf.set_local(
- *local_index as usize,
+ *local_index,
*stack.values.last().expect("localtee: stack is empty. this should have been validated by the parser"),
),
GlobalGet(global_index) => {
- let idx = module.resolve_global_addr(*global_index);
- let global = store.get_global_val(idx as usize)?;
+ let global = store.get_global_val(module.resolve_global_addr(*global_index))?;
stack.values.push(global);
}
GlobalSet(global_index) => {
let idx = module.resolve_global_addr(*global_index);
- store.set_global_val(idx as usize, stack.values.pop()?)?;
+ store.set_global_val(idx, stack.values.pop()?)?;
}
I32Const(val) => stack.values.push((*val).into()),
@@ -344,7 +339,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
}
let mem_idx = module.resolve_mem_addr(*addr);
- let mem = store.get_mem(mem_idx as usize)?;
+ let mem = store.get_mem(mem_idx)?;
stack.values.push((mem.borrow().page_count() as i32).into());
}
@@ -353,16 +348,11 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
return Err(Error::UnsupportedFeature("memory.grow with byte != 0".to_string()));
}
- let mem_idx = module.resolve_mem_addr(*addr);
- let mem = store.get_mem(mem_idx as usize)?;
-
- let (res, prev_size) = {
- let mut mem = mem.borrow_mut();
- let prev_size = mem.page_count() as i32;
- (mem.grow(stack.values.pop_t::<i32>()?), prev_size)
- };
+ let mem = store.get_mem(module.resolve_mem_addr(*addr))?;
+ let mut mem = mem.borrow_mut();
+ let prev_size = mem.page_count() as i32;
- match res {
+ match mem.grow(stack.values.pop_t::<i32>()?) {
Some(_) => stack.values.push(prev_size.into()),
None => stack.values.push((-1).into()),
}
@@ -374,7 +364,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
let src: i32 = stack.values.pop()?.into();
let dst: i32 = stack.values.pop()?.into();
- let mem = store.get_mem(module.resolve_mem_addr(*from) as usize)?;
+ let mem = store.get_mem(module.resolve_mem_addr(*from))?;
let mut mem = mem.borrow_mut();
if from == to {
@@ -382,7 +372,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
mem.copy_within(dst as usize, src as usize, size as usize)?;
} else {
// copy between two memories
- let mem2 = store.get_mem(module.resolve_mem_addr(*to) as usize)?;
+ let mem2 = store.get_mem(module.resolve_mem_addr(*to))?;
let mut mem2 = mem2.borrow_mut();
mem2.copy_from_slice(dst as usize, mem.load(src as usize, size as usize)?)?;
}
@@ -393,9 +383,8 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
let val: i32 = stack.values.pop()?.into();
let dst: i32 = stack.values.pop()?.into();
- let mem = store.get_mem(module.resolve_mem_addr(*addr) as usize)?;
- let mut mem = mem.borrow_mut();
- mem.fill(dst as usize, size as usize, val as u8)?;
+ let mem = store.get_mem(module.resolve_mem_addr(*addr))?;
+ mem.borrow_mut().fill(dst as usize, size as usize, val as u8)?;
}
MemoryInit(data_index, mem_index) => {
@@ -403,7 +392,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
let offset = stack.values.pop_t::<i32>()? as usize;
let dst = stack.values.pop_t::<i32>()? as usize;
- let data = match &store.get_data(module.resolve_data_addr(*data_index) as usize)?.data {
+ let data = match &store.get_data(module.resolve_data_addr(*data_index))?.data {
Some(data) => data,
None => return Err(Trap::MemoryOutOfBounds { offset: 0, len: 0, max: 0 }.into()),
};
@@ -412,18 +401,11 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
return Err(Trap::MemoryOutOfBounds { offset, len: size, max: data.len() }.into());
}
- let mem = store.get_mem(module.resolve_mem_addr(*mem_index) as usize)?;
- let mut mem = mem.borrow_mut();
-
- // mem.store checks bounds
- mem.store(dst, size, &data[offset..(offset + size)])?;
+ let mem = store.get_mem(module.resolve_mem_addr(*mem_index))?;
+ mem.borrow_mut().store(dst, size, &data[offset..(offset + size)])?; // mem.store checks bounds
}
- DataDrop(data_index) => {
- let data_idx = module.resolve_data_addr(*data_index);
- let data = store.get_data_mut(data_idx as usize)?;
- data.drop();
- }
+ DataDrop(data_index) => store.get_data_mut(module.resolve_data_addr(*data_index))?.drop(),
I32Store { mem_addr, offset } => mem_store!(i32, (mem_addr, offset), stack, store, module),
I64Store { mem_addr, offset } => mem_store!(i64, (mem_addr, offset), stack, store, module),
@@ -600,32 +582,28 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
TableGet(table_index) => {
let table_idx = module.resolve_table_addr(*table_index);
- let table = store.get_table(table_idx as usize)?;
- let idx = stack.values.pop_t::<i32>()? as usize;
+ let table = store.get_table(table_idx)?;
+ let idx = stack.values.pop_t::<u32>()?;
let v = table.borrow().get_wasm_val(idx)?;
stack.values.push(v.into());
}
TableSet(table_index) => {
let table_idx = module.resolve_table_addr(*table_index);
- let table = store.get_table(table_idx as usize)?;
+ let table = store.get_table(table_idx)?;
let val = stack.values.pop_t::<u32>()?;
- let idx = stack.values.pop_t::<u32>()? as usize;
+ let idx = stack.values.pop_t::<u32>()?;
table.borrow_mut().set(idx, val)?;
}
TableSize(table_index) => {
- let table_idx = module.resolve_table_addr(*table_index);
- let table = store.get_table(table_idx as usize)?;
+ let table = store.get_table(module.resolve_table_addr(*table_index))?;
stack.values.push(table.borrow().size().into());
}
TableInit(table_index, elem_index) => {
- let table_idx = module.resolve_table_addr(*table_index);
- let table = store.get_table(table_idx as usize)?;
-
- let elem_idx = module.resolve_elem_addr(*elem_index);
- let elem = store.get_elem(elem_idx as usize)?;
+ let table = store.get_table(module.resolve_table_addr(*table_index))?;
+ let elem = store.get_elem(module.resolve_elem_addr(*elem_index))?;
if let ElementKind::Passive = elem.kind {
return Err(Trap::TableOutOfBounds { offset: 0, len: 0, max: 0 }.into());
@@ -648,62 +626,41 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
I64TruncSatF64U => arithmetic_single!(trunc, f64, u64, stack),
// custom instructions
- LocalGet2(a, b) => {
- stack.values.extend_from_slice(&[cf.get_local(*a as usize), cf.get_local(*b as usize)]);
- }
- LocalGet3(a, b, c) => {
- stack.values.extend_from_slice(&[
- cf.get_local(*a as usize),
- cf.get_local(*b as usize),
- cf.get_local(*c as usize),
- ]);
- }
- // LocalGet4(a, b, c, d) => {
- // stack.values.extend_from_slice(&[
- // cf.get_local(*a as usize),
- // cf.get_local(*b as usize),
- // cf.get_local(*c as usize),
- // cf.get_local(*d as usize),
- // ]);
- // }
+ LocalGet2(a, b) => stack.values.extend_from_slice(&[cf.get_local(*a), cf.get_local(*b)]),
+ LocalGet3(a, b, c) => stack.values.extend_from_slice(&[cf.get_local(*a), cf.get_local(*b), cf.get_local(*c)]),
+
LocalTeeGet(a, b) => {
- #[inline]
- fn local_tee_get(cf: &mut CallFrame, stack: &mut Stack, a: u32, b: u32) -> Result<()> {
- let last = *stack
- .values
- .last()
- .expect("localtee: stack is empty. this should have been validated by the parser");
- cf.set_local(a as usize, last);
- stack.values.push(cf.get_local(b as usize));
- Ok(())
+ #[inline(always)]
+ fn local_tee_get(cf: &mut CallFrame, stack: &mut Stack, a: u32, b: u32) {
+ let last = match stack.values.last() {
+ Ok(v) => v,
+ Err(_) => unreachable!("localtee: stack is empty. this should have been validated by the parser"),
+ };
+
+ cf.set_local(a, *last);
+ stack.values.push(cf.get_local(b));
}
- local_tee_get(cf, stack, *a, *b)?;
- }
- LocalGetSet(a, b) => {
- let a = cf.get_local(*a as usize);
- cf.set_local(*b as usize, a);
+
+ local_tee_get(cf, stack, *a, *b);
}
+ LocalGetSet(a, b) => cf.set_local(*b, cf.get_local(*a)),
I64XorConstRotl(rotate_by) => {
- let val = stack.values.pop_t::<i64>()?;
- let mask = stack.values.pop_t::<i64>()?;
+ let val: i64 = stack.values.pop()?.into();
+ let mask: i64 = stack.values.pop()?.into();
let res = val ^ mask;
stack.values.push(res.rotate_left(*rotate_by as u32).into());
}
-
I32LocalGetConstAdd(local, val) => {
- let local: i32 = cf.get_local(*local as usize).into();
+ let local: i32 = cf.get_local(*local).into();
stack.values.push((local + *val).into());
}
-
- I32StoreLocal { local, consti32, offset, mem_addr } => {
+ I32StoreLocal { local, const_i32: consti32, offset, mem_addr } => {
let (mem_addr, offset) = (*mem_addr as u32, *offset as u32);
- let mem = store.get_mem(module.resolve_mem_addr(mem_addr) as usize)?;
- let val = consti32;
- let val = val.to_le_bytes();
- let addr: u64 = cf.get_local(*local as usize).into();
+ let mem = store.get_mem(module.resolve_mem_addr(mem_addr))?;
+ let val = consti32.to_le_bytes();
+ let addr: u64 = cf.get_local(*local).into();
mem.borrow_mut().store((offset as u64 + addr) as usize, val.len(), &val)?;
}
-
i => {
cold();
log::error!("unimplemented instruction: {:?}", i);
diff --git a/crates/tinywasm/src/runtime/stack.rs b/crates/tinywasm/src/runtime/stack.rs
index 3db3c4b..a64b234 100644
--- a/crates/tinywasm/src/runtime/stack.rs
+++ b/crates/tinywasm/src/runtime/stack.rs
@@ -2,7 +2,7 @@ mod block_stack;
mod call_stack;
mod value_stack;
-use self::{call_stack::CallStack, value_stack::ValueStack};
+pub(crate) use self::{call_stack::CallStack, value_stack::ValueStack};
pub(crate) use block_stack::{BlockFrame, BlockStack, BlockType};
pub(crate) use call_stack::CallFrame;
@@ -16,6 +16,6 @@ pub struct Stack {
impl Stack {
pub(crate) fn new(call_frame: CallFrame) -> Self {
- Self { values: ValueStack::default(), blocks: BlockStack::default(), call_stack: CallStack::new(call_frame) }
+ Self { values: ValueStack::default(), blocks: BlockStack::new(), call_stack: CallStack::new(call_frame) }
}
}
diff --git a/crates/tinywasm/src/runtime/stack/block_stack.rs b/crates/tinywasm/src/runtime/stack/block_stack.rs
index 719dc00..2b38cb9 100644
--- a/crates/tinywasm/src/runtime/stack/block_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/block_stack.rs
@@ -2,10 +2,16 @@ use crate::{unlikely, Error, ModuleInstance, Result};
use alloc::vec::Vec;
use tinywasm_types::BlockArgs;
-#[derive(Debug, Clone, Default)]
-pub(crate) struct BlockStack(Vec<BlockFrame>); // TODO: maybe Box<[LabelFrame]> by analyzing the label count when parsing the module?
+#[derive(Debug, Clone)]
+pub(crate) struct BlockStack(Vec<BlockFrame>);
impl BlockStack {
+ pub(crate) fn new() -> Self {
+ let mut vec = Vec::new();
+ vec.reserve(128); // gives a slight performance over with_capacity
+ Self(vec)
+ }
+
#[inline]
pub(crate) fn len(&self) -> usize {
self.0.len()
diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs
index c242b74..d436657 100644
--- a/crates/tinywasm/src/runtime/stack/call_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/call_stack.rs
@@ -1,5 +1,5 @@
use alloc::{boxed::Box, rc::Rc, vec::Vec};
-use tinywasm_types::{Instruction, ModuleInstanceAddr, WasmFunction};
+use tinywasm_types::{Instruction, LocalAddr, ModuleInstanceAddr, WasmFunction};
use crate::runtime::{BlockType, RawWasmValue};
use crate::unlikely;
@@ -136,22 +136,17 @@ impl CallFrame {
}
#[inline]
- pub(crate) fn set_local(&mut self, local_index: usize, value: RawWasmValue) {
- self.locals[local_index] = value;
+ pub(crate) fn set_local(&mut self, local_index: LocalAddr, value: RawWasmValue) {
+ self.locals[local_index as usize] = value;
}
#[inline]
- pub(crate) fn get_local(&self, local_index: usize) -> RawWasmValue {
- self.locals[local_index]
+ pub(crate) fn get_local(&self, local_index: LocalAddr) -> RawWasmValue {
+ self.locals[local_index as usize]
}
#[inline(always)]
pub(crate) fn instructions(&self) -> &[Instruction] {
&self.func_instance.0.instructions
}
-
- #[inline(always)]
- pub(crate) fn current_instruction(&self) -> &Instruction {
- &self.func_instance.0.instructions[self.instr_ptr as usize]
- }
}
diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index 2fa03e9..aa00a64 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -4,8 +4,7 @@ use crate::{cold, runtime::RawWasmValue, unlikely, Error, Result};
use alloc::vec::Vec;
use tinywasm_types::{ValType, WasmValue};
-pub(crate) const MIN_VALUE_STACK_SIZE: usize = 1024;
-// pub(crate) const MAX_VALUE_STACK_SIZE: usize = 1024 * 1024;
+pub(crate) const MIN_VALUE_STACK_SIZE: usize = 1024 * 128;
#[derive(Debug)]
pub(crate) struct ValueStack {
@@ -14,7 +13,9 @@ pub(crate) struct ValueStack {
impl Default for ValueStack {
fn default() -> Self {
- Self { stack: Vec::with_capacity(MIN_VALUE_STACK_SIZE) }
+ let mut vec = Vec::new();
+ vec.reserve(MIN_VALUE_STACK_SIZE); // gives a slight performance over with_capacity
+ Self { stack: vec }
}
}
@@ -85,7 +86,7 @@ impl ValueStack {
match self.stack.pop() {
Some(v) => Ok(v.into()),
None => {
- cold();
+ cold(); // 20+ performance improvement most of the time
Err(Error::ValueStackUnderflow)
}
}
@@ -104,8 +105,7 @@ impl ValueStack {
#[inline]
pub(crate) fn pop_params(&mut self, types: &[ValType]) -> Result<Vec<WasmValue>> {
- let res = self.pop_n_rev(types.len())?.zip(types.iter()).map(|(v, ty)| v.attach_type(*ty)).collect();
- Ok(res)
+ Ok(self.pop_n_rev(types.len())?.zip(types.iter()).map(|(v, ty)| v.attach_type(*ty)).collect())
}
#[inline]
diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs
index 2381657..55aa9fe 100644
--- a/crates/tinywasm/src/runtime/value.rs
+++ b/crates/tinywasm/src/runtime/value.rs
@@ -7,7 +7,6 @@ use tinywasm_types::{ValType, WasmValue};
///
/// See [`WasmValue`] for the public representation.
#[derive(Clone, Copy, Default, PartialEq, Eq)]
-// pub struct RawWasmValue([u8; 16]);
pub struct RawWasmValue([u8; 8]);
impl Debug for RawWasmValue {
@@ -29,23 +28,14 @@ impl RawWasmValue {
ValType::I64 => WasmValue::I64(self.into()),
ValType::F32 => WasmValue::F32(f32::from_bits(self.into())),
ValType::F64 => WasmValue::F64(f64::from_bits(self.into())),
- // ValType::V128 => WasmValue::V128(self.into()),
- ValType::RefExtern => {
- let val: i64 = self.into();
- if val < 0 {
- WasmValue::RefNull(ValType::RefExtern)
- } else {
- WasmValue::RefExtern(val as u32)
- }
- }
- ValType::RefFunc => {
- let val: i64 = self.into();
- if val < 0 {
- WasmValue::RefNull(ValType::RefFunc)
- } else {
- WasmValue::RefFunc(val as u32)
- }
- }
+ ValType::RefExtern => match i64::from(self) {
+ v if v < 0 => WasmValue::RefNull(ValType::RefExtern),
+ addr => WasmValue::RefExtern(addr as u32),
+ },
+ ValType::RefFunc => match i64::from(self) {
+ v if v < 0 => WasmValue::RefNull(ValType::RefFunc),
+ addr => WasmValue::RefFunc(addr as u32),
+ },
}
}
}
@@ -58,7 +48,6 @@ impl From<WasmValue> for RawWasmValue {
WasmValue::I64(i) => Self::from(i),
WasmValue::F32(i) => Self::from(i),
WasmValue::F64(i) => Self::from(i),
- // WasmValue::V128(i) => Self::from(i),
WasmValue::RefExtern(v) => Self::from(v as i64),
WasmValue::RefFunc(v) => Self::from(v as i64),
WasmValue::RefNull(_) => Self::from(-1i64),
@@ -88,24 +77,18 @@ macro_rules! impl_from_raw_wasm_value {
};
}
-type RawValue = u64;
-type RawValueRep = [u8; 8];
-
// This all looks like a lot of extra steps, but the compiler will optimize it all away.
-impl_from_raw_wasm_value!(i32, |x| x as RawValue, |x: RawValueRep| i32::from_ne_bytes(x[0..4].try_into().unwrap()));
-impl_from_raw_wasm_value!(i64, |x| x as RawValue, |x: RawValueRep| i64::from_ne_bytes(x[0..8].try_into().unwrap()));
-impl_from_raw_wasm_value!(f32, |x| f32::to_bits(x) as RawValue, |x: RawValueRep| f32::from_bits(u32::from_ne_bytes(
+impl_from_raw_wasm_value!(i32, |x| x as u64, |x: [u8; 8]| i32::from_ne_bytes(x[0..4].try_into().unwrap()));
+impl_from_raw_wasm_value!(i64, |x| x as u64, |x: [u8; 8]| i64::from_ne_bytes(x[0..8].try_into().unwrap()));
+impl_from_raw_wasm_value!(u8, |x| x as u64, |x: [u8; 8]| u8::from_ne_bytes(x[0..1].try_into().unwrap()));
+impl_from_raw_wasm_value!(u16, |x| x as u64, |x: [u8; 8]| u16::from_ne_bytes(x[0..2].try_into().unwrap()));
+impl_from_raw_wasm_value!(u32, |x| x as u64, |x: [u8; 8]| u32::from_ne_bytes(x[0..4].try_into().unwrap()));
+impl_from_raw_wasm_value!(u64, |x| x as u64, |x: [u8; 8]| u64::from_ne_bytes(x[0..8].try_into().unwrap()));
+impl_from_raw_wasm_value!(i8, |x| x as u64, |x: [u8; 8]| i8::from_ne_bytes(x[0..1].try_into().unwrap()));
+impl_from_raw_wasm_value!(i16, |x| x as u64, |x: [u8; 8]| i16::from_ne_bytes(x[0..2].try_into().unwrap()));
+impl_from_raw_wasm_value!(f32, |x| f32::to_bits(x) as u64, |x: [u8; 8]| f32::from_bits(u32::from_ne_bytes(
x[0..4].try_into().unwrap()
)));
-impl_from_raw_wasm_value!(f64, |x| f64::to_bits(x) as RawValue, |x: RawValueRep| f64::from_bits(u64::from_ne_bytes(
+impl_from_raw_wasm_value!(f64, |x| f64::to_bits(x) as u64, |x: [u8; 8]| f64::from_bits(u64::from_ne_bytes(
x[0..8].try_into().unwrap()
)));
-
-impl_from_raw_wasm_value!(u8, |x| x as RawValue, |x: RawValueRep| u8::from_ne_bytes(x[0..1].try_into().unwrap()));
-impl_from_raw_wasm_value!(u16, |x| x as RawValue, |x: RawValueRep| u16::from_ne_bytes(x[0..2].try_into().unwrap()));
-impl_from_raw_wasm_value!(u32, |x| x as RawValue, |x: RawValueRep| u32::from_ne_bytes(x[0..4].try_into().unwrap()));
-impl_from_raw_wasm_value!(u64, |x| x as RawValue, |x: RawValueRep| u64::from_ne_bytes(x[0..8].try_into().unwrap()));
-// impl_from_raw_wasm_value!(u128, |x| x, |x: RawValueRep| RawValue::from_ne_bytes(x));
-
-impl_from_raw_wasm_value!(i8, |x| x as RawValue, |x: RawValueRep| i8::from_ne_bytes(x[0..1].try_into().unwrap()));
-impl_from_raw_wasm_value!(i16, |x| x as RawValue, |x: RawValueRep| i16::from_ne_bytes(x[0..2].try_into().unwrap()));
diff --git a/crates/tinywasm/src/store/data.rs b/crates/tinywasm/src/store/data.rs
index efbb858..935e761 100644
--- a/crates/tinywasm/src/store/data.rs
+++ b/crates/tinywasm/src/store/data.rs
@@ -15,13 +15,7 @@ impl DataInstance {
Self { data, _owner: owner }
}
- pub(crate) fn drop(&mut self) -> Option<()> {
- match self.data {
- None => None,
- Some(_) => {
- let _ = self.data.take();
- Some(())
- }
- }
+ pub(crate) fn drop(&mut self) {
+ self.data.is_some().then(|| self.data.take());
}
}
diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs
index 1cdcff3..fddf3f4 100644
--- a/crates/tinywasm/src/store/mod.rs
+++ b/crates/tinywasm/src/store/mod.rs
@@ -123,56 +123,60 @@ impl Store {
/// Get the function at the actual index in the store
#[inline]
- pub(crate) fn get_func(&self, addr: usize) -> Result<&FunctionInstance> {
- self.data.funcs.get(addr).ok_or_else(|| Self::not_found_error("function"))
+ pub(crate) fn get_func(&self, addr: FuncAddr) -> Result<&FunctionInstance> {
+ self.data.funcs.get(addr as usize).ok_or_else(|| Self::not_found_error("function"))
}
/// Get the memory at the actual index in the store
#[inline]
- pub(crate) fn get_mem(&self, addr: usize) -> Result<&Rc<RefCell<MemoryInstance>>> {
- self.data.memories.get(addr).ok_or_else(|| Self::not_found_error("memory"))
+ pub(crate) fn get_mem(&self, addr: MemAddr) -> Result<&Rc<RefCell<MemoryInstance>>> {
+ self.data.memories.get(addr as usize).ok_or_else(|| Self::not_found_error("memory"))
}
/// Get the table at the actual index in the store
#[inline]
- pub(crate) fn get_table(&self, addr: usize) -> Result<&Rc<RefCell<TableInstance>>> {
- self.data.tables.get(addr).ok_or_else(|| Self::not_found_error("table"))
+ pub(crate) fn get_table(&self, addr: TableAddr) -> Result<&Rc<RefCell<TableInstance>>> {
+ self.data.tables.get(addr as usize).ok_or_else(|| Self::not_found_error("table"))
}
/// Get the data at the actual index in the store
#[inline]
- pub(crate) fn get_data(&self, addr: usize) -> Result<&DataInstance> {
- self.data.datas.get(addr).ok_or_else(|| Self::not_found_error("data"))
+ pub(crate) fn get_data(&self, addr: DataAddr) -> Result<&DataInstance> {
+ self.data.datas.get(addr as usize).ok_or_else(|| Self::not_found_error("data"))
}
/// Get the data at the actual index in the store
#[inline]
- pub(crate) fn get_data_mut(&mut self, addr: usize) -> Result<&mut DataInstance> {
- self.data.datas.get_mut(addr).ok_or_else(|| Self::not_found_error("data"))
+ pub(crate) fn get_data_mut(&mut self, addr: DataAddr) -> Result<&mut DataInstance> {
+ self.data.datas.get_mut(addr as usize).ok_or_else(|| Self::not_found_error("data"))
}
/// Get the element at the actual index in the store
#[inline]
- pub(crate) fn get_elem(&self, addr: usize) -> Result<&ElementInstance> {
- self.data.elements.get(addr).ok_or_else(|| Self::not_found_error("element"))
+ pub(crate) fn get_elem(&self, addr: ElemAddr) -> Result<&ElementInstance> {
+ self.data.elements.get(addr as usize).ok_or_else(|| Self::not_found_error("element"))
}
/// Get the global at the actual index in the store
#[inline]
- pub(crate) fn get_global(&self, addr: usize) -> Result<&Rc<RefCell<GlobalInstance>>> {
- self.data.globals.get(addr).ok_or_else(|| Self::not_found_error("global"))
+ pub(crate) fn get_global(&self, addr: GlobalAddr) -> Result<&Rc<RefCell<GlobalInstance>>> {
+ self.data.globals.get(addr as usize).ok_or_else(|| Self::not_found_error("global"))
}
/// Get the global at the actual index in the store
#[inline]
- pub fn get_global_val(&self, addr: usize) -> Result<RawWasmValue> {
- self.data.globals.get(addr).ok_or_else(|| Self::not_found_error("global")).map(|global| global.borrow().value)
+ pub fn get_global_val(&self, addr: MemAddr) -> Result<RawWasmValue> {
+ self.data
+ .globals
+ .get(addr as usize)
+ .ok_or_else(|| Self::not_found_error("global"))
+ .map(|global| global.borrow().value)
}
/// Set the global at the actual index in the store
#[inline]
- pub(crate) fn set_global_val(&mut self, addr: usize, value: RawWasmValue) -> Result<()> {
- let global = self.data.globals.get(addr).ok_or_else(|| Self::not_found_error("global"));
+ pub(crate) fn set_global_val(&mut self, addr: MemAddr, value: RawWasmValue) -> Result<()> {
+ let global = self.data.globals.get(addr as usize).ok_or_else(|| Self::not_found_error("global"));
global.map(|global| global.borrow_mut().value = value)
}
}
diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs
index 52c35f6..a094a14 100644
--- a/crates/tinywasm/src/store/table.rs
+++ b/crates/tinywasm/src/store/table.rs
@@ -20,7 +20,7 @@ impl TableInstance {
Self { elements: vec![TableElement::Uninitialized; kind.size_initial as usize], kind, _owner: owner }
}
- pub(crate) fn get_wasm_val(&self, addr: usize) -> Result<WasmValue> {
+ pub(crate) fn get_wasm_val(&self, addr: TableAddr) -> Result<WasmValue> {
let val = self.get(addr)?.addr();
Ok(match self.kind.element_type {
@@ -30,12 +30,13 @@ impl TableInstance {
})
}
- pub(crate) fn get(&self, addr: usize) -> Result<&TableElement> {
- self.elements.get(addr).ok_or_else(|| Error::Trap(Trap::UndefinedElement { index: addr }))
+ pub(crate) fn get(&self, addr: TableAddr) -> Result<&TableElement> {
+ self.elements.get(addr as usize).ok_or_else(|| Error::Trap(Trap::UndefinedElement { index: addr as usize }))
}
- pub(crate) fn set(&mut self, table_idx: usize, value: Addr) -> Result<()> {
- self.grow_to_fit(table_idx + 1).map(|_| self.elements[table_idx] = TableElement::Initialized(value))
+ pub(crate) fn set(&mut self, table_idx: TableAddr, value: Addr) -> Result<()> {
+ self.grow_to_fit(table_idx as usize + 1)
+ .map(|_| self.elements[table_idx as usize] = TableElement::Initialized(value))
}
pub(crate) fn grow_to_fit(&mut self, new_size: usize) -> Result<()> {
diff --git a/crates/tinywasm/tests/generated/mvp.csv b/crates/tinywasm/tests/generated/mvp.csv
index 10c2dbb..6cf7fea 100644
--- a/crates/tinywasm/tests/generated/mvp.csv
+++ b/crates/tinywasm/tests/generated/mvp.csv
@@ -7,3 +7,4 @@
0.4.1,20257,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":99,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":163,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.5.0,20272,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":156,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":98,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
0.6.0,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":98,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
+0.6.1,20278,0,[{"name":"address.wast","passed":260,"failed":0},{"name":"align.wast","passed":162,"failed":0},{"name":"binary-leb128.wast","passed":91,"failed":0},{"name":"binary.wast","passed":112,"failed":0},{"name":"block.wast","passed":223,"failed":0},{"name":"br.wast","passed":97,"failed":0},{"name":"br_if.wast","passed":118,"failed":0},{"name":"br_table.wast","passed":174,"failed":0},{"name":"call.wast","passed":91,"failed":0},{"name":"call_indirect.wast","passed":170,"failed":0},{"name":"comments.wast","passed":8,"failed":0},{"name":"const.wast","passed":778,"failed":0},{"name":"conversions.wast","passed":619,"failed":0},{"name":"custom.wast","passed":11,"failed":0},{"name":"data.wast","passed":61,"failed":0},{"name":"elem.wast","passed":98,"failed":0},{"name":"endianness.wast","passed":69,"failed":0},{"name":"exports.wast","passed":96,"failed":0},{"name":"f32.wast","passed":2514,"failed":0},{"name":"f32_bitwise.wast","passed":364,"failed":0},{"name":"f32_cmp.wast","passed":2407,"failed":0},{"name":"f64.wast","passed":2514,"failed":0},{"name":"f64_bitwise.wast","passed":364,"failed":0},{"name":"f64_cmp.wast","passed":2407,"failed":0},{"name":"fac.wast","passed":8,"failed":0},{"name":"float_exprs.wast","passed":900,"failed":0},{"name":"float_literals.wast","passed":179,"failed":0},{"name":"float_memory.wast","passed":90,"failed":0},{"name":"float_misc.wast","passed":441,"failed":0},{"name":"forward.wast","passed":5,"failed":0},{"name":"func.wast","passed":172,"failed":0},{"name":"func_ptrs.wast","passed":36,"failed":0},{"name":"global.wast","passed":110,"failed":0},{"name":"i32.wast","passed":460,"failed":0},{"name":"i64.wast","passed":416,"failed":0},{"name":"if.wast","passed":241,"failed":0},{"name":"imports.wast","passed":186,"failed":0},{"name":"inline-module.wast","passed":1,"failed":0},{"name":"int_exprs.wast","passed":108,"failed":0},{"name":"int_literals.wast","passed":51,"failed":0},{"name":"labels.wast","passed":29,"failed":0},{"name":"left-to-right.wast","passed":96,"failed":0},{"name":"linking.wast","passed":132,"failed":0},{"name":"load.wast","passed":97,"failed":0},{"name":"local_get.wast","passed":36,"failed":0},{"name":"local_set.wast","passed":53,"failed":0},{"name":"local_tee.wast","passed":97,"failed":0},{"name":"loop.wast","passed":120,"failed":0},{"name":"memory.wast","passed":79,"failed":0},{"name":"memory_grow.wast","passed":96,"failed":0},{"name":"memory_redundancy.wast","passed":8,"failed":0},{"name":"memory_size.wast","passed":42,"failed":0},{"name":"memory_trap.wast","passed":182,"failed":0},{"name":"names.wast","passed":486,"failed":0},{"name":"nop.wast","passed":88,"failed":0},{"name":"return.wast","passed":84,"failed":0},{"name":"select.wast","passed":148,"failed":0},{"name":"skip-stack-guard-page.wast","passed":11,"failed":0},{"name":"stack.wast","passed":7,"failed":0},{"name":"start.wast","passed":20,"failed":0},{"name":"store.wast","passed":68,"failed":0},{"name":"switch.wast","passed":28,"failed":0},{"name":"table.wast","passed":19,"failed":0},{"name":"token.wast","passed":58,"failed":0},{"name":"traps.wast","passed":36,"failed":0},{"name":"type.wast","passed":3,"failed":0},{"name":"unreachable.wast","passed":64,"failed":0},{"name":"unreached-invalid.wast","passed":118,"failed":0},{"name":"unreached-valid.wast","passed":7,"failed":0},{"name":"unwind.wast","passed":50,"failed":0},{"name":"utf8-custom-section-id.wast","passed":176,"failed":0},{"name":"utf8-import-field.wast","passed":176,"failed":0},{"name":"utf8-import-module.wast","passed":176,"failed":0},{"name":"utf8-invalid-encoding.wast","passed":176,"failed":0}]
diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs
index aed23bd..1de633f 100644
--- a/crates/tinywasm/tests/testsuite/run.rs
+++ b/crates/tinywasm/tests/testsuite/run.rs
@@ -408,7 +408,7 @@ impl TestSuite {
let module_global = match match module.export_addr(global) {
Some(ExternVal::Global(addr)) => {
- store.get_global_val(addr as usize).map_err(|_| eyre!("failed to get global"))
+ store.get_global_val(addr).map_err(|_| eyre!("failed to get global"))
}
_ => Err(eyre!("no module to get global from")),
} {
diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs
index fc6fba2..96e8810 100644
--- a/crates/types/src/instructions.rs
+++ b/crates/types/src/instructions.rs
@@ -91,7 +91,7 @@ pub enum Instruction {
// LocalGet + I32Const + I32Store => I32LocalGetConstStore + I32Const
// Also common, helps us skip the stack entirely.
// Has to be followed by an I32Const instruction
- I32StoreLocal { local: LocalAddr, consti32: i32, offset: u32, mem_addr: u8 },
+ I32StoreLocal { local: LocalAddr, const_i32: i32, offset: u32, mem_addr: u8 },
// I64Xor + I64Const + I64RotL
// Commonly used by a few crypto libraries
@@ -103,12 +103,6 @@ pub enum Instruction {
LocalGet3(LocalAddr, LocalAddr, LocalAddr),
LocalGetSet(LocalAddr, LocalAddr),
- // Not implemented yet
- // I32AddConst(i32),
- // I32SubConst(i32),
- // I64AddConst(i64),
- // I64SubConst(i64),
-
// Control Instructions
// See <https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions>
Unreachable,
diff --git a/examples/rust/analyze.py b/examples/rust/analyze.py
index a450a1a..a134a00 100644
--- a/examples/rust/analyze.py
+++ b/examples/rust/analyze.py
@@ -13,17 +13,17 @@ if len(sys.argv) < 2:
file_path = sys.argv[1]
# Regex to match WASM operators, adjust as necessary
-operator_pattern = re.compile(r'\b[a-z0-9_]+\.[a-z0-9_]+\b')
+operator_pattern = re.compile(r"\b[a-z0-9_]+\.[a-z0-9_]+\b")
# Read the file
-with open(file_path, 'r') as file:
+with open(file_path, "r") as file:
content = file.read()
# Find all operators
operators = operator_pattern.findall(content)
# Generate sequences of three consecutive operators
-sequences = [' '.join(operators[i:i+seq_len]) for i in range(len(operators) - 2)]
+sequences = [" ".join(operators[i : i + seq_len]) for i in range(len(operators) - 2)]
# Count occurrences of each sequence
sequence_counts = Counter(sequences)