diff --git a/crates/wasmparser/src/binary_reader.rs b/crates/wasmparser/src/binary_reader.rs index ccd72860fc..e7d4011df7 100644 --- a/crates/wasmparser/src/binary_reader.rs +++ b/crates/wasmparser/src/binary_reader.rs @@ -350,7 +350,7 @@ impl<'a> BinaryReader<'a> { pub(crate) fn read_memory_type(&mut self) -> Result { let pos = self.original_position(); - let flags = self.read_var_u32()?; + let flags = self.read_u8()?; if (flags & !0x7) != 0 { return Err(BinaryReaderError::new( "invalid table resizable limits flags", @@ -1481,34 +1481,34 @@ impl<'a> BinaryReader<'a> { 0x00 => Operator::V128Load { memarg: self.read_memarg()?, }, - 0x01 => Operator::I16x8Load8x8S { + 0x01 => Operator::V128Load8x8S { memarg: self.read_memarg_of_align(3)?, }, - 0x02 => Operator::I16x8Load8x8U { + 0x02 => Operator::V128Load8x8U { memarg: self.read_memarg_of_align(3)?, }, - 0x03 => Operator::I32x4Load16x4S { + 0x03 => Operator::V128Load16x4S { memarg: self.read_memarg_of_align(3)?, }, - 0x04 => Operator::I32x4Load16x4U { + 0x04 => Operator::V128Load16x4U { memarg: self.read_memarg_of_align(3)?, }, - 0x05 => Operator::I64x2Load32x2S { + 0x05 => Operator::V128Load32x2S { memarg: self.read_memarg_of_align(3)?, }, - 0x06 => Operator::I64x2Load32x2U { + 0x06 => Operator::V128Load32x2U { memarg: self.read_memarg_of_align(3)?, }, - 0x07 => Operator::V8x16LoadSplat { + 0x07 => Operator::V128Load8Splat { memarg: self.read_memarg_of_align(0)?, }, - 0x08 => Operator::V16x8LoadSplat { + 0x08 => Operator::V128Load16Splat { memarg: self.read_memarg_of_align(1)?, }, - 0x09 => Operator::V32x4LoadSplat { + 0x09 => Operator::V128Load32Splat { memarg: self.read_memarg_of_align(2)?, }, - 0x0a => Operator::V64x2LoadSplat { + 0x0a => Operator::V128Load64Splat { memarg: self.read_memarg_of_align(3)?, }, 0x0b => Operator::V128Store { @@ -1522,9 +1522,9 @@ impl<'a> BinaryReader<'a> { for lane in &mut lanes { *lane = self.read_lane_index(32)? } - Operator::V8x16Shuffle { lanes } + Operator::I8x16Shuffle { lanes } } - 0x0e => Operator::V8x16Swizzle, + 0x0e => Operator::I8x16Swizzle, 0x0f => Operator::I8x16Splat, 0x10 => Operator::I16x8Splat, 0x11 => Operator::I32x4Splat, @@ -1632,11 +1632,11 @@ impl<'a> BinaryReader<'a> { 0x6c => Operator::I8x16ShrS, 0x6d => Operator::I8x16ShrU, 0x6e => Operator::I8x16Add, - 0x6f => Operator::I8x16AddSaturateS, - 0x70 => Operator::I8x16AddSaturateU, + 0x6f => Operator::I8x16AddSatS, + 0x70 => Operator::I8x16AddSatU, 0x71 => Operator::I8x16Sub, - 0x72 => Operator::I8x16SubSaturateS, - 0x73 => Operator::I8x16SubSaturateU, + 0x72 => Operator::I8x16SubSatS, + 0x73 => Operator::I8x16SubSatU, 0x76 => Operator::I8x16MinS, 0x77 => Operator::I8x16MinU, 0x78 => Operator::I8x16MaxS, @@ -1657,11 +1657,11 @@ impl<'a> BinaryReader<'a> { 0x8c => Operator::I16x8ShrS, 0x8d => Operator::I16x8ShrU, 0x8e => Operator::I16x8Add, - 0x8f => Operator::I16x8AddSaturateS, - 0x90 => Operator::I16x8AddSaturateU, + 0x8f => Operator::I16x8AddSatS, + 0x90 => Operator::I16x8AddSatU, 0x91 => Operator::I16x8Sub, - 0x92 => Operator::I16x8SubSaturateS, - 0x93 => Operator::I16x8SubSaturateU, + 0x92 => Operator::I16x8SubSatS, + 0x93 => Operator::I16x8SubSatU, 0x95 => Operator::I16x8Mul, 0x96 => Operator::I16x8MinS, 0x97 => Operator::I16x8MinU, @@ -1694,6 +1694,14 @@ impl<'a> BinaryReader<'a> { 0xce => Operator::I64x2Add, 0xd1 => Operator::I64x2Sub, 0xd5 => Operator::I64x2Mul, + 0xd8 => Operator::F32x4Ceil, + 0xd9 => Operator::F32x4Floor, + 0xda => Operator::F32x4Trunc, + 0xdb => Operator::F32x4Nearest, + 0xdc => Operator::F64x2Ceil, + 0xdd => Operator::F64x2Floor, + 0xde => Operator::F64x2Trunc, + 0xdf => Operator::F64x2Nearest, 0xe0 => Operator::F32x4Abs, 0xe1 => Operator::F32x4Neg, 0xe3 => Operator::F32x4Sqrt, @@ -1703,6 +1711,8 @@ impl<'a> BinaryReader<'a> { 0xe7 => Operator::F32x4Div, 0xe8 => Operator::F32x4Min, 0xe9 => Operator::F32x4Max, + 0xea => Operator::F32x4PMin, + 0xeb => Operator::F32x4PMax, 0xec => Operator::F64x2Abs, 0xed => Operator::F64x2Neg, 0xef => Operator::F64x2Sqrt, @@ -1712,6 +1722,8 @@ impl<'a> BinaryReader<'a> { 0xf3 => Operator::F64x2Div, 0xf4 => Operator::F64x2Min, 0xf5 => Operator::F64x2Max, + 0xf6 => Operator::F64x2PMin, + 0xf7 => Operator::F64x2PMax, 0xf8 => Operator::I32x4TruncSatF32x4S, 0xf9 => Operator::I32x4TruncSatF32x4U, 0xfa => Operator::F32x4ConvertI32x4S, diff --git a/crates/wasmparser/src/operators_validator.rs b/crates/wasmparser/src/operators_validator.rs index c9887ab20a..8cad006095 100644 --- a/crates/wasmparser/src/operators_validator.rs +++ b/crates/wasmparser/src/operators_validator.rs @@ -1385,12 +1385,16 @@ impl OperatorValidator { | Operator::F32x4Div | Operator::F32x4Min | Operator::F32x4Max + | Operator::F32x4PMin + | Operator::F32x4PMax | Operator::F64x2Add | Operator::F64x2Sub | Operator::F64x2Mul | Operator::F64x2Div | Operator::F64x2Min - | Operator::F64x2Max => { + | Operator::F64x2Max + | Operator::F64x2PMin + | Operator::F64x2PMax => { self.check_non_deterministic_enabled()?; self.check_simd_enabled()?; self.pop_operand(Some(Type::V128))?; @@ -1432,21 +1436,21 @@ impl OperatorValidator { | Operator::V128Or | Operator::V128Xor | Operator::I8x16Add - | Operator::I8x16AddSaturateS - | Operator::I8x16AddSaturateU + | Operator::I8x16AddSatS + | Operator::I8x16AddSatU | Operator::I8x16Sub - | Operator::I8x16SubSaturateS - | Operator::I8x16SubSaturateU + | Operator::I8x16SubSatS + | Operator::I8x16SubSatU | Operator::I8x16MinS | Operator::I8x16MinU | Operator::I8x16MaxS | Operator::I8x16MaxU | Operator::I16x8Add - | Operator::I16x8AddSaturateS - | Operator::I16x8AddSaturateU + | Operator::I16x8AddSatS + | Operator::I16x8AddSatU | Operator::I16x8Sub - | Operator::I16x8SubSaturateS - | Operator::I16x8SubSaturateU + | Operator::I16x8SubSatS + | Operator::I16x8SubSatU | Operator::I16x8Mul | Operator::I16x8MinS | Operator::I16x8MinU @@ -1473,7 +1477,15 @@ impl OperatorValidator { self.pop_operand(Some(Type::V128))?; self.push_operand(Type::V128)?; } - Operator::F32x4Abs + Operator::F32x4Ceil + | Operator::F32x4Floor + | Operator::F32x4Trunc + | Operator::F32x4Nearest + | Operator::F64x2Ceil + | Operator::F64x2Floor + | Operator::F64x2Trunc + | Operator::F64x2Nearest + | Operator::F32x4Abs | Operator::F32x4Neg | Operator::F32x4Sqrt | Operator::F64x2Abs @@ -1545,13 +1557,13 @@ impl OperatorValidator { self.pop_operand(Some(Type::V128))?; self.push_operand(Type::V128)?; } - Operator::V8x16Swizzle => { + Operator::I8x16Swizzle => { self.check_simd_enabled()?; self.pop_operand(Some(Type::V128))?; self.pop_operand(Some(Type::V128))?; self.push_operand(Type::V128)?; } - Operator::V8x16Shuffle { ref lanes } => { + Operator::I8x16Shuffle { ref lanes } => { self.check_simd_enabled()?; self.pop_operand(Some(Type::V128))?; self.pop_operand(Some(Type::V128))?; @@ -1560,31 +1572,31 @@ impl OperatorValidator { } self.push_operand(Type::V128)?; } - Operator::V8x16LoadSplat { memarg } => { + Operator::V128Load8Splat { memarg } => { self.check_simd_enabled()?; let ty = self.check_memarg(memarg, 0, resources)?; self.pop_operand(Some(ty))?; self.push_operand(Type::V128)?; } - Operator::V16x8LoadSplat { memarg } => { + Operator::V128Load16Splat { memarg } => { self.check_simd_enabled()?; let ty = self.check_memarg(memarg, 1, resources)?; self.pop_operand(Some(ty))?; self.push_operand(Type::V128)?; } - Operator::V32x4LoadSplat { memarg } => { + Operator::V128Load32Splat { memarg } => { self.check_simd_enabled()?; let ty = self.check_memarg(memarg, 2, resources)?; self.pop_operand(Some(ty))?; self.push_operand(Type::V128)?; } - Operator::V64x2LoadSplat { memarg } - | Operator::I16x8Load8x8S { memarg } - | Operator::I16x8Load8x8U { memarg } - | Operator::I32x4Load16x4S { memarg } - | Operator::I32x4Load16x4U { memarg } - | Operator::I64x2Load32x2S { memarg } - | Operator::I64x2Load32x2U { memarg } => { + Operator::V128Load64Splat { memarg } + | Operator::V128Load8x8S { memarg } + | Operator::V128Load8x8U { memarg } + | Operator::V128Load16x4S { memarg } + | Operator::V128Load16x4U { memarg } + | Operator::V128Load32x2S { memarg } + | Operator::V128Load32x2U { memarg } => { self.check_simd_enabled()?; let idx = self.check_memarg(memarg, 3, resources)?; self.pop_operand(Some(idx))?; diff --git a/crates/wasmparser/src/primitives.rs b/crates/wasmparser/src/primitives.rs index 04b280653e..1eaee9a1f9 100644 --- a/crates/wasmparser/src/primitives.rs +++ b/crates/wasmparser/src/primitives.rs @@ -692,11 +692,11 @@ pub enum Operator<'a> { I8x16ShrS, I8x16ShrU, I8x16Add, - I8x16AddSaturateS, - I8x16AddSaturateU, + I8x16AddSatS, + I8x16AddSatU, I8x16Sub, - I8x16SubSaturateS, - I8x16SubSaturateU, + I8x16SubSatS, + I8x16SubSatU, I8x16MinS, I8x16MinU, I8x16MaxS, @@ -710,11 +710,11 @@ pub enum Operator<'a> { I16x8ShrS, I16x8ShrU, I16x8Add, - I16x8AddSaturateS, - I16x8AddSaturateU, + I16x8AddSatS, + I16x8AddSatU, I16x8Sub, - I16x8SubSaturateS, - I16x8SubSaturateU, + I16x8SubSatS, + I16x8SubSatU, I16x8Mul, I16x8MinS, I16x8MinU, @@ -742,6 +742,14 @@ pub enum Operator<'a> { I64x2Add, I64x2Sub, I64x2Mul, + F32x4Ceil, + F32x4Floor, + F32x4Trunc, + F32x4Nearest, + F64x2Ceil, + F64x2Floor, + F64x2Trunc, + F64x2Nearest, F32x4Abs, F32x4Neg, F32x4Sqrt, @@ -751,6 +759,8 @@ pub enum Operator<'a> { F32x4Div, F32x4Min, F32x4Max, + F32x4PMin, + F32x4PMax, F64x2Abs, F64x2Neg, F64x2Sqrt, @@ -760,16 +770,18 @@ pub enum Operator<'a> { F64x2Div, F64x2Min, F64x2Max, + F64x2PMin, + F64x2PMax, I32x4TruncSatF32x4S, I32x4TruncSatF32x4U, F32x4ConvertI32x4S, F32x4ConvertI32x4U, - V8x16Swizzle, - V8x16Shuffle { lanes: [SIMDLaneIndex; 16] }, - V8x16LoadSplat { memarg: MemoryImmediate }, - V16x8LoadSplat { memarg: MemoryImmediate }, - V32x4LoadSplat { memarg: MemoryImmediate }, - V64x2LoadSplat { memarg: MemoryImmediate }, + I8x16Swizzle, + I8x16Shuffle { lanes: [SIMDLaneIndex; 16] }, + V128Load8Splat { memarg: MemoryImmediate }, + V128Load16Splat { memarg: MemoryImmediate }, + V128Load32Splat { memarg: MemoryImmediate }, + V128Load64Splat { memarg: MemoryImmediate }, I8x16NarrowI16x8S, I8x16NarrowI16x8U, I16x8NarrowI32x4S, @@ -782,12 +794,12 @@ pub enum Operator<'a> { I32x4WidenHighI16x8S, I32x4WidenLowI16x8U, I32x4WidenHighI16x8U, - I16x8Load8x8S { memarg: MemoryImmediate }, - I16x8Load8x8U { memarg: MemoryImmediate }, - I32x4Load16x4S { memarg: MemoryImmediate }, - I32x4Load16x4U { memarg: MemoryImmediate }, - I64x2Load32x2S { memarg: MemoryImmediate }, - I64x2Load32x2U { memarg: MemoryImmediate }, + V128Load8x8S { memarg: MemoryImmediate }, + V128Load8x8U { memarg: MemoryImmediate }, + V128Load16x4S { memarg: MemoryImmediate }, + V128Load16x4U { memarg: MemoryImmediate }, + V128Load32x2S { memarg: MemoryImmediate }, + V128Load32x2U { memarg: MemoryImmediate }, I8x16RoundingAverageU, I16x8RoundingAverageU, } diff --git a/crates/wasmparser/src/validator.rs b/crates/wasmparser/src/validator.rs index aafd8d8f6d..13f6101529 100644 --- a/crates/wasmparser/src/validator.rs +++ b/crates/wasmparser/src/validator.rs @@ -1183,14 +1183,14 @@ impl Validator { )?; self.section(Order::Global, section, |me, g| { me.global_type(&g.ty)?; - me.init_expr(&g.init_expr, g.ty.content_type)?; + me.init_expr(&g.init_expr, g.ty.content_type, false)?; let def = me.state.def(g.ty); me.state.assert_mut().globals.push(def); Ok(()) }) } - fn init_expr(&mut self, expr: &InitExpr<'_>, expected_ty: Type) -> Result<()> { + fn init_expr(&mut self, expr: &InitExpr<'_>, expected_ty: Type, allow32: bool) -> Result<()> { let mut ops = expr.get_operators_reader().into_iter_with_offsets(); let (op, offset) = match ops.next() { Some(Err(e)) => return Err(e), @@ -1225,7 +1225,9 @@ impl Validator { } }; if ty != expected_ty { - return self.create_error("type mismatch: invalid init_expr type"); + if !allow32 || ty != Type::I32 { + return self.create_error("type mismatch: invalid init_expr type"); + } } // Make sure the next instruction is an `end` @@ -1442,7 +1444,7 @@ impl Validator { if e.ty != table.item.element_type { return me.create_error("element_type != table type"); } - me.init_expr(&init_expr, Type::I32)?; + me.init_expr(&init_expr, Type::I32, false)?; } ElementKind::Passive | ElementKind::Declared => { if !me.features.bulk_memory { @@ -1583,7 +1585,8 @@ impl Validator { init_expr, } => { let ty = me.get_memory(me.state.def(memory_index))?.index_type(); - me.init_expr(&init_expr, ty)?; + let allow32 = ty == Type::I64; + me.init_expr(&init_expr, ty, allow32)?; } } Ok(()) diff --git a/crates/wasmprinter/src/lib.rs b/crates/wasmprinter/src/lib.rs index 2553bd0f04..7e833c23f9 100644 --- a/crates/wasmprinter/src/lib.rs +++ b/crates/wasmprinter/src/lib.rs @@ -1164,11 +1164,11 @@ impl Printer { I8x16ShrU => self.result.push_str("i8x16.shr_u"), I8x16ShrS => self.result.push_str("i8x16.shr_s"), I8x16Add => self.result.push_str("i8x16.add"), - I8x16AddSaturateS => self.result.push_str("i8x16.add_saturate_s"), - I8x16AddSaturateU => self.result.push_str("i8x16.add_saturate_u"), + I8x16AddSatS => self.result.push_str("i8x16.add_sat_s"), + I8x16AddSatU => self.result.push_str("i8x16.add_sat_u"), I8x16Sub => self.result.push_str("i8x16.sub"), - I8x16SubSaturateS => self.result.push_str("i8x16.sub_saturate_s"), - I8x16SubSaturateU => self.result.push_str("i8x16.sub_saturate_u"), + I8x16SubSatS => self.result.push_str("i8x16.sub_sat_s"), + I8x16SubSatU => self.result.push_str("i8x16.sub_sat_u"), I16x8Abs => self.result.push_str("i16x8.abs"), I16x8Neg => self.result.push_str("i16x8.neg"), @@ -1179,11 +1179,11 @@ impl Printer { I16x8ShrU => self.result.push_str("i16x8.shr_u"), I16x8ShrS => self.result.push_str("i16x8.shr_s"), I16x8Add => self.result.push_str("i16x8.add"), - I16x8AddSaturateS => self.result.push_str("i16x8.add_saturate_s"), - I16x8AddSaturateU => self.result.push_str("i16x8.add_saturate_u"), + I16x8AddSatS => self.result.push_str("i16x8.add_sat_s"), + I16x8AddSatU => self.result.push_str("i16x8.add_sat_u"), I16x8Sub => self.result.push_str("i16x8.sub"), - I16x8SubSaturateS => self.result.push_str("i16x8.sub_saturate_s"), - I16x8SubSaturateU => self.result.push_str("i16x8.sub_saturate_u"), + I16x8SubSatS => self.result.push_str("i16x8.sub_sat_s"), + I16x8SubSatU => self.result.push_str("i16x8.sub_sat_u"), I16x8Mul => self.result.push_str("i16x8.mul"), I32x4Abs => self.result.push_str("i32x4.abs"), @@ -1206,6 +1206,14 @@ impl Printer { I64x2Sub => self.result.push_str("i64x2.sub"), I64x2Mul => self.result.push_str("i64x2.mul"), + F32x4Ceil => self.result.push_str("f32x4.ceil"), + F32x4Floor => self.result.push_str("f32x4.floor"), + F32x4Trunc => self.result.push_str("f32x4.trunc"), + F32x4Nearest => self.result.push_str("f32x4.nearest"), + F64x2Ceil => self.result.push_str("f64x2.ceil"), + F64x2Floor => self.result.push_str("f64x2.floor"), + F64x2Trunc => self.result.push_str("f64x2.trunc"), + F64x2Nearest => self.result.push_str("f64x2.nearest"), F32x4Abs => self.result.push_str("f32x4.abs"), F32x4Neg => self.result.push_str("f32x4.neg"), F32x4Sqrt => self.result.push_str("f32x4.sqrt"), @@ -1215,6 +1223,8 @@ impl Printer { F32x4Mul => self.result.push_str("f32x4.mul"), F32x4Min => self.result.push_str("f32x4.min"), F32x4Max => self.result.push_str("f32x4.max"), + F32x4PMin => self.result.push_str("f32x4.pmin"), + F32x4PMax => self.result.push_str("f32x4.pmax"), F64x2Abs => self.result.push_str("f64x2.abs"), F64x2Neg => self.result.push_str("f64x2.neg"), @@ -1225,23 +1235,25 @@ impl Printer { F64x2Mul => self.result.push_str("f64x2.mul"), F64x2Min => self.result.push_str("f64x2.min"), F64x2Max => self.result.push_str("f64x2.max"), + F64x2PMin => self.result.push_str("f64x2.pmin"), + F64x2PMax => self.result.push_str("f64x2.pmax"), I32x4TruncSatF32x4S => self.result.push_str("i32x4.trunc_sat_f32x4_s"), I32x4TruncSatF32x4U => self.result.push_str("i32x4.trunc_sat_f32x4_u"), F32x4ConvertI32x4S => self.result.push_str("f32x4.convert_i32x4_s"), F32x4ConvertI32x4U => self.result.push_str("f32x4.convert_i32x4_u"), - V8x16Swizzle => self.result.push_str("v8x16.swizzle"), - V8x16Shuffle { lanes } => { - self.result.push_str("v8x16.shuffle"); + I8x16Swizzle => self.result.push_str("i8x16.swizzle"), + I8x16Shuffle { lanes } => { + self.result.push_str("i8x16.shuffle"); for lane in lanes { write!(self.result, " {}", lane)?; } } - V8x16LoadSplat { memarg } => self.mem_instr("v8x16.load_splat", memarg, 1)?, - V16x8LoadSplat { memarg } => self.mem_instr("v16x8.load_splat", memarg, 2)?, - V32x4LoadSplat { memarg } => self.mem_instr("v32x4.load_splat", memarg, 4)?, - V64x2LoadSplat { memarg } => self.mem_instr("v64x2.load_splat", memarg, 8)?, + V128Load8Splat { memarg } => self.mem_instr("v128.load8_splat", memarg, 1)?, + V128Load16Splat { memarg } => self.mem_instr("v128.load16_splat", memarg, 2)?, + V128Load32Splat { memarg } => self.mem_instr("v128.load32_splat", memarg, 4)?, + V128Load64Splat { memarg } => self.mem_instr("v128.load64_splat", memarg, 8)?, I8x16NarrowI16x8S => self.result.push_str("i8x16.narrow_i16x8_s"), I8x16NarrowI16x8U => self.result.push_str("i8x16.narrow_i16x8_u"), @@ -1257,12 +1269,12 @@ impl Printer { I32x4WidenLowI16x8U => self.result.push_str("i32x4.widen_low_i16x8_u"), I32x4WidenHighI16x8U => self.result.push_str("i32x4.widen_high_i16x8_u"), - I16x8Load8x8S { memarg } => self.mem_instr("i16x8.load8x8_s", memarg, 8)?, - I16x8Load8x8U { memarg } => self.mem_instr("i16x8.load8x8_u", memarg, 8)?, - I32x4Load16x4S { memarg } => self.mem_instr("i32x4.load16x4_s", memarg, 8)?, - I32x4Load16x4U { memarg } => self.mem_instr("i32x4.load16x4_u", memarg, 8)?, - I64x2Load32x2S { memarg } => self.mem_instr("i64x2.load32x2_s", memarg, 8)?, - I64x2Load32x2U { memarg } => self.mem_instr("i64x2.load32x2_u", memarg, 8)?, + V128Load8x8S { memarg } => self.mem_instr("v128.load8x8_s", memarg, 8)?, + V128Load8x8U { memarg } => self.mem_instr("v128.load8x8_u", memarg, 8)?, + V128Load16x4S { memarg } => self.mem_instr("v128.load16x4_s", memarg, 8)?, + V128Load16x4U { memarg } => self.mem_instr("v128.load16x4_u", memarg, 8)?, + V128Load32x2S { memarg } => self.mem_instr("v128.load32x2_s", memarg, 8)?, + V128Load32x2U { memarg } => self.mem_instr("v128.load32x2_u", memarg, 8)?, I8x16RoundingAverageU => self.result.push_str("i8x16.avgr_u"), I16x8RoundingAverageU => self.result.push_str("i16x8.avgr_u"), diff --git a/crates/wast/src/ast/expr.rs b/crates/wast/src/ast/expr.rs index 2ed1023ce2..c1576f9153 100644 --- a/crates/wast/src/ast/expr.rs +++ b/crates/wast/src/ast/expr.rs @@ -788,21 +788,21 @@ instructions! { // proposal: simd V128Load(MemArg<16>) : [0xfd, 0x00] : "v128.load", - I16x8Load8x8S(MemArg<8>) : [0xfd, 0x01] : "i16x8.load8x8_s", - I16x8Load8x8U(MemArg<8>) : [0xfd, 0x02] : "i16x8.load8x8_u", - I32x4Load16x4S(MemArg<8>) : [0xfd, 0x03] : "i32x4.load16x4_s", - I32x4Load16x4U(MemArg<8>) : [0xfd, 0x04] : "i32x4.load16x4_u", - I64x2Load32x2S(MemArg<8>) : [0xfd, 0x05] : "i64x2.load32x2_s", - I64x2Load32x2U(MemArg<8>) : [0xfd, 0x06] : "i64x2.load32x2_u", - V8x16LoadSplat(MemArg<1>) : [0xfd, 0x07] : "v8x16.load_splat", - V16x8LoadSplat(MemArg<2>) : [0xfd, 0x08] : "v16x8.load_splat", - V32x4LoadSplat(MemArg<4>) : [0xfd, 0x09] : "v32x4.load_splat", - V64x2LoadSplat(MemArg<8>) : [0xfd, 0x0a] : "v64x2.load_splat", + V128Load8x8S(MemArg<8>) : [0xfd, 0x01] : "v128.load8x8_s", + V128Load8x8U(MemArg<8>) : [0xfd, 0x02] : "v128.load8x8_u", + V128Load16x4S(MemArg<8>) : [0xfd, 0x03] : "v128.load16x4_s", + V128Load16x4U(MemArg<8>) : [0xfd, 0x04] : "v128.load16x4_u", + V128Load32x2S(MemArg<8>) : [0xfd, 0x05] : "v128.load32x2_s", + V128Load32x2U(MemArg<8>) : [0xfd, 0x06] : "v128.load32x2_u", + V128Load8Splat(MemArg<1>) : [0xfd, 0x07] : "v128.load8_splat", + V128Load16Splat(MemArg<2>) : [0xfd, 0x08] : "v128.load16_splat", + V128Load32Splat(MemArg<4>) : [0xfd, 0x09] : "v128.load32_splat", + V128Load64Splat(MemArg<8>) : [0xfd, 0x0a] : "v128.load64_splat", V128Store(MemArg<16>) : [0xfd, 0x0b] : "v128.store", V128Const(V128Const) : [0xfd, 0x0c] : "v128.const", - V8x16Shuffle(V8x16Shuffle) : [0xfd, 0x0d] : "v8x16.shuffle", - V8x16Swizzle : [0xfd, 0x0e] : "v8x16.swizzle", + I8x16Shuffle(I8x16Shuffle) : [0xfd, 0x0d] : "i8x16.shuffle", + I8x16Swizzle : [0xfd, 0x0e] : "i8x16.swizzle", I8x16Splat : [0xfd, 0x0f] : "i8x16.splat", I16x8Splat : [0xfd, 0x10] : "i16x8.splat", @@ -811,20 +811,20 @@ instructions! { F32x4Splat : [0xfd, 0x13] : "f32x4.splat", F64x2Splat : [0xfd, 0x14] : "f64x2.splat", - I8x16ExtractLaneS(u8) : [0xfd, 0x15] : "i8x16.extract_lane_s", - I8x16ExtractLaneU(u8) : [0xfd, 0x16] : "i8x16.extract_lane_u", - I8x16ReplaceLane(u8) : [0xfd, 0x17] : "i8x16.replace_lane", - I16x8ExtractLaneS(u8) : [0xfd, 0x18] : "i16x8.extract_lane_s", - I16x8ExtractLaneU(u8) : [0xfd, 0x19] : "i16x8.extract_lane_u", - I16x8ReplaceLane(u8) : [0xfd, 0x1a] : "i16x8.replace_lane", - I32x4ExtractLane(u8) : [0xfd, 0x1b] : "i32x4.extract_lane", - I32x4ReplaceLane(u8) : [0xfd, 0x1c] : "i32x4.replace_lane", - I64x2ExtractLane(u8) : [0xfd, 0x1d] : "i64x2.extract_lane", - I64x2ReplaceLane(u8) : [0xfd, 0x1e] : "i64x2.replace_lane", - F32x4ExtractLane(u8) : [0xfd, 0x1f] : "f32x4.extract_lane", - F32x4ReplaceLane(u8) : [0xfd, 0x20] : "f32x4.replace_lane", - F64x2ExtractLane(u8) : [0xfd, 0x21] : "f64x2.extract_lane", - F64x2ReplaceLane(u8) : [0xfd, 0x22] : "f64x2.replace_lane", + I8x16ExtractLaneS(LaneArg) : [0xfd, 0x15] : "i8x16.extract_lane_s", + I8x16ExtractLaneU(LaneArg) : [0xfd, 0x16] : "i8x16.extract_lane_u", + I8x16ReplaceLane(LaneArg) : [0xfd, 0x17] : "i8x16.replace_lane", + I16x8ExtractLaneS(LaneArg) : [0xfd, 0x18] : "i16x8.extract_lane_s", + I16x8ExtractLaneU(LaneArg) : [0xfd, 0x19] : "i16x8.extract_lane_u", + I16x8ReplaceLane(LaneArg) : [0xfd, 0x1a] : "i16x8.replace_lane", + I32x4ExtractLane(LaneArg) : [0xfd, 0x1b] : "i32x4.extract_lane", + I32x4ReplaceLane(LaneArg) : [0xfd, 0x1c] : "i32x4.replace_lane", + I64x2ExtractLane(LaneArg) : [0xfd, 0x1d] : "i64x2.extract_lane", + I64x2ReplaceLane(LaneArg) : [0xfd, 0x1e] : "i64x2.replace_lane", + F32x4ExtractLane(LaneArg) : [0xfd, 0x1f] : "f32x4.extract_lane", + F32x4ReplaceLane(LaneArg) : [0xfd, 0x20] : "f32x4.replace_lane", + F64x2ExtractLane(LaneArg) : [0xfd, 0x21] : "f64x2.extract_lane", + F64x2ReplaceLane(LaneArg) : [0xfd, 0x22] : "f64x2.replace_lane", I8x16Eq : [0xfd, 0x23] : "i8x16.eq", I8x16Ne : [0xfd, 0x24] : "i8x16.ne", @@ -888,11 +888,11 @@ instructions! { I8x16ShrS : [0xfd, 0x6c] : "i8x16.shr_s", I8x16ShrU : [0xfd, 0x6d] : "i8x16.shr_u", I8x16Add : [0xfd, 0x6e] : "i8x16.add", - I8x16AddSaturateS : [0xfd, 0x6f] : "i8x16.add_saturate_s", - I8x16AddSaturateU : [0xfd, 0x70] : "i8x16.add_saturate_u", + I8x16AddSatS : [0xfd, 0x6f] : "i8x16.add_sat_s", + I8x16AddSatU : [0xfd, 0x70] : "i8x16.add_sat_u", I8x16Sub : [0xfd, 0x71] : "i8x16.sub", - I8x16SubSaturateS : [0xfd, 0x72] : "i8x16.sub_saturate_s", - I8x16SubSaturateU : [0xfd, 0x73] : "i8x16.sub_saturate_u", + I8x16SubSatS : [0xfd, 0x72] : "i8x16.sub_sat_s", + I8x16SubSatU : [0xfd, 0x73] : "i8x16.sub_sat_u", I8x16MinS : [0xfd, 0x76] : "i8x16.min_s", I8x16MinU : [0xfd, 0x77] : "i8x16.min_u", I8x16MaxS : [0xfd, 0x78] : "i8x16.max_s", @@ -914,11 +914,11 @@ instructions! { I16x8ShrS : [0xfd, 0x8c] : "i16x8.shr_s", I16x8ShrU : [0xfd, 0x8d] : "i16x8.shr_u", I16x8Add : [0xfd, 0x8e] : "i16x8.add", - I16x8AddSaturateS : [0xfd, 0x8f] : "i16x8.add_saturate_s", - I16x8AddSaturateU : [0xfd, 0x90] : "i16x8.add_saturate_u", + I16x8AddSatS : [0xfd, 0x8f] : "i16x8.add_sat_s", + I16x8AddSatU : [0xfd, 0x90] : "i16x8.add_sat_u", I16x8Sub : [0xfd, 0x91] : "i16x8.sub", - I16x8SubSaturateS : [0xfd, 0x92] : "i16x8.sub_saturate_s", - I16x8SubSaturateU : [0xfd, 0x93] : "i16x8.sub_saturate_u", + I16x8SubSatS : [0xfd, 0x92] : "i16x8.sub_sat_s", + I16x8SubSatU : [0xfd, 0x93] : "i16x8.sub_sat_u", I16x8Mul : [0xfd, 0x95] : "i16x8.mul", I16x8MinS : [0xfd, 0x96] : "i16x8.min_s", I16x8MinU : [0xfd, 0x97] : "i16x8.min_u", @@ -955,6 +955,15 @@ instructions! { I64x2Sub : [0xfd, 0xd1] : "i64x2.sub", I64x2Mul : [0xfd, 0xd5] : "i64x2.mul", + F32x4Ceil : [0xfd, 0xd8] : "f32x4.ceil", + F32x4Floor : [0xfd, 0xd9] : "f32x4.floor", + F32x4Trunc : [0xfd, 0xda] : "f32x4.trunc", + F32x4Nearest : [0xfd, 0xdb] : "f32x4.nearest", + F64x2Ceil : [0xfd, 0xdc] : "f64x2.ceil", + F64x2Floor : [0xfd, 0xdd] : "f64x2.floor", + F64x2Trunc : [0xfd, 0xde] : "f64x2.trunc", + F64x2Nearest : [0xfd, 0xdf] : "f64x2.nearest", + F32x4Abs : [0xfd, 0xe0] : "f32x4.abs", F32x4Neg : [0xfd, 0xe1] : "f32x4.neg", F32x4Sqrt : [0xfd, 0xe3] : "f32x4.sqrt", @@ -964,6 +973,8 @@ instructions! { F32x4Div : [0xfd, 0xe7] : "f32x4.div", F32x4Min : [0xfd, 0xe8] : "f32x4.min", F32x4Max : [0xfd, 0xe9] : "f32x4.max", + F32x4PMin : [0xfd, 0xea] : "f32x4.pmin", + F32x4PMax : [0xfd, 0xeb] : "f32x4.pmax", F64x2Abs : [0xfd, 0xec] : "f64x2.abs", F64x2Neg : [0xfd, 0xed] : "f64x2.neg", @@ -974,6 +985,8 @@ instructions! { F64x2Div : [0xfd, 0xf3] : "f64x2.div", F64x2Min : [0xfd, 0xf4] : "f64x2.min", F64x2Max : [0xfd, 0xf5] : "f64x2.max", + F64x2PMin : [0xfd, 0xf6] : "f64x2.pmin", + F64x2PMax : [0xfd, 0xf7] : "f64x2.pmax", I32x4TruncSatF32x4S : [0xfd, 0xf8] : "i32x4.trunc_sat_f32x4_s", I32x4TruncSatF32x4U : [0xfd, 0xf9] : "i32x4.trunc_sat_f32x4_u", @@ -1065,6 +1078,33 @@ impl<'a> Parse<'a> for BrTableIndices<'a> { } } +/// Payload for lane-related instructions. Unsigned with no + prefix. +#[derive(Debug)] +pub struct LaneArg { + /// The lane argument. + pub lane: u8, +} + +impl<'a> Parse<'a> for LaneArg { + fn parse(parser: Parser<'a>) -> Result { + let lane = parser.step(|c| { + if let Some((i, rest)) = c.integer() { + if i.sign() == None { + let (src, radix) = i.val(); + let val = u8::from_str_radix(src, radix) + .map_err(|_| c.error("malformed lane index"))?; + Ok((val, rest)) + } else { + Err(c.error("unexpected token")) + } + } else { + Err(c.error("expected a lane index")) + } + })?; + Ok(LaneArg { lane }) + } +} + /// Payload for memory-related instructions indicating offset/alignment of /// memory accesses. #[derive(Debug)] @@ -1479,16 +1519,16 @@ impl<'a> Parse<'a> for V128Const { } } -/// Lanes being shuffled in the `v8x16.shuffle` instruction +/// Lanes being shuffled in the `i8x16.shuffle` instruction #[derive(Debug)] -pub struct V8x16Shuffle { +pub struct I8x16Shuffle { #[allow(missing_docs)] pub lanes: [u8; 16], } -impl<'a> Parse<'a> for V8x16Shuffle { +impl<'a> Parse<'a> for I8x16Shuffle { fn parse(parser: Parser<'a>) -> Result { - Ok(V8x16Shuffle { + Ok(I8x16Shuffle { lanes: [ parser.parse()?, parser.parse()?, diff --git a/crates/wast/src/binary.rs b/crates/wast/src/binary.rs index 7088d38188..11a6c51289 100644 --- a/crates/wast/src/binary.rs +++ b/crates/wast/src/binary.rs @@ -851,6 +851,12 @@ impl Encode for LetType<'_> { } } +impl Encode for LaneArg { + fn encode(&self, e: &mut Vec) { + self.lane.encode(e); + } +} + impl Encode for MemArg<'_> { fn encode(&self, e: &mut Vec) { match self.memory { @@ -1070,7 +1076,7 @@ impl Encode for V128Const { } } -impl Encode for V8x16Shuffle { +impl Encode for I8x16Shuffle { fn encode(&self, dst: &mut Vec) { dst.extend_from_slice(&self.lanes); } diff --git a/crates/wast/src/lexer.rs b/crates/wast/src/lexer.rs index d9288fc3b4..99c46239f1 100644 --- a/crates/wast/src/lexer.rs +++ b/crates/wast/src/lexer.rs @@ -144,6 +144,15 @@ pub enum LexError { __Nonexhaustive, } +/// A sign token for an integer. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum SignToken { + /// Plus sign: "+", + Plus, + /// Minus sign: "-", + Minus, +} + /// A parsed integer, signed or unsigned. /// /// Methods can be use to access the value of the integer. @@ -152,6 +161,7 @@ pub struct Integer<'a>(Box>); #[derive(Debug, PartialEq)] struct IntegerInner<'a> { + sign: Option, src: &'a str, val: Cow<'a, str>, hex: bool, @@ -296,14 +306,16 @@ impl<'a> Lexer<'a> { } fn number(&self, src: &'a str) -> Option> { - let (negative, num) = if src.starts_with('+') { - (false, &src[1..]) + let (sign, num) = if src.starts_with('+') { + (Some(SignToken::Plus), &src[1..]) } else if src.starts_with('-') { - (true, &src[1..]) + (Some(SignToken::Minus), &src[1..]) } else { - (false, src) + (None, src) }; + let negative = sign == Some(SignToken::Minus); + // Handle `inf` and `nan` which are special numbers here if num == "inf" { return Some(Token::Float(Float(Box::new(FloatInner { @@ -359,6 +371,7 @@ impl<'a> Lexer<'a> { // Otherwise this is a valid integer literal! None => { return Some(Token::Integer(Integer(Box::new(IntegerInner { + sign, src, val, hex, @@ -710,6 +723,11 @@ impl<'a> Token<'a> { } impl<'a> Integer<'a> { + /// Returns the sign token for this integer. + pub fn sign(&self) -> Option { + self.0.sign + } + /// Returns the original source text for this integer. pub fn src(&self) -> &'a str { self.0.src diff --git a/crates/wast/src/resolve/names.rs b/crates/wast/src/resolve/names.rs index 9d55609661..55a04f875e 100644 --- a/crates/wast/src/resolve/names.rs +++ b/crates/wast/src/resolve/names.rs @@ -2067,16 +2067,16 @@ impl<'a, 'b> ExprResolver<'a, 'b> { | I64AtomicRmw16CmpxchgU(m) | I64AtomicRmw32CmpxchgU(m) | V128Load(m) - | I16x8Load8x8S(m) - | I16x8Load8x8U(m) - | I32x4Load16x4S(m) - | I32x4Load16x4U(m) - | I64x2Load32x2S(m) - | I64x2Load32x2U(m) - | V8x16LoadSplat(m) - | V16x8LoadSplat(m) - | V32x4LoadSplat(m) - | V64x2LoadSplat(m) + | V128Load8x8S(m) + | V128Load8x8U(m) + | V128Load16x4S(m) + | V128Load16x4U(m) + | V128Load32x2S(m) + | V128Load32x2U(m) + | V128Load8Splat(m) + | V128Load16Splat(m) + | V128Load32Splat(m) + | V128Load64Splat(m) | V128Store(m) | MemoryAtomicNotify(m) | MemoryAtomicWait32(m) diff --git a/tests/local/memory64.wast b/tests/local/memory64.wast index 78404efdfc..500fbdac5a 100644 --- a/tests/local/memory64.wast +++ b/tests/local/memory64.wast @@ -105,16 +105,16 @@ i64.const 0 i64.const 0 i64.const 0 i64.atomic.rmw32.cmpxchg_u drop i64.const 0 v128.load drop - i64.const 0 i16x8.load8x8_s drop - i64.const 0 i16x8.load8x8_u drop - i64.const 0 i32x4.load16x4_s drop - i64.const 0 i32x4.load16x4_u drop - i64.const 0 i64x2.load32x2_s drop - i64.const 0 i64x2.load32x2_u drop - i64.const 0 v8x16.load_splat drop - i64.const 0 v16x8.load_splat drop - i64.const 0 v32x4.load_splat drop - i64.const 0 v64x2.load_splat drop + i64.const 0 v128.load8x8_s drop + i64.const 0 v128.load8x8_u drop + i64.const 0 v128.load16x4_s drop + i64.const 0 v128.load16x4_u drop + i64.const 0 v128.load32x2_s drop + i64.const 0 v128.load32x2_u drop + i64.const 0 v128.load8_splat drop + i64.const 0 v128.load16_splat drop + i64.const 0 v128.load32_splat drop + i64.const 0 v128.load64_splat drop i64.const 0 i32.const 0 i8x16.splat v128.store ) @@ -125,9 +125,6 @@ (assert_invalid (module (memory 1) (data (i64.const 0) "..")) "type mismatch") -(assert_invalid - (module (memory i64 1) (data (i32.const 0) "..")) - "type mismatch") (module $copy_between_memories (memory $m64 i64 1) diff --git a/tests/local/multi-memory.wast b/tests/local/multi-memory.wast index cc2b6cd7e1..ed55c9df8d 100644 --- a/tests/local/multi-memory.wast +++ b/tests/local/multi-memory.wast @@ -177,16 +177,16 @@ i32.const 0 i64.const 0 i64.const 0 i64.atomic.rmw32.cmpxchg_u $b drop i32.const 0 v128.load $b drop - i32.const 0 i16x8.load8x8_s $b drop - i32.const 0 i16x8.load8x8_u $b drop - i32.const 0 i32x4.load16x4_s $b drop - i32.const 0 i32x4.load16x4_u $b drop - i32.const 0 i64x2.load32x2_s $b drop - i32.const 0 i64x2.load32x2_u $b drop - i32.const 0 v8x16.load_splat $b drop - i32.const 0 v16x8.load_splat $b drop - i32.const 0 v32x4.load_splat $b drop - i32.const 0 v64x2.load_splat $b drop + i32.const 0 v128.load8x8_s $b drop + i32.const 0 v128.load8x8_u $b drop + i32.const 0 v128.load16x4_s $b drop + i32.const 0 v128.load16x4_u $b drop + i32.const 0 v128.load32x2_s $b drop + i32.const 0 v128.load32x2_u $b drop + i32.const 0 v128.load8_splat $b drop + i32.const 0 v128.load16_splat $b drop + i32.const 0 v128.load32_splat $b drop + i32.const 0 v128.load64_splat $b drop i32.const 0 i32.const 0 i8x16.splat v128.store $b ) ) diff --git a/tests/local/simd.wat b/tests/local/simd.wat index 442e80f2e2..b8c0b0eba0 100644 --- a/tests/local/simd.wat +++ b/tests/local/simd.wat @@ -16,12 +16,12 @@ (func (;3;) (type 0) (result v128) v128.const i32x4 0xff00ff01 0xff00ff0f 0xff00ffff 0xff00ff7f v128.const i32x4 0x00550055 0x00550055 0x00550055 0x00550155 - v8x16.shuffle 16 1 18 3 20 5 22 7 24 9 26 11 28 13 30 15) + i8x16.shuffle 16 1 18 3 20 5 22 7 24 9 26 11 28 13 30 15) (memory (;0;) 1) (export "v128_load_0" (func 0)) (export "v128_store_0" (func 1)) (export "func_f64x2_replace_lane_0" (func 2)) - (export "func_v8x16_shuffle_0" (func 3)) + (export "func_i8x16_shuffle_0" (func 3)) (data (;0;) (i32.const 0) "\ff\ff\ff\ff") (data (;1;) (i32.const 4) "\00\00\ceA") (data (;2;) (i32.const 8) "\00\00\00\00\00\ff\8f@") diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index 4537b22872..01d2d83a56 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -133,6 +133,8 @@ fn skip_test(test: &Path, contents: &[u8]) -> bool { "dump/reference-types.txt", "interp/reference-types.txt", "expr/reference-types.txt", + // FIXME(WebAssembly/wabt#1553) wabt uses old instruction names for simd + "parse/all-features.txt", ]; if broken.iter().any(|x| test.ends_with(x)) { return true; @@ -161,6 +163,11 @@ fn skip_test(test: &Path, contents: &[u8]) -> bool { if contents.contains("STDIN_FILE") { return true; } + + // FIXME(WebAssembly/wabt#1553) wabt uses old instruction names for simd + if contents.contains("--enable-simd") { + return true; + } } false @@ -270,9 +277,17 @@ impl TestState { && !test.ends_with("atomic.txt") && !test.ends_with("atomic-align.txt") && !test.ends_with("atomic.wast") + + // FIXME(WebAssembly/wabt#1553) wabt uses old instruction names + && !test.iter().any(|t| t == "simd") + + // FIXME wabt seems to print the `i64` in the wrong place + && !test.iter().any(|t| t == "memory64") + && !test.ends_with("local/simd.wat") { if let Some(expected) = self.wasm2wat(contents)? { - self.string_compare(&string, &expected)?; + self.string_compare(&string, &expected) + .context("`wasmprinter` disagrees with `wabt`")?; } } @@ -412,11 +427,11 @@ impl TestState { message, ), Err(e) => { - if error_matches(&e.to_string(), message) { + if error_matches(&format!("{:?}", e), message) { self.bump_ntests(); return Ok(()); } - bail!("bad error: {}\nshould have failed with: {:?}", e, message); + bail!("bad error: {:?}\nshould have failed with: {:?}", e, message); } } } @@ -670,6 +685,10 @@ impl TestState { } "bulk-memory-operations" => features.bulk_memory = true, "tail-call" => features.tail_call = true, + "memory64" => { + features.memory64 = true; + features.bulk_memory = true; + } _ => {} } } diff --git a/tests/testsuite b/tests/testsuite index b7eba900aa..18f83401a4 160000 --- a/tests/testsuite +++ b/tests/testsuite @@ -1 +1 @@ -Subproject commit b7eba900aa5e5e237c7cdbfecacc52d4beb6e528 +Subproject commit 18f83401a47a0e43772cf7d9f216e994bf7c7fa6 diff --git a/tests/wabt b/tests/wabt index c3b9c32b61..76f76f9c01 160000 --- a/tests/wabt +++ b/tests/wabt @@ -1 +1 @@ -Subproject commit c3b9c32b6165295c536e5884dfcfe8e4bdf7a811 +Subproject commit 76f76f9c01b43124c98769d9c92620c9a587dd62