|
1 | 1 | # TinyWasm's Architecture |
2 | 2 |
|
3 | 3 | TinyWasm follows the general Runtime Structure described in the [WebAssembly Specification](https://webassembly.github.io/spec/core/exec/runtime.html). |
4 | | -Some key differences are: |
5 | 4 |
|
6 | | -- **Type Storage**: Types are inferred from usage context rather than stored explicitly, with all values held as `u64`. |
7 | | -- **Stack Design**: Implements a specific stack for values, labels, and frames to simplify the implementation and enable optimizations. |
8 | | -- **Bytecode Format**: Adopts a custom bytecode format to reduce memory usage and improve performance by allowing direct execution without the need for decoding. |
9 | | -- **Global State Access**: Allows cross-module access to the `Store`'s global state, optimizing imports and exports access. Access requires a module instance reference, maintaining implicit ownership through a reference count. |
10 | | -- **Non-thread-safe Store**: Designed for efficiency in single-threaded applications. |
11 | | -- **JIT Compilation Support**: Prepares for JIT compiler integration with function instances designed to accommodate `WasmFunction`, `HostFunction`, or future `JitFunction`. |
12 | | -- **`no_std` Environment Support**: Offers compatibility with `no_std` environments by allowing disabling of `std` feature |
13 | | -- **Call Frame Execution**: Executes call frames in a single loop rather than recursively, using a single stack for all frames, facilitating easier pause, resume, and step-through. |
| 5 | +Key runtime layout: |
14 | 6 |
|
15 | | -## Bytecode Format |
| 7 | +- Values are stored in four fixed-capacity typed stacks: `stack_32` (`i32`/`f32`), `stack_64` (`i64`/`f64`), `stack_128` (`v128`), and `stack_ref` (`funcref`/`externref`). |
| 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. |
16 | 12 |
|
17 | | -To improve performance and reduce code size, instructions are encoded as enum variants instead of opcodes. |
18 | | -This allows preprocessing the bytecode into a more memory aligned format, which can be loaded directly into memory and executed without decoding later. This can skip the decoding step entirely on resource-constrained devices where memory is limited. See this [blog post](https://wasmer.io/posts/improving-with-zero-copy-deserialization) by Wasmer |
19 | | -for more details which inspired this design. |
| 13 | +## Precompiled Modules |
20 | 14 |
|
21 | | -Some instructions are split into multiple variants to reduce the size of the enum (e.g. `br_table` and `br_label`). |
22 | | -Additionally, label instructions contain offsets relative to the current instruction to make branching faster and easier to implement. |
23 | | -Also, `End` instructions are split into `End` and `EndBlock`. Others are also combined, especially in cases where the stack can be skipped. |
| 15 | +`TinyWasmModule` 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. |
24 | 17 |
|
25 | | -See [instructions.rs](./crates/types/src/instructions.rs) for the full list of instructions. |
| 18 | +See: |
26 | 19 |
|
27 | | -This is a area that can still be improved. While being able to load pre-processes bytecode directly into memory is nice, in-place decoding could achieve similar speeds, see [A fast in-place interpreter for WebAssembly](https://arxiv.org/abs/2205.01183). |
| 20 | +- [visit.rs](./crates/parser/src/visit.rs) |
| 21 | +- [instructions.rs](./crates/types/src/instructions.rs) |
| 22 | +- [value_stack.rs](./crates/tinywasm/src/interpreter/stack/value_stack.rs) |
| 23 | +- [call_stack.rs](./crates/tinywasm/src/interpreter/stack/call_stack.rs) |
0 commit comments