diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 87 |
1 files changed, 61 insertions, 26 deletions
@@ -7,25 +7,42 @@ ## Why `tinywasm`? -- **Tiny**: TinyWasm is designed to be as small as possible without significantly compromising performance or functionality -- **Portable**: Runs anywhere Rust can target, supports `no_std`, and keeps external dependencies to a minimum. -- **Safe**: Written entirely safe Rust and designed to prevent untrusted code from crashing the runtime +- **Tiny**: Small by design, without significantly compromising performance or functionality. +- **Portable**: Runs anywhere Rust can target, supports `no_std`, has minimal dependencies, and can itself compile to WebAssembly. +- **Safe**: Written in safe Rust, with optional `unsafe` limited to the `simd-x86` feature. Its sandbox is designed to prevent untrusted Wasm from accessing host memory or escaping the runtime. -## Current Status +## Installation -`tinywasm` passes 100% of WebAssembly MVP and WebAssembly 2.0 tests from the [WebAssembly core testsuite](https://github.com/WebAssembly/testsuite) and is able to run most WebAssembly programs. Additionally, support for WebAssembly 3.0 is on the way. See the [Supported Proposals](#supported-proposals) section for more information. +```toml +[dependencies] +tinywasm = { git = "https://github.com/explodingcamera/tinywasm", branch = "next" } +``` ## Usage -See the [examples](./examples) directory and [documentation](https://docs.rs/tinywasm) for more information on how to use `tinywasm`. -For testing purposes, you can also use the `tinywasm-cli` tool: +```rust +use tinywasm::{ModuleInstance, Store}; + +// Load a module from bytes +let wasm = include_bytes!("../examples/wasm/add.wasm"); +let module = tinywasm::parse_bytes(wasm)?; + +// Create a new store +let mut store = Store::default(); -```sh -$ cargo install tinywasm-cli -$ tinywasm-cli --help +// Instantiate the module +let instance = ModuleInstance::instantiate(&mut store, &module, None)?; + +// Call an exported function with typed parameters +let func = instance.func::<(i32, i32), i32>(&mut store, "add")?; +let result = func.call(&mut store, (1, 2))?; + +assert_eq!(result, 3); ``` -## Feature Flags +See the [examples](./examples) directory and [documentation](https://docs.rs/tinywasm) for more information. + +## Cargo Features - **`std`**\ Enables the use of `std` and `std::io` for parsing from files and streams. This is enabled by default. @@ -34,13 +51,35 @@ $ tinywasm-cli --help - **`parser`**\ Enables the `tinywasm-parser` crate. This is enabled by default. - **`archive`**\ - Enables pre-parsing of archives. This is enabled by default. + Enables serialization/deserialization of compiled modules to the internal `twasm` bytecode format. This is enabled by default. +- **`canonicalize-nans`**\ + Canonicalizes NaN values to a single representation. This is enabled by default. +- **`debug`**\ + Derives `Debug` for runtime types. This is enabled by default. +- **`parallel-parser`**\ + Parallelizes function parsing and validation across threads (requires `std`). This is enabled by default. +- **`guest-debug`**\ + Exposes module-internal by-index inspection APIs (`*_by_index`). +- **`simd-x86`**\ + Enables x86-specific SIMD intrinsics for `i8x16_swizzle` and `i8x16_shuffle` (uses `unsafe` code). -With all these features disabled, `tinywasm` only depends on `core`, `alloc`, and `libm` and can be used in `no_std` environments. Since `libm` is not as performant as the compiler's math intrinsics, it is recommended to use the `std` feature if possible (at least [for now](https://github.com/rust-lang/rfcs/issues/2505)), especially on `wasm32` targets. +With default features disabled, `tinywasm` depends only on `core`, `alloc`, and `libm`[^libm], making it usable in `no_std + alloc` environments. + +Use `Engine` and `engine::Config` when you need non-default runtime settings such as fuel accounting, stack sizing, memory backend selection, or trap-on-OOM behavior. + +[^libm]: [rust-lang/rust#137578](https://github.com/rust-lang/rust/issues/137578) — tracking issue for `libm` as a fallback in `core`. + +## Current Status + +`tinywasm` passes the WebAssembly MVP and WebAssembly 2.0 core testsuites. WebAssembly 3.0 support is still in progress, and some newer proposal suites are tracked in-repo as experimental coverage rather than release guarantees; see [Supported Proposals](#supported-proposals) for details. + +TinyWasm also has its own internal bytecode format, `twasm`. WebAssembly modules can be compiled to `twasm`, which stores TinyWasm's validated and optimized instruction representation for faster loading and reuse. ## Safety -Untrusted WebAssembly code should not be able to crash the runtime or access memory outside of its sandbox. Unvalidated Wasm and untrusted, precompiled twasm bytecode is safe to run as well, but can lead to panics if the bytecode is malformed. In general, it is recommended to validate Wasm bytecode before running it, and to only run trusted twasm bytecode. +TinyWasm only uses safe Rust by default. The optional `simd-x86` feature enables x86-specific SIMD intrinsics and uses `unsafe` internally. WebAssembly input is validated by TinyWasm before execution and runs inside a sandbox: untrusted Wasm should not be able to access host memory, escape the sandbox, or cause undefined behavior in the runtime. + +The internal `twasm` bytecode format is not currently validated as an untrusted input format. Malformed `twasm` may panic, but should not compromise memory safety or allow sandbox escape. Only run trusted `twasm` bytecode, or generate it through TinyWasm from Wasm input. ## Supported Proposals @@ -53,16 +92,13 @@ Untrusted WebAssembly code should not be able to crash the runtime or access mem | [**Bulk Memory Operations**](https://github.com/WebAssembly/spec/blob/master/proposals/bulk-memory-operations/Overview.md) | 🟢 | 0.4.0 | | [**Reference Types**](https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md) | 🟢 | 0.7.0 | | [**Multi-memory**](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md) | 🟢 | 0.8.0 | -| [**Annotations**](https://github.com/WebAssembly/annotations/blob/main/proposals/annotations/Overview.md) | 🟢 | `next` | -| [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | `next` | -| [**Extended Const**](https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md) | 🟢 | `next` | -| [**Fixed-Width SIMD**](https://github.com/WebAssembly/simd/blob/main/proposals/simd/Overview.md) | 🟢 | `next` | -| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🟢 | `next` | -| [**Tail Call**](https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md) | 🟢 | `next` | -| [**Relaxed SIMD**](https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md) | 🟢 | `next` | -| [**Wide Arithmetic**](https://github.com/WebAssembly/wide-arithmetic/blob/main/proposals/wide-arithmetic/Overview.md) | 🟢 | `next` | -| [**Branch Hinting**](https://github.com/WebAssembly/branch-hinting/blob/master/proposals/branch-hinting/Overview.md) | 🌑 | - | -| [**Custom Descriptors**](https://github.com/WebAssembly/custom-descriptors/blob/main/proposals/custom-descriptors/Overview.md) | 🌑 | - | +| [**Custom Page Sizes**](https://github.com/WebAssembly/custom-page-sizes/blob/main/proposals/custom-page-sizes/Overview.md) | 🟢 | 0.9.0 | +| [**Extended Const**](https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md) | 🟢 | 0.9.0 | +| [**Fixed-Width SIMD**](https://github.com/WebAssembly/simd/blob/main/proposals/simd/Overview.md) | 🟢 | 0.9.0 | +| [**Memory64**](https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md) | 🟢 | 0.9.0 | +| [**Tail Call**](https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md) | 🟢 | 0.9.0 | +| [**Relaxed SIMD**](https://github.com/WebAssembly/relaxed-simd/blob/main/proposals/relaxed-simd/Overview.md) | 🟢 | 0.9.0 | +| [**Wide Arithmetic**](https://github.com/WebAssembly/wide-arithmetic/blob/main/proposals/wide-arithmetic/Overview.md) | 🟢 | 0.9.0 | | [**Exception Handling**](https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md) | 🌑 | - | | [**Typed Function References**](https://github.com/WebAssembly/function-references/blob/main/proposals/function-references/Overview.md) | 🌑 | - | | [**Garbage Collection**](https://github.com/WebAssembly/gc/blob/main/proposals/gc/Overview.md) | 🌑 | - | @@ -76,12 +112,11 @@ Untrusted WebAssembly code should not be able to crash the runtime or access mem ## See Also -I encourage you to check these projects out if you're looking for more mature and feature-complete WebAssembly runtimes: +If you need a more mature, production-tested, or performance-focused WebAssembly runtime today, consider one of these projects: - [wasmi](https://github.com/wasmi-labs/wasmi) - efficient and versatile WebAssembly interpreter for embedded systems - [wasm3](https://github.com/wasm3/wasm3) - a fast WebAssembly interpreter written in C - [wazero](https://wazero.io/) - a zero-dependency WebAssembly interpreter written in Go -- [wain](https://github.com/rhysd/wain) - a zero-dependency WebAssembly interpreter written in Rust ## License |
