From cea6e7a40340a8e4794af710e872f36fac122017 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 16:01:14 -0700 Subject: [PATCH 01/11] Add support for Wasm-SIMD ops. --- src/backend/mod.rs | 395 +++++++++++++++ src/frontend.rs | 238 ++++++++- src/op_traits.rs | 1032 ++++++++++++++++++++++++++++++++++++++ src/ops.rs | 691 +++++++++++++++++++++++++ wasm_tests/test-simd.wat | 22 + 5 files changed, 2377 insertions(+), 1 deletion(-) create mode 100644 wasm_tests/test-simd.wat diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 5046953..088a424 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -514,6 +514,401 @@ impl<'a> WasmFuncBackend<'a> { Operator::MemoryGrow { mem } => { Some(wasm_encoder::Instruction::MemoryGrow(mem.index() as u32)) } + + Operator::V128Load { memory } => Some(wasm_encoder::Instruction::V128Load( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load8x8S { memory } => Some(wasm_encoder::Instruction::V128Load8x8S( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load8x8U { memory } => Some(wasm_encoder::Instruction::V128Load8x8U( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load16x4S { memory } => Some(wasm_encoder::Instruction::V128Load16x4S( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load16x4U { memory } => Some(wasm_encoder::Instruction::V128Load16x4U( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load32x2S { memory } => Some(wasm_encoder::Instruction::V128Load32x2S( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load32x2U { memory } => Some(wasm_encoder::Instruction::V128Load32x2U( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load8Splat { memory } => Some(wasm_encoder::Instruction::V128Load8Splat( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load16Splat { memory } => Some( + wasm_encoder::Instruction::V128Load16Splat(wasm_encoder::MemArg::from(*memory)), + ), + Operator::V128Load32Splat { memory } => Some( + wasm_encoder::Instruction::V128Load32Splat(wasm_encoder::MemArg::from(*memory)), + ), + Operator::V128Load64Splat { memory } => Some( + wasm_encoder::Instruction::V128Load64Splat(wasm_encoder::MemArg::from(*memory)), + ), + Operator::V128Load32Zero { memory } => Some(wasm_encoder::Instruction::V128Load32Zero( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load64Zero { memory } => Some(wasm_encoder::Instruction::V128Load64Zero( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Store { memory } => Some(wasm_encoder::Instruction::V128Store( + wasm_encoder::MemArg::from(*memory), + )), + Operator::V128Load8Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Load8Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Load16Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Load16Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Load32Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Load32Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Load64Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Load64Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Store8Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Store8Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Store16Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Store16Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Store32Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Store32Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Store64Lane { memory, lane } => { + Some(wasm_encoder::Instruction::V128Store64Lane { + memarg: wasm_encoder::MemArg::from(*memory), + lane: *lane, + }) + } + Operator::V128Const { value } => { + Some(wasm_encoder::Instruction::V128Const(*value as i128)) + } + + Operator::I8x16Shuffle { lanes } => { + Some(wasm_encoder::Instruction::I8x16Shuffle(lanes.clone())) + } + + Operator::I8x16ExtractLaneS { lane } => { + Some(wasm_encoder::Instruction::I8x16ExtractLaneS(*lane)) + } + Operator::I8x16ExtractLaneU { lane } => { + Some(wasm_encoder::Instruction::I8x16ExtractLaneU(*lane)) + } + Operator::I8x16ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::I8x16ReplaceLane(*lane)) + } + Operator::I16x8ExtractLaneS { lane } => { + Some(wasm_encoder::Instruction::I16x8ExtractLaneS(*lane)) + } + Operator::I16x8ExtractLaneU { lane } => { + Some(wasm_encoder::Instruction::I16x8ExtractLaneU(*lane)) + } + Operator::I16x8ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::I16x8ReplaceLane(*lane)) + } + Operator::I32x4ExtractLane { lane } => { + Some(wasm_encoder::Instruction::I32x4ExtractLane(*lane)) + } + Operator::I32x4ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::I32x4ReplaceLane(*lane)) + } + Operator::I64x2ExtractLane { lane } => { + Some(wasm_encoder::Instruction::I64x2ExtractLane(*lane)) + } + Operator::I64x2ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::I64x2ReplaceLane(*lane)) + } + Operator::F32x4ExtractLane { lane } => { + Some(wasm_encoder::Instruction::F32x4ExtractLane(*lane)) + } + Operator::F32x4ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::F32x4ReplaceLane(*lane)) + } + Operator::F64x2ExtractLane { lane } => { + Some(wasm_encoder::Instruction::F64x2ExtractLane(*lane)) + } + Operator::F64x2ReplaceLane { lane } => { + Some(wasm_encoder::Instruction::F64x2ReplaceLane(*lane)) + } + + Operator::I8x16Swizzle => Some(wasm_encoder::Instruction::I8x16Swizzle), + Operator::I8x16Splat => Some(wasm_encoder::Instruction::I8x16Splat), + Operator::I16x8Splat => Some(wasm_encoder::Instruction::I16x8Splat), + Operator::I32x4Splat => Some(wasm_encoder::Instruction::I32x4Splat), + Operator::I64x2Splat => Some(wasm_encoder::Instruction::I64x2Splat), + Operator::F32x4Splat => Some(wasm_encoder::Instruction::F32x4Splat), + Operator::F64x2Splat => Some(wasm_encoder::Instruction::F64x2Splat), + + Operator::I8x16Eq => Some(wasm_encoder::Instruction::I8x16Eq), + Operator::I8x16Ne => Some(wasm_encoder::Instruction::I8x16Ne), + Operator::I8x16LtS => Some(wasm_encoder::Instruction::I8x16LtS), + Operator::I8x16LtU => Some(wasm_encoder::Instruction::I8x16LtU), + Operator::I8x16GtS => Some(wasm_encoder::Instruction::I8x16GtS), + Operator::I8x16GtU => Some(wasm_encoder::Instruction::I8x16GtU), + Operator::I8x16LeS => Some(wasm_encoder::Instruction::I8x16LeS), + Operator::I8x16LeU => Some(wasm_encoder::Instruction::I8x16LeU), + Operator::I8x16GeS => Some(wasm_encoder::Instruction::I8x16GeS), + Operator::I8x16GeU => Some(wasm_encoder::Instruction::I8x16GeU), + + Operator::I16x8Eq => Some(wasm_encoder::Instruction::I16x8Eq), + Operator::I16x8Ne => Some(wasm_encoder::Instruction::I16x8Ne), + Operator::I16x8LtS => Some(wasm_encoder::Instruction::I16x8LtS), + Operator::I16x8LtU => Some(wasm_encoder::Instruction::I16x8LtU), + Operator::I16x8GtS => Some(wasm_encoder::Instruction::I16x8GtS), + Operator::I16x8GtU => Some(wasm_encoder::Instruction::I16x8GtU), + Operator::I16x8LeS => Some(wasm_encoder::Instruction::I16x8LeS), + Operator::I16x8LeU => Some(wasm_encoder::Instruction::I16x8LeU), + Operator::I16x8GeS => Some(wasm_encoder::Instruction::I16x8GeS), + Operator::I16x8GeU => Some(wasm_encoder::Instruction::I16x8GeU), + + Operator::I32x4Eq => Some(wasm_encoder::Instruction::I32x4Eq), + Operator::I32x4Ne => Some(wasm_encoder::Instruction::I32x4Ne), + Operator::I32x4LtS => Some(wasm_encoder::Instruction::I32x4LtS), + Operator::I32x4LtU => Some(wasm_encoder::Instruction::I32x4LtU), + Operator::I32x4GtS => Some(wasm_encoder::Instruction::I32x4GtS), + Operator::I32x4GtU => Some(wasm_encoder::Instruction::I32x4GtU), + Operator::I32x4LeS => Some(wasm_encoder::Instruction::I32x4LeS), + Operator::I32x4LeU => Some(wasm_encoder::Instruction::I32x4LeU), + Operator::I32x4GeS => Some(wasm_encoder::Instruction::I32x4GeS), + Operator::I32x4GeU => Some(wasm_encoder::Instruction::I32x4GeU), + + Operator::I64x2Eq => Some(wasm_encoder::Instruction::I64x2Eq), + Operator::I64x2Ne => Some(wasm_encoder::Instruction::I64x2Ne), + Operator::I64x2LtS => Some(wasm_encoder::Instruction::I64x2LtS), + Operator::I64x2GtS => Some(wasm_encoder::Instruction::I64x2GtS), + Operator::I64x2LeS => Some(wasm_encoder::Instruction::I64x2LeS), + Operator::I64x2GeS => Some(wasm_encoder::Instruction::I64x2GeS), + + Operator::F32x4Eq => Some(wasm_encoder::Instruction::F32x4Eq), + Operator::F32x4Ne => Some(wasm_encoder::Instruction::F32x4Ne), + Operator::F32x4Lt => Some(wasm_encoder::Instruction::F32x4Lt), + Operator::F32x4Gt => Some(wasm_encoder::Instruction::F32x4Gt), + Operator::F32x4Le => Some(wasm_encoder::Instruction::F32x4Le), + Operator::F32x4Ge => Some(wasm_encoder::Instruction::F32x4Ge), + + Operator::F64x2Eq => Some(wasm_encoder::Instruction::F64x2Eq), + Operator::F64x2Ne => Some(wasm_encoder::Instruction::F64x2Ne), + Operator::F64x2Lt => Some(wasm_encoder::Instruction::F64x2Lt), + Operator::F64x2Gt => Some(wasm_encoder::Instruction::F64x2Gt), + Operator::F64x2Le => Some(wasm_encoder::Instruction::F64x2Le), + Operator::F64x2Ge => Some(wasm_encoder::Instruction::F64x2Ge), + + Operator::V128Not => Some(wasm_encoder::Instruction::V128Not), + Operator::V128And => Some(wasm_encoder::Instruction::V128And), + Operator::V128AndNot => Some(wasm_encoder::Instruction::V128AndNot), + Operator::V128Or => Some(wasm_encoder::Instruction::V128Or), + Operator::V128Xor => Some(wasm_encoder::Instruction::V128Xor), + Operator::V128Bitselect => Some(wasm_encoder::Instruction::V128Bitselect), + Operator::V128AnyTrue => Some(wasm_encoder::Instruction::V128AnyTrue), + + Operator::I8x16Abs => Some(wasm_encoder::Instruction::I8x16Abs), + Operator::I8x16Neg => Some(wasm_encoder::Instruction::I8x16Neg), + Operator::I8x16Popcnt => Some(wasm_encoder::Instruction::I8x16Popcnt), + Operator::I8x16AllTrue => Some(wasm_encoder::Instruction::I8x16AllTrue), + Operator::I8x16Bitmask => Some(wasm_encoder::Instruction::I8x16Bitmask), + Operator::I8x16NarrowI16x8S => Some(wasm_encoder::Instruction::I8x16NarrowI16x8S), + Operator::I8x16NarrowI16x8U => Some(wasm_encoder::Instruction::I8x16NarrowI16x8U), + Operator::I8x16Shl => Some(wasm_encoder::Instruction::I8x16Shl), + Operator::I8x16ShrS => Some(wasm_encoder::Instruction::I8x16ShrS), + Operator::I8x16ShrU => Some(wasm_encoder::Instruction::I8x16ShrU), + Operator::I8x16Add => Some(wasm_encoder::Instruction::I8x16Add), + Operator::I8x16AddSatS => Some(wasm_encoder::Instruction::I8x16AddSatS), + Operator::I8x16AddSatU => Some(wasm_encoder::Instruction::I8x16AddSatU), + Operator::I8x16Sub => Some(wasm_encoder::Instruction::I8x16Sub), + Operator::I8x16SubSatS => Some(wasm_encoder::Instruction::I8x16SubSatS), + Operator::I8x16SubSatU => Some(wasm_encoder::Instruction::I8x16SubSatU), + Operator::I8x16MinS => Some(wasm_encoder::Instruction::I8x16MinS), + Operator::I8x16MinU => Some(wasm_encoder::Instruction::I8x16MinU), + Operator::I8x16MaxS => Some(wasm_encoder::Instruction::I8x16MaxS), + Operator::I8x16MaxU => Some(wasm_encoder::Instruction::I8x16MaxU), + Operator::I8x16AvgrU => Some(wasm_encoder::Instruction::I8x16AvgrU), + + Operator::I16x8ExtAddPairwiseI8x16S => { + Some(wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16S) + } + Operator::I16x8ExtAddPairwiseI8x16U => { + Some(wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16U) + } + Operator::I16x8Abs => Some(wasm_encoder::Instruction::I16x8Abs), + Operator::I16x8Neg => Some(wasm_encoder::Instruction::I16x8Neg), + Operator::I16x8Q15MulrSatS => Some(wasm_encoder::Instruction::I16x8Q15MulrSatS), + Operator::I16x8AllTrue => Some(wasm_encoder::Instruction::I16x8AllTrue), + Operator::I16x8Bitmask => Some(wasm_encoder::Instruction::I16x8Bitmask), + Operator::I16x8NarrowI32x4S => Some(wasm_encoder::Instruction::I16x8NarrowI32x4S), + Operator::I16x8NarrowI32x4U => Some(wasm_encoder::Instruction::I16x8NarrowI32x4U), + Operator::I16x8ExtendLowI8x16S => Some(wasm_encoder::Instruction::I16x8ExtendLowI8x16S), + Operator::I16x8ExtendHighI8x16S => { + Some(wasm_encoder::Instruction::I16x8ExtendHighI8x16S) + } + Operator::I16x8ExtendLowI8x16U => Some(wasm_encoder::Instruction::I16x8ExtendLowI8x16U), + Operator::I16x8ExtendHighI8x16U => { + Some(wasm_encoder::Instruction::I16x8ExtendHighI8x16U) + } + Operator::I16x8Shl => Some(wasm_encoder::Instruction::I16x8Shl), + Operator::I16x8ShrS => Some(wasm_encoder::Instruction::I16x8ShrS), + Operator::I16x8ShrU => Some(wasm_encoder::Instruction::I16x8ShrU), + Operator::I16x8Add => Some(wasm_encoder::Instruction::I16x8Add), + Operator::I16x8AddSatS => Some(wasm_encoder::Instruction::I16x8AddSatS), + Operator::I16x8AddSatU => Some(wasm_encoder::Instruction::I16x8AddSatU), + Operator::I16x8Sub => Some(wasm_encoder::Instruction::I16x8Sub), + Operator::I16x8SubSatS => Some(wasm_encoder::Instruction::I16x8SubSatS), + Operator::I16x8SubSatU => Some(wasm_encoder::Instruction::I16x8SubSatU), + Operator::I16x8Mul => Some(wasm_encoder::Instruction::I16x8Mul), + Operator::I16x8MinS => Some(wasm_encoder::Instruction::I16x8MinS), + Operator::I16x8MinU => Some(wasm_encoder::Instruction::I16x8MinU), + Operator::I16x8MaxS => Some(wasm_encoder::Instruction::I16x8MaxS), + Operator::I16x8MaxU => Some(wasm_encoder::Instruction::I16x8MaxU), + Operator::I16x8AvgrU => Some(wasm_encoder::Instruction::I16x8AvgrU), + Operator::I16x8ExtMulLowI8x16S => Some(wasm_encoder::Instruction::I16x8ExtMulLowI8x16S), + Operator::I16x8ExtMulHighI8x16S => { + Some(wasm_encoder::Instruction::I16x8ExtMulHighI8x16S) + } + Operator::I16x8ExtMulLowI8x16U => Some(wasm_encoder::Instruction::I16x8ExtMulLowI8x16U), + Operator::I16x8ExtMulHighI8x16U => { + Some(wasm_encoder::Instruction::I16x8ExtMulHighI8x16U) + } + + Operator::I32x4ExtAddPairwiseI16x8S => { + Some(wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8S) + } + Operator::I32x4ExtAddPairwiseI16x8U => { + Some(wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8U) + } + Operator::I32x4Abs => Some(wasm_encoder::Instruction::I32x4Abs), + Operator::I32x4Neg => Some(wasm_encoder::Instruction::I32x4Neg), + Operator::I32x4AllTrue => Some(wasm_encoder::Instruction::I32x4AllTrue), + Operator::I32x4Bitmask => Some(wasm_encoder::Instruction::I32x4Bitmask), + Operator::I32x4ExtendLowI16x8S => Some(wasm_encoder::Instruction::I32x4ExtendLowI16x8S), + Operator::I32x4ExtendHighI16x8S => { + Some(wasm_encoder::Instruction::I32x4ExtendHighI16x8S) + } + Operator::I32x4ExtendLowI16x8U => Some(wasm_encoder::Instruction::I32x4ExtendLowI16x8U), + Operator::I32x4ExtendHighI16x8U => { + Some(wasm_encoder::Instruction::I32x4ExtendHighI16x8U) + } + Operator::I32x4Shl => Some(wasm_encoder::Instruction::I32x4Shl), + Operator::I32x4ShrS => Some(wasm_encoder::Instruction::I32x4ShrS), + Operator::I32x4ShrU => Some(wasm_encoder::Instruction::I32x4ShrU), + Operator::I32x4Add => Some(wasm_encoder::Instruction::I32x4Add), + Operator::I32x4Sub => Some(wasm_encoder::Instruction::I32x4Sub), + Operator::I32x4Mul => Some(wasm_encoder::Instruction::I32x4Mul), + Operator::I32x4MinS => Some(wasm_encoder::Instruction::I32x4MinS), + Operator::I32x4MinU => Some(wasm_encoder::Instruction::I32x4MinU), + Operator::I32x4MaxS => Some(wasm_encoder::Instruction::I32x4MaxS), + Operator::I32x4MaxU => Some(wasm_encoder::Instruction::I32x4MaxU), + Operator::I32x4DotI16x8S => Some(wasm_encoder::Instruction::I32x4DotI16x8S), + Operator::I32x4ExtMulLowI16x8S => Some(wasm_encoder::Instruction::I32x4ExtMulLowI16x8S), + Operator::I32x4ExtMulHighI16x8S => { + Some(wasm_encoder::Instruction::I32x4ExtMulHighI16x8S) + } + Operator::I32x4ExtMulLowI16x8U => Some(wasm_encoder::Instruction::I32x4ExtMulLowI16x8U), + Operator::I32x4ExtMulHighI16x8U => { + Some(wasm_encoder::Instruction::I32x4ExtMulHighI16x8U) + } + + Operator::I64x2Abs => Some(wasm_encoder::Instruction::I64x2Abs), + Operator::I64x2Neg => Some(wasm_encoder::Instruction::I64x2Neg), + Operator::I64x2AllTrue => Some(wasm_encoder::Instruction::I64x2AllTrue), + Operator::I64x2Bitmask => Some(wasm_encoder::Instruction::I64x2Bitmask), + Operator::I64x2ExtendLowI32x4S => Some(wasm_encoder::Instruction::I64x2ExtendLowI32x4S), + Operator::I64x2ExtendHighI32x4S => { + Some(wasm_encoder::Instruction::I64x2ExtendHighI32x4S) + } + Operator::I64x2ExtendLowI32x4U => Some(wasm_encoder::Instruction::I64x2ExtendLowI32x4U), + Operator::I64x2ExtendHighI32x4U => { + Some(wasm_encoder::Instruction::I64x2ExtendHighI32x4U) + } + Operator::I64x2Shl => Some(wasm_encoder::Instruction::I64x2Shl), + Operator::I64x2ShrS => Some(wasm_encoder::Instruction::I64x2ShrS), + Operator::I64x2ShrU => Some(wasm_encoder::Instruction::I64x2ShrU), + Operator::I64x2Add => Some(wasm_encoder::Instruction::I64x2Add), + Operator::I64x2Sub => Some(wasm_encoder::Instruction::I64x2Sub), + Operator::I64x2Mul => Some(wasm_encoder::Instruction::I64x2Mul), + Operator::I64x2ExtMulLowI32x4S => Some(wasm_encoder::Instruction::I64x2ExtMulLowI32x4S), + Operator::I64x2ExtMulHighI32x4S => { + Some(wasm_encoder::Instruction::I64x2ExtMulHighI32x4S) + } + Operator::I64x2ExtMulLowI32x4U => Some(wasm_encoder::Instruction::I64x2ExtMulLowI32x4U), + Operator::I64x2ExtMulHighI32x4U => { + Some(wasm_encoder::Instruction::I64x2ExtMulHighI32x4U) + } + + Operator::F32x4Ceil => Some(wasm_encoder::Instruction::F32x4Ceil), + Operator::F32x4Floor => Some(wasm_encoder::Instruction::F32x4Floor), + Operator::F32x4Trunc => Some(wasm_encoder::Instruction::F32x4Trunc), + Operator::F32x4Nearest => Some(wasm_encoder::Instruction::F32x4Nearest), + Operator::F32x4Abs => Some(wasm_encoder::Instruction::F32x4Abs), + Operator::F32x4Neg => Some(wasm_encoder::Instruction::F32x4Neg), + Operator::F32x4Sqrt => Some(wasm_encoder::Instruction::F32x4Sqrt), + Operator::F32x4Add => Some(wasm_encoder::Instruction::F32x4Add), + Operator::F32x4Sub => Some(wasm_encoder::Instruction::F32x4Sub), + Operator::F32x4Mul => Some(wasm_encoder::Instruction::F32x4Mul), + Operator::F32x4Div => Some(wasm_encoder::Instruction::F32x4Div), + Operator::F32x4Min => Some(wasm_encoder::Instruction::F32x4Min), + Operator::F32x4Max => Some(wasm_encoder::Instruction::F32x4Max), + Operator::F32x4PMin => Some(wasm_encoder::Instruction::F32x4PMin), + Operator::F32x4PMax => Some(wasm_encoder::Instruction::F32x4PMax), + + Operator::F64x2Ceil => Some(wasm_encoder::Instruction::F64x2Ceil), + Operator::F64x2Floor => Some(wasm_encoder::Instruction::F64x2Floor), + Operator::F64x2Trunc => Some(wasm_encoder::Instruction::F64x2Trunc), + Operator::F64x2Nearest => Some(wasm_encoder::Instruction::F64x2Nearest), + Operator::F64x2Abs => Some(wasm_encoder::Instruction::F64x2Abs), + Operator::F64x2Neg => Some(wasm_encoder::Instruction::F64x2Neg), + Operator::F64x2Sqrt => Some(wasm_encoder::Instruction::F64x2Sqrt), + Operator::F64x2Add => Some(wasm_encoder::Instruction::F64x2Add), + Operator::F64x2Sub => Some(wasm_encoder::Instruction::F64x2Sub), + Operator::F64x2Mul => Some(wasm_encoder::Instruction::F64x2Mul), + Operator::F64x2Div => Some(wasm_encoder::Instruction::F64x2Div), + Operator::F64x2Min => Some(wasm_encoder::Instruction::F64x2Min), + Operator::F64x2Max => Some(wasm_encoder::Instruction::F64x2Max), + Operator::F64x2PMin => Some(wasm_encoder::Instruction::F64x2PMin), + Operator::F64x2PMax => Some(wasm_encoder::Instruction::F64x2PMax), + + Operator::I32x4TruncSatF32x4S => Some(wasm_encoder::Instruction::I32x4TruncSatF32x4S), + Operator::I32x4TruncSatF32x4U => Some(wasm_encoder::Instruction::I32x4TruncSatF32x4U), + + Operator::F32x4ConvertI32x4S => Some(wasm_encoder::Instruction::F32x4ConvertI32x4S), + Operator::F32x4ConvertI32x4U => Some(wasm_encoder::Instruction::F32x4ConvertI32x4U), + Operator::I32x4TruncSatF64x2SZero => { + Some(wasm_encoder::Instruction::I32x4TruncSatF64x2SZero) + } + Operator::I32x4TruncSatF64x2UZero => { + Some(wasm_encoder::Instruction::I32x4TruncSatF64x2UZero) + } + Operator::F64x2ConvertLowI32x4S => { + Some(wasm_encoder::Instruction::F64x2ConvertLowI32x4S) + } + Operator::F64x2ConvertLowI32x4U => { + Some(wasm_encoder::Instruction::F64x2ConvertLowI32x4U) + } + Operator::F32x4DemoteF64x2Zero => Some(wasm_encoder::Instruction::F32x4DemoteF64x2Zero), + Operator::F64x2PromoteLowF32x4 => Some(wasm_encoder::Instruction::F64x2PromoteLowF32x4), }; if let Some(inst) = inst { diff --git a/src/frontend.rs b/src/frontend.rs index 4b66d7a..c86aae0 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -1151,7 +1151,243 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { | wasmparser::Operator::TableGet { .. } | wasmparser::Operator::TableSet { .. } | wasmparser::Operator::TableGrow { .. } - | wasmparser::Operator::TableSize { .. } => { + | wasmparser::Operator::TableSize { .. } + | wasmparser::Operator::V128Load { .. } + | wasmparser::Operator::V128Load8x8S { .. } + | wasmparser::Operator::V128Load8x8U { .. } + | wasmparser::Operator::V128Load16x4S { .. } + | wasmparser::Operator::V128Load16x4U { .. } + | wasmparser::Operator::V128Load32x2S { .. } + | wasmparser::Operator::V128Load32x2U { .. } + | wasmparser::Operator::V128Load8Splat { .. } + | wasmparser::Operator::V128Load16Splat { .. } + | wasmparser::Operator::V128Load32Splat { .. } + | wasmparser::Operator::V128Load64Splat { .. } + | wasmparser::Operator::V128Load32Zero { .. } + | wasmparser::Operator::V128Load64Zero { .. } + | wasmparser::Operator::V128Store { .. } + | wasmparser::Operator::V128Load8Lane { .. } + | wasmparser::Operator::V128Load16Lane { .. } + | wasmparser::Operator::V128Load32Lane { .. } + | wasmparser::Operator::V128Load64Lane { .. } + | wasmparser::Operator::V128Store8Lane { .. } + | wasmparser::Operator::V128Store16Lane { .. } + | wasmparser::Operator::V128Store32Lane { .. } + | wasmparser::Operator::V128Store64Lane { .. } + | wasmparser::Operator::V128Const { .. } + | wasmparser::Operator::I8x16Shuffle { .. } + | wasmparser::Operator::I8x16ExtractLaneS { .. } + | wasmparser::Operator::I8x16ExtractLaneU { .. } + | wasmparser::Operator::I8x16ReplaceLane { .. } + | wasmparser::Operator::I16x8ExtractLaneS { .. } + | wasmparser::Operator::I16x8ExtractLaneU { .. } + | wasmparser::Operator::I16x8ReplaceLane { .. } + | wasmparser::Operator::I32x4ExtractLane { .. } + | wasmparser::Operator::I32x4ReplaceLane { .. } + | wasmparser::Operator::I64x2ExtractLane { .. } + | wasmparser::Operator::I64x2ReplaceLane { .. } + | wasmparser::Operator::F32x4ExtractLane { .. } + | wasmparser::Operator::F32x4ReplaceLane { .. } + | wasmparser::Operator::F64x2ExtractLane { .. } + | wasmparser::Operator::F64x2ReplaceLane { .. } + | wasmparser::Operator::I8x16Swizzle + | wasmparser::Operator::I8x16Splat + | wasmparser::Operator::I16x8Splat + | wasmparser::Operator::I32x4Splat + | wasmparser::Operator::I64x2Splat + | wasmparser::Operator::F32x4Splat + | wasmparser::Operator::F64x2Splat + | wasmparser::Operator::I8x16Eq + | wasmparser::Operator::I8x16Ne + | wasmparser::Operator::I8x16LtS + | wasmparser::Operator::I8x16LtU + | wasmparser::Operator::I8x16GtS + | wasmparser::Operator::I8x16GtU + | wasmparser::Operator::I8x16LeS + | wasmparser::Operator::I8x16LeU + | wasmparser::Operator::I8x16GeS + | wasmparser::Operator::I8x16GeU + | wasmparser::Operator::I16x8Eq + | wasmparser::Operator::I16x8Ne + | wasmparser::Operator::I16x8LtS + | wasmparser::Operator::I16x8LtU + | wasmparser::Operator::I16x8GtS + | wasmparser::Operator::I16x8GtU + | wasmparser::Operator::I16x8LeS + | wasmparser::Operator::I16x8LeU + | wasmparser::Operator::I16x8GeS + | wasmparser::Operator::I16x8GeU + | wasmparser::Operator::I32x4Eq + | wasmparser::Operator::I32x4Ne + | wasmparser::Operator::I32x4LtS + | wasmparser::Operator::I32x4LtU + | wasmparser::Operator::I32x4GtS + | wasmparser::Operator::I32x4GtU + | wasmparser::Operator::I32x4LeS + | wasmparser::Operator::I32x4LeU + | wasmparser::Operator::I32x4GeS + | wasmparser::Operator::I32x4GeU + | wasmparser::Operator::I64x2Eq + | wasmparser::Operator::I64x2Ne + | wasmparser::Operator::I64x2LtS + | wasmparser::Operator::I64x2GtS + | wasmparser::Operator::I64x2LeS + | wasmparser::Operator::I64x2GeS + | wasmparser::Operator::F32x4Eq + | wasmparser::Operator::F32x4Ne + | wasmparser::Operator::F32x4Lt + | wasmparser::Operator::F32x4Gt + | wasmparser::Operator::F32x4Le + | wasmparser::Operator::F32x4Ge + | wasmparser::Operator::F64x2Eq + | wasmparser::Operator::F64x2Ne + | wasmparser::Operator::F64x2Lt + | wasmparser::Operator::F64x2Gt + | wasmparser::Operator::F64x2Le + | wasmparser::Operator::F64x2Ge + | wasmparser::Operator::V128Not + | wasmparser::Operator::V128And + | wasmparser::Operator::V128AndNot + | wasmparser::Operator::V128Or + | wasmparser::Operator::V128Xor + | wasmparser::Operator::V128Bitselect + | wasmparser::Operator::V128AnyTrue + | wasmparser::Operator::I8x16Abs + | wasmparser::Operator::I8x16Neg + | wasmparser::Operator::I8x16Popcnt + | wasmparser::Operator::I8x16AllTrue + | wasmparser::Operator::I8x16Bitmask + | wasmparser::Operator::I8x16NarrowI16x8S + | wasmparser::Operator::I8x16NarrowI16x8U + | wasmparser::Operator::I8x16Shl + | wasmparser::Operator::I8x16ShrS + | wasmparser::Operator::I8x16ShrU + | wasmparser::Operator::I8x16Add + | wasmparser::Operator::I8x16AddSatS + | wasmparser::Operator::I8x16AddSatU + | wasmparser::Operator::I8x16Sub + | wasmparser::Operator::I8x16SubSatS + | wasmparser::Operator::I8x16SubSatU + | wasmparser::Operator::I8x16MinS + | wasmparser::Operator::I8x16MinU + | wasmparser::Operator::I8x16MaxS + | wasmparser::Operator::I8x16MaxU + | wasmparser::Operator::I8x16AvgrU + | wasmparser::Operator::I16x8ExtAddPairwiseI8x16S + | wasmparser::Operator::I16x8ExtAddPairwiseI8x16U + | wasmparser::Operator::I16x8Abs + | wasmparser::Operator::I16x8Neg + | wasmparser::Operator::I16x8Q15MulrSatS + | wasmparser::Operator::I16x8AllTrue + | wasmparser::Operator::I16x8Bitmask + | wasmparser::Operator::I16x8NarrowI32x4S + | wasmparser::Operator::I16x8NarrowI32x4U + | wasmparser::Operator::I16x8ExtendLowI8x16S + | wasmparser::Operator::I16x8ExtendHighI8x16S + | wasmparser::Operator::I16x8ExtendLowI8x16U + | wasmparser::Operator::I16x8ExtendHighI8x16U + | wasmparser::Operator::I16x8Shl + | wasmparser::Operator::I16x8ShrS + | wasmparser::Operator::I16x8ShrU + | wasmparser::Operator::I16x8Add + | wasmparser::Operator::I16x8AddSatS + | wasmparser::Operator::I16x8AddSatU + | wasmparser::Operator::I16x8Sub + | wasmparser::Operator::I16x8SubSatS + | wasmparser::Operator::I16x8SubSatU + | wasmparser::Operator::I16x8Mul + | wasmparser::Operator::I16x8MinS + | wasmparser::Operator::I16x8MinU + | wasmparser::Operator::I16x8MaxS + | wasmparser::Operator::I16x8MaxU + | wasmparser::Operator::I16x8AvgrU + | wasmparser::Operator::I16x8ExtMulLowI8x16S + | wasmparser::Operator::I16x8ExtMulHighI8x16S + | wasmparser::Operator::I16x8ExtMulLowI8x16U + | wasmparser::Operator::I16x8ExtMulHighI8x16U + | wasmparser::Operator::I32x4ExtAddPairwiseI16x8S + | wasmparser::Operator::I32x4ExtAddPairwiseI16x8U + | wasmparser::Operator::I32x4Abs + | wasmparser::Operator::I32x4Neg + | wasmparser::Operator::I32x4AllTrue + | wasmparser::Operator::I32x4Bitmask + | wasmparser::Operator::I32x4ExtendLowI16x8S + | wasmparser::Operator::I32x4ExtendHighI16x8S + | wasmparser::Operator::I32x4ExtendLowI16x8U + | wasmparser::Operator::I32x4ExtendHighI16x8U + | wasmparser::Operator::I32x4Shl + | wasmparser::Operator::I32x4ShrS + | wasmparser::Operator::I32x4ShrU + | wasmparser::Operator::I32x4Add + | wasmparser::Operator::I32x4Sub + | wasmparser::Operator::I32x4Mul + | wasmparser::Operator::I32x4MinS + | wasmparser::Operator::I32x4MinU + | wasmparser::Operator::I32x4MaxS + | wasmparser::Operator::I32x4MaxU + | wasmparser::Operator::I32x4DotI16x8S + | wasmparser::Operator::I32x4ExtMulLowI16x8S + | wasmparser::Operator::I32x4ExtMulHighI16x8S + | wasmparser::Operator::I32x4ExtMulLowI16x8U + | wasmparser::Operator::I32x4ExtMulHighI16x8U + | wasmparser::Operator::I64x2Abs + | wasmparser::Operator::I64x2Neg + | wasmparser::Operator::I64x2AllTrue + | wasmparser::Operator::I64x2Bitmask + | wasmparser::Operator::I64x2ExtendLowI32x4S + | wasmparser::Operator::I64x2ExtendHighI32x4S + | wasmparser::Operator::I64x2ExtendLowI32x4U + | wasmparser::Operator::I64x2ExtendHighI32x4U + | wasmparser::Operator::I64x2Shl + | wasmparser::Operator::I64x2ShrS + | wasmparser::Operator::I64x2ShrU + | wasmparser::Operator::I64x2Add + | wasmparser::Operator::I64x2Sub + | wasmparser::Operator::I64x2Mul + | wasmparser::Operator::I64x2ExtMulLowI32x4S + | wasmparser::Operator::I64x2ExtMulHighI32x4S + | wasmparser::Operator::I64x2ExtMulLowI32x4U + | wasmparser::Operator::I64x2ExtMulHighI32x4U + | wasmparser::Operator::F32x4Ceil + | wasmparser::Operator::F32x4Floor + | wasmparser::Operator::F32x4Trunc + | wasmparser::Operator::F32x4Nearest + | wasmparser::Operator::F32x4Abs + | wasmparser::Operator::F32x4Neg + | wasmparser::Operator::F32x4Sqrt + | wasmparser::Operator::F32x4Add + | wasmparser::Operator::F32x4Sub + | wasmparser::Operator::F32x4Mul + | wasmparser::Operator::F32x4Div + | wasmparser::Operator::F32x4Min + | wasmparser::Operator::F32x4Max + | wasmparser::Operator::F32x4PMin + | wasmparser::Operator::F32x4PMax + | wasmparser::Operator::F64x2Ceil + | wasmparser::Operator::F64x2Floor + | wasmparser::Operator::F64x2Trunc + | wasmparser::Operator::F64x2Nearest + | wasmparser::Operator::F64x2Abs + | wasmparser::Operator::F64x2Neg + | wasmparser::Operator::F64x2Sqrt + | wasmparser::Operator::F64x2Add + | wasmparser::Operator::F64x2Sub + | wasmparser::Operator::F64x2Mul + | wasmparser::Operator::F64x2Div + | wasmparser::Operator::F64x2Min + | wasmparser::Operator::F64x2Max + | wasmparser::Operator::F64x2PMin + | wasmparser::Operator::F64x2PMax + | wasmparser::Operator::I32x4TruncSatF32x4S + | wasmparser::Operator::I32x4TruncSatF32x4U + | wasmparser::Operator::F32x4ConvertI32x4S + | wasmparser::Operator::F32x4ConvertI32x4U + | wasmparser::Operator::I32x4TruncSatF64x2SZero + | wasmparser::Operator::I32x4TruncSatF64x2UZero + | wasmparser::Operator::F64x2ConvertLowI32x4S + | wasmparser::Operator::F64x2ConvertLowI32x4U + | wasmparser::Operator::F32x4DemoteF64x2Zero + | wasmparser::Operator::F64x2PromoteLowF32x4 => { self.emit(Operator::try_from(&op).unwrap(), loc)? } diff --git a/src/op_traits.rs b/src/op_traits.rs index 8e6a887..36fb535 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -221,6 +221,260 @@ pub fn op_inputs( Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])), Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[])), Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])), + + Operator::V128Load { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load8x8S { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load8x8U { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load16x4S { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load16x4U { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load32x2S { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load32x2U { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load8Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load16Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load32Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load64Splat { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load32Zero { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load64Zero { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Load8Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Load16Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Load32Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Load64Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Store8Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Store16Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Store32Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + Operator::V128Store64Lane { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::V128])), + + Operator::V128Const { .. } => Ok(Cow::Borrowed(&[])), + Operator::I8x16Shuffle { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16ExtractLaneS { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16ExtractLaneU { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8ExtractLaneS { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtractLaneU { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::I64])), + Operator::F32x4ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::F32])), + Operator::F64x2ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128, Type::F64])), + + Operator::I8x16Swizzle => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16Splat => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I16x8Splat => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I32x4Splat => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I64x2Splat => Ok(Cow::Borrowed(&[Type::I64])), + Operator::F32x4Splat => Ok(Cow::Borrowed(&[Type::F32])), + Operator::F64x2Splat => Ok(Cow::Borrowed(&[Type::F64])), + + Operator::I8x16Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16LtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16LtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16GtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16GtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16LeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16LeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16GeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16GeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I16x8Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8LtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8LtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8GtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8GtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8LeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8LeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8GeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8GeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I32x4Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4LtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4LtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4GtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4GtU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4LeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4LeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4GeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4GeU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I64x2Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2LtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2GtS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2LeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2GeS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::F32x4Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Lt => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Gt => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Le => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Ge => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::F64x2Eq => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Ne => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Lt => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Gt => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Le => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Ge => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::V128Not => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128And => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::V128AndNot => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::V128Or => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::V128Xor => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::V128Bitselect => Ok(Cow::Borrowed(&[Type::V128, Type::V128, Type::V128])), + Operator::V128AnyTrue => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I8x16Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Popcnt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16AllTrue => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16NarrowI16x8S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16NarrowI16x8U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I8x16ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I8x16ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I8x16Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16AddSatS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16AddSatU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16SubSatS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16SubSatU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16MinS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16MinU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16MaxS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16MaxU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I8x16AvgrU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I16x8ExtAddPairwiseI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtAddPairwiseI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Q15MulrSatS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8AllTrue => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8NarrowI32x4S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8NarrowI32x4U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8ExtendLowI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendHighI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendLowI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendHighI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8AddSatS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8AddSatU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8SubSatS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8SubSatU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8Mul => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8MinS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8MinU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8MaxS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8MaxU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8AvgrU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8ExtMulLowI8x16S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8ExtMulHighI8x16S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8ExtMulLowI8x16U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I16x8ExtMulHighI8x16U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I32x4ExtAddPairwiseI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtAddPairwiseI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4AllTrue => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendLowI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendHighI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendLowI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendHighI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4Mul => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4MinS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4MinU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4MaxS => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4MaxU => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4DotI16x8S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4ExtMulLowI16x8S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4ExtMulHighI16x8S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4ExtMulLowI16x8U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I32x4ExtMulHighI16x8U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I64x2Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2AllTrue => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendLowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendHighI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendHighI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2Mul => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2ExtMulLowI32x4S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2ExtMulHighI32x4S => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2ExtMulLowI32x4U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::I64x2ExtMulHighI32x4U => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::F32x4Ceil => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Floor => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Trunc => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Nearest => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Sqrt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Mul => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Div => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Min => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4Max => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4PMin => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F32x4PMax => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::F64x2Ceil => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Floor => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Trunc => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Nearest => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Sqrt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Add => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Sub => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Mul => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Div => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Min => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2Max => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2PMin => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + Operator::F64x2PMax => Ok(Cow::Borrowed(&[Type::V128, Type::V128])), + + Operator::I32x4TruncSatF32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF32x4U => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F32x4ConvertI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4ConvertI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF64x2SZero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF64x2UZero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ConvertLowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), } } @@ -425,6 +679,260 @@ pub fn op_outputs( Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])), Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[Type::I32])), Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])), + + Operator::V128Load { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load8x8S { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::V128Load8x8U { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load16x4S { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load16x4U { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load32x2S { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load32x2U { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load8Splat { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load16Splat { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load32Splat { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load64Splat { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load32Zero { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load64Zero { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Store { .. } => Ok(Cow::Borrowed(&[])), + Operator::V128Load8Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load16Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load32Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Load64Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Store8Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Store16Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Store32Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Store64Lane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::V128Const { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Shuffle { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16ExtractLaneS { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I8x16ExtractLaneU { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I8x16ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtractLaneS { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I16x8ExtractLaneU { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I16x8ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I32x4ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::I64])), + Operator::I64x2ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::F32])), + Operator::F32x4ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ExtractLane { .. } => Ok(Cow::Borrowed(&[Type::F64])), + Operator::F64x2ReplaceLane { .. } => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I8x16Swizzle => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Splat => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Splat => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Splat => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Splat => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Splat => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Splat => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I8x16Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16LtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16LtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16GtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16GtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16LeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16LeU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16GeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16GeU => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I16x8Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8LtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8LtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8GtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8GtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8LeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8LeU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8GeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8GeU => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I32x4Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4LtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4LtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4GtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4GtU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4LeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4LeU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4GeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4GeU => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I64x2Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2LtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2GtS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2LeS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2GeS => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F32x4Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Lt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Gt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Le => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Ge => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F64x2Eq => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Ne => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Lt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Gt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Le => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Ge => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::V128Not => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128And => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128AndNot => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Or => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Xor => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128Bitselect => Ok(Cow::Borrowed(&[Type::V128])), + Operator::V128AnyTrue => Ok(Cow::Borrowed(&[Type::I32])), + + Operator::I8x16Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Popcnt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16AllTrue => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I8x16Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16NarrowI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16NarrowI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Shl => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16ShrS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16ShrU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16AddSatS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16AddSatU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16SubSatS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16SubSatU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16MinS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16MinU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16MaxS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16MaxU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I8x16AvgrU => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I16x8ExtAddPairwiseI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtAddPairwiseI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Q15MulrSatS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8AllTrue => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I16x8Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8NarrowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8NarrowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendLowI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendHighI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendLowI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtendHighI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I16x8Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8AddSatS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8AddSatU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8SubSatS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8SubSatU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8Mul => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8MinS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8MinU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8MaxS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8MaxU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8AvgrU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtMulLowI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtMulHighI8x16S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtMulLowI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I16x8ExtMulHighI8x16U => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I32x4ExtAddPairwiseI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtAddPairwiseI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4AllTrue => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I32x4Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendLowI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendHighI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendLowI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtendHighI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I32x4Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4Mul => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4MinS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4MinU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4MaxS => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4MaxU => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4DotI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtMulLowI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtMulHighI16x8S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtMulLowI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4ExtMulHighI16x8U => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I64x2Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2AllTrue => Ok(Cow::Borrowed(&[Type::I32])), + Operator::I64x2Bitmask => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendLowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendHighI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtendHighI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Shl => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2ShrS => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2ShrU => Ok(Cow::Borrowed(&[Type::V128, Type::I32])), + Operator::I64x2Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2Mul => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtMulLowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtMulHighI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtMulLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I64x2ExtMulHighI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F32x4Ceil => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Floor => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Trunc => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Nearest => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Sqrt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Mul => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Div => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Min => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4Max => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4PMin => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4PMax => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F64x2Ceil => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Floor => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Trunc => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Nearest => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Abs => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Neg => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Sqrt => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Add => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Sub => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Mul => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Div => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Min => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2Max => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2PMin => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2PMax => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::I32x4TruncSatF32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF32x4U => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::F32x4ConvertI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4ConvertI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF64x2SZero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::I32x4TruncSatF64x2UZero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ConvertLowI32x4S => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), + Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), } } @@ -635,6 +1143,260 @@ impl Operator { Operator::TableSize { .. } => &[ReadTable], Operator::MemorySize { .. } => &[ReadMem], Operator::MemoryGrow { .. } => &[WriteMem, Trap], + + Operator::V128Load { .. } => &[ReadMem], + Operator::V128Load8x8S { .. } => &[ReadMem], + Operator::V128Load8x8U { .. } => &[ReadMem], + Operator::V128Load16x4S { .. } => &[ReadMem], + Operator::V128Load16x4U { .. } => &[ReadMem], + Operator::V128Load32x2S { .. } => &[ReadMem], + Operator::V128Load32x2U { .. } => &[ReadMem], + Operator::V128Load8Splat { .. } => &[ReadMem], + Operator::V128Load16Splat { .. } => &[ReadMem], + Operator::V128Load32Splat { .. } => &[ReadMem], + Operator::V128Load64Splat { .. } => &[ReadMem], + Operator::V128Load32Zero { .. } => &[ReadMem], + Operator::V128Load64Zero { .. } => &[ReadMem], + Operator::V128Store { .. } => &[WriteMem], + Operator::V128Load8Lane { .. } => &[ReadMem], + Operator::V128Load16Lane { .. } => &[ReadMem], + Operator::V128Load32Lane { .. } => &[ReadMem], + Operator::V128Load64Lane { .. } => &[ReadMem], + Operator::V128Store8Lane { .. } => &[WriteMem], + Operator::V128Store16Lane { .. } => &[WriteMem], + Operator::V128Store32Lane { .. } => &[WriteMem], + Operator::V128Store64Lane { .. } => &[WriteMem], + + Operator::V128Const { .. } => &[], + Operator::I8x16Shuffle { .. } => &[], + Operator::I8x16ExtractLaneS { .. } => &[], + Operator::I8x16ExtractLaneU { .. } => &[], + Operator::I8x16ReplaceLane { .. } => &[], + Operator::I16x8ExtractLaneS { .. } => &[], + Operator::I16x8ExtractLaneU { .. } => &[], + Operator::I16x8ReplaceLane { .. } => &[], + Operator::I32x4ExtractLane { .. } => &[], + Operator::I32x4ReplaceLane { .. } => &[], + Operator::I64x2ExtractLane { .. } => &[], + Operator::I64x2ReplaceLane { .. } => &[], + Operator::F32x4ExtractLane { .. } => &[], + Operator::F32x4ReplaceLane { .. } => &[], + Operator::F64x2ExtractLane { .. } => &[], + Operator::F64x2ReplaceLane { .. } => &[], + + Operator::I8x16Swizzle => &[], + Operator::I8x16Splat => &[], + Operator::I16x8Splat => &[], + Operator::I32x4Splat => &[], + Operator::I64x2Splat => &[], + Operator::F32x4Splat => &[], + Operator::F64x2Splat => &[], + + Operator::I8x16Eq => &[], + Operator::I8x16Ne => &[], + Operator::I8x16LtS => &[], + Operator::I8x16LtU => &[], + Operator::I8x16GtS => &[], + Operator::I8x16GtU => &[], + Operator::I8x16LeS => &[], + Operator::I8x16LeU => &[], + Operator::I8x16GeS => &[], + Operator::I8x16GeU => &[], + + Operator::I16x8Eq => &[], + Operator::I16x8Ne => &[], + Operator::I16x8LtS => &[], + Operator::I16x8LtU => &[], + Operator::I16x8GtS => &[], + Operator::I16x8GtU => &[], + Operator::I16x8LeS => &[], + Operator::I16x8LeU => &[], + Operator::I16x8GeS => &[], + Operator::I16x8GeU => &[], + + Operator::I32x4Eq => &[], + Operator::I32x4Ne => &[], + Operator::I32x4LtS => &[], + Operator::I32x4LtU => &[], + Operator::I32x4GtS => &[], + Operator::I32x4GtU => &[], + Operator::I32x4LeS => &[], + Operator::I32x4LeU => &[], + Operator::I32x4GeS => &[], + Operator::I32x4GeU => &[], + + Operator::I64x2Eq => &[], + Operator::I64x2Ne => &[], + Operator::I64x2LtS => &[], + Operator::I64x2GtS => &[], + Operator::I64x2LeS => &[], + Operator::I64x2GeS => &[], + + Operator::F32x4Eq => &[], + Operator::F32x4Ne => &[], + Operator::F32x4Lt => &[], + Operator::F32x4Gt => &[], + Operator::F32x4Le => &[], + Operator::F32x4Ge => &[], + + Operator::F64x2Eq => &[], + Operator::F64x2Ne => &[], + Operator::F64x2Lt => &[], + Operator::F64x2Gt => &[], + Operator::F64x2Le => &[], + Operator::F64x2Ge => &[], + + Operator::V128Not => &[], + Operator::V128And => &[], + Operator::V128AndNot => &[], + Operator::V128Or => &[], + Operator::V128Xor => &[], + Operator::V128Bitselect => &[], + Operator::V128AnyTrue => &[], + + Operator::I8x16Abs => &[], + Operator::I8x16Neg => &[], + Operator::I8x16Popcnt => &[], + Operator::I8x16AllTrue => &[], + Operator::I8x16Bitmask => &[], + Operator::I8x16NarrowI16x8S => &[], + Operator::I8x16NarrowI16x8U => &[], + Operator::I8x16Shl => &[], + Operator::I8x16ShrS => &[], + Operator::I8x16ShrU => &[], + Operator::I8x16Add => &[], + Operator::I8x16AddSatS => &[], + Operator::I8x16AddSatU => &[], + Operator::I8x16Sub => &[], + Operator::I8x16SubSatS => &[], + Operator::I8x16SubSatU => &[], + Operator::I8x16MinS => &[], + Operator::I8x16MinU => &[], + Operator::I8x16MaxS => &[], + Operator::I8x16MaxU => &[], + Operator::I8x16AvgrU => &[], + + Operator::I16x8ExtAddPairwiseI8x16S => &[], + Operator::I16x8ExtAddPairwiseI8x16U => &[], + Operator::I16x8Abs => &[], + Operator::I16x8Neg => &[], + Operator::I16x8Q15MulrSatS => &[], + Operator::I16x8AllTrue => &[], + Operator::I16x8Bitmask => &[], + Operator::I16x8NarrowI32x4S => &[], + Operator::I16x8NarrowI32x4U => &[], + Operator::I16x8ExtendLowI8x16S => &[], + Operator::I16x8ExtendHighI8x16S => &[], + Operator::I16x8ExtendLowI8x16U => &[], + Operator::I16x8ExtendHighI8x16U => &[], + Operator::I16x8Shl => &[], + Operator::I16x8ShrS => &[], + Operator::I16x8ShrU => &[], + Operator::I16x8Add => &[], + Operator::I16x8AddSatS => &[], + Operator::I16x8AddSatU => &[], + Operator::I16x8Sub => &[], + Operator::I16x8SubSatS => &[], + Operator::I16x8SubSatU => &[], + Operator::I16x8Mul => &[], + Operator::I16x8MinS => &[], + Operator::I16x8MinU => &[], + Operator::I16x8MaxS => &[], + Operator::I16x8MaxU => &[], + Operator::I16x8AvgrU => &[], + Operator::I16x8ExtMulLowI8x16S => &[], + Operator::I16x8ExtMulHighI8x16S => &[], + Operator::I16x8ExtMulLowI8x16U => &[], + Operator::I16x8ExtMulHighI8x16U => &[], + + Operator::I32x4ExtAddPairwiseI16x8S => &[], + Operator::I32x4ExtAddPairwiseI16x8U => &[], + Operator::I32x4Abs => &[], + Operator::I32x4Neg => &[], + Operator::I32x4AllTrue => &[], + Operator::I32x4Bitmask => &[], + Operator::I32x4ExtendLowI16x8S => &[], + Operator::I32x4ExtendHighI16x8S => &[], + Operator::I32x4ExtendLowI16x8U => &[], + Operator::I32x4ExtendHighI16x8U => &[], + Operator::I32x4Shl => &[], + Operator::I32x4ShrS => &[], + Operator::I32x4ShrU => &[], + Operator::I32x4Add => &[], + Operator::I32x4Sub => &[], + Operator::I32x4Mul => &[], + Operator::I32x4MinS => &[], + Operator::I32x4MinU => &[], + Operator::I32x4MaxS => &[], + Operator::I32x4MaxU => &[], + Operator::I32x4DotI16x8S => &[], + Operator::I32x4ExtMulLowI16x8S => &[], + Operator::I32x4ExtMulHighI16x8S => &[], + Operator::I32x4ExtMulLowI16x8U => &[], + Operator::I32x4ExtMulHighI16x8U => &[], + + Operator::I64x2Abs => &[], + Operator::I64x2Neg => &[], + Operator::I64x2AllTrue => &[], + Operator::I64x2Bitmask => &[], + Operator::I64x2ExtendLowI32x4S => &[], + Operator::I64x2ExtendHighI32x4S => &[], + Operator::I64x2ExtendLowI32x4U => &[], + Operator::I64x2ExtendHighI32x4U => &[], + Operator::I64x2Shl => &[], + Operator::I64x2ShrS => &[], + Operator::I64x2ShrU => &[], + Operator::I64x2Add => &[], + Operator::I64x2Sub => &[], + Operator::I64x2Mul => &[], + Operator::I64x2ExtMulLowI32x4S => &[], + Operator::I64x2ExtMulHighI32x4S => &[], + Operator::I64x2ExtMulLowI32x4U => &[], + Operator::I64x2ExtMulHighI32x4U => &[], + + Operator::F32x4Ceil => &[], + Operator::F32x4Floor => &[], + Operator::F32x4Trunc => &[], + Operator::F32x4Nearest => &[], + Operator::F32x4Abs => &[], + Operator::F32x4Neg => &[], + Operator::F32x4Sqrt => &[], + Operator::F32x4Add => &[], + Operator::F32x4Sub => &[], + Operator::F32x4Mul => &[], + Operator::F32x4Div => &[], + Operator::F32x4Min => &[], + Operator::F32x4Max => &[], + Operator::F32x4PMin => &[], + Operator::F32x4PMax => &[], + + Operator::F64x2Ceil => &[], + Operator::F64x2Floor => &[], + Operator::F64x2Trunc => &[], + Operator::F64x2Nearest => &[], + Operator::F64x2Abs => &[], + Operator::F64x2Neg => &[], + Operator::F64x2Sqrt => &[], + Operator::F64x2Add => &[], + Operator::F64x2Sub => &[], + Operator::F64x2Mul => &[], + Operator::F64x2Div => &[], + Operator::F64x2Min => &[], + Operator::F64x2Max => &[], + Operator::F64x2PMin => &[], + Operator::F64x2PMax => &[], + + Operator::I32x4TruncSatF32x4S => &[], + Operator::I32x4TruncSatF32x4U => &[], + + Operator::F32x4ConvertI32x4S => &[], + Operator::F32x4ConvertI32x4U => &[], + Operator::I32x4TruncSatF64x2SZero => &[], + Operator::I32x4TruncSatF64x2UZero => &[], + Operator::F64x2ConvertLowI32x4S => &[], + Operator::F64x2ConvertLowI32x4U => &[], + Operator::F32x4DemoteF64x2Zero => &[], + Operator::F64x2PromoteLowF32x4 => &[], } } @@ -853,6 +1615,276 @@ impl std::fmt::Display for Operator { Operator::TableSize { table_index, .. } => write!(f, "table_size<{}>", table_index)?, Operator::MemorySize { mem } => write!(f, "memory_size<{}>", mem)?, Operator::MemoryGrow { mem } => write!(f, "memory_grow<{}>", mem)?, + + Operator::V128Load { memory } => write!(f, "v128load<{}>", memory)?, + Operator::V128Load8x8S { memory } => write!(f, "v128load8x8s<{}>", memory)?, + Operator::V128Load8x8U { memory } => write!(f, "v128load8x8u<{}>", memory)?, + Operator::V128Load16x4S { memory } => write!(f, "v128load16x4s<{}>", memory)?, + Operator::V128Load16x4U { memory } => write!(f, "v128load16x4u<{}>", memory)?, + Operator::V128Load32x2S { memory } => write!(f, "v128load32x2s<{}>", memory)?, + Operator::V128Load32x2U { memory } => write!(f, "v128load32x2u<{}>", memory)?, + Operator::V128Load8Splat { memory } => write!(f, "v128load8splat<{}>", memory)?, + Operator::V128Load16Splat { memory } => write!(f, "v128load16splat<{}>", memory)?, + Operator::V128Load32Splat { memory } => write!(f, "v128load32splat<{}>", memory)?, + Operator::V128Load64Splat { memory } => write!(f, "v128load64splat<{}>", memory)?, + Operator::V128Load32Zero { memory } => write!(f, "v128load32zero<{}>", memory)?, + Operator::V128Load64Zero { memory } => write!(f, "v128load64zero<{}>", memory)?, + Operator::V128Store { memory } => write!(f, "v128store<{}>", memory)?, + Operator::V128Load8Lane { memory, lane } => { + write!(f, "v128load8lane<{}, {}>", memory, lane)? + } + Operator::V128Load16Lane { memory, lane } => { + write!(f, "v128load16lane<{}, {}>", memory, lane)? + } + Operator::V128Load32Lane { memory, lane } => { + write!(f, "v128load32lane<{}, {}>", memory, lane)? + } + Operator::V128Load64Lane { memory, lane } => { + write!(f, "v128load64lane<{}, {}>", memory, lane)? + } + Operator::V128Store8Lane { memory, lane } => { + write!(f, "v128store8lane<{}, {}>", memory, lane)? + } + Operator::V128Store16Lane { memory, lane } => { + write!(f, "v128store16lane<{}, {}>", memory, lane)? + } + Operator::V128Store32Lane { memory, lane } => { + write!(f, "v128store32lane<{}, {}>", memory, lane)? + } + Operator::V128Store64Lane { memory, lane } => { + write!(f, "v128store64lane<{}, {}>", memory, lane)? + } + + Operator::V128Const { value } => write!(f, "v128const<{}>", value)?, + Operator::I8x16Shuffle { lanes } => write!(f, "i8x16shuffle<{:?}>", lanes)?, + Operator::I8x16ExtractLaneS { lane } => write!(f, "i8x16extractlanes<{}>", lane)?, + Operator::I8x16ExtractLaneU { lane } => write!(f, "i8x16extractlaneu<{}>", lane)?, + Operator::I8x16ReplaceLane { lane } => write!(f, "i8x16replacelane<{}>", lane)?, + Operator::I16x8ExtractLaneS { lane } => write!(f, "i16x8extractlanes<{}>", lane)?, + Operator::I16x8ExtractLaneU { lane } => write!(f, "i16x8extractlaneu<{}>", lane)?, + Operator::I16x8ReplaceLane { lane } => write!(f, "i16x8replacelane<{}>", lane)?, + Operator::I32x4ExtractLane { lane } => write!(f, "i32x4extractlane<{}>", lane)?, + Operator::I32x4ReplaceLane { lane } => write!(f, "i32x4replacelane<{}>", lane)?, + Operator::I64x2ExtractLane { lane } => write!(f, "i64x2extractlane<{}>", lane)?, + Operator::I64x2ReplaceLane { lane } => write!(f, "i64x2replacelane<{}>", lane)?, + Operator::F32x4ExtractLane { lane } => write!(f, "f32x4extractlane<{}>", lane)?, + Operator::F32x4ReplaceLane { lane } => write!(f, "f32x4replacelane<{}>", lane)?, + Operator::F64x2ExtractLane { lane } => write!(f, "f64x2extractlane<{}>", lane)?, + Operator::F64x2ReplaceLane { lane } => write!(f, "f64x2replacelane<{}>", lane)?, + + Operator::I8x16Swizzle => write!(f, "i8x16swizzle")?, + Operator::I8x16Splat => write!(f, "i8x16splat")?, + Operator::I16x8Splat => write!(f, "i16x8splat")?, + Operator::I32x4Splat => write!(f, "i32x4splat")?, + Operator::I64x2Splat => write!(f, "i64x2splat")?, + Operator::F32x4Splat => write!(f, "f32x4splat")?, + Operator::F64x2Splat => write!(f, "f64x2splat")?, + + Operator::I8x16Eq => write!(f, "i8x16eq")?, + Operator::I8x16Ne => write!(f, "i8x16ne")?, + Operator::I8x16LtS => write!(f, "i8x16lts")?, + Operator::I8x16LtU => write!(f, "i8x16ltu")?, + Operator::I8x16GtS => write!(f, "i8x16gts")?, + Operator::I8x16GtU => write!(f, "i8x16gtu")?, + Operator::I8x16LeS => write!(f, "i8x16les")?, + Operator::I8x16LeU => write!(f, "i8x16leu")?, + Operator::I8x16GeS => write!(f, "i8x16ges")?, + Operator::I8x16GeU => write!(f, "i8x16geu")?, + + Operator::I16x8Eq => write!(f, "i16x8eq")?, + Operator::I16x8Ne => write!(f, "i16x8ne")?, + Operator::I16x8LtS => write!(f, "i16x8lts")?, + Operator::I16x8LtU => write!(f, "i16x8ltu")?, + Operator::I16x8GtS => write!(f, "i16x8gts")?, + Operator::I16x8GtU => write!(f, "i16x8gtu")?, + Operator::I16x8LeS => write!(f, "i16x8les")?, + Operator::I16x8LeU => write!(f, "i16x8leu")?, + Operator::I16x8GeS => write!(f, "i16x8ges")?, + Operator::I16x8GeU => write!(f, "i16x8geu")?, + + Operator::I32x4Eq => write!(f, "i32x4eq")?, + Operator::I32x4Ne => write!(f, "i32x4ne")?, + Operator::I32x4LtS => write!(f, "i32x4lts")?, + Operator::I32x4LtU => write!(f, "i32x4ltu")?, + Operator::I32x4GtS => write!(f, "i32x4gts")?, + Operator::I32x4GtU => write!(f, "i32x4gtu")?, + Operator::I32x4LeS => write!(f, "i32x4les")?, + Operator::I32x4LeU => write!(f, "i32x4leu")?, + Operator::I32x4GeS => write!(f, "i32x4ges")?, + Operator::I32x4GeU => write!(f, "i32x4geu")?, + + Operator::I64x2Eq => write!(f, "i64x2eq")?, + Operator::I64x2Ne => write!(f, "i64x2ne")?, + Operator::I64x2LtS => write!(f, "i64x2lts")?, + Operator::I64x2GtS => write!(f, "i64x2gts")?, + Operator::I64x2LeS => write!(f, "i64x2les")?, + Operator::I64x2GeS => write!(f, "i64x2ges")?, + + Operator::F32x4Eq => write!(f, "f32x4eq")?, + Operator::F32x4Ne => write!(f, "f32x4ne")?, + Operator::F32x4Lt => write!(f, "f32x4lt")?, + Operator::F32x4Gt => write!(f, "f32x2gt")?, + Operator::F32x4Le => write!(f, "f32x4le")?, + Operator::F32x4Ge => write!(f, "f32x4ge")?, + + Operator::F64x2Eq => write!(f, "f64x2eq")?, + Operator::F64x2Ne => write!(f, "f64x2ne")?, + Operator::F64x2Lt => write!(f, "f64x2lt")?, + Operator::F64x2Gt => write!(f, "f64x2gt")?, + Operator::F64x2Le => write!(f, "f64x2le")?, + Operator::F64x2Ge => write!(f, "f64x2ge")?, + + Operator::V128Not => write!(f, "v128not")?, + Operator::V128And => write!(f, "v128and")?, + Operator::V128AndNot => write!(f, "v128andnot")?, + Operator::V128Or => write!(f, "v128or")?, + Operator::V128Xor => write!(f, "v128xor")?, + Operator::V128Bitselect => write!(f, "v128bitselect")?, + Operator::V128AnyTrue => write!(f, "v128anytrue")?, + + Operator::I8x16Abs => write!(f, "i8x16abs")?, + Operator::I8x16Neg => write!(f, "i8x16neg")?, + Operator::I8x16Popcnt => write!(f, "i8x16popcnt")?, + Operator::I8x16AllTrue => write!(f, "i8x16alltrue")?, + Operator::I8x16Bitmask => write!(f, "i8x16bitmask")?, + Operator::I8x16NarrowI16x8S => write!(f, "i8x16narrow16x8s")?, + Operator::I8x16NarrowI16x8U => write!(f, "i8x16narrow16x8u")?, + Operator::I8x16Shl => write!(f, "i8x16shl")?, + Operator::I8x16ShrS => write!(f, "i8x16shrs")?, + Operator::I8x16ShrU => write!(f, "i8x16shru")?, + Operator::I8x16Add => write!(f, "i8x16add")?, + Operator::I8x16AddSatS => write!(f, "i8x16addsats")?, + Operator::I8x16AddSatU => write!(f, "i8x16addsatu")?, + Operator::I8x16Sub => write!(f, "i8x16sub")?, + Operator::I8x16SubSatS => write!(f, "i8x16subsats")?, + Operator::I8x16SubSatU => write!(f, "i8x16subsatu")?, + Operator::I8x16MinS => write!(f, "i8x16mins")?, + Operator::I8x16MinU => write!(f, "i8x16minu")?, + Operator::I8x16MaxS => write!(f, "i8x16maxs")?, + Operator::I8x16MaxU => write!(f, "i8x16maxu")?, + Operator::I8x16AvgrU => write!(f, "i8x16avgru")?, + + Operator::I16x8ExtAddPairwiseI8x16S => write!(f, "i16x8extaddpairwisei8x16s")?, + Operator::I16x8ExtAddPairwiseI8x16U => write!(f, "i16x8extaddpairwisei8x16u")?, + Operator::I16x8Abs => write!(f, "i16x8abs")?, + Operator::I16x8Neg => write!(f, "i16x8neg")?, + Operator::I16x8Q15MulrSatS => write!(f, "i16x8q15mulrsats")?, + Operator::I16x8AllTrue => write!(f, "i16x8alltrue")?, + Operator::I16x8Bitmask => write!(f, "i16x8bitmask")?, + Operator::I16x8NarrowI32x4S => write!(f, "i16x8narrowi32x4s")?, + Operator::I16x8NarrowI32x4U => write!(f, "i16x8narrowi32x4u")?, + Operator::I16x8ExtendLowI8x16S => write!(f, "i16x8extendlowi8x16s")?, + Operator::I16x8ExtendHighI8x16S => write!(f, "i16x8extendhighi8x16s")?, + Operator::I16x8ExtendLowI8x16U => write!(f, "i16x8extendlowi8x16u")?, + Operator::I16x8ExtendHighI8x16U => write!(f, "i16x8extendhighi8x16u")?, + Operator::I16x8Shl => write!(f, "i16x8shl")?, + Operator::I16x8ShrS => write!(f, "i16x8shrs")?, + Operator::I16x8ShrU => write!(f, "i16x8shru")?, + Operator::I16x8Add => write!(f, "i16x8add")?, + Operator::I16x8AddSatS => write!(f, "i16x8addsats")?, + Operator::I16x8AddSatU => write!(f, "i16x8addsatu")?, + Operator::I16x8Sub => write!(f, "i16x8sub")?, + Operator::I16x8SubSatS => write!(f, "i16x8subsats")?, + Operator::I16x8SubSatU => write!(f, "i16x8subsatu")?, + Operator::I16x8Mul => write!(f, "i16x8mul")?, + Operator::I16x8MinS => write!(f, "i16x8mins")?, + Operator::I16x8MinU => write!(f, "i16x8minu")?, + Operator::I16x8MaxS => write!(f, "i16x8maxs")?, + Operator::I16x8MaxU => write!(f, "i16x8maxu")?, + Operator::I16x8AvgrU => write!(f, "i16x8avgru")?, + Operator::I16x8ExtMulLowI8x16S => write!(f, "i16x8extmullowi8x16s")?, + Operator::I16x8ExtMulHighI8x16S => write!(f, "i16x8extmulhighi8x16s")?, + Operator::I16x8ExtMulLowI8x16U => write!(f, "i16x8extmullowi8x16u")?, + Operator::I16x8ExtMulHighI8x16U => write!(f, "i16x8extmulhighi8x16u")?, + + Operator::I32x4ExtAddPairwiseI16x8S => write!(f, "i32x4extaddpairwisei16x8s")?, + Operator::I32x4ExtAddPairwiseI16x8U => write!(f, "i32x4extaddpairwisei16x8u")?, + Operator::I32x4Abs => write!(f, "i32x4abs")?, + Operator::I32x4Neg => write!(f, "i32x4neg")?, + Operator::I32x4AllTrue => write!(f, "i32x4alltrue")?, + Operator::I32x4Bitmask => write!(f, "i32x4bitmask")?, + Operator::I32x4ExtendLowI16x8S => write!(f, "i32x4extendlowi16x8s")?, + Operator::I32x4ExtendHighI16x8S => write!(f, "i32x4extendhighi16x8s")?, + Operator::I32x4ExtendLowI16x8U => write!(f, "i32x4extendlowi16x8u")?, + Operator::I32x4ExtendHighI16x8U => write!(f, "i32x4extendhighi16x8u")?, + Operator::I32x4Shl => write!(f, "i32x4shl")?, + Operator::I32x4ShrS => write!(f, "i32x4shrs")?, + Operator::I32x4ShrU => write!(f, "i32x4shru")?, + Operator::I32x4Add => write!(f, "i32x4add")?, + Operator::I32x4Sub => write!(f, "i32x4sub")?, + Operator::I32x4Mul => write!(f, "i32x4mul")?, + Operator::I32x4MinS => write!(f, "i32x4mins")?, + Operator::I32x4MinU => write!(f, "i32x4minu")?, + Operator::I32x4MaxS => write!(f, "i32x4maxs")?, + Operator::I32x4MaxU => write!(f, "i32x4maxu")?, + Operator::I32x4DotI16x8S => write!(f, "i32x4doti16x8s")?, + Operator::I32x4ExtMulLowI16x8S => write!(f, "i32x4extmullowi16x8s")?, + Operator::I32x4ExtMulHighI16x8S => write!(f, "i32x4extmulhighi16x8s")?, + Operator::I32x4ExtMulLowI16x8U => write!(f, "i32x4extmullowi16x8u")?, + Operator::I32x4ExtMulHighI16x8U => write!(f, "i32x4extmulhighi16x8u")?, + + Operator::I64x2Abs => write!(f, "i64x2abs")?, + Operator::I64x2Neg => write!(f, "i64x2neg")?, + Operator::I64x2AllTrue => write!(f, "i64x2alltrue")?, + Operator::I64x2Bitmask => write!(f, "i64x2bitmask")?, + Operator::I64x2ExtendLowI32x4S => write!(f, "i64x2extendlowi32x4s")?, + Operator::I64x2ExtendHighI32x4S => write!(f, "i64x2extendhighi32x4s")?, + Operator::I64x2ExtendLowI32x4U => write!(f, "i64x2extendlowi32x4u")?, + Operator::I64x2ExtendHighI32x4U => write!(f, "i64x2extendhighi32x4u")?, + Operator::I64x2Shl => write!(f, "i64x2shl")?, + Operator::I64x2ShrS => write!(f, "i64x2shrs")?, + Operator::I64x2ShrU => write!(f, "i64x2shru")?, + Operator::I64x2Add => write!(f, "i64x2add")?, + Operator::I64x2Sub => write!(f, "i64x2sub")?, + Operator::I64x2Mul => write!(f, "i64x2mul")?, + Operator::I64x2ExtMulLowI32x4S => write!(f, "i64x2extmullowi32x4s")?, + Operator::I64x2ExtMulHighI32x4S => write!(f, "i64x2extmulhighi32x4s")?, + Operator::I64x2ExtMulLowI32x4U => write!(f, "i64x2extmullowi32x4u")?, + Operator::I64x2ExtMulHighI32x4U => write!(f, "i64x2extmulhighi32x4u")?, + + Operator::F32x4Ceil => write!(f, "f32x4ceil")?, + Operator::F32x4Floor => write!(f, "f32x4floor")?, + Operator::F32x4Trunc => write!(f, "f32x4trunc")?, + Operator::F32x4Nearest => write!(f, "f32x4nearest")?, + Operator::F32x4Abs => write!(f, "f32x4abs")?, + Operator::F32x4Neg => write!(f, "f32x4neg")?, + Operator::F32x4Sqrt => write!(f, "f32x4sqrt")?, + Operator::F32x4Add => write!(f, "f32x4add")?, + Operator::F32x4Sub => write!(f, "f32x4sub")?, + Operator::F32x4Mul => write!(f, "f32x4mul")?, + Operator::F32x4Div => write!(f, "f32x4div")?, + Operator::F32x4Min => write!(f, "f32x4min")?, + Operator::F32x4Max => write!(f, "f32x4max")?, + Operator::F32x4PMin => write!(f, "f32x4pmin")?, + Operator::F32x4PMax => write!(f, "f32x4pmax")?, + + Operator::F64x2Ceil => write!(f, "f64x2ceil")?, + Operator::F64x2Floor => write!(f, "f64x2floor")?, + Operator::F64x2Trunc => write!(f, "f64x2trunc")?, + Operator::F64x2Nearest => write!(f, "f64x2nearest")?, + Operator::F64x2Abs => write!(f, "f64x2abs")?, + Operator::F64x2Neg => write!(f, "f64x2neg")?, + Operator::F64x2Sqrt => write!(f, "f64x2sqrt")?, + Operator::F64x2Add => write!(f, "f64x2add")?, + Operator::F64x2Sub => write!(f, "f64x2sub")?, + Operator::F64x2Mul => write!(f, "f64x2mul")?, + Operator::F64x2Div => write!(f, "f64x2div")?, + Operator::F64x2Min => write!(f, "f64x2min")?, + Operator::F64x2Max => write!(f, "f64x2max")?, + Operator::F64x2PMin => write!(f, "f64x2pmin")?, + Operator::F64x2PMax => write!(f, "f64x2pmax")?, + + Operator::I32x4TruncSatF32x4S => write!(f, "i32x4truncsatf32x4s")?, + Operator::I32x4TruncSatF32x4U => write!(f, "i32x4truncsatf32x4u")?, + + Operator::F32x4ConvertI32x4S => write!(f, "f32x4converti32x4s")?, + Operator::F32x4ConvertI32x4U => write!(f, "f32x4converti32x4u")?, + Operator::I32x4TruncSatF64x2SZero => write!(f, "i32x4truncsatf64x2szero")?, + Operator::I32x4TruncSatF64x2UZero => write!(f, "i32x4truncsatf64x2uzero")?, + Operator::F64x2ConvertLowI32x4S => write!(f, "f64x2convertlowi32x4s")?, + Operator::F64x2ConvertLowI32x4U => write!(f, "f64x2convertlowi32x4u")?, + Operator::F32x4DemoteF64x2Zero => write!(f, "f32x4demotef64x2zero")?, + Operator::F64x2PromoteLowF32x4 => write!(f, "f64x2promotelowf32x4")?, } Ok(()) diff --git a/src/ops.rs b/src/ops.rs index ea7851d..75d82e6 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -295,6 +295,341 @@ pub enum Operator { MemoryGrow { mem: Memory, }, + + V128Load { + memory: MemoryArg, + }, + V128Load8x8S { + memory: MemoryArg, + }, + V128Load8x8U { + memory: MemoryArg, + }, + V128Load16x4S { + memory: MemoryArg, + }, + V128Load16x4U { + memory: MemoryArg, + }, + V128Load32x2S { + memory: MemoryArg, + }, + V128Load32x2U { + memory: MemoryArg, + }, + V128Load8Splat { + memory: MemoryArg, + }, + V128Load16Splat { + memory: MemoryArg, + }, + V128Load32Splat { + memory: MemoryArg, + }, + V128Load64Splat { + memory: MemoryArg, + }, + V128Load32Zero { + memory: MemoryArg, + }, + V128Load64Zero { + memory: MemoryArg, + }, + V128Store { + memory: MemoryArg, + }, + V128Load8Lane { + memory: MemoryArg, + lane: u8, + }, + V128Load16Lane { + memory: MemoryArg, + lane: u8, + }, + V128Load32Lane { + memory: MemoryArg, + lane: u8, + }, + V128Load64Lane { + memory: MemoryArg, + lane: u8, + }, + V128Store8Lane { + memory: MemoryArg, + lane: u8, + }, + V128Store16Lane { + memory: MemoryArg, + lane: u8, + }, + V128Store32Lane { + memory: MemoryArg, + lane: u8, + }, + V128Store64Lane { + memory: MemoryArg, + lane: u8, + }, + + V128Const { + value: u128, + }, + + I8x16Shuffle { + lanes: [u8; 16], + }, + + I8x16ExtractLaneS { + lane: u8, + }, + I8x16ExtractLaneU { + lane: u8, + }, + I8x16ReplaceLane { + lane: u8, + }, + I16x8ExtractLaneS { + lane: u8, + }, + I16x8ExtractLaneU { + lane: u8, + }, + I16x8ReplaceLane { + lane: u8, + }, + I32x4ExtractLane { + lane: u8, + }, + I32x4ReplaceLane { + lane: u8, + }, + I64x2ExtractLane { + lane: u8, + }, + I64x2ReplaceLane { + lane: u8, + }, + F32x4ExtractLane { + lane: u8, + }, + F32x4ReplaceLane { + lane: u8, + }, + F64x2ExtractLane { + lane: u8, + }, + F64x2ReplaceLane { + lane: u8, + }, + + I8x16Swizzle, + I8x16Splat, + I16x8Splat, + I32x4Splat, + I64x2Splat, + F32x4Splat, + F64x2Splat, + + I8x16Eq, + I8x16Ne, + I8x16LtS, + I8x16LtU, + I8x16GtS, + I8x16GtU, + I8x16LeS, + I8x16LeU, + I8x16GeS, + I8x16GeU, + + I16x8Eq, + I16x8Ne, + I16x8LtS, + I16x8LtU, + I16x8GtS, + I16x8GtU, + I16x8LeS, + I16x8LeU, + I16x8GeS, + I16x8GeU, + + I32x4Eq, + I32x4Ne, + I32x4LtS, + I32x4LtU, + I32x4GtS, + I32x4GtU, + I32x4LeS, + I32x4LeU, + I32x4GeS, + I32x4GeU, + + I64x2Eq, + I64x2Ne, + I64x2LtS, + I64x2GtS, + I64x2LeS, + I64x2GeS, + + F32x4Eq, + F32x4Ne, + F32x4Lt, + F32x4Gt, + F32x4Le, + F32x4Ge, + + F64x2Eq, + F64x2Ne, + F64x2Lt, + F64x2Gt, + F64x2Le, + F64x2Ge, + + V128Not, + V128And, + V128AndNot, + V128Or, + V128Xor, + V128Bitselect, + V128AnyTrue, + + I8x16Abs, + I8x16Neg, + I8x16Popcnt, + I8x16AllTrue, + I8x16Bitmask, + I8x16NarrowI16x8S, + I8x16NarrowI16x8U, + I8x16Shl, + I8x16ShrS, + I8x16ShrU, + I8x16Add, + I8x16AddSatS, + I8x16AddSatU, + I8x16Sub, + I8x16SubSatS, + I8x16SubSatU, + I8x16MinS, + I8x16MinU, + I8x16MaxS, + I8x16MaxU, + I8x16AvgrU, + + I16x8ExtAddPairwiseI8x16S, + I16x8ExtAddPairwiseI8x16U, + I16x8Abs, + I16x8Neg, + I16x8Q15MulrSatS, + I16x8AllTrue, + I16x8Bitmask, + I16x8NarrowI32x4S, + I16x8NarrowI32x4U, + I16x8ExtendLowI8x16S, + I16x8ExtendHighI8x16S, + I16x8ExtendLowI8x16U, + I16x8ExtendHighI8x16U, + I16x8Shl, + I16x8ShrS, + I16x8ShrU, + I16x8Add, + I16x8AddSatS, + I16x8AddSatU, + I16x8Sub, + I16x8SubSatS, + I16x8SubSatU, + I16x8Mul, + I16x8MinS, + I16x8MinU, + I16x8MaxS, + I16x8MaxU, + I16x8AvgrU, + I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S, + I16x8ExtMulLowI8x16U, + I16x8ExtMulHighI8x16U, + I32x4ExtAddPairwiseI16x8S, + I32x4ExtAddPairwiseI16x8U, + + I32x4Abs, + I32x4Neg, + I32x4AllTrue, + I32x4Bitmask, + I32x4ExtendLowI16x8S, + I32x4ExtendHighI16x8S, + I32x4ExtendLowI16x8U, + I32x4ExtendHighI16x8U, + I32x4Shl, + I32x4ShrS, + I32x4ShrU, + I32x4Add, + I32x4Sub, + I32x4Mul, + I32x4MinS, + I32x4MinU, + I32x4MaxS, + I32x4MaxU, + I32x4DotI16x8S, + I32x4ExtMulLowI16x8S, + I32x4ExtMulHighI16x8S, + I32x4ExtMulLowI16x8U, + I32x4ExtMulHighI16x8U, + I64x2Abs, + I64x2Neg, + I64x2AllTrue, + I64x2Bitmask, + I64x2ExtendLowI32x4S, + I64x2ExtendHighI32x4S, + I64x2ExtendLowI32x4U, + I64x2ExtendHighI32x4U, + I64x2Shl, + I64x2ShrS, + I64x2ShrU, + I64x2Add, + I64x2Sub, + I64x2Mul, + I64x2ExtMulLowI32x4S, + I64x2ExtMulHighI32x4S, + I64x2ExtMulLowI32x4U, + I64x2ExtMulHighI32x4U, + 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, } #[test] @@ -568,6 +903,362 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator { &wasmparser::Operator::MemoryGrow { mem, .. } => Ok(Operator::MemoryGrow { mem: Memory::from(mem), }), + + &wasmparser::Operator::V128Load { memarg } => Ok(Operator::V128Load { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load8x8S { memarg } => Ok(Operator::V128Load8x8S { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load8x8U { memarg } => Ok(Operator::V128Load8x8U { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load16x4S { memarg } => Ok(Operator::V128Load16x4S { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load16x4U { memarg } => Ok(Operator::V128Load16x4U { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load32x2S { memarg } => Ok(Operator::V128Load32x2S { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load32x2U { memarg } => Ok(Operator::V128Load32x2U { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load8Splat { memarg } => Ok(Operator::V128Load8Splat { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load16Splat { memarg } => Ok(Operator::V128Load16Splat { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load32Splat { memarg } => Ok(Operator::V128Load32Splat { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load64Splat { memarg } => Ok(Operator::V128Load64Splat { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load32Zero { memarg } => Ok(Operator::V128Load32Zero { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load64Zero { memarg } => Ok(Operator::V128Load64Zero { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Store { memarg } => Ok(Operator::V128Store { + memory: memarg.into(), + }), + &wasmparser::Operator::V128Load8Lane { memarg, lane } => Ok(Operator::V128Load8Lane { + memory: memarg.into(), + lane, + }), + &wasmparser::Operator::V128Load16Lane { memarg, lane } => { + Ok(Operator::V128Load16Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Load32Lane { memarg, lane } => { + Ok(Operator::V128Load32Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Load64Lane { memarg, lane } => { + Ok(Operator::V128Load64Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Store8Lane { memarg, lane } => { + Ok(Operator::V128Store8Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Store16Lane { memarg, lane } => { + Ok(Operator::V128Store16Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Store32Lane { memarg, lane } => { + Ok(Operator::V128Store32Lane { + memory: memarg.into(), + lane, + }) + } + &wasmparser::Operator::V128Store64Lane { memarg, lane } => { + Ok(Operator::V128Store64Lane { + memory: memarg.into(), + lane, + }) + } + + &wasmparser::Operator::V128Const { value } => Ok(Operator::V128Const { + value: value.i128() as u128, + }), + + &wasmparser::Operator::I8x16Shuffle { lanes } => Ok(Operator::I8x16Shuffle { lanes }), + + &wasmparser::Operator::I8x16ExtractLaneS { lane } => { + Ok(Operator::I8x16ExtractLaneS { lane }) + } + &wasmparser::Operator::I8x16ExtractLaneU { lane } => { + Ok(Operator::I8x16ExtractLaneU { lane }) + } + &wasmparser::Operator::I8x16ReplaceLane { lane } => { + Ok(Operator::I8x16ReplaceLane { lane }) + } + &wasmparser::Operator::I16x8ExtractLaneS { lane } => { + Ok(Operator::I16x8ExtractLaneS { lane }) + } + &wasmparser::Operator::I16x8ExtractLaneU { lane } => { + Ok(Operator::I16x8ExtractLaneU { lane }) + } + &wasmparser::Operator::I16x8ReplaceLane { lane } => { + Ok(Operator::I16x8ReplaceLane { lane }) + } + &wasmparser::Operator::I32x4ExtractLane { lane } => { + Ok(Operator::I32x4ExtractLane { lane }) + } + &wasmparser::Operator::I32x4ReplaceLane { lane } => { + Ok(Operator::I32x4ReplaceLane { lane }) + } + &wasmparser::Operator::I64x2ExtractLane { lane } => { + Ok(Operator::I64x2ExtractLane { lane }) + } + &wasmparser::Operator::I64x2ReplaceLane { lane } => { + Ok(Operator::I64x2ReplaceLane { lane }) + } + &wasmparser::Operator::F32x4ExtractLane { lane } => { + Ok(Operator::F32x4ExtractLane { lane }) + } + &wasmparser::Operator::F32x4ReplaceLane { lane } => { + Ok(Operator::F32x4ReplaceLane { lane }) + } + &wasmparser::Operator::F64x2ExtractLane { lane } => { + Ok(Operator::F64x2ExtractLane { lane }) + } + &wasmparser::Operator::F64x2ReplaceLane { lane } => { + Ok(Operator::F64x2ReplaceLane { lane }) + } + + &wasmparser::Operator::I8x16Swizzle => Ok(Operator::I8x16Swizzle), + &wasmparser::Operator::I8x16Splat => Ok(Operator::I8x16Splat), + &wasmparser::Operator::I16x8Splat => Ok(Operator::I16x8Splat), + &wasmparser::Operator::I32x4Splat => Ok(Operator::I32x4Splat), + &wasmparser::Operator::I64x2Splat => Ok(Operator::I64x2Splat), + &wasmparser::Operator::F32x4Splat => Ok(Operator::F32x4Splat), + &wasmparser::Operator::F64x2Splat => Ok(Operator::F64x2Splat), + + &wasmparser::Operator::I8x16Eq => Ok(Operator::I8x16Eq), + &wasmparser::Operator::I8x16Ne => Ok(Operator::I8x16Ne), + &wasmparser::Operator::I8x16LtS => Ok(Operator::I8x16LtS), + &wasmparser::Operator::I8x16LtU => Ok(Operator::I8x16LtU), + &wasmparser::Operator::I8x16GtS => Ok(Operator::I8x16GtS), + &wasmparser::Operator::I8x16GtU => Ok(Operator::I8x16GtU), + &wasmparser::Operator::I8x16LeS => Ok(Operator::I8x16LeS), + &wasmparser::Operator::I8x16LeU => Ok(Operator::I8x16LeU), + &wasmparser::Operator::I8x16GeS => Ok(Operator::I8x16GeS), + &wasmparser::Operator::I8x16GeU => Ok(Operator::I8x16GeU), + + &wasmparser::Operator::I16x8Eq => Ok(Operator::I16x8Eq), + &wasmparser::Operator::I16x8Ne => Ok(Operator::I16x8Ne), + &wasmparser::Operator::I16x8LtS => Ok(Operator::I16x8LtS), + &wasmparser::Operator::I16x8LtU => Ok(Operator::I16x8LtU), + &wasmparser::Operator::I16x8GtS => Ok(Operator::I16x8GtS), + &wasmparser::Operator::I16x8GtU => Ok(Operator::I16x8GtU), + &wasmparser::Operator::I16x8LeS => Ok(Operator::I16x8LeS), + &wasmparser::Operator::I16x8LeU => Ok(Operator::I16x8LeU), + &wasmparser::Operator::I16x8GeS => Ok(Operator::I16x8GeS), + &wasmparser::Operator::I16x8GeU => Ok(Operator::I16x8GeU), + + &wasmparser::Operator::I32x4Eq => Ok(Operator::I32x4Eq), + &wasmparser::Operator::I32x4Ne => Ok(Operator::I32x4Ne), + &wasmparser::Operator::I32x4LtS => Ok(Operator::I32x4LtS), + &wasmparser::Operator::I32x4LtU => Ok(Operator::I32x4LtU), + &wasmparser::Operator::I32x4GtS => Ok(Operator::I32x4GtS), + &wasmparser::Operator::I32x4GtU => Ok(Operator::I32x4GtU), + &wasmparser::Operator::I32x4LeS => Ok(Operator::I32x4LeS), + &wasmparser::Operator::I32x4LeU => Ok(Operator::I32x4LeU), + &wasmparser::Operator::I32x4GeS => Ok(Operator::I32x4GeS), + &wasmparser::Operator::I32x4GeU => Ok(Operator::I32x4GeU), + + &wasmparser::Operator::I64x2Eq => Ok(Operator::I64x2Eq), + &wasmparser::Operator::I64x2Ne => Ok(Operator::I64x2Ne), + &wasmparser::Operator::I64x2LtS => Ok(Operator::I64x2LtS), + &wasmparser::Operator::I64x2GtS => Ok(Operator::I64x2GtS), + &wasmparser::Operator::I64x2LeS => Ok(Operator::I64x2LeS), + &wasmparser::Operator::I64x2GeS => Ok(Operator::I64x2GeS), + + &wasmparser::Operator::F32x4Eq => Ok(Operator::F32x4Eq), + &wasmparser::Operator::F32x4Ne => Ok(Operator::F32x4Ne), + &wasmparser::Operator::F32x4Lt => Ok(Operator::F32x4Lt), + &wasmparser::Operator::F32x4Gt => Ok(Operator::F32x4Gt), + &wasmparser::Operator::F32x4Le => Ok(Operator::F32x4Le), + &wasmparser::Operator::F32x4Ge => Ok(Operator::F32x4Ge), + + &wasmparser::Operator::F64x2Eq => Ok(Operator::F64x2Eq), + &wasmparser::Operator::F64x2Ne => Ok(Operator::F64x2Ne), + &wasmparser::Operator::F64x2Lt => Ok(Operator::F64x2Lt), + &wasmparser::Operator::F64x2Gt => Ok(Operator::F64x2Gt), + &wasmparser::Operator::F64x2Le => Ok(Operator::F64x2Le), + &wasmparser::Operator::F64x2Ge => Ok(Operator::F64x2Ge), + + &wasmparser::Operator::V128Not => Ok(Operator::V128Not), + &wasmparser::Operator::V128And => Ok(Operator::V128And), + &wasmparser::Operator::V128AndNot => Ok(Operator::V128AndNot), + &wasmparser::Operator::V128Or => Ok(Operator::V128Or), + &wasmparser::Operator::V128Xor => Ok(Operator::V128Xor), + &wasmparser::Operator::V128Bitselect => Ok(Operator::V128Bitselect), + &wasmparser::Operator::V128AnyTrue => Ok(Operator::V128AnyTrue), + + &wasmparser::Operator::I8x16Abs => Ok(Operator::I8x16Abs), + &wasmparser::Operator::I8x16Neg => Ok(Operator::I8x16Neg), + &wasmparser::Operator::I8x16Popcnt => Ok(Operator::I8x16Popcnt), + &wasmparser::Operator::I8x16AllTrue => Ok(Operator::I8x16AllTrue), + &wasmparser::Operator::I8x16Bitmask => Ok(Operator::I8x16Bitmask), + &wasmparser::Operator::I8x16NarrowI16x8S => Ok(Operator::I8x16NarrowI16x8S), + &wasmparser::Operator::I8x16NarrowI16x8U => Ok(Operator::I8x16NarrowI16x8U), + &wasmparser::Operator::I8x16Shl => Ok(Operator::I8x16Shl), + &wasmparser::Operator::I8x16ShrS => Ok(Operator::I8x16ShrS), + &wasmparser::Operator::I8x16ShrU => Ok(Operator::I8x16ShrU), + &wasmparser::Operator::I8x16Add => Ok(Operator::I8x16Add), + &wasmparser::Operator::I8x16AddSatS => Ok(Operator::I8x16AddSatS), + &wasmparser::Operator::I8x16AddSatU => Ok(Operator::I8x16AddSatU), + &wasmparser::Operator::I8x16Sub => Ok(Operator::I8x16Sub), + &wasmparser::Operator::I8x16SubSatS => Ok(Operator::I8x16SubSatS), + &wasmparser::Operator::I8x16SubSatU => Ok(Operator::I8x16SubSatU), + &wasmparser::Operator::I8x16MinS => Ok(Operator::I8x16MinS), + &wasmparser::Operator::I8x16MinU => Ok(Operator::I8x16MinU), + &wasmparser::Operator::I8x16MaxS => Ok(Operator::I8x16MaxS), + &wasmparser::Operator::I8x16MaxU => Ok(Operator::I8x16MaxU), + &wasmparser::Operator::I8x16AvgrU => Ok(Operator::I8x16AvgrU), + + &wasmparser::Operator::I16x8ExtAddPairwiseI8x16S => { + Ok(Operator::I16x8ExtAddPairwiseI8x16S) + } + &wasmparser::Operator::I16x8ExtAddPairwiseI8x16U => { + Ok(Operator::I16x8ExtAddPairwiseI8x16U) + } + &wasmparser::Operator::I16x8Abs => Ok(Operator::I16x8Abs), + &wasmparser::Operator::I16x8Neg => Ok(Operator::I16x8Neg), + &wasmparser::Operator::I16x8Q15MulrSatS => Ok(Operator::I16x8Q15MulrSatS), + &wasmparser::Operator::I16x8AllTrue => Ok(Operator::I16x8AllTrue), + &wasmparser::Operator::I16x8Bitmask => Ok(Operator::I16x8Bitmask), + &wasmparser::Operator::I16x8NarrowI32x4S => Ok(Operator::I16x8NarrowI32x4S), + &wasmparser::Operator::I16x8NarrowI32x4U => Ok(Operator::I16x8NarrowI32x4U), + &wasmparser::Operator::I16x8ExtendLowI8x16S => Ok(Operator::I16x8ExtendLowI8x16S), + &wasmparser::Operator::I16x8ExtendHighI8x16S => Ok(Operator::I16x8ExtendHighI8x16S), + &wasmparser::Operator::I16x8ExtendLowI8x16U => Ok(Operator::I16x8ExtendLowI8x16U), + &wasmparser::Operator::I16x8ExtendHighI8x16U => Ok(Operator::I16x8ExtendHighI8x16U), + &wasmparser::Operator::I16x8Shl => Ok(Operator::I16x8Shl), + &wasmparser::Operator::I16x8ShrS => Ok(Operator::I16x8ShrS), + &wasmparser::Operator::I16x8ShrU => Ok(Operator::I16x8ShrU), + &wasmparser::Operator::I16x8Add => Ok(Operator::I16x8Add), + &wasmparser::Operator::I16x8AddSatS => Ok(Operator::I16x8AddSatS), + &wasmparser::Operator::I16x8AddSatU => Ok(Operator::I16x8AddSatU), + &wasmparser::Operator::I16x8Sub => Ok(Operator::I16x8Sub), + &wasmparser::Operator::I16x8SubSatS => Ok(Operator::I16x8SubSatS), + &wasmparser::Operator::I16x8SubSatU => Ok(Operator::I16x8SubSatU), + &wasmparser::Operator::I16x8Mul => Ok(Operator::I16x8Mul), + &wasmparser::Operator::I16x8MinS => Ok(Operator::I16x8MinS), + &wasmparser::Operator::I16x8MinU => Ok(Operator::I16x8MinU), + &wasmparser::Operator::I16x8MaxS => Ok(Operator::I16x8MaxS), + &wasmparser::Operator::I16x8MaxU => Ok(Operator::I16x8MaxU), + &wasmparser::Operator::I16x8AvgrU => Ok(Operator::I16x8AvgrU), + &wasmparser::Operator::I16x8ExtMulLowI8x16S => Ok(Operator::I16x8ExtMulLowI8x16S), + &wasmparser::Operator::I16x8ExtMulHighI8x16S => Ok(Operator::I16x8ExtMulHighI8x16S), + &wasmparser::Operator::I16x8ExtMulLowI8x16U => Ok(Operator::I16x8ExtMulLowI8x16U), + &wasmparser::Operator::I16x8ExtMulHighI8x16U => Ok(Operator::I16x8ExtMulHighI8x16U), + &wasmparser::Operator::I32x4ExtAddPairwiseI16x8S => { + Ok(Operator::I32x4ExtAddPairwiseI16x8S) + } + &wasmparser::Operator::I32x4ExtAddPairwiseI16x8U => { + Ok(Operator::I32x4ExtAddPairwiseI16x8U) + } + + &wasmparser::Operator::I32x4Abs => Ok(Operator::I32x4Abs), + &wasmparser::Operator::I32x4Neg => Ok(Operator::I32x4Neg), + &wasmparser::Operator::I32x4AllTrue => Ok(Operator::I32x4AllTrue), + &wasmparser::Operator::I32x4Bitmask => Ok(Operator::I32x4Bitmask), + &wasmparser::Operator::I32x4ExtendLowI16x8S => Ok(Operator::I32x4ExtendLowI16x8S), + &wasmparser::Operator::I32x4ExtendHighI16x8S => Ok(Operator::I32x4ExtendHighI16x8S), + &wasmparser::Operator::I32x4ExtendLowI16x8U => Ok(Operator::I32x4ExtendLowI16x8U), + &wasmparser::Operator::I32x4ExtendHighI16x8U => Ok(Operator::I32x4ExtendHighI16x8U), + &wasmparser::Operator::I32x4Shl => Ok(Operator::I32x4Shl), + &wasmparser::Operator::I32x4ShrS => Ok(Operator::I32x4ShrS), + &wasmparser::Operator::I32x4ShrU => Ok(Operator::I32x4ShrU), + &wasmparser::Operator::I32x4Add => Ok(Operator::I32x4Add), + &wasmparser::Operator::I32x4Sub => Ok(Operator::I32x4Sub), + &wasmparser::Operator::I32x4Mul => Ok(Operator::I32x4Mul), + &wasmparser::Operator::I32x4MinS => Ok(Operator::I32x4MinS), + &wasmparser::Operator::I32x4MinU => Ok(Operator::I32x4MinU), + &wasmparser::Operator::I32x4MaxS => Ok(Operator::I32x4MaxS), + &wasmparser::Operator::I32x4MaxU => Ok(Operator::I32x4MaxU), + &wasmparser::Operator::I32x4DotI16x8S => Ok(Operator::I32x4DotI16x8S), + &wasmparser::Operator::I32x4ExtMulLowI16x8S => Ok(Operator::I32x4ExtMulLowI16x8S), + &wasmparser::Operator::I32x4ExtMulHighI16x8S => Ok(Operator::I32x4ExtMulHighI16x8S), + &wasmparser::Operator::I32x4ExtMulLowI16x8U => Ok(Operator::I32x4ExtMulLowI16x8U), + &wasmparser::Operator::I32x4ExtMulHighI16x8U => Ok(Operator::I32x4ExtMulHighI16x8U), + &wasmparser::Operator::I64x2Abs => Ok(Operator::I64x2Abs), + &wasmparser::Operator::I64x2Neg => Ok(Operator::I64x2Neg), + &wasmparser::Operator::I64x2AllTrue => Ok(Operator::I64x2AllTrue), + &wasmparser::Operator::I64x2Bitmask => Ok(Operator::I64x2Bitmask), + &wasmparser::Operator::I64x2ExtendLowI32x4S => Ok(Operator::I64x2ExtendLowI32x4S), + &wasmparser::Operator::I64x2ExtendHighI32x4S => Ok(Operator::I64x2ExtendHighI32x4S), + &wasmparser::Operator::I64x2ExtendLowI32x4U => Ok(Operator::I64x2ExtendLowI32x4U), + &wasmparser::Operator::I64x2ExtendHighI32x4U => Ok(Operator::I64x2ExtendHighI32x4U), + &wasmparser::Operator::I64x2Shl => Ok(Operator::I64x2Shl), + &wasmparser::Operator::I64x2ShrS => Ok(Operator::I64x2ShrS), + &wasmparser::Operator::I64x2ShrU => Ok(Operator::I64x2ShrU), + &wasmparser::Operator::I64x2Add => Ok(Operator::I64x2Add), + &wasmparser::Operator::I64x2Sub => Ok(Operator::I64x2Sub), + &wasmparser::Operator::I64x2Mul => Ok(Operator::I64x2Mul), + &wasmparser::Operator::I64x2ExtMulLowI32x4S => Ok(Operator::I64x2ExtMulLowI32x4S), + &wasmparser::Operator::I64x2ExtMulHighI32x4S => Ok(Operator::I64x2ExtMulHighI32x4S), + &wasmparser::Operator::I64x2ExtMulLowI32x4U => Ok(Operator::I64x2ExtMulLowI32x4U), + &wasmparser::Operator::I64x2ExtMulHighI32x4U => Ok(Operator::I64x2ExtMulHighI32x4U), + &wasmparser::Operator::F32x4Ceil => Ok(Operator::F32x4Ceil), + &wasmparser::Operator::F32x4Floor => Ok(Operator::F32x4Floor), + &wasmparser::Operator::F32x4Trunc => Ok(Operator::F32x4Trunc), + &wasmparser::Operator::F32x4Nearest => Ok(Operator::F32x4Nearest), + &wasmparser::Operator::F32x4Abs => Ok(Operator::F32x4Abs), + &wasmparser::Operator::F32x4Neg => Ok(Operator::F32x4Neg), + &wasmparser::Operator::F32x4Sqrt => Ok(Operator::F32x4Sqrt), + &wasmparser::Operator::F32x4Add => Ok(Operator::F32x4Add), + &wasmparser::Operator::F32x4Sub => Ok(Operator::F32x4Sub), + &wasmparser::Operator::F32x4Mul => Ok(Operator::F32x4Mul), + &wasmparser::Operator::F32x4Div => Ok(Operator::F32x4Div), + &wasmparser::Operator::F32x4Min => Ok(Operator::F32x4Min), + &wasmparser::Operator::F32x4Max => Ok(Operator::F32x4Max), + &wasmparser::Operator::F32x4PMin => Ok(Operator::F32x4PMin), + &wasmparser::Operator::F32x4PMax => Ok(Operator::F32x4PMax), + &wasmparser::Operator::F64x2Ceil => Ok(Operator::F64x2Ceil), + &wasmparser::Operator::F64x2Floor => Ok(Operator::F64x2Floor), + &wasmparser::Operator::F64x2Trunc => Ok(Operator::F64x2Trunc), + &wasmparser::Operator::F64x2Nearest => Ok(Operator::F64x2Nearest), + &wasmparser::Operator::F64x2Abs => Ok(Operator::F64x2Abs), + &wasmparser::Operator::F64x2Neg => Ok(Operator::F64x2Neg), + &wasmparser::Operator::F64x2Sqrt => Ok(Operator::F64x2Sqrt), + &wasmparser::Operator::F64x2Add => Ok(Operator::F64x2Add), + &wasmparser::Operator::F64x2Sub => Ok(Operator::F64x2Sub), + &wasmparser::Operator::F64x2Mul => Ok(Operator::F64x2Mul), + &wasmparser::Operator::F64x2Div => Ok(Operator::F64x2Div), + &wasmparser::Operator::F64x2Min => Ok(Operator::F64x2Min), + &wasmparser::Operator::F64x2Max => Ok(Operator::F64x2Max), + &wasmparser::Operator::F64x2PMin => Ok(Operator::F64x2PMin), + &wasmparser::Operator::F64x2PMax => Ok(Operator::F64x2PMax), + &wasmparser::Operator::I32x4TruncSatF32x4S => Ok(Operator::I32x4TruncSatF32x4S), + &wasmparser::Operator::I32x4TruncSatF32x4U => Ok(Operator::I32x4TruncSatF32x4U), + &wasmparser::Operator::F32x4ConvertI32x4S => Ok(Operator::F32x4ConvertI32x4S), + &wasmparser::Operator::F32x4ConvertI32x4U => Ok(Operator::F32x4ConvertI32x4U), + &wasmparser::Operator::I32x4TruncSatF64x2SZero => Ok(Operator::I32x4TruncSatF64x2SZero), + &wasmparser::Operator::I32x4TruncSatF64x2UZero => Ok(Operator::I32x4TruncSatF64x2UZero), + &wasmparser::Operator::F64x2ConvertLowI32x4S => Ok(Operator::F64x2ConvertLowI32x4S), + &wasmparser::Operator::F64x2ConvertLowI32x4U => Ok(Operator::F64x2ConvertLowI32x4U), + &wasmparser::Operator::F32x4DemoteF64x2Zero => Ok(Operator::F32x4DemoteF64x2Zero), + &wasmparser::Operator::F64x2PromoteLowF32x4 => Ok(Operator::F64x2PromoteLowF32x4), + _ => Err(()), } } diff --git a/wasm_tests/test-simd.wat b/wasm_tests/test-simd.wat new file mode 100644 index 0000000..9bee004 --- /dev/null +++ b/wasm_tests/test-simd.wat @@ -0,0 +1,22 @@ +(module + (memory 1 1) + (func (export "pack") (param i64 i64) (result v128) + v128.const i64x2 0 0 + local.get 0 + i64x2.replace_lane 0 + local.get 1 + i64x2.replace_lane 1 + return) + (func (export "unpack") (param v128) (result i64 i64) + local.get 0 + i64x2.extract_lane 0 + local.get 0 + i64x2.extract_lane 1 + return) + (func (export "load") (param i32) (result v128) + local.get 0 + v128.load) + (func (export "store") (param i32 v128) + local.get 0 + local.get 1 + v128.store)) From aaaf725000ed33a8d8d45302ba284fae1c106ef9 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 16:21:19 -0700 Subject: [PATCH 02/11] Fix test expectation: Operator grew in size due to vector constants. --- src/ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ops.rs b/src/ops.rs index 75d82e6..3072a65 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -634,7 +634,7 @@ pub enum Operator { #[test] fn op_size() { - assert_eq!(std::mem::size_of::(), 16); + assert_eq!(std::mem::size_of::(), 32); } impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator { From 6603189fc293c2f97198c40f161ce93e926cbf7c Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 16:21:27 -0700 Subject: [PATCH 03/11] Version bump to 0.0.23. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0fe3fe1..17a99ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "waffle" -version = "0.0.22" +version = "0.0.23" description = "Wasm Analysis Framework For Lightweight Experiments" authors = ["Chris Fallin "] license = "Apache-2.0 WITH LLVM-exception" From 8e42abe91bd3fd6b1c641e1dfa8c467157c35e4a Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 22:35:16 -0700 Subject: [PATCH 04/11] Actually support V128 types in frontend. --- src/frontend.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/frontend.rs b/src/frontend.rs index c86aae0..1fef966 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -679,6 +679,11 @@ impl LocalTracker { ListRef::default(), types, )), + Type::V128 => body.add_value(ValueDef::Operator( + Operator::V128Const { value: 0 }, + ListRef::default(), + types, + )), _ => todo!("unsupported type: {:?}", ty), }; body.append_to_block(at_block, val); From 0691e48ed8711799a5314c8d65805fa6e76bc5ea Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 22:39:17 -0700 Subject: [PATCH 05/11] Do not attempt cprop on vector ops that are not implemented. --- src/interp.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interp.rs b/src/interp.rs index b6657e1..d92f9f1 100644 --- a/src/interp.rs +++ b/src/interp.rs @@ -1172,11 +1172,7 @@ pub fn const_eval( Some(ConstVal::None) }), (_, args) if args.iter().any(|&arg| arg == ConstVal::None) => None, - (op, args) => unimplemented!( - "Undefined operator or arg combination: {:?}, {:?}", - op, - args - ), + _ => None, } } From e567f0d3c5db12ede5f39e7631e3351be5977311 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 22:39:58 -0700 Subject: [PATCH 06/11] Warning fix: remove redundant import of Default. --- src/pool.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pool.rs b/src/pool.rs index 1a17ab8..794fac1 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -1,7 +1,6 @@ //! Pooled list data structure. use std::convert::TryFrom; -use std::default::Default; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; From 11992bb1246fa43711de0728af8da78c37540cd8 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Wed, 27 Mar 2024 22:40:15 -0700 Subject: [PATCH 07/11] Bump to v0.0.24. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 17a99ff..459a7c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "waffle" -version = "0.0.23" +version = "0.0.24" description = "Wasm Analysis Framework For Lightweight Experiments" authors = ["Chris Fallin "] license = "Apache-2.0 WITH LLVM-exception" From fcbd32e6b45bffcd6edff1b448c160013c655f3d Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 28 Mar 2024 13:38:34 -0700 Subject: [PATCH 08/11] Upgrade to latest wasmparser and wasm_encoder. --- Cargo.toml | 14 +++---- src/backend/mod.rs | 5 +-- src/frontend.rs | 94 +++++++++++++++++++++++----------------------- src/ir.rs | 54 ++++++++++++++++++++------ 4 files changed, 99 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 459a7c6..bad5591 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,22 +7,22 @@ license = "Apache-2.0 WITH LLVM-exception" edition = "2018" [dependencies] -wasmparser = "0.95" -wasm-encoder = "0.20" +wasmparser = "0.202" +wasm-encoder = "0.202" anyhow = "1.0" structopt = "0.3" log = "0.4" -env_logger = "0.9" +env_logger = "0.11" fxhash = "0.2" -smallvec = "1.7" -rayon = "1.5" +smallvec = "1.13" +rayon = "1.10" lazy_static = "1.4" libc = "0.2" -addr2line = "0.19" +addr2line = "0.21" # For fuzzing only. Versions must match those in fuzz/Cargo.toml. libfuzzer-sys = { version = "0.4", optional = true } -wasm-smith = { version = "0.8", optional = true } +wasm-smith = { version = "0.202", optional = true } [features] default = [] diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 088a424..8535d76 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -950,7 +950,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { num_table_imports += 1; let table = &module.tables[table]; wasm_encoder::EntityType::Table(wasm_encoder::TableType { - element_type: wasm_encoder::ValType::from(table.ty), + element_type: wasm_encoder::RefType::from(table.ty), minimum: table .func_elements .as_ref() @@ -1000,7 +1000,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { let mut tables = wasm_encoder::TableSection::new(); for table_data in module.tables.values().skip(num_table_imports) { tables.table(wasm_encoder::TableType { - element_type: wasm_encoder::ValType::from(table_data.ty), + element_type: wasm_encoder::RefType::from(table_data.ty), minimum: table_data .func_elements .as_ref() @@ -1084,7 +1084,6 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { elem.active( Some(table.index() as u32), &wasm_encoder::ConstExpr::i32_const(i as i32), - wasm_encoder::ValType::FuncRef, wasm_encoder::Elements::Functions(&[elt.index() as u32]), ); } diff --git a/src/frontend.rs b/src/frontend.rs index 1fef966..5bae767 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -96,10 +96,17 @@ fn handle_payload<'a>( trace!("Wasm parser item: {:?}", payload); match payload { Payload::TypeSection(reader) => { - for ty in reader { - let ty = ty?; - let wasmparser::Type::Func(fty) = ty; - module.signatures.push(fty.into()); + for rec_group in reader { + for ty in rec_group?.into_types() { + match &ty.composite_type { + wasmparser::CompositeType::Func(fty) => { + module.signatures.push(fty.into()); + } + _ => bail!(FrontendError::UnsupportedFeature( + "non-function type in type section".into() + )), + } + } } } Payload::ImportSection(reader) => { @@ -167,7 +174,7 @@ fn handle_payload<'a>( Payload::TableSection(reader) => { for table in reader { let table = table?; - module.frontend_add_table(table.element_type.into(), table.maximum); + module.frontend_add_table(table.ty.element_type.into(), table.ty.maximum); } } Payload::FunctionSection(reader) => { @@ -237,7 +244,7 @@ fn handle_payload<'a>( } } Payload::CustomSection(reader) if reader.name() == "name" => { - let name_reader = NameSectionReader::new(reader.data(), reader.data_offset())?; + let name_reader = NameSectionReader::new(reader.data(), reader.data_offset()); for subsection in name_reader { let subsection = subsection?; match subsection { @@ -302,12 +309,6 @@ fn handle_payload<'a>( Payload::ElementSection(reader) => { for element in reader { let element = element?; - if element.ty != wasmparser::ValType::FuncRef { - bail!(FrontendError::UnsupportedFeature(format!( - "Unsupported table type: {:?}", - element.ty - ))); - } match &element.kind { wasmparser::ElementKind::Passive => {} wasmparser::ElementKind::Declared => {} @@ -315,44 +316,45 @@ fn handle_payload<'a>( table_index, offset_expr, } => { - let table = Table::from(*table_index); + let table = Table::from(table_index.unwrap_or(0)); let offset = parse_init_expr(&offset_expr)?.unwrap_or(0) as usize; - let items = element - .items - .get_items_reader()? - .into_iter() - .collect::, _>>()?; - let mut funcs = vec![]; - for item in items { - let func = match item { - wasmparser::ElementItem::Func(func_idx) => Func::from(func_idx), - _ => bail!(FrontendError::UnsupportedFeature(format!( - "Unsupported element item: {:?}", - item - ))), - }; - funcs.push(func); - } + match element.items { + wasmparser::ElementItems::Functions(items) => { + let mut funcs = vec![]; + for item in items { + let item = item?; + let func = Func::from(item); + funcs.push(func); + } - let table_items = module.tables[table].func_elements.as_mut().unwrap(); - let new_size = offset.checked_add(funcs.len()).ok_or_else(|| { - FrontendError::TooLarge(format!( - "Overflowing element offset + length: {} + {}", - offset, - funcs.len() - )) - })?; - if new_size > table_items.len() { - static MAX_TABLE: usize = 100_000; - if new_size > MAX_TABLE { - bail!(FrontendError::TooLarge(format!( - "Too many table elements: {:?}", - new_size - ))); + let table_items = + module.tables[table].func_elements.as_mut().unwrap(); + let new_size = + offset.checked_add(funcs.len()).ok_or_else(|| { + FrontendError::TooLarge(format!( + "Overflowing element offset + length: {} + {}", + offset, + funcs.len() + )) + })?; + if new_size > table_items.len() { + static MAX_TABLE: usize = 100_000; + if new_size > MAX_TABLE { + bail!(FrontendError::TooLarge(format!( + "Too many table elements: {:?}", + new_size + ))); + } + table_items.resize(new_size, Func::invalid()); + } + table_items[offset..new_size].copy_from_slice(&funcs[..]); + } + wasmparser::ElementItems::Expressions(..) => { + bail!(FrontendError::UnsupportedFeature( + "Expression element items".into() + )) } - table_items.resize(new_size, Func::invalid()); } - table_items[offset..new_size].copy_from_slice(&funcs[..]); } } } diff --git a/src/ir.rs b/src/ir.rs index c7d10ad..71b14d6 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -10,6 +10,7 @@ pub enum Type { F64, V128, FuncRef, + TypedFuncRef(bool, u32), } impl From for Type { fn from(ty: wasmparser::ValType) -> Self { @@ -19,23 +20,39 @@ impl From for Type { wasmparser::ValType::F32 => Type::F32, wasmparser::ValType::F64 => Type::F64, wasmparser::ValType::V128 => Type::V128, - wasmparser::ValType::FuncRef => Type::FuncRef, - _ => panic!("Unsupported type: {:?}", ty), + wasmparser::ValType::Ref(r) => r.into(), + } + } +} +impl From for Type { + fn from(ty: wasmparser::RefType) -> Self { + assert!(ty.is_func_ref(), "only funcrefs are supported right now"); + match ty.type_index() { + Some(idx) => { + let nullable = ty.is_nullable(); + Type::TypedFuncRef(nullable, idx.as_module_index().unwrap()) + } + None => Type::FuncRef, } } } impl std::fmt::Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let s = match self { - Type::I32 => "i32", - Type::I64 => "i64", - Type::F32 => "f32", - Type::F64 => "f64", - Type::V128 => "v128", - Type::FuncRef => "funcref", - }; - write!(f, "{}", s) + match self { + Type::I32 => write!(f, "i32"), + Type::I64 => write!(f, "i64"), + Type::F32 => write!(f, "f32"), + Type::F64 => write!(f, "f64"), + Type::V128 => write!(f, "v128"), + Type::FuncRef => write!(f, "funcref"), + Type::TypedFuncRef(nullable, idx) => write!( + f, + "funcref({}, {})", + if *nullable { "null" } else { "not_null" }, + idx + ), + } } } @@ -47,7 +64,20 @@ impl From for wasm_encoder::ValType { Type::F32 => wasm_encoder::ValType::F32, Type::F64 => wasm_encoder::ValType::F64, Type::V128 => wasm_encoder::ValType::V128, - Type::FuncRef => wasm_encoder::ValType::FuncRef, + Type::FuncRef | Type::TypedFuncRef(..) => wasm_encoder::ValType::Ref(ty.into()), + } + } +} + +impl From for wasm_encoder::RefType { + fn from(ty: Type) -> wasm_encoder::RefType { + match ty { + Type::FuncRef => wasm_encoder::RefType::FUNCREF, + Type::TypedFuncRef(nullable, idx) => wasm_encoder::RefType { + nullable, + heap_type: wasm_encoder::HeapType::Concrete(idx), + }, + _ => panic!("Cannot convert {:?} into reftype", ty), } } } From f0b378a895e73b886e1ba76c6418f9d00e95b978 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 28 Mar 2024 16:36:07 -0700 Subject: [PATCH 09/11] Handle typed funcrefs. --- src/backend/mod.rs | 34 +++++++++++++++---- src/frontend.rs | 82 ++++++++++++++++++++++++++++++---------------- src/ir.rs | 1 - src/ir/module.rs | 10 +++--- src/op_traits.rs | 22 +++++++++++++ src/ops.rs | 14 ++++++++ 6 files changed, 122 insertions(+), 41 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 8535d76..296046b 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -909,6 +909,13 @@ impl<'a> WasmFuncBackend<'a> { } Operator::F32x4DemoteF64x2Zero => Some(wasm_encoder::Instruction::F32x4DemoteF64x2Zero), Operator::F64x2PromoteLowF32x4 => Some(wasm_encoder::Instruction::F64x2PromoteLowF32x4), + + Operator::CallRef { sig_index } => { + Some(wasm_encoder::Instruction::CallRef(sig_index.index() as u32)) + } + Operator::RefFunc { func_index } => { + Some(wasm_encoder::Instruction::RefFunc(func_index.index() as u32)) + } }; if let Some(inst) = inst { @@ -955,7 +962,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { .func_elements .as_ref() .map(|elts| elts.len() as u32) - .unwrap_or(0), + .unwrap_or(table.initial), maximum: table.max, }) } @@ -1081,11 +1088,26 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { if let Some(elts) = &table_data.func_elements { for (i, &elt) in elts.iter().enumerate() { if elt.is_valid() { - elem.active( - Some(table.index() as u32), - &wasm_encoder::ConstExpr::i32_const(i as i32), - wasm_encoder::Elements::Functions(&[elt.index() as u32]), - ); + match table_data.ty { + Type::FuncRef => { + elem.active( + Some(table.index() as u32), + &wasm_encoder::ConstExpr::i32_const(i as i32), + wasm_encoder::Elements::Functions(&[elt.index() as u32]), + ); + } + Type::TypedFuncRef(..) => { + elem.active( + Some(table.index() as u32), + &wasm_encoder::ConstExpr::i32_const(i as i32), + wasm_encoder::Elements::Expressions( + table_data.ty.into(), + &[wasm_encoder::ConstExpr::ref_func(elt.index() as u32)], + ), + ); + } + _ => unreachable!(), + } } } } diff --git a/src/frontend.rs b/src/frontend.rs index 5bae767..e28af19 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -133,7 +133,11 @@ fn handle_payload<'a>( ImportKind::Global(global) } TypeRef::Table(ty) => { - let table = module.frontend_add_table(ty.element_type.into(), None); + let table = module.frontend_add_table( + ty.element_type.into(), + ty.initial, + ty.maximum, + ); ImportKind::Table(table) } TypeRef::Memory(mem) => { @@ -174,7 +178,11 @@ fn handle_payload<'a>( Payload::TableSection(reader) => { for table in reader { let table = table?; - module.frontend_add_table(table.ty.element_type.into(), table.ty.maximum); + module.frontend_add_table( + table.ty.element_type.into(), + table.ty.initial, + table.ty.maximum, + ); } } Payload::FunctionSection(reader) => { @@ -318,7 +326,7 @@ fn handle_payload<'a>( } => { let table = Table::from(table_index.unwrap_or(0)); let offset = parse_init_expr(&offset_expr)?.unwrap_or(0) as usize; - match element.items { + let funcs = match element.items { wasmparser::ElementItems::Functions(items) => { let mut funcs = vec![]; for item in items { @@ -326,35 +334,51 @@ fn handle_payload<'a>( let func = Func::from(item); funcs.push(func); } - - let table_items = - module.tables[table].func_elements.as_mut().unwrap(); - let new_size = - offset.checked_add(funcs.len()).ok_or_else(|| { - FrontendError::TooLarge(format!( - "Overflowing element offset + length: {} + {}", - offset, - funcs.len() - )) - })?; - if new_size > table_items.len() { - static MAX_TABLE: usize = 100_000; - if new_size > MAX_TABLE { - bail!(FrontendError::TooLarge(format!( - "Too many table elements: {:?}", - new_size - ))); + funcs + } + wasmparser::ElementItems::Expressions(_, const_exprs) => { + let mut funcs = vec![]; + for const_expr in const_exprs { + let const_expr = const_expr?; + let mut func = None; + for op in const_expr.get_operators_reader() { + let op = op?; + match op { + wasmparser::Operator::End => {} + wasmparser::Operator::RefFunc { function_index } => { + func = Some(Func::from(function_index)); + } + wasmparser::Operator::RefNull { .. } => { + func = Some(Func::invalid()); + } + _ => panic!("Unsupported table-init op: {:?}", op), + } } - table_items.resize(new_size, Func::invalid()); + funcs.push(func.unwrap_or(Func::invalid())); } - table_items[offset..new_size].copy_from_slice(&funcs[..]); + funcs } - wasmparser::ElementItems::Expressions(..) => { - bail!(FrontendError::UnsupportedFeature( - "Expression element items".into() - )) + }; + + let table_items = module.tables[table].func_elements.as_mut().unwrap(); + let new_size = offset.checked_add(funcs.len()).ok_or_else(|| { + FrontendError::TooLarge(format!( + "Overflowing element offset + length: {} + {}", + offset, + funcs.len() + )) + })?; + if new_size > table_items.len() { + static MAX_TABLE: usize = 100_000; + if new_size > MAX_TABLE { + bail!(FrontendError::TooLarge(format!( + "Too many table elements: {:?}", + new_size + ))); } + table_items.resize(new_size, Func::invalid()); } + table_items[offset..new_size].copy_from_slice(&funcs[..]); } } } @@ -1394,7 +1418,9 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { | wasmparser::Operator::F64x2ConvertLowI32x4S | wasmparser::Operator::F64x2ConvertLowI32x4U | wasmparser::Operator::F32x4DemoteF64x2Zero - | wasmparser::Operator::F64x2PromoteLowF32x4 => { + | wasmparser::Operator::F64x2PromoteLowF32x4 + | wasmparser::Operator::CallRef { .. } + | wasmparser::Operator::RefFunc { .. } => { self.emit(Operator::try_from(&op).unwrap(), loc)? } diff --git a/src/ir.rs b/src/ir.rs index 71b14d6..2a40cd0 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -26,7 +26,6 @@ impl From for Type { } impl From for Type { fn from(ty: wasmparser::RefType) -> Self { - assert!(ty.is_func_ref(), "only funcrefs are supported right now"); match ty.type_index() { Some(idx) => { let nullable = ty.is_nullable(); diff --git a/src/ir/module.rs b/src/ir/module.rs index 05795db..f4a438e 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -43,6 +43,7 @@ pub struct MemorySegment { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TableData { pub ty: Type, + pub initial: u32, pub max: Option, pub func_elements: Option>, } @@ -170,15 +171,12 @@ impl<'a> Module<'a> { } impl<'a> Module<'a> { - pub(crate) fn frontend_add_table(&mut self, ty: Type, max: Option) -> Table { - let func_elements = if ty == Type::FuncRef { - Some(vec![]) - } else { - None - }; + pub(crate) fn frontend_add_table(&mut self, ty: Type, initial: u32, max: Option) -> Table { + let func_elements = Some(vec![]); self.tables.push(TableData { ty, func_elements, + initial, max, }) } diff --git a/src/op_traits.rs b/src/op_traits.rs index 36fb535..8d2fadc 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -1,5 +1,6 @@ //! Metadata on operators. +use crate::entity::EntityRef; use crate::ir::{Module, Type, Value}; use crate::Operator; use anyhow::Result; @@ -475,6 +476,13 @@ pub fn op_inputs( Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::CallRef { sig_index } => { + let mut params = module.signatures[*sig_index].params.to_vec(); + params.push(Type::TypedFuncRef(true, sig_index.index() as u32)); + Ok(params.into()) + } + Operator::RefFunc { .. } => Ok(Cow::Borrowed(&[])), } } @@ -933,6 +941,14 @@ pub fn op_outputs( Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::CallRef { sig_index } => { + Ok(Vec::from(module.signatures[*sig_index].returns.clone()).into()) + } + Operator::RefFunc { func_index } => { + let ty = module.funcs[*func_index].sig(); + Ok(vec![Type::TypedFuncRef(true, ty.index() as u32)].into()) + } } } @@ -1397,6 +1413,9 @@ impl Operator { Operator::F64x2ConvertLowI32x4U => &[], Operator::F32x4DemoteF64x2Zero => &[], Operator::F64x2PromoteLowF32x4 => &[], + + Operator::CallRef { .. } => &[All], + Operator::RefFunc { .. } => &[], } } @@ -1885,6 +1904,9 @@ impl std::fmt::Display for Operator { Operator::F64x2ConvertLowI32x4U => write!(f, "f64x2convertlowi32x4u")?, Operator::F32x4DemoteF64x2Zero => write!(f, "f32x4demotef64x2zero")?, Operator::F64x2PromoteLowF32x4 => write!(f, "f64x2promotelowf32x4")?, + + Operator::CallRef { sig_index } => write!(f, "call_ref<{}>", sig_index)?, + Operator::RefFunc { func_index } => write!(f, "ref_func<{}>", func_index)?, } Ok(()) diff --git a/src/ops.rs b/src/ops.rs index 3072a65..b5634c1 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -630,6 +630,13 @@ pub enum Operator { F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, + + CallRef { + sig_index: Signature, + }, + RefFunc { + func_index: Func, + }, } #[test] @@ -1259,6 +1266,13 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator { &wasmparser::Operator::F32x4DemoteF64x2Zero => Ok(Operator::F32x4DemoteF64x2Zero), &wasmparser::Operator::F64x2PromoteLowF32x4 => Ok(Operator::F64x2PromoteLowF32x4), + &wasmparser::Operator::CallRef { type_index } => Ok(Operator::CallRef { + sig_index: Signature::from(type_index), + }), + &wasmparser::Operator::RefFunc { function_index } => Ok(Operator::RefFunc { + func_index: Func::from(function_index), + }), + _ => Err(()), } } From 86be4c06e1eee3a0e212d6683e27a9e48800ec68 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 28 Mar 2024 16:36:07 -0700 Subject: [PATCH 10/11] Handle typed funcrefs. --- src/backend/mod.rs | 34 ++++++++++++--- src/frontend.rs | 82 ++++++++++++++++++++++++------------ src/ir.rs | 1 - src/ir/module.rs | 10 ++--- src/op_traits.rs | 22 ++++++++++ src/ops.rs | 14 ++++++ wasm_tests/typed-funcref.wat | 21 +++++++++ 7 files changed, 143 insertions(+), 41 deletions(-) create mode 100644 wasm_tests/typed-funcref.wat diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 8535d76..296046b 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -909,6 +909,13 @@ impl<'a> WasmFuncBackend<'a> { } Operator::F32x4DemoteF64x2Zero => Some(wasm_encoder::Instruction::F32x4DemoteF64x2Zero), Operator::F64x2PromoteLowF32x4 => Some(wasm_encoder::Instruction::F64x2PromoteLowF32x4), + + Operator::CallRef { sig_index } => { + Some(wasm_encoder::Instruction::CallRef(sig_index.index() as u32)) + } + Operator::RefFunc { func_index } => { + Some(wasm_encoder::Instruction::RefFunc(func_index.index() as u32)) + } }; if let Some(inst) = inst { @@ -955,7 +962,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { .func_elements .as_ref() .map(|elts| elts.len() as u32) - .unwrap_or(0), + .unwrap_or(table.initial), maximum: table.max, }) } @@ -1081,11 +1088,26 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { if let Some(elts) = &table_data.func_elements { for (i, &elt) in elts.iter().enumerate() { if elt.is_valid() { - elem.active( - Some(table.index() as u32), - &wasm_encoder::ConstExpr::i32_const(i as i32), - wasm_encoder::Elements::Functions(&[elt.index() as u32]), - ); + match table_data.ty { + Type::FuncRef => { + elem.active( + Some(table.index() as u32), + &wasm_encoder::ConstExpr::i32_const(i as i32), + wasm_encoder::Elements::Functions(&[elt.index() as u32]), + ); + } + Type::TypedFuncRef(..) => { + elem.active( + Some(table.index() as u32), + &wasm_encoder::ConstExpr::i32_const(i as i32), + wasm_encoder::Elements::Expressions( + table_data.ty.into(), + &[wasm_encoder::ConstExpr::ref_func(elt.index() as u32)], + ), + ); + } + _ => unreachable!(), + } } } } diff --git a/src/frontend.rs b/src/frontend.rs index 5bae767..e28af19 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -133,7 +133,11 @@ fn handle_payload<'a>( ImportKind::Global(global) } TypeRef::Table(ty) => { - let table = module.frontend_add_table(ty.element_type.into(), None); + let table = module.frontend_add_table( + ty.element_type.into(), + ty.initial, + ty.maximum, + ); ImportKind::Table(table) } TypeRef::Memory(mem) => { @@ -174,7 +178,11 @@ fn handle_payload<'a>( Payload::TableSection(reader) => { for table in reader { let table = table?; - module.frontend_add_table(table.ty.element_type.into(), table.ty.maximum); + module.frontend_add_table( + table.ty.element_type.into(), + table.ty.initial, + table.ty.maximum, + ); } } Payload::FunctionSection(reader) => { @@ -318,7 +326,7 @@ fn handle_payload<'a>( } => { let table = Table::from(table_index.unwrap_or(0)); let offset = parse_init_expr(&offset_expr)?.unwrap_or(0) as usize; - match element.items { + let funcs = match element.items { wasmparser::ElementItems::Functions(items) => { let mut funcs = vec![]; for item in items { @@ -326,35 +334,51 @@ fn handle_payload<'a>( let func = Func::from(item); funcs.push(func); } - - let table_items = - module.tables[table].func_elements.as_mut().unwrap(); - let new_size = - offset.checked_add(funcs.len()).ok_or_else(|| { - FrontendError::TooLarge(format!( - "Overflowing element offset + length: {} + {}", - offset, - funcs.len() - )) - })?; - if new_size > table_items.len() { - static MAX_TABLE: usize = 100_000; - if new_size > MAX_TABLE { - bail!(FrontendError::TooLarge(format!( - "Too many table elements: {:?}", - new_size - ))); + funcs + } + wasmparser::ElementItems::Expressions(_, const_exprs) => { + let mut funcs = vec![]; + for const_expr in const_exprs { + let const_expr = const_expr?; + let mut func = None; + for op in const_expr.get_operators_reader() { + let op = op?; + match op { + wasmparser::Operator::End => {} + wasmparser::Operator::RefFunc { function_index } => { + func = Some(Func::from(function_index)); + } + wasmparser::Operator::RefNull { .. } => { + func = Some(Func::invalid()); + } + _ => panic!("Unsupported table-init op: {:?}", op), + } } - table_items.resize(new_size, Func::invalid()); + funcs.push(func.unwrap_or(Func::invalid())); } - table_items[offset..new_size].copy_from_slice(&funcs[..]); + funcs } - wasmparser::ElementItems::Expressions(..) => { - bail!(FrontendError::UnsupportedFeature( - "Expression element items".into() - )) + }; + + let table_items = module.tables[table].func_elements.as_mut().unwrap(); + let new_size = offset.checked_add(funcs.len()).ok_or_else(|| { + FrontendError::TooLarge(format!( + "Overflowing element offset + length: {} + {}", + offset, + funcs.len() + )) + })?; + if new_size > table_items.len() { + static MAX_TABLE: usize = 100_000; + if new_size > MAX_TABLE { + bail!(FrontendError::TooLarge(format!( + "Too many table elements: {:?}", + new_size + ))); } + table_items.resize(new_size, Func::invalid()); } + table_items[offset..new_size].copy_from_slice(&funcs[..]); } } } @@ -1394,7 +1418,9 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { | wasmparser::Operator::F64x2ConvertLowI32x4S | wasmparser::Operator::F64x2ConvertLowI32x4U | wasmparser::Operator::F32x4DemoteF64x2Zero - | wasmparser::Operator::F64x2PromoteLowF32x4 => { + | wasmparser::Operator::F64x2PromoteLowF32x4 + | wasmparser::Operator::CallRef { .. } + | wasmparser::Operator::RefFunc { .. } => { self.emit(Operator::try_from(&op).unwrap(), loc)? } diff --git a/src/ir.rs b/src/ir.rs index 71b14d6..2a40cd0 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -26,7 +26,6 @@ impl From for Type { } impl From for Type { fn from(ty: wasmparser::RefType) -> Self { - assert!(ty.is_func_ref(), "only funcrefs are supported right now"); match ty.type_index() { Some(idx) => { let nullable = ty.is_nullable(); diff --git a/src/ir/module.rs b/src/ir/module.rs index 05795db..f4a438e 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -43,6 +43,7 @@ pub struct MemorySegment { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TableData { pub ty: Type, + pub initial: u32, pub max: Option, pub func_elements: Option>, } @@ -170,15 +171,12 @@ impl<'a> Module<'a> { } impl<'a> Module<'a> { - pub(crate) fn frontend_add_table(&mut self, ty: Type, max: Option) -> Table { - let func_elements = if ty == Type::FuncRef { - Some(vec![]) - } else { - None - }; + pub(crate) fn frontend_add_table(&mut self, ty: Type, initial: u32, max: Option) -> Table { + let func_elements = Some(vec![]); self.tables.push(TableData { ty, func_elements, + initial, max, }) } diff --git a/src/op_traits.rs b/src/op_traits.rs index 36fb535..8d2fadc 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -1,5 +1,6 @@ //! Metadata on operators. +use crate::entity::EntityRef; use crate::ir::{Module, Type, Value}; use crate::Operator; use anyhow::Result; @@ -475,6 +476,13 @@ pub fn op_inputs( Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::CallRef { sig_index } => { + let mut params = module.signatures[*sig_index].params.to_vec(); + params.push(Type::TypedFuncRef(true, sig_index.index() as u32)); + Ok(params.into()) + } + Operator::RefFunc { .. } => Ok(Cow::Borrowed(&[])), } } @@ -933,6 +941,14 @@ pub fn op_outputs( Operator::F64x2ConvertLowI32x4U => Ok(Cow::Borrowed(&[Type::V128])), Operator::F32x4DemoteF64x2Zero => Ok(Cow::Borrowed(&[Type::V128])), Operator::F64x2PromoteLowF32x4 => Ok(Cow::Borrowed(&[Type::V128])), + + Operator::CallRef { sig_index } => { + Ok(Vec::from(module.signatures[*sig_index].returns.clone()).into()) + } + Operator::RefFunc { func_index } => { + let ty = module.funcs[*func_index].sig(); + Ok(vec![Type::TypedFuncRef(true, ty.index() as u32)].into()) + } } } @@ -1397,6 +1413,9 @@ impl Operator { Operator::F64x2ConvertLowI32x4U => &[], Operator::F32x4DemoteF64x2Zero => &[], Operator::F64x2PromoteLowF32x4 => &[], + + Operator::CallRef { .. } => &[All], + Operator::RefFunc { .. } => &[], } } @@ -1885,6 +1904,9 @@ impl std::fmt::Display for Operator { Operator::F64x2ConvertLowI32x4U => write!(f, "f64x2convertlowi32x4u")?, Operator::F32x4DemoteF64x2Zero => write!(f, "f32x4demotef64x2zero")?, Operator::F64x2PromoteLowF32x4 => write!(f, "f64x2promotelowf32x4")?, + + Operator::CallRef { sig_index } => write!(f, "call_ref<{}>", sig_index)?, + Operator::RefFunc { func_index } => write!(f, "ref_func<{}>", func_index)?, } Ok(()) diff --git a/src/ops.rs b/src/ops.rs index 3072a65..b5634c1 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -630,6 +630,13 @@ pub enum Operator { F64x2ConvertLowI32x4U, F32x4DemoteF64x2Zero, F64x2PromoteLowF32x4, + + CallRef { + sig_index: Signature, + }, + RefFunc { + func_index: Func, + }, } #[test] @@ -1259,6 +1266,13 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator { &wasmparser::Operator::F32x4DemoteF64x2Zero => Ok(Operator::F32x4DemoteF64x2Zero), &wasmparser::Operator::F64x2PromoteLowF32x4 => Ok(Operator::F64x2PromoteLowF32x4), + &wasmparser::Operator::CallRef { type_index } => Ok(Operator::CallRef { + sig_index: Signature::from(type_index), + }), + &wasmparser::Operator::RefFunc { function_index } => Ok(Operator::RefFunc { + func_index: Func::from(function_index), + }), + _ => Err(()), } } diff --git a/wasm_tests/typed-funcref.wat b/wasm_tests/typed-funcref.wat new file mode 100644 index 0000000..a532f58 --- /dev/null +++ b/wasm_tests/typed-funcref.wat @@ -0,0 +1,21 @@ +(module + (type $t (func (param i32 i32) (result i32))) + + (table $tab 10 10 (ref null $t)) + (table $tab2 10 10 (ref null $t)) + + (elem (table $tab2) (i32.const 0) (ref null $t) (ref.func $f)) + + (func $callit (param i32 i32 i32) (result i32) + (call_ref $t (local.get 1) + (local.get 2) + (table.get $tab (local.get 0)))) + + (func $setit (param i32 (ref null $t)) + (table.set $tab (local.get 0) (local.get 1))) + + (func $getf (result (ref null $t)) + (ref.func $f)) + + (func $f (param i32 i32) (result i32) + local.get 0)) From d258d6a689aaf92f6755232a2a81deac9356c72b Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 28 Mar 2024 16:36:33 -0700 Subject: [PATCH 11/11] Version 0.0.25. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bad5591..74bf443 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "waffle" -version = "0.0.24" +version = "0.0.25" description = "Wasm Analysis Framework For Lightweight Experiments" authors = ["Chris Fallin "] license = "Apache-2.0 WITH LLVM-exception"