summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yaml8
-rw-r--r--Cargo.lock8
-rw-r--r--crates/parser/src/visit.rs253
-rw-r--r--crates/tinywasm/src/interpreter/simd.rs130
-rw-r--r--crates/tinywasm/tests/test-wasm-2.rs2
-rw-r--r--crates/types/Cargo.toml2
-rw-r--r--crates/types/src/instructions.rs22
-rw-r--r--crates/wasm-testsuite/lib.rs2
8 files changed, 176 insertions, 251 deletions
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index f6de2d1..ebf0487 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -99,11 +99,3 @@ jobs:
target: ${{ matrix.target }}
toolchain: ${{ matrix.rust }}
if: matrix.target != ''
-
- - name: Run clippy (${{ matrix.target }})
- uses: houseabsolute/actions-rust-cross@v0.0.13
- with:
- command: clippy
- target: ${{ matrix.target }}
- toolchain: ${{ matrix.rust }}
- if: matrix.target != ''
diff --git a/Cargo.lock b/Cargo.lock
index 695bde4..670a20e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -616,9 +616,9 @@ dependencies = [
[[package]]
name = "rkyv"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d7fa2297190bd08087add407c3dedf28eb3be1d75955ffbd3bc312834325760"
+checksum = "1a1dfb7c03271e31aad881e521cfe25bda0206ee94b1af152957f4f49e25ee23"
dependencies = [
"bytecheck",
"bytes",
@@ -635,9 +635,9 @@ dependencies = [
[[package]]
name = "rkyv_derive"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4aad510db4f88722adf0e4586ff0dedfca4af57b17c075b2420bac1db446d22c"
+checksum = "aa3ca4a30c576aeb76aea84370da286f74d12d32029da8caec3d53b5a36a7539"
dependencies = [
"proc-macro2",
"quote",
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index 73cf9b4..4e39a5a 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -43,29 +43,34 @@ pub(crate) fn process_operators_and_validate<R: WasmModuleResources>(
Ok((builder.instructions.into_boxed_slice(), builder.validator.into_allocations()))
}
-macro_rules! define_operands {
- ($($name:ident, $instr:expr),*) => {$(
- fn $name(&mut self) -> Self::Output {
- self.instructions.push($instr);
- }
- )*};
-}
-
-macro_rules! define_primitive_operands {
- ($($name:ident, $instr:expr, $ty:ty),*) => {$(
+macro_rules! define_operand {
+ ($name:ident($instr:ident, $ty:ty)) => {
fn $name(&mut self, arg: $ty) -> Self::Output {
- self.instructions.push($instr(arg));
+ self.instructions.push(Instruction::$instr(arg));
}
- )*};
- ($($name:ident, $instr:expr, $ty:ty, $ty2:ty),*) => {$(
+ };
+
+ ($name:ident($instr:ident, $ty:ty, $ty2:ty)) => {
fn $name(&mut self, arg: $ty, arg2: $ty2) -> Self::Output {
- self.instructions.push($instr(arg, arg2));
+ self.instructions.push(Instruction::$instr(arg, arg2));
+ }
+ };
+
+ ($name:ident($instr:ident)) => {
+ fn $name(&mut self) -> Self::Output {
+ self.instructions.push(Instruction::$instr);
}
+ };
+}
+
+macro_rules! define_operands {
+ ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$(
+ define_operand!($name($instr $(,$ty)*));
)*};
}
macro_rules! define_mem_operands {
- ($($name:ident, $instr:ident),*) => {$(
+ ($($name:ident($instr:ident)),*) => {$(
fn $name(&mut self, memarg: wasmparser::MemArg) -> Self::Output {
self.instructions.push(Instruction::$instr {
offset: memarg.offset,
@@ -123,6 +128,7 @@ macro_rules! impl_visit_operator {
(@@saturating_float_to_int $($rest:tt)* ) => {};
(@@bulk_memory $($rest:tt)* ) => {};
(@@tail_call $($rest:tt)* ) => {};
+ // (@@simd $($rest:tt)* ) => {};
(@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => {
#[cold]
fn $visit(&mut self $($(,$arg: $argty)*)?) {
@@ -135,187 +141,28 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
type Output = ();
wasmparser::for_each_operator!(impl_visit_operator);
- define_primitive_operands! {
- visit_br, Instruction::Br, u32,
- visit_br_if, Instruction::BrIf, u32,
- visit_global_get, Instruction::GlobalGet, u32,
- visit_i32_const, Instruction::I32Const, i32,
- visit_i64_const, Instruction::I64Const, i64,
- visit_call, Instruction::Call, u32,
- visit_memory_size, Instruction::MemorySize, u32,
- visit_memory_grow, Instruction::MemoryGrow, u32
- }
-
define_mem_operands! {
- visit_i32_load, I32Load,
- visit_i64_load, I64Load,
- visit_f32_load, F32Load,
- visit_f64_load, F64Load,
- visit_i32_load8_s, I32Load8S,
- visit_i32_load8_u, I32Load8U,
- visit_i32_load16_s, I32Load16S,
- visit_i32_load16_u, I32Load16U,
- visit_i64_load8_s, I64Load8S,
- visit_i64_load8_u, I64Load8U,
- visit_i64_load16_s, I64Load16S,
- visit_i64_load16_u, I64Load16U,
- visit_i64_load32_s, I64Load32S,
- visit_i64_load32_u, I64Load32U,
- // visit_i32_store, I32Store, custom implementation
- visit_i64_store, I64Store,
- visit_f32_store, F32Store,
- visit_f64_store, F64Store,
- visit_i32_store8, I32Store8,
- visit_i32_store16, I32Store16,
- visit_i64_store8, I64Store8,
- visit_i64_store16, I64Store16,
- visit_i64_store32, I64Store32
+ visit_i32_load(I32Load), visit_i64_load(I64Load), visit_f32_load(F32Load), visit_f64_load(F64Load), visit_i32_load8_s(I32Load8S), visit_i32_load8_u(I32Load8U), visit_i32_load16_s(I32Load16S), visit_i32_load16_u(I32Load16U), visit_i64_load8_s(I64Load8S), visit_i64_load8_u(I64Load8U), visit_i64_load16_s(I64Load16S), visit_i64_load16_u(I64Load16U), visit_i64_load32_s(I64Load32S), visit_i64_load32_u(I64Load32U), /* visit_i32_store( I32Store), custom implementation */ visit_i64_store(I64Store), visit_f32_store(F32Store), visit_f64_store(F64Store), visit_i32_store8(I32Store8), visit_i32_store16(I32Store16), visit_i64_store8(I64Store8), visit_i64_store16(I64Store16), visit_i64_store32(I64Store32)
}
define_operands! {
- visit_unreachable, Instruction::Unreachable,
- visit_nop, Instruction::Nop,
- visit_return, Instruction::Return,
- visit_i32_eqz, Instruction::I32Eqz,
- visit_i32_eq, Instruction::I32Eq,
- visit_i32_ne, Instruction::I32Ne,
- visit_i32_lt_s, Instruction::I32LtS,
- visit_i32_lt_u, Instruction::I32LtU,
- visit_i32_gt_s, Instruction::I32GtS,
- visit_i32_gt_u, Instruction::I32GtU,
- visit_i32_le_s, Instruction::I32LeS,
- visit_i32_le_u, Instruction::I32LeU,
- visit_i32_ge_s, Instruction::I32GeS,
- visit_i32_ge_u, Instruction::I32GeU,
- visit_i64_eqz, Instruction::I64Eqz,
- visit_i64_eq, Instruction::I64Eq,
- visit_i64_ne, Instruction::I64Ne,
- visit_i64_lt_s, Instruction::I64LtS,
- visit_i64_lt_u, Instruction::I64LtU,
- visit_i64_gt_s, Instruction::I64GtS,
- visit_i64_gt_u, Instruction::I64GtU,
- visit_i64_le_s, Instruction::I64LeS,
- visit_i64_le_u, Instruction::I64LeU,
- visit_i64_ge_s, Instruction::I64GeS,
- visit_i64_ge_u, Instruction::I64GeU,
- visit_f32_eq, Instruction::F32Eq,
- visit_f32_ne, Instruction::F32Ne,
- visit_f32_lt, Instruction::F32Lt,
- visit_f32_gt, Instruction::F32Gt,
- visit_f32_le, Instruction::F32Le,
- visit_f32_ge, Instruction::F32Ge,
- visit_f64_eq, Instruction::F64Eq,
- visit_f64_ne, Instruction::F64Ne,
- visit_f64_lt, Instruction::F64Lt,
- visit_f64_gt, Instruction::F64Gt,
- visit_f64_le, Instruction::F64Le,
- visit_f64_ge, Instruction::F64Ge,
- visit_i32_clz, Instruction::I32Clz,
- visit_i32_ctz, Instruction::I32Ctz,
- visit_i32_popcnt, Instruction::I32Popcnt,
- // visit_i32_add, Instruction::I32Add, custom implementation
- visit_i32_sub, Instruction::I32Sub,
- visit_i32_mul, Instruction::I32Mul,
- visit_i32_div_s, Instruction::I32DivS,
- visit_i32_div_u, Instruction::I32DivU,
- visit_i32_rem_s, Instruction::I32RemS,
- visit_i32_rem_u, Instruction::I32RemU,
- visit_i32_and, Instruction::I32And,
- visit_i32_or, Instruction::I32Or,
- visit_i32_xor, Instruction::I32Xor,
- visit_i32_shl, Instruction::I32Shl,
- visit_i32_shr_s, Instruction::I32ShrS,
- visit_i32_shr_u, Instruction::I32ShrU,
- visit_i32_rotl, Instruction::I32Rotl,
- visit_i32_rotr, Instruction::I32Rotr,
- visit_i64_clz, Instruction::I64Clz,
- visit_i64_ctz, Instruction::I64Ctz,
- visit_i64_popcnt, Instruction::I64Popcnt,
- visit_i64_add, Instruction::I64Add,
- visit_i64_sub, Instruction::I64Sub,
- visit_i64_mul, Instruction::I64Mul,
- visit_i64_div_s, Instruction::I64DivS,
- visit_i64_div_u, Instruction::I64DivU,
- visit_i64_rem_s, Instruction::I64RemS,
- visit_i64_rem_u, Instruction::I64RemU,
- visit_i64_and, Instruction::I64And,
- visit_i64_or, Instruction::I64Or,
- visit_i64_xor, Instruction::I64Xor,
- visit_i64_shl, Instruction::I64Shl,
- visit_i64_shr_s, Instruction::I64ShrS,
- visit_i64_shr_u, Instruction::I64ShrU,
- // visit_i64_rotl, Instruction::I64Rotl, custom implementation
- visit_i64_rotr, Instruction::I64Rotr,
- visit_f32_abs, Instruction::F32Abs,
- visit_f32_neg, Instruction::F32Neg,
- visit_f32_ceil, Instruction::F32Ceil,
- visit_f32_floor, Instruction::F32Floor,
- visit_f32_trunc, Instruction::F32Trunc,
- visit_f32_nearest, Instruction::F32Nearest,
- visit_f32_sqrt, Instruction::F32Sqrt,
- visit_f32_add, Instruction::F32Add,
- visit_f32_sub, Instruction::F32Sub,
- visit_f32_mul, Instruction::F32Mul,
- visit_f32_div, Instruction::F32Div,
- visit_f32_min, Instruction::F32Min,
- visit_f32_max, Instruction::F32Max,
- visit_f32_copysign, Instruction::F32Copysign,
- visit_f64_abs, Instruction::F64Abs,
- visit_f64_neg, Instruction::F64Neg,
- visit_f64_ceil, Instruction::F64Ceil,
- visit_f64_floor, Instruction::F64Floor,
- visit_f64_trunc, Instruction::F64Trunc,
- visit_f64_nearest, Instruction::F64Nearest,
- visit_f64_sqrt, Instruction::F64Sqrt,
- visit_f64_add, Instruction::F64Add,
- visit_f64_sub, Instruction::F64Sub,
- visit_f64_mul, Instruction::F64Mul,
- visit_f64_div, Instruction::F64Div,
- visit_f64_min, Instruction::F64Min,
- visit_f64_max, Instruction::F64Max,
- visit_f64_copysign, Instruction::F64Copysign,
- visit_i32_wrap_i64, Instruction::I32WrapI64,
- visit_i32_trunc_f32_s, Instruction::I32TruncF32S,
- visit_i32_trunc_f32_u, Instruction::I32TruncF32U,
- visit_i32_trunc_f64_s, Instruction::I32TruncF64S,
- visit_i32_trunc_f64_u, Instruction::I32TruncF64U,
- visit_i64_extend_i32_s, Instruction::I64ExtendI32S,
- visit_i64_extend_i32_u, Instruction::I64ExtendI32U,
- visit_i64_trunc_f32_s, Instruction::I64TruncF32S,
- visit_i64_trunc_f32_u, Instruction::I64TruncF32U,
- visit_i64_trunc_f64_s, Instruction::I64TruncF64S,
- visit_i64_trunc_f64_u, Instruction::I64TruncF64U,
- visit_f32_convert_i32_s, Instruction::F32ConvertI32S,
- visit_f32_convert_i32_u, Instruction::F32ConvertI32U,
- visit_f32_convert_i64_s, Instruction::F32ConvertI64S,
- visit_f32_convert_i64_u, Instruction::F32ConvertI64U,
- visit_f32_demote_f64, Instruction::F32DemoteF64,
- visit_f64_convert_i32_s, Instruction::F64ConvertI32S,
- visit_f64_convert_i32_u, Instruction::F64ConvertI32U,
- visit_f64_convert_i64_s, Instruction::F64ConvertI64S,
- visit_f64_convert_i64_u, Instruction::F64ConvertI64U,
- visit_f64_promote_f32, Instruction::F64PromoteF32,
- visit_i32_reinterpret_f32, Instruction::I32ReinterpretF32,
- visit_i64_reinterpret_f64, Instruction::I64ReinterpretF64,
- visit_f32_reinterpret_i32, Instruction::F32ReinterpretI32,
- visit_f64_reinterpret_i64, Instruction::F64ReinterpretI64,
+ // basic instructions
+ visit_br(Br, u32), visit_br_if(BrIf, u32), visit_global_get(GlobalGet, u32), visit_i32_const(I32Const, i32), visit_i64_const(I64Const, i64), visit_call(Call, u32), visit_memory_size(MemorySize, u32), visit_memory_grow(MemoryGrow, u32), visit_unreachable(Unreachable), visit_nop(Nop), visit_return(Return), visit_i32_eqz(I32Eqz), visit_i32_eq(I32Eq), visit_i32_ne(I32Ne), visit_i32_lt_s(I32LtS), visit_i32_lt_u(I32LtU), visit_i32_gt_s(I32GtS), visit_i32_gt_u(I32GtU), visit_i32_le_s(I32LeS), visit_i32_le_u(I32LeU), visit_i32_ge_s(I32GeS), visit_i32_ge_u(I32GeU), visit_i64_eqz(I64Eqz), visit_i64_eq(I64Eq), visit_i64_ne(I64Ne), visit_i64_lt_s(I64LtS), visit_i64_lt_u(I64LtU), visit_i64_gt_s(I64GtS), visit_i64_gt_u(I64GtU), visit_i64_le_s(I64LeS), visit_i64_le_u(I64LeU), visit_i64_ge_s(I64GeS), visit_i64_ge_u(I64GeU), visit_f32_eq(F32Eq), visit_f32_ne(F32Ne), visit_f32_lt(F32Lt), visit_f32_gt(F32Gt), visit_f32_le(F32Le), visit_f32_ge(F32Ge), visit_f64_eq(F64Eq), visit_f64_ne(F64Ne), visit_f64_lt(F64Lt), visit_f64_gt(F64Gt), visit_f64_le(F64Le), visit_f64_ge(F64Ge), visit_i32_clz(I32Clz), visit_i32_ctz(I32Ctz), visit_i32_popcnt(I32Popcnt), visit_i32_add(I32Add), visit_i32_sub(I32Sub), visit_i32_mul(I32Mul), visit_i32_div_s(I32DivS), visit_i32_div_u(I32DivU), visit_i32_rem_s(I32RemS), visit_i32_rem_u(I32RemU), visit_i32_and(I32And), visit_i32_or(I32Or), visit_i32_xor(I32Xor), visit_i32_shl(I32Shl), visit_i32_shr_s(I32ShrS), visit_i32_shr_u(I32ShrU), visit_i32_rotl(I32Rotl), visit_i32_rotr(I32Rotr), visit_i64_clz(I64Clz), visit_i64_ctz(I64Ctz), visit_i64_popcnt(I64Popcnt), visit_i64_add(I64Add), visit_i64_sub(I64Sub), visit_i64_mul(I64Mul), visit_i64_div_s(I64DivS), visit_i64_div_u(I64DivU), visit_i64_rem_s(I64RemS), visit_i64_rem_u(I64RemU), visit_i64_and(I64And), visit_i64_or(I64Or), visit_i64_xor(I64Xor), visit_i64_shl(I64Shl), visit_i64_shr_s(I64ShrS), visit_i64_shr_u(I64ShrU), visit_i64_rotl(I64Rotl), visit_i64_rotr(I64Rotr), visit_f32_abs(F32Abs), visit_f32_neg(F32Neg), visit_f32_ceil(F32Ceil), visit_f32_floor(F32Floor), visit_f32_trunc(F32Trunc), visit_f32_nearest(F32Nearest), visit_f32_sqrt(F32Sqrt), visit_f32_add(F32Add), visit_f32_sub(F32Sub), visit_f32_mul(F32Mul), visit_f32_div(F32Div), visit_f32_min(F32Min), visit_f32_max(F32Max), visit_f32_copysign(F32Copysign), visit_f64_abs(F64Abs), visit_f64_neg(F64Neg), visit_f64_ceil(F64Ceil), visit_f64_floor(F64Floor), visit_f64_trunc(F64Trunc), visit_f64_nearest(F64Nearest), visit_f64_sqrt(F64Sqrt), visit_f64_add(F64Add), visit_f64_sub(F64Sub), visit_f64_mul(F64Mul), visit_f64_div(F64Div), visit_f64_min(F64Min), visit_f64_max(F64Max), visit_f64_copysign(F64Copysign), visit_i32_wrap_i64(I32WrapI64), visit_i32_trunc_f32_s(I32TruncF32S), visit_i32_trunc_f32_u(I32TruncF32U), visit_i32_trunc_f64_s(I32TruncF64S), visit_i32_trunc_f64_u(I32TruncF64U), visit_i64_extend_i32_s(I64ExtendI32S), visit_i64_extend_i32_u(I64ExtendI32U), visit_i64_trunc_f32_s(I64TruncF32S), visit_i64_trunc_f32_u(I64TruncF32U), visit_i64_trunc_f64_s(I64TruncF64S), visit_i64_trunc_f64_u(I64TruncF64U), visit_f32_convert_i32_s(F32ConvertI32S), visit_f32_convert_i32_u(F32ConvertI32U), visit_f32_convert_i64_s(F32ConvertI64S), visit_f32_convert_i64_u(F32ConvertI64U), visit_f32_demote_f64(F32DemoteF64), visit_f64_convert_i32_s(F64ConvertI32S), visit_f64_convert_i32_u(F64ConvertI32U), visit_f64_convert_i64_s(F64ConvertI64S), visit_f64_convert_i64_u(F64ConvertI64U), visit_f64_promote_f32(F64PromoteF32), visit_i32_reinterpret_f32(I32ReinterpretF32), visit_i64_reinterpret_f64(I64ReinterpretF64), visit_f32_reinterpret_i32(F32ReinterpretI32), visit_f64_reinterpret_i64(F64ReinterpretI64),
// sign_extension
- visit_i32_extend8_s, Instruction::I32Extend8S,
- visit_i32_extend16_s, Instruction::I32Extend16S,
- visit_i64_extend8_s, Instruction::I64Extend8S,
- visit_i64_extend16_s, Instruction::I64Extend16S,
- visit_i64_extend32_s, Instruction::I64Extend32S,
+ visit_i32_extend8_s(I32Extend8S), visit_i32_extend16_s(I32Extend16S), visit_i64_extend8_s(I64Extend8S), visit_i64_extend16_s(I64Extend16S), visit_i64_extend32_s(I64Extend32S),
// Non-trapping Float-to-int Conversions
- visit_i32_trunc_sat_f32_s, Instruction::I32TruncSatF32S,
- visit_i32_trunc_sat_f32_u, Instruction::I32TruncSatF32U,
- visit_i32_trunc_sat_f64_s, Instruction::I32TruncSatF64S,
- visit_i32_trunc_sat_f64_u, Instruction::I32TruncSatF64U,
- visit_i64_trunc_sat_f32_s, Instruction::I64TruncSatF32S,
- visit_i64_trunc_sat_f32_u, Instruction::I64TruncSatF32U,
- visit_i64_trunc_sat_f64_s, Instruction::I64TruncSatF64S,
- visit_i64_trunc_sat_f64_u, Instruction::I64TruncSatF64U
+ visit_i32_trunc_sat_f32_s(I32TruncSatF32S), visit_i32_trunc_sat_f32_u(I32TruncSatF32U), visit_i32_trunc_sat_f64_s(I32TruncSatF64S), visit_i32_trunc_sat_f64_u(I32TruncSatF64U), visit_i64_trunc_sat_f32_s(I64TruncSatF32S), visit_i64_trunc_sat_f32_u(I64TruncSatF32U), visit_i64_trunc_sat_f64_s(I64TruncSatF64S), visit_i64_trunc_sat_f64_u(I64TruncSatF64U),
+
+ // Reference Types
+ visit_ref_func(RefFunc, u32), visit_table_fill(TableFill, u32), visit_table_get(TableGet, u32), visit_table_set(TableSet, u32), visit_table_grow(TableGrow, u32), visit_table_size(TableSize, u32),
+
+ // Bulk Memory
+ visit_memory_init(MemoryInit, u32, u32), visit_memory_copy(MemoryCopy, u32, u32), visit_table_init(TableInit, u32, u32), visit_memory_fill(MemoryFill, u32), visit_data_drop(DataDrop, u32), visit_elem_drop(ElemDrop, u32)
+
+ // simd
+ // visit_v128_load(V128Load), visit_v128_store(V128Store), visit_v128_const(V128Const), visit_v128_not(V128Not), visit_v128_and(V128And), visit_v128_or(V128Or), visit_v128_xor(V128Xor), visit_v128_bitselect(V128Bitselect), visit_v128_any_true(V128AnyTrue), visit_v128_all_true(V128AllTrue), visit_v128_shl(V128Shl), visit_v128_shr_s(V128ShrS), visit_v128_shr_u(V128ShrU), visit_v128_add(V128Add), visit_v128_sub(V128Sub), visit_v128_mul(V128Mul), visit_v128_div_s(V128DivS), visit_v128_div_u(V128DivU), visit_v128_min_s(V128MinS), visit_v128_min_u(V128MinU), visit_v128_max_s(V128MaxS), visit_v128_max_u(V128MaxU), visit_v128_eq(V128Eq), visit_v128_ne(V128Ne), visit_v128_lt_s(V128LtS), visit_v128_lt_u(V128LtU), visit_v128_le_s(V128LeS), visit_v128_le_u(V128LeU), visit_v128_gt_s(V128GtS), visit_v128_gt_u(V128GtU), visit_v128_ge_s(V128GeS), visit_v128_ge_u(V128GeU), visit_v128_narrow_i32x4_s(V128NarrowI32x4S), visit_v128_narrow_i32x4_u(V128NarrowI32x4U), visit_v128_widen_low_i8x16_s(V128WidenLowI8x16S), visit_v128_widen_high_i8x16_s(V128WidenHighI8x16S), visit_v128_widen_low_i8x16_u(V128WidenLowI8x16U), visit_v128_widen_high_i8x16_u(V128WidenHighI8x16U), visit_v128_widen_low_i16x8_s(V128WidenLowI16x8S), visit_v128_widen_high_i16x8_s(V128WidenHighI16x8S), visit_v128_widen_low_i16x8_u(V128WidenLowI16x8U)
}
fn visit_return_call(&mut self, function_index: u32) -> Self::Output {
@@ -452,14 +299,6 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
}
}
- fn visit_i64_rotl(&mut self) -> Self::Output {
- self.instructions.push(Instruction::I64Rotl);
- }
-
- fn visit_i32_add(&mut self) -> Self::Output {
- self.instructions.push(Instruction::I32Add);
- }
-
fn visit_block(&mut self, blockty: wasmparser::BlockType) -> Self::Output {
self.label_ptrs.push(self.instructions.len());
self.instructions.push(match blockty {
@@ -582,19 +421,6 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
self.instructions.push(Instruction::F64Const(f64::from_bits(val.bits())));
}
- // Bulk Memory Operations
-
- define_primitive_operands! {
- visit_memory_init, Instruction::MemoryInit, u32, u32,
- visit_memory_copy, Instruction::MemoryCopy, u32, u32,
- visit_table_init, Instruction::TableInit, u32, u32
- }
- define_primitive_operands! {
- visit_memory_fill, Instruction::MemoryFill, u32,
- visit_data_drop, Instruction::DataDrop, u32,
- visit_elem_drop, Instruction::ElemDrop, u32
- }
-
fn visit_table_copy(&mut self, dst_table: u32, src_table: u32) -> Self::Output {
self.instructions.push(Instruction::TableCopy { from: src_table, to: dst_table });
}
@@ -618,13 +444,4 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
wasmparser::ValType::Ref(_) => Instruction::SelectRef,
});
}
-
- define_primitive_operands! {
- visit_ref_func, Instruction::RefFunc, u32,
- visit_table_fill, Instruction::TableFill, u32,
- visit_table_get, Instruction::TableGet, u32,
- visit_table_set, Instruction::TableSet, u32,
- visit_table_grow, Instruction::TableGrow, u32,
- visit_table_size, Instruction::TableSize, u32
- }
}
diff --git a/crates/tinywasm/src/interpreter/simd.rs b/crates/tinywasm/src/interpreter/simd.rs
new file mode 100644
index 0000000..bc2f402
--- /dev/null
+++ b/crates/tinywasm/src/interpreter/simd.rs
@@ -0,0 +1,130 @@
+// WIP
+
+struct V128([u8; 16]);
+
+impl V128 {
+ fn f32x4(&self) -> [f32; 4] {
+ let mut res = [0.0; 4];
+ for i in 0..4 {
+ let mut f = [0; 4];
+ for j in 0..4 {
+ f[j] = self.0[i * 4 + j];
+ }
+ res[i] = f32::from_le_bytes(f);
+ }
+ res
+ }
+
+ fn i32x4(&self) -> [i32; 4] {
+ let mut res = [0; 4];
+ for i in 0..4 {
+ let mut f = [0; 4];
+ for j in 0..4 {
+ f[j] = self.0[i * 4 + j];
+ }
+ res[i] = i32::from_le_bytes(f);
+ }
+ res
+ }
+
+ fn i64x2(&self) -> [i64; 2] {
+ let mut res = [0; 2];
+ for i in 0..2 {
+ let mut f = [0; 8];
+ for j in 0..8 {
+ f[j] = self.0[i * 8 + j];
+ }
+ res[i] = i64::from_le_bytes(f);
+ }
+ res
+ }
+
+ fn f64x2(&self) -> [f64; 2] {
+ let mut res = [0.0; 2];
+ for i in 0..2 {
+ let mut f = [0; 8];
+ for j in 0..8 {
+ f[j] = self.0[i * 8 + j];
+ }
+ res[i] = f64::from_le_bytes(f);
+ }
+ res
+ }
+
+ fn i16x8(&self) -> [i16; 8] {
+ let mut res = [0; 8];
+ for i in 0..8 {
+ let mut f = [0; 2];
+ for j in 0..2 {
+ f[j] = self.0[i * 2 + j];
+ }
+ res[i] = i16::from_le_bytes(f);
+ }
+ res
+ }
+
+ fn i8x16(&self) -> [i8; 16] {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = i8::from_le_bytes([self.0[i]]);
+ }
+ res
+ }
+}
+
+fn vvunop(c1: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = !c1.0[i];
+ }
+ V128(res)
+}
+
+fn vvbinop(c1: V128, c2: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = c1.0[i] & c2.0[i];
+ }
+ V128(res)
+}
+
+fn vvternop(c1: V128, c2: V128, c3: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = c1.0[i] & c2.0[i] | !c1.0[i] & c3.0[i];
+ }
+ V128(res)
+}
+
+fn any_true(val: V128) -> bool {
+ val.0.iter().any(|&x| x != 0)
+}
+
+fn i8x16_swizzle(c1: V128, c2: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = c1.0[c2.0[i] as usize];
+ }
+ V128(res)
+}
+
+fn i18x16_shuffle(c1: V128, c2: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..16 {
+ res[i] = c1.0[(c2.0[i] & 0xf) as usize];
+ }
+ V128(res)
+}
+
+fn f32x4_abs(val: V128) -> V128 {
+ let mut res = [0; 16];
+ for i in 0..4 {
+ let f = val.f32x4();
+ let f = f32::abs(f[i]);
+ let f = f.to_le_bytes();
+ for j in 0..4 {
+ res[i * 4 + j] = f[j];
+ }
+ }
+ V128(res)
+}
diff --git a/crates/tinywasm/tests/test-wasm-2.rs b/crates/tinywasm/tests/test-wasm-2.rs
index bd1afe6..336632f 100644
--- a/crates/tinywasm/tests/test-wasm-2.rs
+++ b/crates/tinywasm/tests/test-wasm-2.rs
@@ -7,7 +7,7 @@ fn main() -> Result<()> {
let mut test_suite = TestSuite::new();
TestSuite::set_log_level(log::LevelFilter::Off);
- test_suite.run_spec_group(wasm_testsuite::V2_DRAFT_1_TESTS)?;
+ test_suite.run_spec_group(wasm_testsuite::V2_TESTS)?;
test_suite.save_csv("./tests/generated/wasm-2.csv", env!("CARGO_PKG_VERSION"))?;
if test_suite.failed() {
diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml
index 7531ab4..9d9f9af 100644
--- a/crates/types/Cargo.toml
+++ b/crates/types/Cargo.toml
@@ -10,7 +10,7 @@ rust-version.workspace=true
[dependencies]
log={workspace=true, optional=true}
-rkyv={version="0.8.0-rc.2", optional=true, default-features=false, features=["alloc", "bytecheck"]}
+rkyv={version="0.8.1", optional=true, default-features=false, features=["alloc", "bytecheck"]}
[features]
default=["std", "logging", "archive"]
diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs
index 2030942..a3c2fee 100644
--- a/crates/types/src/instructions.rs
+++ b/crates/types/src/instructions.rs
@@ -42,24 +42,6 @@ pub enum ConstInstruction {
// should be kept as small as possible (16 bytes max)
#[rustfmt::skip]
pub enum Instruction {
- // > Custom Instructions
- // // LocalGet + I32Const + I32Add
- // I32LocalGetConstAdd(LocalAddr, i32),
- // // LocalGet + I32Const + I32Store
- // I32ConstStoreLocal { local: LocalAddr, const_i32: i32, offset: u32, mem_addr: u8 },
- // // LocalGet + LocalGet + I32Store
- // I32StoreLocal { local_a: LocalAddr, local_b: LocalAddr, offset: u32, mem_addr: u8 },
- // // I64Xor + I64Const + I64RotL
- // // Commonly used by a few crypto libraries
- // I64XorConstRotl(i64),
- // // LocalTee + LocalGet
- // LocalTeeGet(LocalAddr, LocalAddr),
- // LocalGet2(LocalAddr, LocalAddr),
- // LocalGet3(LocalAddr, LocalAddr, LocalAddr),
- // LocalGetSet(LocalAddr, LocalAddr),
-
- // LocalGetGet32(LocalAddr, LocalAddr), LocalGetGet64(LocalAddr, LocalAddr), LocalGetGet128(LocalAddr, LocalAddr),
- // LocalTeeGet32(LocalAddr, LocalAddr), LocalTeeGet64(LocalAddr, LocalAddr), LocalTeeGet128(LocalAddr, LocalAddr),
LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(LocalAddr, LocalAddr), LocalCopy128Ref(LocalAddr, LocalAddr), LocalCopyRef(LocalAddr, LocalAddr),
LocalsStore32(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore64(LocalAddr, LocalAddr, u32, MemAddr), LocalsStore128(LocalAddr, LocalAddr, u32, MemAddr), LocalsStoreRef(LocalAddr, LocalAddr, u32, MemAddr),
@@ -205,4 +187,8 @@ pub enum Instruction {
MemoryFill(MemAddr),
DataDrop(DataAddr),
ElemDrop(ElemAddr),
+
+ // // > SIMD Instructions
+ // V128Load(MemoryArg), V128Load8x8S { offset: u64, mem_addr: MemAddr }, V128Load8x8U { offset: u64, mem_addr: MemAddr }, V128Load16x4S { offset: u64, mem_addr: MemAddr }, V128Load16x4U { offset: u64, mem_addr: MemAddr }, V128Load32x2S { offset: u64, mem_addr: MemAddr }, V128Load32x2U { offset: u64, mem_addr: MemAddr }, V128Load8Splat { offset: u64, mem_addr: MemAddr }, V128Load16Splat { offset: u64, mem_addr: MemAddr }, V128Load32Splat { offset: u64, mem_addr: MemAddr }, V128Load64Splat { offset: u64, mem_addr: MemAddr }, V128Load32Zero { offset: u64, mem_addr: MemAddr }, V128Load64Zero { offset: u64, mem_addr: MemAddr },
+ // V128Store { offset: u64, mem_addr: MemAddr }, V128Store8x8 { offset: u64, mem_addr: MemAddr }, V128Store16x4 { offset: u64, mem_addr: MemAddr }, V128Store32x2 { offset: u64, mem_addr: MemAddr },
}
diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs
index 12bf459..2a2892c 100644
--- a/crates/wasm-testsuite/lib.rs
+++ b/crates/wasm-testsuite/lib.rs
@@ -32,7 +32,7 @@ pub const MVP_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wa
/// List of all tests that apply to the V2 draft 1 spec.
#[rustfmt::skip]
-pub const V2_DRAFT_1_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "bulk.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_copy.wast", "memory_fill.wast", "memory_grow.wast", "memory_init.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "obsolete-keywords.wast", "ref_func.wast", "ref_is_null.wast", "ref_null.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table-sub.wast", "table.wast", "table_copy.wast", "table_fill.wast", "table_get.wast", "table_grow.wast", "table_init.wast", "table_set.wast", "table_size.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-invalid.wast", "unreached-valid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"];
+pub const V2_TESTS: &[&str] = &["address.wast", "align.wast", "binary-leb128.wast", "binary.wast", "block.wast", "br.wast", "br_if.wast", "br_table.wast", "bulk.wast", "call.wast", "call_indirect.wast", "comments.wast", "const.wast", "conversions.wast", "custom.wast", "data.wast", "elem.wast", "endianness.wast", "exports.wast", "f32.wast", "f32_bitwise.wast", "f32_cmp.wast", "f64.wast", "f64_bitwise.wast", "f64_cmp.wast", "fac.wast", "float_exprs.wast", "float_literals.wast", "float_memory.wast", "float_misc.wast", "forward.wast", "func.wast", "func_ptrs.wast", "global.wast", "i32.wast", "i64.wast", "if.wast", "imports.wast", "inline-module.wast", "int_exprs.wast", "int_literals.wast", "labels.wast", "left-to-right.wast", "linking.wast", "load.wast", "local_get.wast", "local_set.wast", "local_tee.wast", "loop.wast", "memory.wast", "memory_copy.wast", "memory_fill.wast", "memory_grow.wast", "memory_init.wast", "memory_redundancy.wast", "memory_size.wast", "memory_trap.wast", "names.wast", "nop.wast", "obsolete-keywords.wast", "ref_func.wast", "ref_is_null.wast", "ref_null.wast", "return.wast", "select.wast", "skip-stack-guard-page.wast", "stack.wast", "start.wast", "store.wast", "switch.wast", "table-sub.wast", "table.wast", "table_copy.wast", "table_fill.wast", "table_get.wast", "table_grow.wast", "table_init.wast", "table_set.wast", "table_size.wast", "token.wast", "traps.wast", "type.wast", "unreachable.wast", "unreached-invalid.wast", "unreached-valid.wast", "unwind.wast", "utf8-custom-section-id.wast", "utf8-import-field.wast", "utf8-import-module.wast", "utf8-invalid-encoding.wast"];
/// List of all tests that apply to the simd proposal
#[rustfmt::skip]