diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2025-02-12 18:42:10 +0100 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2025-02-12 18:42:10 +0100 |
| commit | 7e668f9e321c941f38395e47a29501dce0fc81a9 (patch) | |
| tree | 95ff21b080140759b2e09d84b3664d6e21b782ba | |
| parent | e9782276a3a51f3b9ff4cdc6b56c447b1ab0d463 (diff) | |
feat: use postcard for new twasm format
Closes #32, #31
Co-authored-by: Mateusz <dragonn@op.pl>
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | Cargo.lock | 185 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 18 | ||||
| -rw-r--r-- | crates/tinywasm/benches/argon2id.rs | 16 | ||||
| -rw-r--r-- | crates/tinywasm/benches/fibonacci.rs | 14 | ||||
| -rw-r--r-- | crates/tinywasm/benches/tinywasm.rs | 14 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/executor.rs | 3 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/mod.rs | 1 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/simd.rs | 32 | ||||
| -rw-r--r-- | crates/types/Cargo.toml | 8 | ||||
| -rw-r--r-- | crates/types/src/archive.rs | 37 | ||||
| -rw-r--r-- | crates/types/src/instructions.rs | 25 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 40 | ||||
| -rw-r--r-- | crates/types/src/value.rs | 2 | ||||
| -rw-r--r-- | examples/archive.rs | 2 |
15 files changed, 109 insertions, 290 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ab30d8d..0222a0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- **Breaking:**: New backwards-incompatible version of the twasm format (upgraded `rkyv` to 0.8.0) +- **Breaking:**: New backwards-incompatible version of the twasm format based on `postcard` (thanks [@dragonnn](https://github.com/dragonnn)) - **Breaking:**: `RefNull` has been removed and replaced with new `FuncRef` and `ExternRef` structs - Increased MSRV to 1.83.0 @@ -74,35 +74,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "bytecheck" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50690fb3370fb9fe3550372746084c46f2ac8c9685c583d2be10eefd89d3d1a3" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "rancor", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb7846e0cb180355c2dec69e721edafa36919850f1a9f52ffba4ebc0393cb71" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "bytes" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" - -[[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -143,18 +114,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.28" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" dependencies = [ "anstyle", "clap_lex", @@ -167,6 +138,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] name = "criterion" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -239,6 +216,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] name = "env_logger" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -393,26 +382,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] -name = "munge" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64142d38c84badf60abf06ff9bd80ad2174306a5b11bd4706535090a30a419df" -dependencies = [ - "munge_macro", -] - -[[package]] -name = "munge_macro" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -440,6 +409,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] name = "pretty_env_logger" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -459,26 +440,6 @@ dependencies = [ ] [[package]] -name = "ptr_meta" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "quote" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -488,15 +449,6 @@ dependencies = [ ] [[package]] -name = "rancor" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf5f7161924b9d1cea0e4cabc97c372cea92b5f927fc13c6bca67157a0ad947" -dependencies = [ - "ptr_meta", -] - -[[package]] name = "rayon" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -546,45 +498,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "rend" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "rkyv" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e147371c75553e1e2fcdb483944a8540b8438c31426279553b9a8182a9b7b65" -dependencies = [ - "bytecheck", - "bytes", - "hashbrown", - "indexmap", - "munge", - "ptr_meta", - "rancor", - "rend", - "rkyv_derive", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246b40ac189af6c675d124b802e8ef6d5246c53e17367ce9501f8f66a81abb7a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "rust-fuzzy-search" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -644,12 +557,6 @@ dependencies = [ ] [[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] name = "syn" version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -680,21 +587,6 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] name = "tinywasm" version = "0.9.0-alpha.0" dependencies = [ @@ -750,7 +642,8 @@ name = "tinywasm-types" version = "0.9.0-alpha.0" dependencies = [ "log", - "rkyv", + "postcard", + "serde", ] [[package]] @@ -766,12 +659,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] -name = "uuid" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" - -[[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 098caf9..89c27d1 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -3,7 +3,7 @@ use crate::Result; use crate::conversion::{convert_heaptype, convert_valtype}; use alloc::string::ToString; use alloc::{boxed::Box, vec::Vec}; -use tinywasm_types::{Instruction, MemoryArg, SimdInstruction, WasmFunctionData}; +use tinywasm_types::{Instruction, MemoryArg, WasmFunctionData}; use wasmparser::{ FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, VisitSimdOperator, WasmModuleResources, }; @@ -84,12 +84,6 @@ macro_rules! define_operands { )*}; } -macro_rules! define_operands_simd { - ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( - define_operand!($name(SimdInstruction::$instr $(,$ty)*)); - )*}; -} - macro_rules! define_mem_operands { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { @@ -101,7 +95,7 @@ macro_rules! define_mem_operands { macro_rules! define_mem_operands_simd { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output { - self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory)).into()); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory)).into()); } )*}; } @@ -109,7 +103,7 @@ macro_rules! define_mem_operands_simd { macro_rules! define_mem_operands_simd_lane { ($($name:ident($instr:ident)),*) => {$( fn $name(&mut self, memarg: wasmparser::MemArg, lane: u8) -> Self::Output { - self.instructions.push(SimdInstruction::$instr(MemoryArg::new(memarg.offset, memarg.memory), lane).into()); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory), lane).into()); } )*}; } @@ -496,7 +490,7 @@ impl<R: WasmModuleResources> wasmparser::VisitSimdOperator<'_> for FunctionBuild visit_v128_load8_lane(V128Load8Lane), visit_v128_load16_lane(V128Load16Lane), visit_v128_load32_lane(V128Load32Lane), visit_v128_load64_lane(V128Load64Lane), visit_v128_store8_lane(V128Store8Lane), visit_v128_store16_lane(V128Store16Lane), visit_v128_store32_lane(V128Store32Lane), visit_v128_store64_lane(V128Store64Lane) } - define_operands_simd! { + define_operands! { visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_andnot(V128AndNot), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), visit_i8x16_splat(I8x16Splat), visit_i8x16_swizzle(I8x16Swizzle), visit_i8x16_eq(I8x16Eq), visit_i8x16_ne(I8x16Ne), visit_i8x16_lt_s(I8x16LtS), visit_i8x16_lt_u(I8x16LtU), visit_i8x16_gt_s(I8x16GtS), visit_i8x16_gt_u(I8x16GtU), visit_i8x16_le_s(I8x16LeS), visit_i8x16_le_u(I8x16LeU), visit_i8x16_ge_s(I8x16GeS), visit_i8x16_ge_u(I8x16GeU), visit_i16x8_splat(I16x8Splat), visit_i16x8_eq(I16x8Eq), visit_i16x8_ne(I16x8Ne), visit_i16x8_lt_s(I16x8LtS), visit_i16x8_lt_u(I16x8LtU), visit_i16x8_gt_s(I16x8GtS), visit_i16x8_gt_u(I16x8GtU), visit_i16x8_le_s(I16x8LeS), visit_i16x8_le_u(I16x8LeU), visit_i16x8_ge_s(I16x8GeS), visit_i16x8_ge_u(I16x8GeU), @@ -537,11 +531,11 @@ impl<R: WasmModuleResources> wasmparser::VisitSimdOperator<'_> for FunctionBuild fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { self.v128_constants.push(u128::from_le_bytes(lanes)); - self.instructions.push(SimdInstruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::I8x16Shuffle(self.v128_constants.len() as u32 - 1).into()); } fn visit_v128_const(&mut self, value: wasmparser::V128) -> Self::Output { self.v128_constants.push(value.i128() as u128); - self.instructions.push(SimdInstruction::V128Const(self.v128_constants.len() as u32 - 1).into()); + self.instructions.push(Instruction::V128Const(self.v128_constants.len() as u32 - 1).into()); } } diff --git a/crates/tinywasm/benches/argon2id.rs b/crates/tinywasm/benches/argon2id.rs index 6dd5ae4..d977352 100644 --- a/crates/tinywasm/benches/argon2id.rs +++ b/crates/tinywasm/benches/argon2id.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/argon2id.opt.wasm"); @@ -11,13 +11,13 @@ fn argon2id_parse() -> Result<TinyWasmModule> { Ok(data) } -fn argon2id_to_twasm(module: TinyWasmModule) -> Result<AlignedVec> { - let twasm = module.serialize_twasm(); +fn argon2id_to_twasm(module: &TinyWasmModule) -> Result<Vec<u8>> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn argon2id_from_twasm(twasm: AlignedVec) -> Result<TinyWasmModule> { - let module = TinyWasmModule::from_twasm(&twasm)?; +fn argon2id_from_twasm(twasm: &[u8]) -> Result<TinyWasmModule> { + let module = TinyWasmModule::from_twasm(twasm)?; Ok(module) } @@ -31,11 +31,11 @@ fn argon2id_run(module: TinyWasmModule) -> Result<()> { fn criterion_benchmark(c: &mut Criterion) { let module = argon2id_parse().expect("argon2id_parse"); - let twasm = argon2id_to_twasm(module.clone()).expect("argon2id_to_twasm"); + let twasm = argon2id_to_twasm(&module).expect("argon2id_to_twasm"); c.bench_function("argon2id_parse", |b| b.iter(argon2id_parse)); - c.bench_function("argon2id_to_twasm", |b| b.iter(|| argon2id_to_twasm(module.clone()))); - c.bench_function("argon2id_from_twasm", |b| b.iter(|| argon2id_from_twasm(twasm.clone()))); + c.bench_function("argon2id_to_twasm", |b| b.iter(|| argon2id_to_twasm(&module))); + c.bench_function("argon2id_from_twasm", |b| b.iter(|| argon2id_from_twasm(&twasm))); c.bench_function("argon2id", |b| b.iter(|| argon2id_run(module.clone()))); } diff --git a/crates/tinywasm/benches/fibonacci.rs b/crates/tinywasm/benches/fibonacci.rs index 9c994ca..dcf6eb9 100644 --- a/crates/tinywasm/benches/fibonacci.rs +++ b/crates/tinywasm/benches/fibonacci.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/fibonacci.opt.wasm"); @@ -11,12 +11,12 @@ fn fibonacci_parse() -> Result<TinyWasmModule> { Ok(data) } -fn fibonacci_to_twasm(module: TinyWasmModule) -> Result<AlignedVec> { - let twasm = module.serialize_twasm(); +fn fibonacci_to_twasm(module: &TinyWasmModule) -> Result<Vec<u8>> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn fibonacci_from_twasm(twasm: AlignedVec) -> Result<TinyWasmModule> { +fn fibonacci_from_twasm(twasm: &[u8]) -> Result<TinyWasmModule> { let module = TinyWasmModule::from_twasm(&twasm)?; Ok(module) } @@ -37,11 +37,11 @@ fn fibonacci_run(module: TinyWasmModule, recursive: bool, n: i32) -> Result<()> fn criterion_benchmark(c: &mut Criterion) { let module = fibonacci_parse().expect("fibonacci_parse"); - let twasm = fibonacci_to_twasm(module.clone()).expect("fibonacci_to_twasm"); + let twasm = fibonacci_to_twasm(&module).expect("fibonacci_to_twasm"); c.bench_function("fibonacci_parse", |b| b.iter(fibonacci_parse)); - c.bench_function("fibonacci_to_twasm", |b| b.iter(|| fibonacci_to_twasm(module.clone()))); - c.bench_function("fibonacci_from_twasm", |b| b.iter(|| fibonacci_from_twasm(twasm.clone()))); + c.bench_function("fibonacci_to_twasm", |b| b.iter(|| fibonacci_to_twasm(&module))); + c.bench_function("fibonacci_from_twasm", |b| b.iter(|| fibonacci_from_twasm(&twasm))); c.bench_function("fibonacci_iterative_60", |b| b.iter(|| fibonacci_run(module.clone(), false, 60))); c.bench_function("fibonacci_recursive_26", |b| b.iter(|| fibonacci_run(module.clone(), true, 26))); } diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index da16eb8..8552d6c 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,7 +1,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; use tinywasm::{types, Extern, FuncContext, Imports, ModuleInstance, Store}; -use types::{archive::AlignedVec, TinyWasmModule}; +use types::TinyWasmModule; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.opt.wasm"); @@ -11,12 +11,12 @@ fn tinywasm_parse() -> Result<TinyWasmModule> { Ok(data) } -fn tinywasm_to_twasm(module: TinyWasmModule) -> Result<AlignedVec> { - let twasm = module.serialize_twasm(); +fn tinywasm_to_twasm(module: &TinyWasmModule) -> Result<Vec<u8>> { + let twasm = module.serialize_twasm()?; Ok(twasm) } -fn tinywasm_from_twasm(twasm: AlignedVec) -> Result<TinyWasmModule> { +fn tinywasm_from_twasm(twasm: &[u8]) -> Result<TinyWasmModule> { let module = TinyWasmModule::from_twasm(&twasm)?; Ok(module) } @@ -33,11 +33,11 @@ fn tinywasm_run(module: TinyWasmModule) -> Result<()> { fn criterion_benchmark(c: &mut Criterion) { let module = tinywasm_parse().expect("tinywasm_parse"); - let twasm = tinywasm_to_twasm(module.clone()).expect("tinywasm_to_twasm"); + let twasm = tinywasm_to_twasm(&module).expect("tinywasm_to_twasm"); c.bench_function("tinywasm_parse", |b| b.iter(tinywasm_parse)); - c.bench_function("tinywasm_to_twasm", |b| b.iter(|| tinywasm_to_twasm(module.clone()))); - c.bench_function("tinywasm_from_twasm", |b| b.iter(|| tinywasm_from_twasm(twasm.clone()))); + c.bench_function("tinywasm_to_twasm", |b| b.iter(|| tinywasm_to_twasm(&module))); + c.bench_function("tinywasm_from_twasm", |b| b.iter(|| tinywasm_from_twasm(&twasm))); c.bench_function("tinywasm", |b| b.iter(|| tinywasm_run(module.clone()))); } diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index f05ae30..3c579c1 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -4,7 +4,6 @@ use super::no_std_floats::NoStdFloatExt; use alloc::{format, rc::Rc, string::ToString}; use core::ops::ControlFlow; -use interpreter::simd::exec_next_simd; use interpreter::stack::CallFrame; use tinywasm_types::*; @@ -303,7 +302,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { LocalCopy128(from, to) => self.exec_local_copy::<Value128>(*from, *to), LocalCopyRef(from, to) => self.exec_local_copy::<ValueRef>(*from, *to), - Simd(op) => exec_next_simd(self, *op).to_cf()?, + i => return ControlFlow::Break(Some(Error::UnsupportedFeature(format!("unimplemented opcode: {i:?}")))), }; self.cf.incr_instr_ptr(); diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index e5c1081..0b7df2f 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -1,6 +1,5 @@ pub(crate) mod executor; pub(crate) mod num_helpers; -pub(crate) mod simd; pub(crate) mod stack; mod values; diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs deleted file mode 100644 index e996edc..0000000 --- a/crates/tinywasm/src/interpreter/simd.rs +++ /dev/null @@ -1,32 +0,0 @@ -use tinywasm_types::SimdInstruction; - -use crate::Result; - -#[cfg(not(feature = "std"))] -#[allow(unused_imports)] -use super::no_std_floats::NoStdFloatExt; -use super::{executor::Executor, Value128}; - -#[inline(always)] -pub(crate) fn exec_next_simd(e: &mut Executor<'_, '_>, op: SimdInstruction) -> Result<()> { - match op { - // unops - SimdInstruction::V128Not => e.stack.values.replace_top_same(|a: Value128| Ok(!a))?, - // binops - SimdInstruction::V128And => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & b))?, - SimdInstruction::V128AndNot => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a & !b))?, - SimdInstruction::V128Or => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a | b))?, - SimdInstruction::V128Xor => e.stack.values.calculate_same(|a: Value128, b: Value128| Ok(a ^ b))?, - // ternops - SimdInstruction::V128Bitselect => { - let c: Value128 = e.stack.values.pop(); - e.stack.values.calculate(|a: Value128, b: Value128| Ok((a & b) | (!a & c)))?; - } - // shifts - _ => {} - } - Ok(()) -} - -// trait SimdExt {} -// impl SimdExt for Value128 {} diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 9d9f9af..fda8a86 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -10,10 +10,12 @@ rust-version.workspace=true [dependencies] log={workspace=true, optional=true} -rkyv={version="0.8.1", optional=true, default-features=false, features=["alloc", "bytecheck"]} +postcard={version="1.1", optional=true, default-features=false, features=["alloc"]} +serde={version="1.0", optional=true, default-features=false, features=["alloc"]} [features] default=["std", "logging", "archive"] -std=["rkyv?/std"] -archive=["dep:rkyv"] + +std=["serde?/std"] +archive=["dep:postcard", "dep:serde"] logging=["dep:log"] diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index 30b54c7..a725e3d 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -1,21 +1,14 @@ use core::fmt::{Display, Formatter}; +use alloc::vec::Vec; + use crate::TinyWasmModule; -use rkyv::{ - access, - api::high::to_bytes_in_with_alloc, - deserialize, - ser::{allocator::Arena, WriterExt}, - Archived, -}; const TWASM_MAGIC_PREFIX: &[u8; 4] = b"TWAS"; -const TWASM_VERSION: &[u8; 2] = b"02"; +const TWASM_VERSION: &[u8; 2] = b"03"; #[rustfmt::skip] const TWASM_MAGIC: [u8; 16] = [ TWASM_MAGIC_PREFIX[0], TWASM_MAGIC_PREFIX[1], TWASM_MAGIC_PREFIX[2], TWASM_MAGIC_PREFIX[3], TWASM_VERSION[0], TWASM_VERSION[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -pub use rkyv::util::AlignedVec; - fn validate_magic(wasm: &[u8]) -> Result<usize, TwasmError> { if wasm.len() < TWASM_MAGIC.len() || &wasm[..TWASM_MAGIC_PREFIX.len()] != TWASM_MAGIC_PREFIX { return Err(TwasmError::InvalidMagic); @@ -35,7 +28,7 @@ pub enum TwasmError { InvalidMagic, InvalidVersion, InvalidPadding, - InvalidArchive(rkyv::rancor::Error), + InvalidArchive(postcard::Error), } impl Display for TwasmError { @@ -58,20 +51,14 @@ impl TinyWasmModule { /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result<TinyWasmModule, TwasmError> { let len = validate_magic(wasm)?; - let root = access::<Archived<Self>, rkyv::rancor::Error>(&wasm[len..]).map_err(TwasmError::InvalidArchive)?; - deserialize::<TinyWasmModule, rkyv::rancor::Error>(root).map_err(TwasmError::InvalidArchive) + + postcard::from_bytes(&wasm[len..]).map_err(|e| TwasmError::InvalidArchive(e)) } /// Serializes the `TinyWasmModule` into a vector of bytes. - /// `AlignedVec` can be deferenced as a slice of bytes and - /// implements `io::Write` when the `std` feature is enabled. - pub fn serialize_twasm(&self) -> AlignedVec { - let mut arena = Arena::new(); - let mut bytes = AlignedVec::new(); - <AlignedVec as WriterExt<rkyv::rancor::Error>>::pad(&mut bytes, TWASM_MAGIC.len()).unwrap(); - let mut bytes = to_bytes_in_with_alloc::<_, _, rkyv::rancor::Error>(self, bytes, arena.acquire()).unwrap(); - bytes[..TWASM_MAGIC.len()].copy_from_slice(&TWASM_MAGIC); - bytes + pub fn serialize_twasm(&self) -> Result<Vec<u8>, TwasmError> { + let buf = Vec::from(TWASM_MAGIC); + postcard::to_extend(self, buf).map_err(|e| TwasmError::InvalidArchive(e)) } } @@ -82,7 +69,7 @@ mod tests { #[test] fn test_serialize() { let wasm = TinyWasmModule::default(); - let twasm = wasm.serialize_twasm(); + let twasm = wasm.serialize_twasm().expect("should serialize"); let wasm2 = TinyWasmModule::from_twasm(&twasm).unwrap(); assert_eq!(wasm, wasm2); } @@ -90,7 +77,7 @@ mod tests { #[test] fn test_invalid_magic() { let wasm = TinyWasmModule::default(); - let mut twasm = wasm.serialize_twasm(); + let mut twasm = wasm.serialize_twasm().expect("should serialize"); twasm[0] = 0; assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidMagic))); } @@ -98,7 +85,7 @@ mod tests { #[test] fn test_invalid_version() { let wasm = TinyWasmModule::default(); - let mut twasm = wasm.serialize_twasm(); + let mut twasm = wasm.serialize_twasm().expect("should serialize"); twasm[4] = 0; assert!(matches!(TinyWasmModule::from_twasm(&twasm), Err(TwasmError::InvalidVersion))); } diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index 8f77b31..c61a02f 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -3,7 +3,7 @@ use crate::{ConstIdx, DataAddr, ElemAddr, ExternAddr, MemAddr}; /// Represents a memory immediate in a WebAssembly memory instruction. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct MemoryArg([u8; 12]); @@ -30,7 +30,7 @@ type EndOffset = u32; type ElseOffset = u32; #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ConstInstruction { I32Const(i32), I64Const(i64), @@ -53,7 +53,7 @@ pub enum ConstInstruction { /// /// See <https://webassembly.github.io/spec/core/binary/instructions.html> #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { @@ -184,19 +184,6 @@ pub enum Instruction { ElemDrop(ElemAddr), // > SIMD Instructions - Simd(SimdInstruction), -} - -impl From<SimdInstruction> for Instruction { - fn from(instr: SimdInstruction) -> Self { - Instruction::Simd(instr) - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] -#[rustfmt::skip] -pub enum SimdInstruction { V128Load(MemoryArg), V128Load8x8S(MemoryArg), V128Load8x8U(MemoryArg), V128Load16x4S(MemoryArg), V128Load16x4U(MemoryArg), @@ -256,12 +243,8 @@ pub enum SimdInstruction { I32x4TruncSatF64x2SZero, I32x4TruncSatF64x2UZero, F64x2ConvertLowI32x4S, F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, -} -#[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] -#[rustfmt::skip] -pub enum RelaxedSimd { + // > Relaxed SIMD I8x16RelaxedSwizzle, I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, I32x4RelaxedTruncF64x2SZero, I32x4RelaxedTruncF64x2UZero, diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 58120fe..81eec13 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -51,7 +51,7 @@ pub mod archive; /// `TinyWasmModules` are validated before being created, so they are guaranteed to be valid (as long as they were created by `TinyWasm`). /// This means you should not trust a `TinyWasmModule` created by a third party to be valid. #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct TinyWasmModule { /// Optional address of the start function /// @@ -108,7 +108,7 @@ pub struct TinyWasmModule { /// /// See <https://webassembly.github.io/spec/core/syntax/types.html#external-types> #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ExternalKind { /// A WebAssembly Function. Func, @@ -180,14 +180,14 @@ impl ExternVal { /// /// See <https://webassembly.github.io/spec/core/syntax/types.html#function-types> #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct FuncType { pub params: Box<[ValType]>, pub results: Box<[ValType]>, } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct ValueCounts { pub c32: u32, pub c64: u32, @@ -196,7 +196,7 @@ pub struct ValueCounts { } #[derive(Debug, Default, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct ValueCountsSmall { pub c32: u16, pub c64: u16, @@ -235,7 +235,7 @@ impl<'a, T: IntoIterator<Item = &'a ValType>> From<T> for ValueCountsSmall { } #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct WasmFunction { pub instructions: Box<[Instruction]>, pub data: WasmFunctionData, @@ -245,14 +245,14 @@ pub struct WasmFunction { } #[derive(Debug, Clone, PartialEq, Default)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct WasmFunctionData { pub v128_constants: Box<[u128]>, } /// A WebAssembly Module Export #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Export { /// The name of the export. pub name: Box<str>, @@ -263,21 +263,21 @@ pub struct Export { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Global { pub ty: GlobalType, pub init: ConstInstruction, } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct GlobalType { pub mutable: bool, pub ty: ValType, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct TableType { pub element_type: ValType, pub size_initial: u32, @@ -296,7 +296,7 @@ impl TableType { /// Represents a memory's type. #[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct MemoryType { arch: MemoryArch, page_count_initial: u64, @@ -335,14 +335,14 @@ impl MemoryType { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum MemoryArch { I32, I64, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Import { pub module: Box<str>, pub name: Box<str>, @@ -350,7 +350,7 @@ pub struct Import { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ImportKind { Function(TypeAddr), Table(TableType), @@ -371,7 +371,7 @@ impl From<&ImportKind> for ExternalKind { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Data { pub data: Box<[u8]>, pub range: Range<usize>, @@ -379,14 +379,14 @@ pub struct Data { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum DataKind { Active { mem: MemAddr, offset: ConstInstruction }, Passive, } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub struct Element { pub kind: ElementKind, pub items: Box<[ElementItem]>, @@ -395,7 +395,7 @@ pub struct Element { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ElementKind { Passive, Active { table: TableAddr, offset: ConstInstruction }, @@ -403,7 +403,7 @@ pub enum ElementKind { } #[derive(Debug, Clone, Copy, PartialEq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ElementItem { Func(FuncAddr), Expr(ConstInstruction), diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index 6651c0e..01a31d5 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -249,7 +249,7 @@ impl WasmValue { /// Type of a WebAssembly value. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "archive", derive(serde::Serialize, serde::Deserialize))] pub enum ValType { /// A 32-bit integer. I32, diff --git a/examples/archive.rs b/examples/archive.rs index f1a19b6..6a3d54e 100644 --- a/examples/archive.rs +++ b/examples/archive.rs @@ -13,7 +13,7 @@ const WASM: &str = r#" fn main() -> Result<()> { let wasm = wat::parse_str(WASM).expect("Failed to parse WAT"); let module = Parser::default().parse_module_bytes(wasm)?; - let twasm = module.serialize_twasm(); + let twasm = module.serialize_twasm()?; // Now, you could e.g. write `twasm` to a file called `add.twasm` // and load it later in a different program. |
