diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/cli/Cargo.toml | 2 | ||||
| -rw-r--r-- | crates/parser/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/parser/src/conversion.rs | 4 | ||||
| -rw-r--r-- | crates/parser/src/lib.rs | 3 | ||||
| -rw-r--r-- | crates/parser/src/module.rs | 21 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 130 | ||||
| -rw-r--r-- | crates/tinywasm/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/executor.rs | 56 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/stack/call_stack.rs | 27 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/stack/value_stack.rs | 4 | ||||
| -rw-r--r-- | crates/tinywasm/src/interpreter/values.rs | 46 | ||||
| -rw-r--r-- | crates/tinywasm/tests/generated/wasm-simd.csv | 1 | ||||
| -rw-r--r-- | crates/types/src/instructions.rs | 211 | ||||
| -rw-r--r-- | crates/types/src/lib.rs | 38 | ||||
| -rw-r--r-- | crates/wasm-testsuite/Cargo.toml | 2 |
15 files changed, 382 insertions, 171 deletions
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 51a669d..d5e64a8 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,7 +15,7 @@ path="src/bin.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tinywasm={version="0.8.0-alpha.0", path="../tinywasm", features=["std", "parser"]} +tinywasm={version="0.9.0-alpha.0", path="../tinywasm", features=["std", "parser"]} argh="0.1" eyre={workspace=true} log={workspace=true} diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index aa2f589..83bb32b 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -9,9 +9,9 @@ repository.workspace=true rust-version.workspace=true [dependencies] -wasmparser={version="0.218", default-features=false, features=["validate", "features"]} +wasmparser={version="0.219", default-features=false, features=["validate", "features"]} log={workspace=true, optional=true} -tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} +tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} [features] default=["std", "logging"] diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 76099ca..1ebe392 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -203,8 +203,8 @@ pub(crate) fn convert_module_code( } } - let (body, allocations) = process_operators_and_validate(validator, func, local_addr_map)?; - Ok(((body, local_counts), allocations)) + let (body, data, allocations) = process_operators_and_validate(validator, func, local_addr_map)?; + Ok(((body, data, local_counts), allocations)) } pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType> { diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index e736576..2222ffa 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -61,10 +61,11 @@ impl Parser { function_references: true, tail_call: true, multi_memory: true, - memory64: false, simd: true, + memory64: true, custom_page_sizes: true, + wide_arithmetic: false, gc_types: true, stack_switching: false, component_model: false, diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index ff7d109..9b31f9e 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -3,12 +3,12 @@ use crate::{conversion, ParseError, Result}; use alloc::string::ToString; use alloc::{boxed::Box, format, vec::Vec}; use tinywasm_types::{ - Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, TinyWasmModule, ValType, - ValueCounts, ValueCountsSmall, WasmFunction, + Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, TinyWasmModule, ValueCounts, + ValueCountsSmall, WasmFunction, WasmFunctionData, }; use wasmparser::{FuncValidatorAllocations, Payload, Validator}; -pub(crate) type Code = (Box<[Instruction]>, ValueCounts); +pub(crate) type Code = (Box<[Instruction]>, WasmFunctionData, ValueCounts); #[derive(Default)] pub(crate) struct ModuleReader { @@ -179,7 +179,6 @@ impl ModuleReader { Ok(()) } - #[inline] pub(crate) fn into_module(self) -> Result<TinyWasmModule> { if !self.end_reached { return Err(ParseError::EndNotReached); @@ -193,18 +192,10 @@ impl ModuleReader { .code .into_iter() .zip(self.code_type_addrs) - .map(|((instructions, locals), ty_idx)| { - let mut params = ValueCountsSmall::default(); + .map(|((instructions, data, locals), ty_idx)| { let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(); - for param in &ty.params { - match param { - ValType::I32 | ValType::F32 => params.c32 += 1, - ValType::I64 | ValType::F64 => params.c64 += 1, - ValType::V128 => params.c128 += 1, - ValType::RefExtern | ValType::RefFunc => params.cref += 1, - } - } - WasmFunction { instructions, locals, params, ty } + let params = ValueCountsSmall::from(&ty.params); + WasmFunction { instructions, data, locals, params, ty } }) .collect::<Vec<_>>() .into_boxed_slice(); diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index c9e5eac..2e80d20 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}; +use tinywasm_types::{Instruction, MemoryArg, SimdInstruction, WasmFunctionData}; use wasmparser::{FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, WasmModuleResources}; struct ValidateThenVisit<'a, R: WasmModuleResources>(usize, &'a mut FunctionBuilder<R>); @@ -26,7 +26,7 @@ pub(crate) fn process_operators_and_validate<R: WasmModuleResources>( validator: FuncValidator<R>, body: FunctionBody<'_>, local_addr_map: Vec<u32>, -) -> Result<(Box<[Instruction]>, FuncValidatorAllocations)> { +) -> Result<(Box<[Instruction]>, WasmFunctionData, FuncValidatorAllocations)> { let mut reader = body.get_operators_reader()?; let remaining = reader.get_binary_reader().bytes_remaining(); let mut builder = FunctionBuilder::new(remaining, validator, local_addr_map); @@ -40,42 +40,65 @@ pub(crate) fn process_operators_and_validate<R: WasmModuleResources>( return Err(builder.errors.remove(0)); } - Ok((builder.instructions.into_boxed_slice(), builder.validator.into_allocations())) + Ok(( + builder.instructions.into_boxed_slice(), + WasmFunctionData { v128_constants: builder.v128_constants.into_boxed_slice() }, + builder.validator.into_allocations(), + )) } macro_rules! define_operand { - ($name:ident($instr:ident, $ty:ty)) => { + ($name:ident($instr:expr, $ty:ty)) => { fn $name(&mut self, arg: $ty) -> Self::Output { - self.instructions.push(Instruction::$instr(arg)); + self.instructions.push($instr(arg).into()); } }; - ($name:ident($instr:ident, $ty:ty, $ty2:ty)) => { + ($name:ident($instr:expr, $ty:ty, $ty2:ty)) => { fn $name(&mut self, arg: $ty, arg2: $ty2) -> Self::Output { - self.instructions.push(Instruction::$instr(arg, arg2)); + self.instructions.push($instr(arg, arg2).into()); } }; - ($name:ident($instr:ident)) => { + ($name:ident($instr:expr)) => { fn $name(&mut self) -> Self::Output { - self.instructions.push(Instruction::$instr); + self.instructions.push($instr.into()); } }; } macro_rules! define_operands { ($($name:ident($instr:ident $(,$ty:ty)*)),*) => {$( - define_operand!($name($instr $(,$ty)*)); + define_operand!($name(Instruction::$instr $(,$ty)*)); + )*}; +} + +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 { - self.instructions.push(Instruction::$instr { - offset: memarg.offset, - mem_addr: memarg.memory, - }); + self.instructions.push(Instruction::$instr(MemoryArg::new(memarg.offset, memarg.memory))); + } + )*}; +} + +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()); + } + )*}; +} + +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()); } )*}; } @@ -83,6 +106,7 @@ macro_rules! define_mem_operands { pub(crate) struct FunctionBuilder<R: WasmModuleResources> { validator: FuncValidator<R>, instructions: Vec<Instruction>, + v128_constants: Vec<u128>, label_ptrs: Vec<usize>, local_addr_map: Vec<u32>, errors: Vec<crate::ParseError>, @@ -107,6 +131,7 @@ impl<R: WasmModuleResources> FunctionBuilder<R> { validator, local_addr_map, instructions: Vec::with_capacity(instr_capacity), + v128_constants: Vec::new(), label_ptrs: Vec::with_capacity(256), errors: Vec::new(), } @@ -127,8 +152,8 @@ macro_rules! impl_visit_operator { (@@sign_extension $($rest:tt)* ) => {}; (@@saturating_float_to_int $($rest:tt)* ) => {}; (@@bulk_memory $($rest:tt)* ) => {}; - (@@tail_call $($rest:tt)* ) => {}; - // (@@simd $($rest:tt)* ) => {}; + // (@@tail_call $($rest:tt)* ) => {}; + (@@simd $($rest:tt)* ) => {}; (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { #[cold] fn $visit(&mut self $($(,$arg: $argty)*)?) { @@ -142,7 +167,7 @@ impl<R: WasmModuleResources> wasmparser::VisitOperator<'_> for FunctionBuilder<R wasmparser::for_each_operator!(impl_visit_operator); 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), 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! { @@ -160,19 +185,73 @@ impl<R: WasmModuleResources> wasmparser::VisitOperator<'_> for FunctionBuilder<R // 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) + // simd + define_mem_operands_simd! { + visit_v128_load(V128Load), visit_v128_load8x8_s(V128Load8x8S), visit_v128_load8x8_u(V128Load8x8U), visit_v128_load16x4_s(V128Load16x4S), visit_v128_load16x4_u(V128Load16x4U), visit_v128_load32x2_s(V128Load32x2S), visit_v128_load32x2_u(V128Load32x2U), visit_v128_load8_splat(V128Load8Splat), visit_v128_load16_splat(V128Load16Splat), visit_v128_load32_splat(V128Load32Splat), visit_v128_load64_splat(V128Load64Splat), visit_v128_load32_zero(V128Load32Zero), visit_v128_load64_zero(V128Load64Zero), visit_v128_store(V128Store) + } + define_mem_operands_simd_lane! { + 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! { + 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), + visit_i32x4_splat(I32x4Splat), visit_i32x4_eq(I32x4Eq), visit_i32x4_ne(I32x4Ne), visit_i32x4_lt_s(I32x4LtS), visit_i32x4_lt_u(I32x4LtU), visit_i32x4_gt_s(I32x4GtS), visit_i32x4_gt_u(I32x4GtU), visit_i32x4_le_s(I32x4LeS), visit_i32x4_le_u(I32x4LeU), visit_i32x4_ge_s(I32x4GeS), visit_i32x4_ge_u(I32x4GeU), + visit_i64x2_splat(I64x2Splat), visit_i64x2_eq(I64x2Eq), visit_i64x2_ne(I64x2Ne), visit_i64x2_lt_s(I64x2LtS), visit_i64x2_gt_s(I64x2GtS), visit_i64x2_le_s(I64x2LeS), visit_i64x2_ge_s(I64x2GeS), + visit_f32x4_splat(F32x4Splat), visit_f32x4_eq(F32x4Eq), visit_f32x4_ne(F32x4Ne), visit_f32x4_lt(F32x4Lt), visit_f32x4_gt(F32x4Gt), visit_f32x4_le(F32x4Le), visit_f32x4_ge(F32x4Ge), + visit_f64x2_splat(F64x2Splat), visit_f64x2_eq(F64x2Eq), visit_f64x2_ne(F64x2Ne), visit_f64x2_lt(F64x2Lt), visit_f64x2_gt(F64x2Gt), visit_f64x2_le(F64x2Le), visit_f64x2_ge(F64x2Ge), + visit_i8x16_abs(I8x16Abs), visit_i8x16_neg(I8x16Neg), visit_i8x16_all_true(I8x16AllTrue), visit_i8x16_bitmask(I8x16Bitmask), visit_i8x16_shl(I8x16Shl), visit_i8x16_shr_s(I8x16ShrS), visit_i8x16_shr_u(I8x16ShrU), visit_i8x16_add(I8x16Add), visit_i8x16_sub(I8x16Sub), visit_i8x16_min_s(I8x16MinS), visit_i8x16_min_u(I8x16MinU), visit_i8x16_max_s(I8x16MaxS), visit_i8x16_max_u(I8x16MaxU), + visit_i16x8_abs(I16x8Abs), visit_i16x8_neg(I16x8Neg), visit_i16x8_all_true(I16x8AllTrue), visit_i16x8_bitmask(I16x8Bitmask), visit_i16x8_shl(I16x8Shl), visit_i16x8_shr_s(I16x8ShrS), visit_i16x8_shr_u(I16x8ShrU), visit_i16x8_add(I16x8Add), visit_i16x8_sub(I16x8Sub), visit_i16x8_min_s(I16x8MinS), visit_i16x8_min_u(I16x8MinU), visit_i16x8_max_s(I16x8MaxS), visit_i16x8_max_u(I16x8MaxU), + visit_i32x4_abs(I32x4Abs), visit_i32x4_neg(I32x4Neg), visit_i32x4_all_true(I32x4AllTrue), visit_i32x4_bitmask(I32x4Bitmask), visit_i32x4_shl(I32x4Shl), visit_i32x4_shr_s(I32x4ShrS), visit_i32x4_shr_u(I32x4ShrU), visit_i32x4_add(I32x4Add), visit_i32x4_sub(I32x4Sub), visit_i32x4_min_s(I32x4MinS), visit_i32x4_min_u(I32x4MinU), visit_i32x4_max_s(I32x4MaxS), visit_i32x4_max_u(I32x4MaxU), + visit_i64x2_abs(I64x2Abs), visit_i64x2_neg(I64x2Neg), visit_i64x2_all_true(I64x2AllTrue), visit_i64x2_bitmask(I64x2Bitmask), visit_i64x2_shl(I64x2Shl), visit_i64x2_shr_s(I64x2ShrS), visit_i64x2_shr_u(I64x2ShrU), visit_i64x2_add(I64x2Add), visit_i64x2_sub(I64x2Sub), visit_i64x2_mul(I64x2Mul), + visit_i8x16_narrow_i16x8_s(I8x16NarrowI16x8S), visit_i8x16_narrow_i16x8_u(I8x16NarrowI16x8U), visit_i8x16_add_sat_s(I8x16AddSatS), visit_i8x16_add_sat_u(I8x16AddSatU), visit_i8x16_sub_sat_s(I8x16SubSatS), visit_i8x16_sub_sat_u(I8x16SubSatU), visit_i8x16_avgr_u(I8x16AvgrU), + visit_i16x8_narrow_i32x4_s(I16x8NarrowI32x4S), visit_i16x8_narrow_i32x4_u(I16x8NarrowI32x4U), visit_i16x8_add_sat_s(I16x8AddSatS), visit_i16x8_add_sat_u(I16x8AddSatU), visit_i16x8_sub_sat_s(I16x8SubSatS), visit_i16x8_sub_sat_u(I16x8SubSatU), visit_i16x8_avgr_u(I16x8AvgrU), + visit_i16x8_extadd_pairwise_i8x16_s(I16x8ExtAddPairwiseI8x16S), visit_i16x8_extadd_pairwise_i8x16_u(I16x8ExtAddPairwiseI8x16U), visit_i16x8_mul(I16x8Mul), + visit_i32x4_extadd_pairwise_i16x8_s(I32x4ExtAddPairwiseI16x8S), visit_i32x4_extadd_pairwise_i16x8_u(I32x4ExtAddPairwiseI16x8U), visit_i32x4_mul(I32x4Mul), + visit_i16x8_extmul_low_i8x16_s(I16x8ExtMulLowI8x16S), visit_i16x8_extmul_low_i8x16_u(I16x8ExtMulLowI8x16U), visit_i16x8_extmul_high_i8x16_s(I16x8ExtMulHighI8x16S), visit_i16x8_extmul_high_i8x16_u(I16x8ExtMulHighI8x16U), + visit_i32x4_extmul_low_i16x8_s(I32x4ExtMulLowI16x8S), visit_i32x4_extmul_low_i16x8_u(I32x4ExtMulLowI16x8U), visit_i32x4_extmul_high_i16x8_s(I32x4ExtMulHighI16x8S), visit_i32x4_extmul_high_i16x8_u(I32x4ExtMulHighI16x8U), + visit_i64x2_extmul_low_i32x4_s(I64x2ExtMulLowI32x4S), visit_i64x2_extmul_low_i32x4_u(I64x2ExtMulLowI32x4U), visit_i64x2_extmul_high_i32x4_s(I64x2ExtMulHighI32x4S), visit_i64x2_extmul_high_i32x4_u(I64x2ExtMulHighI32x4U), + visit_i16x8_extend_low_i8x16_s(I16x8ExtendLowI8x16S), visit_i16x8_extend_low_i8x16_u(I16x8ExtendLowI8x16U), visit_i16x8_extend_high_i8x16_s(I16x8ExtendHighI8x16S), visit_i16x8_extend_high_i8x16_u(I16x8ExtendHighI8x16U), + visit_i32x4_extend_low_i16x8_s(I32x4ExtendLowI16x8S), visit_i32x4_extend_low_i16x8_u(I32x4ExtendLowI16x8U), visit_i32x4_extend_high_i16x8_s(I32x4ExtendHighI16x8S), visit_i32x4_extend_high_i16x8_u(I32x4ExtendHighI16x8U), + visit_i64x2_extend_low_i32x4_s(I64x2ExtendLowI32x4S), visit_i64x2_extend_low_i32x4_u(I64x2ExtendLowI32x4U), visit_i64x2_extend_high_i32x4_s(I64x2ExtendHighI32x4S), visit_i64x2_extend_high_i32x4_u(I64x2ExtendHighI32x4U), + visit_i8x16_popcnt(I8x16Popcnt), visit_i16x8_q15mulr_sat_s(I16x8Q15MulrSatS), visit_i32x4_dot_i16x8_s(I32x4DotI16x8S), + visit_f32x4_ceil(F32x4Ceil), visit_f32x4_floor(F32x4Floor), visit_f32x4_trunc(F32x4Trunc), visit_f32x4_nearest(F32x4Nearest), visit_f32x4_abs(F32x4Abs), visit_f32x4_neg(F32x4Neg), visit_f32x4_sqrt(F32x4Sqrt), visit_f32x4_add(F32x4Add), visit_f32x4_sub(F32x4Sub), visit_f32x4_mul(F32x4Mul), visit_f32x4_div(F32x4Div), visit_f32x4_min(F32x4Min), visit_f32x4_max(F32x4Max), visit_f32x4_pmin(F32x4PMin), visit_f32x4_pmax(F32x4PMax), + visit_f64x2_ceil(F64x2Ceil), visit_f64x2_floor(F64x2Floor), visit_f64x2_trunc(F64x2Trunc), visit_f64x2_nearest(F64x2Nearest), visit_f64x2_abs(F64x2Abs), visit_f64x2_neg(F64x2Neg), visit_f64x2_sqrt(F64x2Sqrt), visit_f64x2_add(F64x2Add), visit_f64x2_sub(F64x2Sub), visit_f64x2_mul(F64x2Mul), visit_f64x2_div(F64x2Div), visit_f64x2_min(F64x2Min), visit_f64x2_max(F64x2Max), visit_f64x2_pmin(F64x2PMin), visit_f64x2_pmax(F64x2PMax), + visit_i32x4_trunc_sat_f32x4_s(I32x4TruncSatF32x4S), visit_i32x4_trunc_sat_f32x4_u(I32x4TruncSatF32x4U), + visit_f32x4_convert_i32x4_s(F32x4ConvertI32x4S), visit_f32x4_convert_i32x4_u(F32x4ConvertI32x4U), + visit_i32x4_trunc_sat_f64x2_s_zero(I32x4TruncSatF64x2SZero), visit_i32x4_trunc_sat_f64x2_u_zero(I32x4TruncSatF64x2UZero), + visit_f64x2_convert_low_i32x4_s(F64x2ConvertLowI32x4S), visit_f64x2_convert_low_i32x4_u(F64x2ConvertLowI32x4U), + visit_f32x4_demote_f64x2_zero(F32x4DemoteF64x2Zero), visit_f64x2_promote_low_f32x4(F64x2PromoteLowF32x4), - fn visit_return_call(&mut self, function_index: u32) -> Self::Output { - self.instructions.push(Instruction::ReturnCall(function_index)); + visit_i8x16_extract_lane_s(I8x16ExtractLaneS, u8), visit_i8x16_extract_lane_u(I8x16ExtractLaneU, u8), visit_i8x16_replace_lane(I8x16ReplaceLane, u8), + visit_i16x8_extract_lane_s(I16x8ExtractLaneS, u8), visit_i16x8_extract_lane_u(I16x8ExtractLaneU, u8), visit_i16x8_replace_lane(I16x8ReplaceLane, u8), + visit_i32x4_extract_lane(I32x4ExtractLane, u8), visit_i32x4_replace_lane(I32x4ReplaceLane, u8), + visit_i64x2_extract_lane(I64x2ExtractLane, u8), visit_i64x2_replace_lane(I64x2ReplaceLane, u8), + visit_f32x4_extract_lane(F32x4ExtractLane, u8), visit_f32x4_replace_lane(F32x4ReplaceLane, u8), + visit_f64x2_extract_lane(F64x2ExtractLane, u8), visit_f64x2_replace_lane(F64x2ReplaceLane, u8) } - fn visit_return_call_indirect(&mut self, type_index: u32, table_index: u32) -> Self::Output { - self.instructions.push(Instruction::ReturnCallIndirect(type_index, table_index)); + 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()); } + 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()); + } + + // fn visit_return_call(&mut self, function_index: u32) -> Self::Output { + // self.instructions.push(Instruction::ReturnCall(function_index)); + // } + + // fn visit_return_call_indirect(&mut self, type_index: u32, table_index: u32) -> Self::Output { + // self.instructions.push(Instruction::ReturnCallIndirect(type_index, table_index)); + // } + fn visit_global_set(&mut self, global_index: u32) -> Self::Output { match self.validator.get_operand_type(0) { Some(Some(t)) => self.instructions.push(match t { @@ -206,11 +285,6 @@ impl<R: WasmModuleResources> wasmparser::VisitOperator<'_> for FunctionBuilder<R _ => self.visit_unreachable(), } } - fn visit_i32_store(&mut self, memarg: wasmparser::MemArg) -> Self::Output { - let arg = MemoryArg { offset: memarg.offset, mem_addr: memarg.memory }; - let i32store = Instruction::I32Store { offset: arg.offset, mem_addr: arg.mem_addr }; - self.instructions.push(i32store); - } fn visit_local_get(&mut self, idx: u32) -> Self::Output { let Ok(resolved_idx) = self.local_addr_map[idx as usize].try_into() else { diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml index 4dc82bb..401e3de 100644 --- a/crates/tinywasm/Cargo.toml +++ b/crates/tinywasm/Cargo.toml @@ -15,8 +15,8 @@ path="src/lib.rs" [dependencies] log={workspace=true, optional=true} -tinywasm-parser={version="0.8.0-alpha.0", path="../parser", default-features=false, optional=true} -tinywasm-types={version="0.8.0-alpha.0", path="../types", default-features=false} +tinywasm-parser={version="0.9.0-alpha.0", path="../parser", default-features=false, optional=true} +tinywasm-types={version="0.9.0-alpha.0", path="../types", default-features=false} libm={version="0.2", default-features=false} [dev-dependencies] diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index c2df82c..2326227 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -26,7 +26,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { Ok(Self { cf: current_frame, module: current_module, stack, store }) } - #[inline] + #[inline(always)] pub(crate) fn run_to_completion(&mut self) -> Result<()> { loop { if let ControlFlow::Break(res) = self.exec_next() { @@ -114,30 +114,30 @@ impl<'store, 'stack> Executor<'store, 'stack> { ElemDrop(elem_index) => self.exec_elem_drop(*elem_index), TableCopy { from, to } => self.exec_table_copy(*from, *to).to_cf()?, - I32Store { mem_addr, offset } => self.exec_mem_store::<i32, i32, 4>(*mem_addr, *offset, |v| v)?, - I64Store { mem_addr, offset } => self.exec_mem_store::<i64, i64, 8>(*mem_addr, *offset, |v| v)?, - F32Store { mem_addr, offset } => self.exec_mem_store::<f32, f32, 4>(*mem_addr, *offset, |v| v)?, - F64Store { mem_addr, offset } => self.exec_mem_store::<f64, f64, 8>(*mem_addr, *offset, |v| v)?, - I32Store8 { mem_addr, offset } => self.exec_mem_store::<i32, i8, 1>(*mem_addr, *offset, |v| v as i8)?, - I32Store16 { mem_addr, offset } => self.exec_mem_store::<i32, i16, 2>(*mem_addr, *offset, |v| v as i16)?, - I64Store8 { mem_addr, offset } => self.exec_mem_store::<i64, i8, 1>(*mem_addr, *offset, |v| v as i8)?, - I64Store16 { mem_addr, offset } => self.exec_mem_store::<i64, i16, 2>(*mem_addr, *offset, |v| v as i16)?, - I64Store32 { mem_addr, offset } => self.exec_mem_store::<i64, i32, 4>(*mem_addr, *offset, |v| v as i32)?, + I32Store(m) => self.exec_mem_store::<i32, i32, 4>(m.mem_addr(), m.offset(), |v| v)?, + I64Store(m) => self.exec_mem_store::<i64, i64, 8>(m.mem_addr(), m.offset(), |v| v)?, + F32Store(m) => self.exec_mem_store::<f32, f32, 4>(m.mem_addr(), m.offset(), |v| v)?, + F64Store(m) => self.exec_mem_store::<f64, f64, 8>(m.mem_addr(), m.offset(), |v| v)?, + I32Store8(m) => self.exec_mem_store::<i32, i8, 1>(m.mem_addr(), m.offset(), |v| v as i8)?, + I32Store16(m) => self.exec_mem_store::<i32, i16, 2>(m.mem_addr(), m.offset(), |v| v as i16)?, + I64Store8(m) => self.exec_mem_store::<i64, i8, 1>(m.mem_addr(), m.offset(), |v| v as i8)?, + I64Store16(m) => self.exec_mem_store::<i64, i16, 2>(m.mem_addr(), m.offset(), |v| v as i16)?, + I64Store32(m) => self.exec_mem_store::<i64, i32, 4>(m.mem_addr(), m.offset(), |v| v as i32)?, - I32Load { mem_addr, offset } => self.exec_mem_load::<i32, 4, _>(*mem_addr, *offset, |v| v)?, - I64Load { mem_addr, offset } => self.exec_mem_load::<i64, 8, _>(*mem_addr, *offset, |v| v)?, - F32Load { mem_addr, offset } => self.exec_mem_load::<f32, 4, _>(*mem_addr, *offset, |v| v)?, - F64Load { mem_addr, offset } => self.exec_mem_load::<f64, 8, _>(*mem_addr, *offset, |v| v)?, - I32Load8S { mem_addr, offset } => self.exec_mem_load::<i8, 1, _>(*mem_addr, *offset, |v| v as i32)?, - I32Load8U { mem_addr, offset } => self.exec_mem_load::<u8, 1, _>(*mem_addr, *offset, |v| v as i32)?, - I32Load16S { mem_addr, offset } => self.exec_mem_load::<i16, 2, _>(*mem_addr, *offset, |v| v as i32)?, - I32Load16U { mem_addr, offset } => self.exec_mem_load::<u16, 2, _>(*mem_addr, *offset, |v| v as i32)?, - I64Load8S { mem_addr, offset } => self.exec_mem_load::<i8, 1, _>(*mem_addr, *offset, |v| v as i64)?, - I64Load8U { mem_addr, offset } => self.exec_mem_load::<u8, 1, _>(*mem_addr, *offset, |v| v as i64)?, - I64Load16S { mem_addr, offset } => self.exec_mem_load::<i16, 2, _>(*mem_addr, *offset, |v| v as i64)?, - I64Load16U { mem_addr, offset } => self.exec_mem_load::<u16, 2, _>(*mem_addr, *offset, |v| v as i64)?, - I64Load32S { mem_addr, offset } => self.exec_mem_load::<i32, 4, _>(*mem_addr, *offset, |v| v as i64)?, - I64Load32U { mem_addr, offset } => self.exec_mem_load::<u32, 4, _>(*mem_addr, *offset, |v| v as i64)?, + I32Load(m) => self.exec_mem_load::<i32, 4, _>(m.mem_addr(), m.offset(), |v| v)?, + I64Load(m) => self.exec_mem_load::<i64, 8, _>(m.mem_addr(), m.offset(), |v| v)?, + F32Load(m) => self.exec_mem_load::<f32, 4, _>(m.mem_addr(), m.offset(), |v| v)?, + F64Load(m) => self.exec_mem_load::<f64, 8, _>(m.mem_addr(), m.offset(), |v| v)?, + I32Load8S(m) => self.exec_mem_load::<i8, 1, _>(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load8U(m) => self.exec_mem_load::<u8, 1, _>(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load16S(m) => self.exec_mem_load::<i16, 2, _>(m.mem_addr(), m.offset(), |v| v as i32)?, + I32Load16U(m) => self.exec_mem_load::<u16, 2, _>(m.mem_addr(), m.offset(), |v| v as i32)?, + I64Load8S(m) => self.exec_mem_load::<i8, 1, _>(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load8U(m) => self.exec_mem_load::<u8, 1, _>(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load16S(m) => self.exec_mem_load::<i16, 2, _>(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load16U(m) => self.exec_mem_load::<u16, 2, _>(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load32S(m) => self.exec_mem_load::<i32, 4, _>(m.mem_addr(), m.offset(), |v| v as i64)?, + I64Load32U(m) => self.exec_mem_load::<u32, 4, _>(m.mem_addr(), m.offset(), |v| v as i64)?, I64Eqz => self.stack.values.replace_top::<i64, _>(|v| Ok(i32::from(v == 0))).to_cf()?, I32Eqz => self.stack.values.replace_top_same::<i32>(|v| Ok(i32::from(v == 0))).to_cf()?, @@ -302,6 +302,10 @@ 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(_) => { + unreachable!("unimplemented sidm instruction"); + } + instr => { unreachable!("unimplemented instruction: {:?}", instr); } @@ -585,10 +589,10 @@ impl<'store, 'stack> Executor<'store, 'stack> { mem.store(dst as usize, size as usize, &data[offset as usize..((offset + size) as usize)]) } fn exec_data_drop(&mut self, data_index: u32) { - self.store.get_data_mut(self.module.resolve_data_addr(data_index)).drop() + self.store.get_data_mut(self.module.resolve_data_addr(data_index)).drop(); } fn exec_elem_drop(&mut self, elem_index: u32) { - self.store.get_elem_mut(self.module.resolve_elem_addr(elem_index)).drop() + self.store.get_elem_mut(self.module.resolve_elem_addr(elem_index)).drop(); } fn exec_table_copy(&mut self, from: u32, to: u32) -> Result<()> { let size: i32 = self.stack.values.pop(); diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index 7c2be9c..f0e8d18 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -22,12 +22,12 @@ impl CallStack { Self { stack: vec![initial_frame] } } - #[inline(always)] + #[inline] pub(crate) fn pop(&mut self) -> Option<CallFrame> { self.stack.pop() } - #[inline(always)] + #[inline] pub(crate) fn push(&mut self, call_frame: CallFrame) -> ControlFlow<Option<Error>> { if unlikely((self.stack.len() + 1) >= MAX_CALL_STACK_SIZE) { return ControlFlow::Break(Some(Trap::CallStackOverflow.into())); @@ -60,44 +60,47 @@ impl Locals { } pub(crate) fn set<T: InternalValue>(&mut self, local_index: LocalAddr, value: T) { - T::local_set(self, local_index, value) + T::local_set(self, local_index, value); } } impl CallFrame { - #[inline(always)] + #[inline] pub(crate) fn instr_ptr(&self) -> usize { self.instr_ptr } - #[inline(always)] + #[inline] pub(crate) fn incr_instr_ptr(&mut self) { self.instr_ptr += 1; } - #[inline(always)] + #[inline] pub(crate) fn jump(&mut self, offset: usize) { self.instr_ptr += offset; } - #[inline(always)] + #[inline] pub(crate) fn module_addr(&self) -> ModuleInstanceAddr { self.module_addr } - #[inline(always)] + #[inline] pub(crate) fn block_ptr(&self) -> u32 { self.block_ptr } #[inline(always)] pub(crate) fn fetch_instr(&self) -> &Instruction { - &self.func_instance.instructions[self.instr_ptr] + match self.func_instance.instructions.get(self.instr_ptr) { + Some(instr) => instr, + None => unreachable!("Instruction out of bounds, this is a bug"), + } } /// Break to a block at the given index (relative to the current frame) /// Returns `None` if there is no block at the given index (e.g. if we need to return, this is handled by the caller) - #[inline(always)] + #[inline] pub(crate) fn break_to( &mut self, break_to_relative: u32, @@ -140,7 +143,7 @@ impl CallFrame { Some(()) } - #[inline(always)] + #[inline] pub(crate) fn new( wasm_func_inst: Rc<WasmFunction>, owner: ModuleInstanceAddr, @@ -192,7 +195,7 @@ impl CallFrame { Self { instr_ptr: 0, func_instance: wasm_func_inst, module_addr: owner, block_ptr, locals } } - #[inline(always)] + #[inline] pub(crate) fn instructions(&self) -> &[Instruction] { &self.func_instance.instructions } diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 03c676e..7cbf612 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -48,7 +48,7 @@ impl ValueStack { #[inline] pub(crate) fn push<T: InternalValue>(&mut self, value: T) { - T::stack_push(self, value) + T::stack_push(self, value); } #[inline] @@ -180,7 +180,7 @@ impl ValueStack { pub(crate) fn extend_from_wasmvalues(&mut self, values: &[WasmValue]) { for value in values { - self.push_dyn(value.into()) + self.push_dyn(value.into()); } } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index 7b363a8..99cf443 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -169,7 +169,6 @@ macro_rules! impl_internalvalue { impl sealed::Sealed for $outer {} impl From<$outer> for TinyWasmValue { - #[inline(always)] fn from(value: $outer) -> Self { TinyWasmValue::$variant($to_internal(value)) } @@ -180,44 +179,59 @@ macro_rules! impl_internalvalue { fn stack_push(stack: &mut ValueStack, value: Self) { stack.$stack.push($to_internal(value)); } + #[inline(always)] fn stack_pop(stack: &mut ValueStack) -> Self { - ($to_outer)(stack.$stack.pop().expect("ValueStack underflow, this is a bug")) + match stack.$stack.pop() { + Some(v) => $to_outer(v), + None => unreachable!("ValueStack underflow, this is a bug"), + } } + #[inline(always)] fn stack_peek(stack: &ValueStack) -> Self { - ($to_outer)(*stack.$stack.last().expect("ValueStack underflow, this is a bug")) + match stack.$stack.last() { + Some(v) => $to_outer(*v), + None => unreachable!("ValueStack underflow, this is a bug"), + } } #[inline(always)] fn stack_calculate(stack: &mut ValueStack, func: fn(Self, Self) -> Result<Self>) -> Result<()> { let v2 = stack.$stack.pop(); let v1 = stack.$stack.last_mut(); - if let (Some(v1), Some(v2)) = (v1, v2) { - *v1 = $to_internal(func($to_outer(*v1), $to_outer(v2))?); - } else { - unreachable!("ValueStack underflow, this is a bug"); - } - Ok(()) + let (Some(v1), Some(v2)) = (v1, v2) else { + unreachable!("ValueStack underflow, this is a bug"); + }; + + *v1 = $to_internal(func($to_outer(*v1), $to_outer(v2))?); + return Ok(()) } #[inline(always)] fn replace_top(stack: &mut ValueStack, func: fn(Self) -> Result<Self>) -> Result<()> { - if let Some(v) = stack.$stack.last_mut() { - *v = $to_internal(func($to_outer(*v))?); - Ok(()) - } else { + let Some(v) = stack.$stack.last_mut() else { unreachable!("ValueStack underflow, this is a bug"); - } + }; + + *v = $to_internal(func($to_outer(*v))?); + Ok(()) } #[inline(always)] fn local_get(locals: &Locals, index: LocalAddr) -> Self { - $to_outer(locals.$locals[index as usize]) + match locals.$locals.get(index as usize) { + Some(v) => $to_outer(*v), + None => unreachable!("Local variable out of bounds, this is a bug"), + } } + #[inline(always)] fn local_set(locals: &mut Locals, index: LocalAddr, value: Self) { - locals.$locals[index as usize] = $to_internal(value); + match locals.$locals.get_mut(index as usize) { + Some(v) => *v = $to_internal(value), + None => unreachable!("Local variable out of bounds, this is a bug"), + } } } )* diff --git a/crates/tinywasm/tests/generated/wasm-simd.csv b/crates/tinywasm/tests/generated/wasm-simd.csv index e9bc8ae..a7fc7ef 100644 --- a/crates/tinywasm/tests/generated/wasm-simd.csv +++ b/crates/tinywasm/tests/generated/wasm-simd.csv @@ -1 +1,2 @@ 0.8.0,1300,24679,[{"name":"simd_address.wast","passed":4,"failed":45},{"name":"simd_align.wast","passed":46,"failed":54},{"name":"simd_bit_shift.wast","passed":39,"failed":213},{"name":"simd_bitwise.wast","passed":28,"failed":141},{"name":"simd_boolean.wast","passed":16,"failed":261},{"name":"simd_const.wast","passed":301,"failed":456},{"name":"simd_conversions.wast","passed":48,"failed":234},{"name":"simd_f32x4.wast","passed":16,"failed":774},{"name":"simd_f32x4_arith.wast","passed":16,"failed":1806},{"name":"simd_f32x4_cmp.wast","passed":24,"failed":2583},{"name":"simd_f32x4_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f32x4_rounding.wast","passed":24,"failed":177},{"name":"simd_f64x2.wast","passed":8,"failed":795},{"name":"simd_f64x2_arith.wast","passed":16,"failed":1809},{"name":"simd_f64x2_cmp.wast","passed":24,"failed":2661},{"name":"simd_f64x2_pmin_pmax.wast","passed":14,"failed":3873},{"name":"simd_f64x2_rounding.wast","passed":24,"failed":177},{"name":"simd_i16x8_arith.wast","passed":11,"failed":183},{"name":"simd_i16x8_arith2.wast","passed":19,"failed":153},{"name":"simd_i16x8_cmp.wast","passed":30,"failed":435},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":4,"failed":17},{"name":"simd_i16x8_extmul_i8x16.wast","passed":12,"failed":105},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":3,"failed":27},{"name":"simd_i16x8_sat_arith.wast","passed":16,"failed":206},{"name":"simd_i32x4_arith.wast","passed":11,"failed":183},{"name":"simd_i32x4_arith2.wast","passed":26,"failed":123},{"name":"simd_i32x4_cmp.wast","passed":40,"failed":435},{"name":"simd_i32x4_dot_i16x8.wast","passed":3,"failed":27},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":4,"failed":17},{"name":"simd_i32x4_extmul_i16x8.wast","passed":12,"failed":105},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":4,"failed":103},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":4,"failed":103},{"name":"simd_i64x2_arith.wast","passed":11,"failed":189},{"name":"simd_i64x2_arith2.wast","passed":2,"failed":23},{"name":"simd_i64x2_cmp.wast","passed":10,"failed":103},{"name":"simd_i64x2_extmul_i32x4.wast","passed":12,"failed":105},{"name":"simd_i8x16_arith.wast","passed":8,"failed":123},{"name":"simd_i8x16_arith2.wast","passed":25,"failed":186},{"name":"simd_i8x16_cmp.wast","passed":30,"failed":415},{"name":"simd_i8x16_sat_arith.wast","passed":24,"failed":190},{"name":"simd_int_to_int_extend.wast","passed":24,"failed":229},{"name":"simd_lane.wast","passed":189,"failed":286},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":8,"failed":31},{"name":"simd_load16_lane.wast","passed":3,"failed":33},{"name":"simd_load32_lane.wast","passed":3,"failed":21},{"name":"simd_load64_lane.wast","passed":3,"failed":13},{"name":"simd_load8_lane.wast","passed":3,"failed":49},{"name":"simd_load_extend.wast","passed":18,"failed":86},{"name":"simd_load_splat.wast","passed":12,"failed":114},{"name":"simd_load_zero.wast","passed":10,"failed":29},{"name":"simd_splat.wast","passed":23,"failed":162},{"name":"simd_store.wast","passed":9,"failed":19},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] +0.9.0-alpha.0,1702,24277,[{"name":"simd_address.wast","passed":7,"failed":42},{"name":"simd_align.wast","passed":92,"failed":8},{"name":"simd_bit_shift.wast","passed":41,"failed":211},{"name":"simd_bitwise.wast","passed":30,"failed":139},{"name":"simd_boolean.wast","passed":18,"failed":259},{"name":"simd_const.wast","passed":551,"failed":206},{"name":"simd_conversions.wast","passed":50,"failed":232},{"name":"simd_f32x4.wast","passed":18,"failed":772},{"name":"simd_f32x4_arith.wast","passed":19,"failed":1803},{"name":"simd_f32x4_cmp.wast","passed":26,"failed":2581},{"name":"simd_f32x4_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f32x4_rounding.wast","passed":25,"failed":176},{"name":"simd_f64x2.wast","passed":10,"failed":793},{"name":"simd_f64x2_arith.wast","passed":19,"failed":1806},{"name":"simd_f64x2_cmp.wast","passed":26,"failed":2659},{"name":"simd_f64x2_pmin_pmax.wast","passed":15,"failed":3872},{"name":"simd_f64x2_rounding.wast","passed":25,"failed":176},{"name":"simd_i16x8_arith.wast","passed":13,"failed":181},{"name":"simd_i16x8_arith2.wast","passed":21,"failed":151},{"name":"simd_i16x8_cmp.wast","passed":32,"failed":433},{"name":"simd_i16x8_extadd_pairwise_i8x16.wast","passed":5,"failed":16},{"name":"simd_i16x8_extmul_i8x16.wast","passed":13,"failed":104},{"name":"simd_i16x8_q15mulr_sat_s.wast","passed":4,"failed":26},{"name":"simd_i16x8_sat_arith.wast","passed":18,"failed":204},{"name":"simd_i32x4_arith.wast","passed":13,"failed":181},{"name":"simd_i32x4_arith2.wast","passed":28,"failed":121},{"name":"simd_i32x4_cmp.wast","passed":42,"failed":433},{"name":"simd_i32x4_dot_i16x8.wast","passed":4,"failed":26},{"name":"simd_i32x4_extadd_pairwise_i16x8.wast","passed":5,"failed":16},{"name":"simd_i32x4_extmul_i16x8.wast","passed":13,"failed":104},{"name":"simd_i32x4_trunc_sat_f32x4.wast","passed":5,"failed":102},{"name":"simd_i32x4_trunc_sat_f64x2.wast","passed":5,"failed":102},{"name":"simd_i64x2_arith.wast","passed":13,"failed":187},{"name":"simd_i64x2_arith2.wast","passed":4,"failed":21},{"name":"simd_i64x2_cmp.wast","passed":11,"failed":102},{"name":"simd_i64x2_extmul_i32x4.wast","passed":13,"failed":104},{"name":"simd_i8x16_arith.wast","passed":10,"failed":121},{"name":"simd_i8x16_arith2.wast","passed":27,"failed":184},{"name":"simd_i8x16_cmp.wast","passed":32,"failed":413},{"name":"simd_i8x16_sat_arith.wast","passed":26,"failed":188},{"name":"simd_int_to_int_extend.wast","passed":25,"failed":228},{"name":"simd_lane.wast","passed":200,"failed":275},{"name":"simd_linking.wast","passed":0,"failed":3},{"name":"simd_load.wast","passed":22,"failed":17},{"name":"simd_load16_lane.wast","passed":4,"failed":32},{"name":"simd_load32_lane.wast","passed":4,"failed":20},{"name":"simd_load64_lane.wast","passed":4,"failed":12},{"name":"simd_load8_lane.wast","passed":4,"failed":48},{"name":"simd_load_extend.wast","passed":20,"failed":84},{"name":"simd_load_splat.wast","passed":14,"failed":112},{"name":"simd_load_zero.wast","passed":12,"failed":27},{"name":"simd_splat.wast","passed":26,"failed":159},{"name":"simd_store.wast","passed":11,"failed":17},{"name":"simd_store16_lane.wast","passed":3,"failed":33},{"name":"simd_store32_lane.wast","passed":3,"failed":21},{"name":"simd_store64_lane.wast","passed":3,"failed":13},{"name":"simd_store8_lane.wast","passed":3,"failed":49}] diff --git a/crates/types/src/instructions.rs b/crates/types/src/instructions.rs index a3c2fee..1edfef7 100644 --- a/crates/types/src/instructions.rs +++ b/crates/types/src/instructions.rs @@ -1,12 +1,27 @@ use super::{FuncAddr, GlobalAddr, LabelAddr, LocalAddr, TableAddr, TypeAddr, ValType}; -use crate::{DataAddr, ElemAddr, MemAddr}; +use crate::{ConstIdx, DataAddr, ElemAddr, 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))] -pub struct MemoryArg { - pub offset: u64, - pub mem_addr: MemAddr, + +pub struct MemoryArg([u8; 12]); + +impl MemoryArg { + pub fn new(offset: u64, mem_addr: MemAddr) -> Self { + let mut bytes = [0; 12]; + bytes[0..8].copy_from_slice(&offset.to_le_bytes()); + bytes[8..12].copy_from_slice(&mem_addr.to_le_bytes()); + Self(bytes) + } + + pub fn offset(&self) -> u64 { + u64::from_le_bytes(self.0[0..8].try_into().expect("invalid offset")) + } + + pub fn mem_addr(&self) -> MemAddr { + MemAddr::from_le_bytes(self.0[8..12].try_into().expect("invalid mem_addr")) + } } type BrTableDefault = u32; @@ -42,8 +57,8 @@ pub enum ConstInstruction { // should be kept as small as possible (16 bytes max) #[rustfmt::skip] pub enum Instruction { - 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), + LocalCopy32(LocalAddr, LocalAddr), LocalCopy64(LocalAddr, LocalAddr), LocalCopy128(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), // > Control Instructions // See <https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions> @@ -71,68 +86,48 @@ pub enum Instruction { Return, Call(FuncAddr), CallIndirect(TypeAddr, TableAddr), - ReturnCall(FuncAddr), - ReturnCallIndirect(TypeAddr, TableAddr), + // ReturnCall(FuncAddr), + // ReturnCallIndirect(TypeAddr, TableAddr), // > Parametric Instructions // See <https://webassembly.github.io/spec/core/binary/instructions.html#parametric-instructions> - Drop32, - Drop64, - Drop128, - DropRef, - - Select32, - Select64, - Select128, - SelectRef, + Drop32, Select32, + Drop64, Select64, + Drop128, Select128, + DropRef, SelectRef, // > Variable Instructions // See <https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions> - LocalGet32(LocalAddr), - LocalGet64(LocalAddr), - LocalGet128(LocalAddr), - LocalGetRef(LocalAddr), - - LocalSet32(LocalAddr), - LocalSet64(LocalAddr), - LocalSet128(LocalAddr), - LocalSetRef(LocalAddr), - - LocalTee32(LocalAddr), - LocalTee64(LocalAddr), - LocalTee128(LocalAddr), - LocalTeeRef(LocalAddr), - GlobalGet(GlobalAddr), - GlobalSet32(GlobalAddr), - GlobalSet64(GlobalAddr), - GlobalSet128(GlobalAddr), - GlobalSetRef(GlobalAddr), + LocalGet32(LocalAddr), LocalSet32(LocalAddr), LocalTee32(LocalAddr), GlobalSet32(GlobalAddr), + LocalGet64(LocalAddr), LocalSet64(LocalAddr), LocalTee64(LocalAddr), GlobalSet64(GlobalAddr), + LocalGet128(LocalAddr), LocalSet128(LocalAddr), LocalTee128(LocalAddr), GlobalSet128(GlobalAddr), + LocalGetRef(LocalAddr), LocalSetRef(LocalAddr), LocalTeeRef(LocalAddr), GlobalSetRef(GlobalAddr), // > Memory Instructions - I32Load { offset: u64, mem_addr: MemAddr }, - I64Load { offset: u64, mem_addr: MemAddr }, - F32Load { offset: u64, mem_addr: MemAddr }, - F64Load { offset: u64, mem_addr: MemAddr }, - I32Load8S { offset: u64, mem_addr: MemAddr }, - I32Load8U { offset: u64, mem_addr: MemAddr }, - I32Load16S { offset: u64, mem_addr: MemAddr }, - I32Load16U { offset: u64, mem_addr: MemAddr }, - I64Load8S { offset: u64, mem_addr: MemAddr }, - I64Load8U { offset: u64, mem_addr: MemAddr }, - I64Load16S { offset: u64, mem_addr: MemAddr }, - I64Load16U { offset: u64, mem_addr: MemAddr }, - I64Load32S { offset: u64, mem_addr: MemAddr }, - I64Load32U { offset: u64, mem_addr: MemAddr }, - I32Store { offset: u64, mem_addr: MemAddr }, - I64Store { offset: u64, mem_addr: MemAddr }, - F32Store { offset: u64, mem_addr: MemAddr }, - F64Store { offset: u64, mem_addr: MemAddr }, - I32Store8 { offset: u64, mem_addr: MemAddr }, - I32Store16 { offset: u64, mem_addr: MemAddr }, - I64Store8 { offset: u64, mem_addr: MemAddr }, - I64Store16 { offset: u64, mem_addr: MemAddr }, - I64Store32 { offset: u64, mem_addr: MemAddr }, + I32Load(MemoryArg), + I64Load(MemoryArg), + F32Load(MemoryArg), + F64Load(MemoryArg), + I32Load8S(MemoryArg), + I32Load8U(MemoryArg), + I32Load16S(MemoryArg), + I32Load16U(MemoryArg), + I64Load8S(MemoryArg), + I64Load8U(MemoryArg), + I64Load16S(MemoryArg), + I64Load16U(MemoryArg), + I64Load32S(MemoryArg), + I64Load32U(MemoryArg), + I32Store(MemoryArg), + I64Store(MemoryArg), + F32Store(MemoryArg), + F64Store(MemoryArg), + I32Store8(MemoryArg), + I32Store16(MemoryArg), + I64Store8(MemoryArg), + I64Store16(MemoryArg), + I64Store32(MemoryArg), MemorySize(MemAddr), MemoryGrow(MemAddr), @@ -146,7 +141,7 @@ pub enum Instruction { RefNull(ValType), RefFunc(FuncAddr), RefIsNull, - + // > Numeric Instructions // See <https://webassembly.github.io/spec/core/binary/instructions.html#numeric-instructions> I32Eqz, I32Eq, I32Ne, I32LtS, I32LtU, I32GtS, I32GtU, I32LeS, I32LeU, I32GeS, I32GeU, @@ -188,7 +183,97 @@ pub enum Instruction { 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 }, + // > SIMD Instructions + Simd(SimdInstruction), +} + +impl From<SimdInstruction> for Instruction { + fn from(instr: SimdInstruction) -> Self { + Instruction::Simd(instr) + } +} + +#[derive(Debug, Clone, 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), + V128Load32x2S(MemoryArg), V128Load32x2U(MemoryArg), + + V128Load8Splat(MemoryArg), V128Load16Splat(MemoryArg), V128Load32Splat(MemoryArg), V128Load64Splat(MemoryArg), + V128Load8Lane(MemoryArg, u8), V128Load16Lane(MemoryArg, u8), V128Load32Lane(MemoryArg, u8), V128Load64Lane(MemoryArg, u8), + + V128Load32Zero(MemoryArg), V128Load64Zero(MemoryArg), + + V128Store(MemoryArg), V128Store8Lane(MemoryArg, u8), V128Store16Lane(MemoryArg, u8), V128Store32Lane(MemoryArg, u8), V128Store64Lane(MemoryArg, u8), + + I8x16Shuffle(ConstIdx), + V128Const(ConstIdx), + + I8x16ExtractLaneS(u8), I8x16ExtractLaneU(u8), I8x16ReplaceLane(u8), + I16x8ExtractLaneS(u8), I16x8ExtractLaneU(u8), I16x8ReplaceLane(u8), + I32x4ExtractLane(u8), I32x4ReplaceLane(u8), + I64x2ExtractLane(u8), I64x2ReplaceLane(u8), + F32x4ExtractLane(u8), F32x4ReplaceLane(u8), + F64x2ExtractLane(u8), F64x2ReplaceLane(u8), + + V128Not, V128And, V128AndNot, V128Or, V128Xor, V128Bitselect, V128AnyTrue, + + I8x16Splat, I8x16Swizzle, I8x16Eq, I8x16Ne, I8x16LtS, I8x16LtU, I8x16GtS, I8x16GtU, I8x16LeS, I8x16LeU, I8x16GeS, I8x16GeU, + I16x8Splat, I16x8Eq, I16x8Ne, I16x8LtS, I16x8LtU, I16x8GtS, I16x8GtU, I16x8LeS, I16x8LeU, I16x8GeS, I16x8GeU, + I32x4Splat, I32x4Eq, I32x4Ne, I32x4LtS, I32x4LtU, I32x4GtS, I32x4GtU, I32x4LeS, I32x4LeU, I32x4GeS, I32x4GeU, + I64x2Splat, I64x2Eq, I64x2Ne, I64x2LtS, I64x2GtS, I64x2LeS, I64x2GeS, + F32x4Splat, F32x4Eq, F32x4Ne, F32x4Lt, F32x4Gt, F32x4Le, F32x4Ge, + F64x2Splat, F64x2Eq, F64x2Ne, F64x2Lt, F64x2Gt, F64x2Le, F64x2Ge, + + I8x16Abs, I8x16Neg, I8x16AllTrue, I8x16Bitmask, I8x16Shl, I8x16ShrS, I8x16ShrU, I8x16Add, I8x16Sub, I8x16MinS, I8x16MinU, I8x16MaxS, I8x16MaxU, + I16x8Abs, I16x8Neg, I16x8AllTrue, I16x8Bitmask, I16x8Shl, I16x8ShrS, I16x8ShrU, I16x8Add, I16x8Sub, I16x8MinS, I16x8MinU, I16x8MaxS, I16x8MaxU, + I32x4Abs, I32x4Neg, I32x4AllTrue, I32x4Bitmask, I32x4Shl, I32x4ShrS, I32x4ShrU, I32x4Add, I32x4Sub, I32x4MinS, I32x4MinU, I32x4MaxS, I32x4MaxU, + I64x2Abs, I64x2Neg, I64x2AllTrue, I64x2Bitmask, I64x2Shl, I64x2ShrS, I64x2ShrU, I64x2Add, I64x2Sub, I64x2Mul, + + I8x16NarrowI16x8S, I8x16NarrowI16x8U, I8x16AddSatS, I8x16AddSatU, I8x16SubSatS, I8x16SubSatU, I8x16AvgrU, + I16x8NarrowI32x4S, I16x8NarrowI32x4U, I16x8AddSatS, I16x8AddSatU, I16x8SubSatS, I16x8SubSatU, I16x8AvgrU, + + I16x8ExtAddPairwiseI8x16S, I16x8ExtAddPairwiseI8x16U, I16x8Mul, + I32x4ExtAddPairwiseI16x8S, I32x4ExtAddPairwiseI16x8U, I32x4Mul, + + I16x8ExtMulLowI8x16S, I16x8ExtMulLowI8x16U, I16x8ExtMulHighI8x16S, I16x8ExtMulHighI8x16U, + I32x4ExtMulLowI16x8S, I32x4ExtMulLowI16x8U, I32x4ExtMulHighI16x8S, I32x4ExtMulHighI16x8U, + I64x2ExtMulLowI32x4S, I64x2ExtMulLowI32x4U, I64x2ExtMulHighI32x4S, I64x2ExtMulHighI32x4U, + + I16x8ExtendLowI8x16S, I16x8ExtendLowI8x16U, I16x8ExtendHighI8x16S, I16x8ExtendHighI8x16U, + I32x4ExtendLowI16x8S, I32x4ExtendLowI16x8U, I32x4ExtendHighI16x8S, I32x4ExtendHighI16x8U, + I64x2ExtendLowI32x4S, I64x2ExtendLowI32x4U, I64x2ExtendHighI32x4S, I64x2ExtendHighI32x4U, + + I8x16Popcnt, I16x8Q15MulrSatS, I32x4DotI16x8S, + + F32x4Ceil, F32x4Floor, F32x4Trunc, F32x4Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, F32x4Add, F32x4Sub, F32x4Mul, F32x4Div, F32x4Min, F32x4Max, F32x4PMin, F32x4PMax, + F64x2Ceil, F64x2Floor, F64x2Trunc, F64x2Nearest, F64x2Abs, F64x2Neg, F64x2Sqrt, F64x2Add, F64x2Sub, F64x2Mul, F64x2Div, F64x2Min, F64x2Max, F64x2PMin, F64x2PMax, + I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, + F32x4ConvertI32x4S, F32x4ConvertI32x4U, + 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 { + I8x16RelaxedSwizzle, + I32x4RelaxedTruncF32x4S, I32x4RelaxedTruncF32x4U, + I32x4RelaxedTruncF64x2SZero, I32x4RelaxedTruncF64x2UZero, + F32x4RelaxedMadd, F32x4RelaxedNmadd, + F64x2RelaxedMadd, F64x2RelaxedNmadd, + I8x16RelaxedLaneselect, + I16x8RelaxedLaneselect, + I32x4RelaxedLaneselect, + I64x2RelaxedLaneselect, + F32x4RelaxedMin, F32x4RelaxedMax, + F64x2RelaxedMin, F64x2RelaxedMax, + I16x8RelaxedQ15mulrS, + I16x8RelaxedDotI8x16I7x16S, + I32x4RelaxedDotI8x16I7x16AddS } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 8ee044f..58120fe 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -135,6 +135,7 @@ pub type GlobalAddr = Addr; pub type ElemAddr = Addr; pub type DataAddr = Addr; pub type ExternAddr = Addr; +pub type ConstIdx = Addr; // additional internal addresses pub type TypeAddr = Addr; @@ -203,15 +204,52 @@ pub struct ValueCountsSmall { pub cref: u16, } +impl<'a, T: IntoIterator<Item = &'a ValType>> From<T> for ValueCounts { + fn from(types: T) -> Self { + let mut counts = ValueCounts::default(); + for ty in types { + match ty { + ValType::I32 | ValType::F32 => counts.c32 += 1, + ValType::I64 | ValType::F64 => counts.c64 += 1, + ValType::V128 => counts.c128 += 1, + ValType::RefExtern | ValType::RefFunc => counts.cref += 1, + } + } + counts + } +} + +impl<'a, T: IntoIterator<Item = &'a ValType>> From<T> for ValueCountsSmall { + fn from(types: T) -> Self { + let mut counts = ValueCountsSmall::default(); + for ty in types { + match ty { + ValType::I32 | ValType::F32 => counts.c32 += 1, + ValType::I64 | ValType::F64 => counts.c64 += 1, + ValType::V128 => counts.c128 += 1, + ValType::RefExtern | ValType::RefFunc => counts.cref += 1, + } + } + counts + } +} + #[derive(Debug, Clone, PartialEq, Default)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] pub struct WasmFunction { pub instructions: Box<[Instruction]>, + pub data: WasmFunctionData, pub locals: ValueCounts, pub params: ValueCountsSmall, pub ty: FuncType, } +#[derive(Debug, Clone, PartialEq, Default)] +#[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::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))] diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml index 8edcb8a..46df77f 100644 --- a/crates/wasm-testsuite/Cargo.toml +++ b/crates/wasm-testsuite/Cargo.toml @@ -1,6 +1,6 @@ [package] name="wasm-testsuite" -version="0.5.0" +version="0.6.0-alpha.0" description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations" license="Apache-2.0" readme="README.md" |
