You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TinyWasm follows the general Runtime Structure described in the [WebAssembly Specification](https://webassembly.github.io/spec/core/exec/runtime.html).
3
+
TinyWasm follows the general runtime model described in the [WebAssembly specification](https://webassembly.github.io/spec/core/exec/runtime.html), but lowers validated WebAssembly into a compact internal instruction format before execution.
4
4
5
-
Key runtime layout:
5
+
## Runtime Layout
6
6
7
-
- Values are stored in four fixed-capacity typed stacks: `stack_32` (`i32`/`f32`/`funcref`/`externref`), `stack_64` (`i64`/`f64`), `stack_128` (`v128`)
8
-
- Locals are allocated in those value stacks. Each `CallFrame` stores `locals_base`, and local ops index from that base.
9
-
- Calls use a separate fixed-capacity `CallStack` of `CallFrame`s.
10
-
- Structured control (`block`/`loop`/`if`/`br*`) is lowered during parsing to jump-oriented instructions: `Jump`, `JumpIfZero`, `BranchTable*`, `DropKeep*`, and `Return`.
11
-
- The interpreter executes this lowered bytecode in a single iterative loop.
7
+
- Values are stored in untyped stacks:
8
+
-`stack_32` for `i32`, `f32`, `funcref`, and `externref`
9
+
-`stack_64` for `i64` and `f64`
10
+
-`stack_128` for `v128`
11
+
- Locals are stored directly in the value stacks. Each `CallFrame` stores a `locals_base`, and local instructions index from that base.
12
+
- Structured control flow (`block`, `loop`, `if`, `br*`) is lowered during parsing to jump-oriented internal instructions such as `Jump`, `JumpIfZero`, `BranchTable*`, `DropKeep*`, and `Return`.
13
+
- Execution is a single iterative interpreter loop over the lowered instruction stream.
12
14
13
-
## Precompiled Modules
15
+
## Internal Bytecode
14
16
15
-
Modules can be serialized to `.twasm` (`serialize_twasm`) and loaded later (`from_twasm`).
16
-
This allows deployments that execute precompiled modules without enabling the parser in the runtime binary.
17
+
TinyWasm does not interpret WebAssembly instructions directly. During parsing and validation, WebAssembly is translated into TinyWasm's internal bytecode format.
17
18
18
-
See:
19
+
This internal representation is designed to make execution simpler and cheaper:
- structured control flow is resolved ahead of time
22
+
- stack effects are made explicit
23
+
- common instruction sequences can be fused into superinstructions
24
+
- modules can optionally be serialized as `.twasm` for reuse
25
+
26
+
## Optimizer
27
+
28
+
During parsing, a peephole optimizer (`optimize.rs`) fuses common instruction sequences into superinstructions. These reduce interpreter dispatch overhead by combining multiple logical operations into one internal instruction.
Linear memory is implemented through the `LinearMemory` trait. The backend is selected with `engine::Config::with_memory_backend()`.
40
+
41
+
Available backends:
42
+
43
+
-`VecMemory` - contiguous `Vec<u8>` backing; the default backend.
44
+
-`PagedMemory` - chunk-based allocation, useful when growing memory without reallocating one large buffer.
45
+
-`LazyLinearMemory` - wraps another backend and allocates memory on first access.
46
+
- Custom backends through `MemoryBackend::custom()`.
47
+
48
+
## Future Experiments
49
+
50
+
TinyWasm's interpreter is intentionally simple today: validated WebAssembly is lowered to internal instructions, optimized with peephole fusion, and executed by an iterative dispatch loop.
51
+
52
+
Future work may explore additional dispatch and code-generation strategies, including Rust's experimental `loop_match` state-machine work, explicit tail calls, more aggressive superinstruction fusion, top-of-stack register allocation, or even optional JIT compilation.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+46-51Lines changed: 46 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,67 +7,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
This release is a major runtime and API rework. It adds support for several newer WebAssembly proposals, introduces the new `Engine` configuration API, rewrites large parts of execution and validation, and changes the internal `twasm` archive format. Benchmarks in the repository currently show roughly 30-90% improvement over 0.8.0 depending on workload and execution mode.
11
+
10
12
### Added
11
13
12
14
- Support for the `custom_page_sizes` proposal ([#22](https://github.com/explodingcamera/tinywasm/pull/22) by [@danielstuart14](https://github.com/danielstuart14))
13
-
- Support for the `tail_call` proposal
14
-
- Support for the `memory64` proposal
15
-
- Support for the `simd` proposal
16
-
- Support for the `relaxed_simd` proposal
17
-
- Support for the `wide_arithmetic` proposal
15
+
- Support for the `tail_call`, `memory64`, `simd`, `relaxed_simd`, `wide_arithmetic`, and `extended_const` proposals ([#37](https://github.com/explodingcamera/tinywasm/pull/37), [#38](https://github.com/explodingcamera/tinywasm/pull/38), [#39](https://github.com/explodingcamera/tinywasm/pull/39))
16
+
- Parse-only support for the `annotations` proposal
18
17
- New `Engine` API (`tinywasm::Engine` and `engine::Config`) for runtime configuration
19
-
- Resumable function execution with fuel/time-budget APIs (`call_resumable`, `resume_with_fuel`, `resume_with_time_budget`, `ExecProgress`)
18
+
- Resumable execution APIs: `call_resumable`, `resume_with_fuel`, `resume_with_time_budget`, and `ExecProgress`
20
19
- Host-function fuel APIs: `FuncContext::charge_fuel` and `FuncContext::remaining_fuel`
21
-
-`engine::FuelPolicy` and `engine::Config::fuel_policy` for fuel accounting behavior
22
-
- New `canonicalize_nans` feature flag to enable canonicalizing NaN values in the `f32`, `f64`, and `v128` types
- handle-based runtime objects with explicit store access: `Memory`, `Table`, `Global`, `Function`
20
+
-`engine::Config` support for fuel policy, stack sizing, memory backend selection, and trap-on-OOM behavior
21
+
- New feature flags: `canonicalize-nans`, `simd-x86`, `guest-debug`, `debug`, and `parallel-parser`
22
+
- Top-level parser re-exports behind the `parser` feature: `parse_bytes`, `parse_file`, and `parse_stream`
30
23
31
24
### Changed
32
25
33
-
- Locals are now stored in the typed value stacks instead of a separate locals structure
34
-
- Structured control flow is fully lowered to jump-oriented internal instructions during parsing
35
-
- Stack and call-stack limits can now be configured via `engine::Config`
36
-
- Module-internal by-index inspection APIs are now gated behind the `guest_debug` feature
37
-
38
-
### Breaking Changes
39
-
40
-
- New backwards-incompatible version of the twasm format based on `postcard` (thanks [@dragonnn](https://github.com/dragonnn))
41
-
-`RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs
42
-
-`Store::new` now takes an `Engine`; use `Store::default()` for default settings
43
-
-`Error`, `Trap`, and `LinkingError` are now `#[non_exhaustive]`
44
-
-`Trap` variant discriminant values changed (if you cast variants to integers)
45
-
-`tinywasm::interpreter` is no longer a public module; `InterpreterRuntime` and `TinyWasmValue` are no longer public API
46
-
-`FuncHandle::name` was removed
47
-
- Cargo feature `simd` was removed
48
-
- Cargo feature `tinywasm-parser` was renamed to`parser`
49
-
- Cargo feature `logging` was renamed to `log`
50
-
- Increased MSRV to 1.90
51
-
-`Error::ParseError` was renamed to `Error::Parser`, and `Error::Twasm` was added
52
-
-`ModuleInstance` export lookup APIs were renamed:
53
-
-`exported_func_untyped` -> `func_untyped`
54
-
-`exported_func` -> `func`
55
-
-`exported_memory` -> `memory`
56
-
-`ModuleInstance` mutable export lookup variants were removed:
57
-
-`memory_mut`, `table_mut`, `global_mut`
58
-
-`extern_item_mut`
59
-
-`FuncHandle` / `FuncHandleTyped` were renamed to `Function` / `FunctionTyped`
60
-
-`HostFunction::new` / `HostFunction::func` / `HostFunction::typed` now require `&mut Store`
61
-
-`Imports::link_module` now takes a `ModuleInstance` instead of a raw module instance id
62
-
-`func_typed` now validates the exact wasm signature at lookup time and fails immediately on mismatches
26
+
-`Store::new` now takes an `Engine`; use `Store::default()` for default settings.
27
+
-`ModuleInstance::func` now validates exact Wasm signatures at lookup time and fails immediately on mismatches.
28
+
- Stack and call-stack limits now come from `engine::Config`, and memory allocation is lazy until first access.
29
+
- Module-internal by-index inspection APIs are now gated behind `guest-debug`, and runtime `Debug` implementations are gated behind `debug`.
30
+
-`Module` is now re-exported directly from `tinywasm_types`; the `module` submodule was removed.
31
+
- MSRV increased to 1.95 and the crate now uses Rust 2024.
32
+
-`Error`, `Trap`, and `LinkingError` are now `#[non_exhaustive]`.
33
+
-`Trap` variant discriminants changed; do not rely on casting variants to integers.
34
+
-`HostFunction::new`, `HostFunction::func`, and `HostFunction::typed` now require `&mut Store`, and `Imports::link_module` now takes a `ModuleInstance` instead of a raw module instance id.
35
+
- Cargo features were renamed from `tinywasm-parser` to `parser` and from `logging` to `log`.
36
+
-`Error::ParseError` was renamed to `Error::Parser`, and `Error::Twasm` was added.
37
+
-`FuncHandle` and `FuncHandleTyped` were renamed to `Function` and `FunctionTyped`, and module export lookups moved from `exported_*` to `func_untyped`, `func`, and `memory`.
38
+
- The `twasm` archive format is now postcard-based and backwards-incompatible with previous versions (thanks [@dragonnn](https://github.com/dragonnn)).
39
+
- The interpreter was refactored around more superinstruction fusion, lower-overhead dispatch, typed-stack locals, jump-oriented lowering, and optional parallel parsing.
40
+
41
+
### Removed
42
+
43
+
- Cargo feature `simd` was removed.
44
+
-`RefNull` was removed and replaced with `FuncRef` and `ExternRef`.
45
+
-`tinywasm::interpreter` is no longer a public module.
46
+
-`InterpreterRuntime` and `TinyWasmValue` are no longer public API.
47
+
-`FuncHandle::name` was removed.
48
+
- Mutable `ModuleInstance` export lookup variants `memory_mut`, `table_mut`, `global_mut`, and `extern_item_mut` were removed.
63
49
64
50
### Fixed
65
51
66
-
- Fixed archive **no_std** support which was broken in the previous release, and added more tests to ensure it stays working
67
-
-`ModuleInstance::exported_memory` and `FuncContext::exported_memory` are now actually immutable ([#41](https://github.com/explodingcamera/tinywasm/pull/41))
68
-
- Check returns in untyped host functions ([#27](https://github.com/explodingcamera/tinywasm/pull/27)) (thanks [@WhaleKit](https://github.com/WhaleKit))
69
-
-`MemoryRefMut::copy_within(src, dst, len)` now follows its documented argument order
70
-
- Imported tables created with `Extern::table(ty, init)` now honor the provided init value
52
+
- Fixed archive **no_std** support, which was broken in the previous release, and added tests to ensure it stays working.
53
+
-`ModuleInstance::memory` and `FuncContext::memory` are now actually immutable ([#41](https://github.com/explodingcamera/tinywasm/pull/41)).
54
+
- Untyped host functions now check return values correctly ([#27](https://github.com/explodingcamera/tinywasm/pull/27)) by [@WhaleKit](https://github.com/WhaleKit).
55
+
-`MemoryRefMut::copy_within(src, dst, len)` now follows its documented argument order.
56
+
- Imported tables created with `Extern::table(ty, init)` now honor the provided init value.
57
+
- Fixed unchecked memory offsets causing issues on 32-bit platforms.
58
+
59
+
### Migration Notes
60
+
61
+
- Replace `Store::new()` with `Store::default()` for default settings, or `Store::new(Engine::new(config))` for custom runtime configuration.
62
+
- Rename the cargo features `tinywasm-parser` to `parser` and `logging` to `log`.
63
+
- Rename `FuncHandle` to `Function` and `FuncHandleTyped` to `FunctionTyped`.
64
+
- Rename module export lookups from `exported_*` methods to `func`, `func_untyped`, and `memory`.
65
+
- Regenerate any persisted `twasm` archives; the format is now postcard-based and not backwards compatible with earlier releases.
71
66
72
67
## [0.8.0] - 2024-08-29
73
68
@@ -184,7 +179,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
0 commit comments