summaryrefslogtreecommitdiff
path: root/ARCHITECTURE.md
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-03-06 13:39:06 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-03-06 13:39:06 +0100
commitc50bae752f3e788faf66b376d065374cc4085931 (patch)
treeb022bb832442b1687840113cd294031cfc7cc6db /ARCHITECTURE.md
parentf5a16aa930ba94ba0473969d1aec27bc31c4ef96 (diff)
docs: update readme
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'ARCHITECTURE.md')
-rw-r--r--ARCHITECTURE.md22
1 files changed, 10 insertions, 12 deletions
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index d3816d0..7aaa99c 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -3,26 +3,24 @@
TinyWasm follows the general Runtime Structure described in the [WebAssembly Specification](https://webassembly.github.io/spec/core/exec/runtime.html).
Some key differences are:
-- Values are stored without their type, (as `u64`), and the type is inferred from the instruction that uses them. This is possible because the instructions are validated before execution and the type of each value can be inferred from the instruction.
-- TinyWasm has a explicit stack for values, labels and frames. This is mostly for simplicity in the implementation, but also allows for some optimizations.
-- Floats always use a canonical NaN representation, the spec allows for multiple NaN representations.
-- TinyWasm uses a custom bytecode format (see [Bytecode Format](#bytecode-format) for more details)
-- Global state in the `Store` can be addressed from module instances other than the owning module. This is to allow more efficient access to imports and exports. Ownership is still enforced implicitly by requiring a reference to the instance to access it which can not be changed using the WebAssembly instructions.
-- The `Store` is not thread-safe. This is to allow for more efficient access to the `Store` and its contents. When later adding support for threads, a `Mutex` can be used to make it thread-safe but the overhead of requiring a lock for every access is not necessary for single-threaded applications.
-- TinyWasm is architectured to allow for a JIT compiler to be added later. Functions are stored as FunctionInstances which can contain either a `WasmFunction` or a `HostFunction`. A third variant `JitFunction` could be added later to store a pointer to the compiled function. This would allow for the JIT to be used transparently without changing the rest of the runtime.
-- TinyWasm is designed to be used in `no_std` environments. The `std` feature is enabled by default, but can be disabled to remove the dependency on `std` and `std::io`. This is done by disabling the `std` and `parser` features. The `logging` feature can also be disabled to remove the dependency on `log`. This is not recommended, since `libm` is not as performant as the compiler's math intrinsics, especially on wasm32 targets, but can be useful for resource-constrained devices or other environments where `std` is not available such as OS kernels.
-- Call Frames are executed in a loop instead of recursively. This allows the use of a single stack for all frames and makes it easier to pause execution and resume it later, or to step through the code one instruction at a time.
-- While other interpreters convert `locals` to be register-based when parsing the function body, TinyWasm keeps them in a stack. This is mostly for simplicity in the implementation, but performance is still comparable or better than other interpreters.
+- **Type Storage**: Types are inferred from usage context rather than stored explicitly, with all values held as `u64`.
+- **Stack Design**: Implements a specific stack for values, labels, and frames to simplify the implementation and enable optimizations.
+- **Bytecode Format**: Adopts a custom bytecode format to reduce memory usage and improve performance by allowing direct execution without the need for decoding.
+- **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.
+- **Non-thread-safe Store**: Designed for efficiency in single-threaded applications.
+- **JIT Compilation Support**: Prepares for JIT compiler integration with function instances designed to accommodate `WasmFunction`, `HostFunction`, or future `JitFunction`.
+- **`no_std` Environment Support**: Offers compatibility with `no_std` environments by allowing disabling of `std` feature
+- **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.
## Bytecode Format
To improve performance and reduce code size, instructions are encoded as enum variants instead of opcodes.
-This allows preprocessing the bytecode into a more compact 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
+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
for more details which inspired this design.
Some instructions are split into multiple variants to reduce the size of the enum (e.g. `br_table` and `br_label`).
Additionally, label instructions contain offsets relative to the current instruction to make branching faster and easier to implement.
-Also, `End` instructions are split into `End` and `EndBlock`.
+Also, `End` instructions are split into `End` and `EndBlock`. Others are also combined, especially in cases where the stack can be skipped.
See [instructions.rs](./crates/types/src/instructions.rs) for the full list of instructions.