diff --git a/crates/wasm-encoder/src/core/code.rs b/crates/wasm-encoder/src/core/code.rs index 12a4eae25a..8bfb8fdcf6 100644 --- a/crates/wasm-encoder/src/core/code.rs +++ b/crates/wasm-encoder/src/core/code.rs @@ -1087,6 +1087,122 @@ pub enum Instruction<'a> { ordering: Ordering, global_index: u32, }, + TableAtomicGet { + ordering: Ordering, + table_index: u32, + }, + TableAtomicSet { + ordering: Ordering, + table_index: u32, + }, + TableAtomicRmwXchg { + ordering: Ordering, + table_index: u32, + }, + TableAtomicRmwCmpxchg { + ordering: Ordering, + table_index: u32, + }, + StructAtomicGet { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicGetS { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicGetU { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicSet { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwAdd { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwSub { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwAnd { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwOr { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwXor { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwXchg { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + StructAtomicRmwCmpxchg { + ordering: Ordering, + struct_type_index: u32, + field_index: u32, + }, + ArrayAtomicGet { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicGetS { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicGetU { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicSet { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwAdd { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwSub { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwAnd { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwOr { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwXor { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwXchg { + ordering: Ordering, + array_type_index: u32, + }, + ArrayAtomicRmwCmpxchg { + ordering: Ordering, + array_type_index: u32, + }, + RefI31Shared, } impl Encode for Instruction<'_> { @@ -3319,6 +3435,266 @@ impl Encode for Instruction<'_> { ordering.encode(sink); global_index.encode(sink); } + Instruction::TableAtomicGet { + ordering, + table_index, + } => { + sink.push(0xFE); + sink.push(0x58); + ordering.encode(sink); + table_index.encode(sink); + } + Instruction::TableAtomicSet { + ordering, + table_index, + } => { + sink.push(0xFE); + sink.push(0x59); + ordering.encode(sink); + table_index.encode(sink); + } + Instruction::TableAtomicRmwXchg { + ordering, + table_index, + } => { + sink.push(0xFE); + sink.push(0x5A); + ordering.encode(sink); + table_index.encode(sink); + } + Instruction::TableAtomicRmwCmpxchg { + ordering, + table_index, + } => { + sink.push(0xFE); + sink.push(0x5B); + ordering.encode(sink); + table_index.encode(sink); + } + Instruction::StructAtomicGet { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x5C); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicGetS { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x5D); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicGetU { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x5E); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicSet { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x5F); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwAdd { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x60); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwSub { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x61); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwAnd { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x62); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwOr { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x63); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwXor { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x64); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwXchg { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x65); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::StructAtomicRmwCmpxchg { + ordering, + struct_type_index, + field_index, + } => { + sink.push(0xFE); + sink.push(0x66); + ordering.encode(sink); + struct_type_index.encode(sink); + field_index.encode(sink); + } + Instruction::ArrayAtomicGet { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x67); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicGetS { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x68); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicGetU { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x69); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicSet { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6A); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwAdd { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6B); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwSub { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6C); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwAnd { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6D); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwOr { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6E); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwXor { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x6F); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwXchg { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x70); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::ArrayAtomicRmwCmpxchg { + ordering, + array_type_index, + } => { + sink.push(0xFE); + sink.push(0x71); + ordering.encode(sink); + array_type_index.encode(sink); + } + Instruction::RefI31Shared => { + sink.push(0xFE); + sink.push(0x1F); + } } } } diff --git a/crates/wasmparser/src/binary_reader.rs b/crates/wasmparser/src/binary_reader.rs index c93187df5d..3fa9a772c8 100644 --- a/crates/wasmparser/src/binary_reader.rs +++ b/crates/wasmparser/src/binary_reader.rs @@ -1727,6 +1727,85 @@ impl<'a> BinaryReader<'a> { 0x57 => { visitor.visit_global_atomic_rmw_cmpxchg(self.read_ordering()?, self.read_var_u32()?) } + 0x58 => visitor.visit_table_atomic_get(self.read_ordering()?, self.read_var_u32()?), + 0x59 => visitor.visit_table_atomic_set(self.read_ordering()?, self.read_var_u32()?), + 0x5a => { + visitor.visit_table_atomic_rmw_xchg(self.read_ordering()?, self.read_var_u32()?) + } + 0x5b => { + visitor.visit_table_atomic_rmw_cmpxchg(self.read_ordering()?, self.read_var_u32()?) + } + 0x5c => visitor.visit_struct_atomic_get( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x5d => visitor.visit_struct_atomic_get_s( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x5e => visitor.visit_struct_atomic_get_u( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x5f => visitor.visit_struct_atomic_set( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x60 => visitor.visit_struct_atomic_rmw_add( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x61 => visitor.visit_struct_atomic_rmw_sub( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x62 => visitor.visit_struct_atomic_rmw_and( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x63 => visitor.visit_struct_atomic_rmw_or( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x64 => visitor.visit_struct_atomic_rmw_xor( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x65 => visitor.visit_struct_atomic_rmw_xchg( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x66 => visitor.visit_struct_atomic_rmw_cmpxchg( + self.read_ordering()?, + self.read_var_u32()?, + self.read_var_u32()?, + ), + 0x67 => visitor.visit_array_atomic_get(self.read_ordering()?, self.read_var_u32()?), + 0x68 => visitor.visit_array_atomic_get_s(self.read_ordering()?, self.read_var_u32()?), + 0x69 => visitor.visit_array_atomic_get_u(self.read_ordering()?, self.read_var_u32()?), + 0x6a => visitor.visit_array_atomic_set(self.read_ordering()?, self.read_var_u32()?), + 0x6b => visitor.visit_array_atomic_rmw_add(self.read_ordering()?, self.read_var_u32()?), + 0x6c => visitor.visit_array_atomic_rmw_sub(self.read_ordering()?, self.read_var_u32()?), + 0x6d => visitor.visit_array_atomic_rmw_and(self.read_ordering()?, self.read_var_u32()?), + 0x6e => visitor.visit_array_atomic_rmw_or(self.read_ordering()?, self.read_var_u32()?), + 0x6f => visitor.visit_array_atomic_rmw_xor(self.read_ordering()?, self.read_var_u32()?), + 0x70 => { + visitor.visit_array_atomic_rmw_xchg(self.read_ordering()?, self.read_var_u32()?) + } + 0x71 => { + visitor.visit_array_atomic_rmw_cmpxchg(self.read_ordering()?, self.read_var_u32()?) + } + 0x72 => visitor.visit_ref_i31_shared(), _ => bail!(pos, "unknown 0xfe subopcode: 0x{code:x}"), }) diff --git a/crates/wasmparser/src/lib.rs b/crates/wasmparser/src/lib.rs index 18183a4875..0b1c02db94 100644 --- a/crates/wasmparser/src/lib.rs +++ b/crates/wasmparser/src/lib.rs @@ -505,6 +505,33 @@ macro_rules! for_each_operator { @shared_everything_threads GlobalAtomicRmwXor { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xor @shared_everything_threads GlobalAtomicRmwXchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xchg @shared_everything_threads GlobalAtomicRmwCmpxchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_cmpxchg + @shared_everything_threads TableAtomicGet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_get + @shared_everything_threads TableAtomicSet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_set + @shared_everything_threads TableAtomicRmwXchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_xchg + @shared_everything_threads TableAtomicRmwCmpxchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_cmpxchg + @shared_everything_threads StructAtomicGet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_get + @shared_everything_threads StructAtomicGetS { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_get_s + @shared_everything_threads StructAtomicGetU { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_get_u + @shared_everything_threads StructAtomicSet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_set + @shared_everything_threads StructAtomicRmwAdd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_add + @shared_everything_threads StructAtomicRmwSub { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_sub + @shared_everything_threads StructAtomicRmwAnd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_and + @shared_everything_threads StructAtomicRmwOr { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_or + @shared_everything_threads StructAtomicRmwXor { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_xor + @shared_everything_threads StructAtomicRmwXchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_xchg + @shared_everything_threads StructAtomicRmwCmpxchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32 } => visit_struct_atomic_rmw_cmpxchg + @shared_everything_threads ArrayAtomicGet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get + @shared_everything_threads ArrayAtomicGetS { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_s + @shared_everything_threads ArrayAtomicGetU { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_u + @shared_everything_threads ArrayAtomicSet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_set + @shared_everything_threads ArrayAtomicRmwAdd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_add + @shared_everything_threads ArrayAtomicRmwSub { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_sub + @shared_everything_threads ArrayAtomicRmwAnd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_and + @shared_everything_threads ArrayAtomicRmwOr { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_or + @shared_everything_threads ArrayAtomicRmwXor { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xor + @shared_everything_threads ArrayAtomicRmwXchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xchg + @shared_everything_threads ArrayAtomicRmwCmpxchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_cmpxchg + @shared_everything_threads RefI31Shared => visit_ref_i31_shared // 0xFD operators // 128-bit SIMD diff --git a/crates/wasmparser/src/validator/operators.rs b/crates/wasmparser/src/validator/operators.rs index 824fe093a1..65c44b9216 100644 --- a/crates/wasmparser/src/validator/operators.rs +++ b/crates/wasmparser/src/validator/operators.rs @@ -28,7 +28,7 @@ use crate::{ Result, StorageType, StructType, SubType, TableType, TryTable, UnpackedIndex, ValType, VisitOperator, WasmFeatures, WasmModuleResources, V128, }; -use crate::{prelude::*, CompositeInnerType}; +use crate::{prelude::*, CompositeInnerType, Ordering}; use core::ops::{Deref, DerefMut}; pub(crate) struct OperatorValidator { @@ -758,17 +758,6 @@ where Ok(index_ty) } - /// Validates that the `table` is valid and returns the type it points to. - fn check_table_index(&self, table: u32) -> Result { - match self.resources.table_at(table) { - Some(ty) => Ok(ty), - None => bail!( - self.offset, - "unknown table {table}: table index out of bounds" - ), - } - } - fn check_floats_enabled(&self) -> Result<()> { if !self.features.floats() { bail!(self.offset, "floating-point instruction disallowed"); @@ -892,7 +881,7 @@ where type_index: u32, table_index: u32, ) -> Result<&'resources FuncType> { - let tab = self.check_table_index(table_index)?; + let tab = self.table_type_at(table_index)?; if !self .resources .is_subtype(ValType::Ref(tab.element_type), ValType::FUNCREF) @@ -1173,6 +1162,52 @@ where Ok(ty) } + /// Common helper for checking the types of structs accessed with atomic RMW + /// instructions, which only allow `i32` and `i64` types. + fn check_struct_atomic_rmw( + &mut self, + op: &'static str, + struct_type_index: u32, + field_index: u32, + ) -> Result<()> { + let ty = self + .struct_field_at(struct_type_index, field_index)? + .element_type; + let field_ty = match ty { + StorageType::Val(ValType::I32) => ValType::I32, + StorageType::Val(ValType::I64) => ValType::I64, + _ => bail!( + self.offset, + "invalid type: `struct.atomic.rmw.{}` only allows `i32` and `i64`", + op + ), + }; + self.pop_operand(Some(field_ty))?; + self.pop_concrete_ref(true, struct_type_index)?; + self.push_operand(field_ty)?; + Ok(()) + } + + /// Common helper for checking the types of arrays accessed with atomic RMW + /// instructions, which only allow `i32` and `i64`. + fn check_array_atomic_rmw(&mut self, op: &'static str, type_index: u32) -> Result<()> { + let ty = self.array_type_at(type_index)?.0.element_type; + let elem_ty = match ty { + StorageType::Val(ValType::I32) => ValType::I32, + StorageType::Val(ValType::I64) => ValType::I64, + _ => bail!( + self.offset, + "invalid type: `array.atomic.rmw.{}` only allows `i32` and `i64`", + op + ), + }; + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(ValType::I32))?; + self.pop_concrete_ref(true, type_index)?; + self.push_operand(elem_ty)?; + Ok(()) + } + fn element_type_at(&self, elem_index: u32) -> Result { match self.resources.element_type_at(elem_index) { Some(ty) => Ok(ty), @@ -1253,6 +1288,17 @@ where } } + /// Validates that the `table` is valid and returns the type it points to. + fn table_type_at(&self, table: u32) -> Result { + match self.resources.table_at(table) { + Some(ty) => Ok(ty), + None => bail!( + self.offset, + "unknown table {table}: table index out of bounds" + ), + } + } + fn params(&self, ty: BlockType) -> Result + 'resources> { Ok(match ty { BlockType::Empty | BlockType::Type(_) => Either::B(None.into_iter()), @@ -1691,11 +1737,7 @@ where self.push_operand(ty)?; Ok(()) } - fn visit_global_atomic_get( - &mut self, - _ordering: crate::Ordering, - global_index: u32, - ) -> Self::Output { + fn visit_global_atomic_get(&mut self, _ordering: Ordering, global_index: u32) -> Self::Output { self.visit_global_get(global_index)?; // No validation of `ordering` is needed because `global.atomic.get` can // be used on both shared and unshared globals. But we do need to limit @@ -1718,11 +1760,7 @@ where self.pop_operand(Some(ty.content_type))?; Ok(()) } - fn visit_global_atomic_set( - &mut self, - _ordering: crate::Ordering, - global_index: u32, - ) -> Self::Output { + fn visit_global_atomic_set(&mut self, _ordering: Ordering, global_index: u32) -> Self::Output { self.visit_global_set(global_index)?; // No validation of `ordering` is needed because `global.atomic.get` can // be used on both shared and unshared globals. @@ -3616,7 +3654,7 @@ where Ok(()) } fn visit_table_init(&mut self, segment: u32, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; let segment_ty = self.element_type_at(segment)?; if !self .resources @@ -3640,8 +3678,8 @@ where Ok(()) } fn visit_table_copy(&mut self, dst_table: u32, src_table: u32) -> Self::Output { - let src = self.check_table_index(src_table)?; - let dst = self.check_table_index(dst_table)?; + let src = self.table_type_at(src_table)?; + let dst = self.table_type_at(dst_table)?; if !self.resources.is_subtype( ValType::Ref(src.element_type), ValType::Ref(dst.element_type), @@ -3663,21 +3701,51 @@ where Ok(()) } fn visit_table_get(&mut self, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; debug_assert_type_indices_are_ids(table.element_type.into()); self.pop_operand(Some(table.index_type()))?; self.push_operand(table.element_type)?; Ok(()) } + fn visit_table_atomic_get(&mut self, _ordering: Ordering, table: u32) -> Self::Output { + self.visit_table_get(table)?; + // No validation of `ordering` is needed because `table.atomic.get` can + // be used on both shared and unshared tables. But we do need to limit + // which types can be used with this instruction. + let ty = self.table_type_at(table)?.element_type; + let supertype = RefType::ANYREF.shared().unwrap(); + if !self.resources.is_subtype(ty.into(), supertype.into()) { + bail!( + self.offset, + "invalid type: `table.atomic.get` only allows subtypes of `anyref`" + ); + } + Ok(()) + } fn visit_table_set(&mut self, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; debug_assert_type_indices_are_ids(table.element_type.into()); self.pop_operand(Some(table.element_type.into()))?; self.pop_operand(Some(table.index_type()))?; Ok(()) } + fn visit_table_atomic_set(&mut self, _ordering: Ordering, table: u32) -> Self::Output { + self.visit_table_set(table)?; + // No validation of `ordering` is needed because `table.atomic.set` can + // be used on both shared and unshared tables. But we do need to limit + // which types can be used with this instruction. + let ty = self.table_type_at(table)?.element_type; + let supertype = RefType::ANYREF.shared().unwrap(); + if !self.resources.is_subtype(ty.into(), supertype.into()) { + bail!( + self.offset, + "invalid type: `table.atomic.set` only allows subtypes of `anyref`" + ); + } + Ok(()) + } fn visit_table_grow(&mut self, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; debug_assert_type_indices_are_ids(table.element_type.into()); self.pop_operand(Some(table.index_type()))?; self.pop_operand(Some(table.element_type.into()))?; @@ -3685,18 +3753,51 @@ where Ok(()) } fn visit_table_size(&mut self, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; self.push_operand(table.index_type())?; Ok(()) } fn visit_table_fill(&mut self, table: u32) -> Self::Output { - let table = self.check_table_index(table)?; + let table = self.table_type_at(table)?; debug_assert_type_indices_are_ids(table.element_type.into()); self.pop_operand(Some(table.index_type()))?; self.pop_operand(Some(table.element_type.into()))?; self.pop_operand(Some(table.index_type()))?; Ok(()) } + fn visit_table_atomic_rmw_xchg(&mut self, _ordering: Ordering, table: u32) -> Self::Output { + let table = self.table_type_at(table)?; + let elem_ty = table.element_type.into(); + debug_assert_type_indices_are_ids(elem_ty); + let supertype = RefType::ANYREF.shared().unwrap(); + if !self.resources.is_subtype(elem_ty, supertype.into()) { + bail!( + self.offset, + "invalid type: `table.atomic.rmw.xchg` only allows subtypes of `anyref`" + ); + } + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(table.index_type()))?; + self.push_operand(elem_ty)?; + Ok(()) + } + fn visit_table_atomic_rmw_cmpxchg(&mut self, _ordering: Ordering, table: u32) -> Self::Output { + let table = self.table_type_at(table)?; + let elem_ty = table.element_type.into(); + debug_assert_type_indices_are_ids(elem_ty); + let supertype = RefType::EQREF.shared().unwrap(); + if !self.resources.is_subtype(elem_ty, supertype.into()) { + bail!( + self.offset, + "invalid type: `table.atomic.rmw.cmpxchg` only allows subtypes of `eqref`" + ); + } + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(table.index_type()))?; + self.push_operand(elem_ty)?; + Ok(()) + } fn visit_struct_new(&mut self, struct_type_index: u32) -> Self::Output { let struct_ty = self.struct_type_at(struct_type_index)?; for ty in struct_ty.fields.iter().rev() { @@ -3730,6 +3831,32 @@ where self.pop_concrete_ref(true, struct_type_index)?; self.push_operand(field_ty.element_type.unpack()) } + fn visit_struct_atomic_get( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.visit_struct_get(struct_type_index, field_index)?; + // The `atomic` version has some additional type restrictions. + let ty = self + .struct_field_at(struct_type_index, field_index)? + .element_type; + let is_valid_type = match ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `struct.atomic.get` only allows `i32`, `i64` and subtypes of `anyref`" + ); + } + Ok(()) + } fn visit_struct_get_s(&mut self, struct_type_index: u32, field_index: u32) -> Self::Output { let field_ty = self.struct_field_at(struct_type_index, field_index)?; if !field_ty.element_type.is_packed() { @@ -3741,6 +3868,21 @@ where self.pop_concrete_ref(true, struct_type_index)?; self.push_operand(field_ty.element_type.unpack()) } + fn visit_struct_atomic_get_s( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.visit_struct_get_s(struct_type_index, field_index)?; + // This instruction has the same type restrictions as the non-`atomic` version. + debug_assert!(matches!( + self.struct_field_at(struct_type_index, field_index)? + .element_type, + StorageType::I8 | StorageType::I16 + )); + Ok(()) + } fn visit_struct_get_u(&mut self, struct_type_index: u32, field_index: u32) -> Self::Output { let field_ty = self.struct_field_at(struct_type_index, field_index)?; if !field_ty.element_type.is_packed() { @@ -3752,6 +3894,21 @@ where self.pop_concrete_ref(true, struct_type_index)?; self.push_operand(field_ty.element_type.unpack()) } + fn visit_struct_atomic_get_u( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.visit_struct_get_s(struct_type_index, field_index)?; + // This instruction has the same type restrictions as the non-`atomic` version. + debug_assert!(matches!( + self.struct_field_at(struct_type_index, field_index)? + .element_type, + StorageType::I8 | StorageType::I16 + )); + Ok(()) + } fn visit_struct_set(&mut self, struct_type_index: u32, field_index: u32) -> Self::Output { let field_ty = self.struct_field_at(struct_type_index, field_index)?; if !field_ty.mutable { @@ -3761,6 +3918,129 @@ where self.pop_concrete_ref(true, struct_type_index)?; Ok(()) } + fn visit_struct_atomic_set( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.visit_struct_set(struct_type_index, field_index)?; + // The `atomic` version has some additional type restrictions. + let ty = self + .struct_field_at(struct_type_index, field_index)? + .element_type; + let is_valid_type = match ty { + StorageType::I8 | StorageType::I16 => true, + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `struct.atomic.set` only allows `i8`, `i16`, `i32`, `i64` and subtypes of `anyref`" + ); + } + Ok(()) + } + fn visit_struct_atomic_rmw_add( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.check_struct_atomic_rmw("add", struct_type_index, field_index) + } + fn visit_struct_atomic_rmw_sub( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.check_struct_atomic_rmw("sub", struct_type_index, field_index) + } + fn visit_struct_atomic_rmw_and( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.check_struct_atomic_rmw("and", struct_type_index, field_index) + } + fn visit_struct_atomic_rmw_or( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.check_struct_atomic_rmw("or", struct_type_index, field_index) + } + fn visit_struct_atomic_rmw_xor( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + self.check_struct_atomic_rmw("xor", struct_type_index, field_index) + } + fn visit_struct_atomic_rmw_xchg( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + let field_ty = self + .struct_field_at(struct_type_index, field_index)? + .element_type; + let is_valid_type = match field_ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `struct.atomic.rmw.xchg` only allows `i32`, `i64` and subtypes of `anyref`" + ); + } + let field_ty = field_ty.unpack(); + self.pop_operand(Some(field_ty))?; + self.pop_concrete_ref(true, struct_type_index)?; + self.push_operand(field_ty)?; + Ok(()) + } + fn visit_struct_atomic_rmw_cmpxchg( + &mut self, + _ordering: Ordering, + struct_type_index: u32, + field_index: u32, + ) -> Self::Output { + let field_ty = self + .struct_field_at(struct_type_index, field_index)? + .element_type; + let is_valid_type = match field_ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::EQREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `struct.atomic.rmw.cmpxchg` only allows `i32`, `i64` and subtypes of `eqref`" + ); + } + let field_ty = field_ty.unpack(); + self.pop_operand(Some(field_ty))?; + self.pop_operand(Some(field_ty))?; + self.pop_concrete_ref(true, struct_type_index)?; + self.push_operand(field_ty)?; + Ok(()) + } fn visit_array_new(&mut self, type_index: u32) -> Self::Output { let array_ty = self.array_type_at(type_index)?; self.pop_operand(Some(ValType::I32))?; @@ -3843,6 +4123,25 @@ where self.pop_concrete_ref(true, type_index)?; self.push_operand(elem_ty.unpack()) } + fn visit_array_atomic_get(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.visit_array_get(type_index)?; + // The `atomic` version has some additional type restrictions. + let elem_ty = self.array_type_at(type_index)?.0.element_type; + let is_valid_type = match elem_ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `array.atomic.get` only allows `i32`, `i64` and subtypes of `anyref`" + ); + } + Ok(()) + } fn visit_array_get_s(&mut self, type_index: u32) -> Self::Output { let array_ty = self.array_type_at(type_index)?; let elem_ty = array_ty.0.element_type; @@ -3856,6 +4155,15 @@ where self.pop_concrete_ref(true, type_index)?; self.push_operand(elem_ty.unpack()) } + fn visit_array_atomic_get_s(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.visit_array_get_s(type_index)?; + // This instruction has the same type restrictions as the non-`atomic` version. + debug_assert!(matches!( + self.array_type_at(type_index)?.0.element_type, + StorageType::I8 | StorageType::I16 + )); + Ok(()) + } fn visit_array_get_u(&mut self, type_index: u32) -> Self::Output { let array_ty = self.array_type_at(type_index)?; let elem_ty = array_ty.0.element_type; @@ -3869,6 +4177,15 @@ where self.pop_concrete_ref(true, type_index)?; self.push_operand(elem_ty.unpack()) } + fn visit_array_atomic_get_u(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.visit_array_get_u(type_index)?; + // This instruction has the same type restrictions as the non-`atomic` version. + debug_assert!(matches!( + self.array_type_at(type_index)?.0.element_type, + StorageType::I8 | StorageType::I16 + )); + Ok(()) + } fn visit_array_set(&mut self, type_index: u32) -> Self::Output { let array_ty = self.array_type_at(type_index)?; if !array_ty.0.mutable { @@ -3879,6 +4196,25 @@ where self.pop_concrete_ref(true, type_index)?; Ok(()) } + fn visit_array_atomic_set(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.visit_array_set(type_index)?; + // The `atomic` version has some additional type restrictions. + let elem_ty = self.array_type_at(type_index)?.0.element_type; + let is_valid_type = match elem_ty { + StorageType::I8 | StorageType::I16 => true, + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `array.atomic.set` only allows `i8`, `i16`, `i32`, `i64` and subtypes of `anyref`" + ); + } + Ok(()) + } fn visit_array_len(&mut self) -> Self::Output { self.pop_operand(Some(RefType::ARRAY.nullable().into()))?; self.push_operand(ValType::I32) @@ -3993,6 +4329,74 @@ where self.pop_concrete_ref(true, type_index)?; Ok(()) } + fn visit_array_atomic_rmw_add(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.check_array_atomic_rmw("add", type_index) + } + fn visit_array_atomic_rmw_sub(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.check_array_atomic_rmw("sub", type_index) + } + fn visit_array_atomic_rmw_and(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.check_array_atomic_rmw("and", type_index) + } + fn visit_array_atomic_rmw_or(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.check_array_atomic_rmw("or", type_index) + } + fn visit_array_atomic_rmw_xor(&mut self, _ordering: Ordering, type_index: u32) -> Self::Output { + self.check_array_atomic_rmw("xor", type_index) + } + fn visit_array_atomic_rmw_xchg( + &mut self, + _ordering: Ordering, + type_index: u32, + ) -> Self::Output { + let elem_ty = self.array_type_at(type_index)?.0.element_type; + let is_valid_type = match elem_ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::ANYREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `array.atomic.rmw.xchg` only allows `i32`, `i64` and subtypes of `anyref`" + ); + } + let elem_ty = elem_ty.unpack(); + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(ValType::I32))?; + self.pop_concrete_ref(true, type_index)?; + self.push_operand(elem_ty)?; + Ok(()) + } + fn visit_array_atomic_rmw_cmpxchg( + &mut self, + _ordering: Ordering, + type_index: u32, + ) -> Self::Output { + let elem_ty = self.array_type_at(type_index)?.0.element_type; + let is_valid_type = match elem_ty { + StorageType::Val(ValType::I32) | StorageType::Val(ValType::I64) => true, + StorageType::Val(v) => self + .resources + .is_subtype(v, RefType::EQREF.shared().unwrap().into()), + _ => false, + }; + if !is_valid_type { + bail!( + self.offset, + "invalid type: `array.atomic.rmw.cmpxchg` only allows `i32`, `i64` and subtypes of `eqref`" + ); + } + let elem_ty = elem_ty.unpack(); + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(elem_ty))?; + self.pop_operand(Some(ValType::I32))?; + self.pop_concrete_ref(true, type_index)?; + self.push_operand(elem_ty)?; + Ok(()) + } fn visit_any_convert_extern(&mut self) -> Self::Output { let extern_ref = self.pop_operand(Some(RefType::EXTERNREF.into()))?; let is_nullable = extern_ref @@ -4064,7 +4468,7 @@ where ), None => bail!( self.offset, - "type mismtach: br_on_cast to label with empty types, must have a reference type" + "type mismatch: br_on_cast to label with empty types, must have a reference type" ), }; @@ -4120,6 +4524,10 @@ where self.pop_operand(Some(ValType::I32))?; self.push_operand(ValType::Ref(RefType::I31)) } + fn visit_ref_i31_shared(&mut self) -> Self::Output { + self.pop_operand(Some(ValType::I32))?; + self.push_operand(ValType::Ref(RefType::I31)) // TODO: handle shared--is this correct? + } fn visit_i31_get_s(&mut self) -> Self::Output { self.pop_operand(Some(ValType::Ref(RefType::I31REF)))?; self.push_operand(ValType::I32) diff --git a/crates/wasmprinter/src/operator.rs b/crates/wasmprinter/src/operator.rs index fa7e2ca456..558bdc863f 100644 --- a/crates/wasmprinter/src/operator.rs +++ b/crates/wasmprinter/src/operator.rs @@ -595,6 +595,78 @@ macro_rules! define_visit { $self.push_str(" ")?; $self.printer.print_field_idx($self.state, $ty, $field)?; ); + (payload $self:ident StructAtomicGet $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicGetS $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicGetU $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicSet $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicSet $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwAdd $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwSub $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwAnd $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwOr $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwXor $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwXchg $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); + (payload $self:ident StructAtomicRmwCmpxchg $order:ident $ty:ident $field:ident) => ( + $self.ordering($order)?; + $self.struct_type_index($ty)?; + $self.push_str(" ")?; + $self.printer.print_field_idx($self.state, $ty, $field)?; + ); (payload $self:ident $op:ident $($arg:ident)*) => ( $($self.$arg($arg)?;)* ); @@ -1180,6 +1252,33 @@ macro_rules! define_visit { (name GlobalAtomicRmwXor) => ("global.atomic.rmw.xor"); (name GlobalAtomicRmwXchg) => ("global.atomic.rmw.xchg"); (name GlobalAtomicRmwCmpxchg) => ("global.atomic.rmw.cmpxchg"); + (name TableAtomicGet) => ("table.atomic.get"); + (name TableAtomicSet) => ("table.atomic.set"); + (name TableAtomicRmwXchg) => ("table.atomic.rmw.xchg"); + (name TableAtomicRmwCmpxchg) => ("table.atomic.rmw.cmpxchg"); + (name StructAtomicGet) => ("struct.atomic.get"); + (name StructAtomicGetS) => ("struct.atomic.get_s"); + (name StructAtomicGetU) => ("struct.atomic.get_u"); + (name StructAtomicSet) => ("struct.atomic.set"); + (name StructAtomicRmwAdd) => ("struct.atomic.rmw.add"); + (name StructAtomicRmwSub) => ("struct.atomic.rmw.sub"); + (name StructAtomicRmwAnd) => ("struct.atomic.rmw.and"); + (name StructAtomicRmwOr) => ("struct.atomic.rmw.or"); + (name StructAtomicRmwXor) => ("struct.atomic.rmw.xor"); + (name StructAtomicRmwXchg) => ("struct.atomic.rmw.xchg"); + (name StructAtomicRmwCmpxchg) => ("struct.atomic.rmw.cmpxchg"); + (name ArrayAtomicGet) => ("array.atomic.get"); + (name ArrayAtomicGetS) => ("array.atomic.get_s"); + (name ArrayAtomicGetU) => ("array.atomic.get_u"); + (name ArrayAtomicSet) => ("array.atomic.set"); + (name ArrayAtomicRmwAdd) => ("array.atomic.rmw.add"); + (name ArrayAtomicRmwSub) => ("array.atomic.rmw.sub"); + (name ArrayAtomicRmwAnd) => ("array.atomic.rmw.and"); + (name ArrayAtomicRmwOr) => ("array.atomic.rmw.or"); + (name ArrayAtomicRmwXor) => ("array.atomic.rmw.xor"); + (name ArrayAtomicRmwXchg) => ("array.atomic.rmw.xchg"); + (name ArrayAtomicRmwCmpxchg) => ("array.atomic.rmw.cmpxchg"); + (name RefI31Shared) => ("ref.i31_shared") } impl<'a> VisitOperator<'a> for PrintOperator<'_, '_, '_, '_> { diff --git a/crates/wast/src/core/binary.rs b/crates/wast/src/core/binary.rs index 47fd4b0dd0..5007c4255d 100644 --- a/crates/wast/src/core/binary.rs +++ b/crates/wast/src/core/binary.rs @@ -928,10 +928,13 @@ impl Encode for Ordering { } } -impl Encode for OrderedAccess<'_> { +impl Encode for Ordered +where + T: Encode, +{ fn encode(&self, buf: &mut Vec) { self.ordering.encode(buf); - self.index.encode(buf); + self.inner.encode(buf); } } diff --git a/crates/wast/src/core/expr.rs b/crates/wast/src/core/expr.rs index 9104a8ea7f..c45203106b 100644 --- a/crates/wast/src/core/expr.rs +++ b/crates/wast/src/core/expr.rs @@ -859,15 +859,42 @@ instructions! { I64AtomicRmw32CmpxchgU(MemArg<4>) : [0xfe, 0x4e] : "i64.atomic.rmw32.cmpxchg_u", // proposal: shared-everything-threads - GlobalAtomicGet(OrderedAccess<'a>) : [0xfe, 0x4f] : "global.atomic.get", - GlobalAtomicSet(OrderedAccess<'a>) : [0xfe, 0x50] : "global.atomic.set", - GlobalAtomicRmwAdd(OrderedAccess<'a>) : [0xfe, 0x51] : "global.atomic.rmw.add", - GlobalAtomicRmwSub(OrderedAccess<'a>) : [0xfe, 0x52] : "global.atomic.rmw.sub", - GlobalAtomicRmwAnd(OrderedAccess<'a>) : [0xfe, 0x53] : "global.atomic.rmw.and", - GlobalAtomicRmwOr(OrderedAccess<'a>) : [0xfe, 0x54] : "global.atomic.rmw.or", - GlobalAtomicRmwXor(OrderedAccess<'a>) : [0xfe, 0x55] : "global.atomic.rmw.xor", - GlobalAtomicRmwXchg(OrderedAccess<'a>) : [0xfe, 0x56] : "global.atomic.rmw.xchg", - GlobalAtomicRmwCmpxchg(OrderedAccess<'a>) : [0xfe, 0x57] : "global.atomic.rmw.cmpxchg", + GlobalAtomicGet(Ordered>) : [0xfe, 0x4f] : "global.atomic.get", + GlobalAtomicSet(Ordered>) : [0xfe, 0x50] : "global.atomic.set", + GlobalAtomicRmwAdd(Ordered>) : [0xfe, 0x51] : "global.atomic.rmw.add", + GlobalAtomicRmwSub(Ordered>) : [0xfe, 0x52] : "global.atomic.rmw.sub", + GlobalAtomicRmwAnd(Ordered>) : [0xfe, 0x53] : "global.atomic.rmw.and", + GlobalAtomicRmwOr(Ordered>) : [0xfe, 0x54] : "global.atomic.rmw.or", + GlobalAtomicRmwXor(Ordered>) : [0xfe, 0x55] : "global.atomic.rmw.xor", + GlobalAtomicRmwXchg(Ordered>) : [0xfe, 0x56] : "global.atomic.rmw.xchg", + GlobalAtomicRmwCmpxchg(Ordered>) : [0xfe, 0x57] : "global.atomic.rmw.cmpxchg", + TableAtomicGet(Ordered>) : [0xfe, 0x58] : "table.atomic.get", + TableAtomicSet(Ordered>) : [0xfe, 0x59] : "table.atomic.set", + TableAtomicRmwXchg(Ordered>) : [0xfe, 0x5A] : "table.atomic.rmw.xchg", + TableAtomicRmwCmpxchg(Ordered>) : [0xFE, 0x5B] : "table.atomic.rmw.cmpxchg", + StructAtomicGet(Ordered>) : [0xFE, 0x5C] : "struct.atomic.get", + StructAtomicGetS(Ordered>) : [0xFE, 0x5D] : "struct.atomic.get_s", + StructAtomicGetU(Ordered>) : [0xFE, 0x5E] : "struct.atomic.get_u", + StructAtomicSet(Ordered>) : [0xFE, 0x5F] : "struct.atomic.set", + StructAtomicRmwAdd(Ordered>) : [0xFE, 0x60] : "struct.atomic.rmw.add", + StructAtomicRmwSub(Ordered>) : [0xFE, 0x61] : "struct.atomic.rmw.sub", + StructAtomicRmwAnd(Ordered>) : [0xFE, 0x62] : "struct.atomic.rmw.and", + StructAtomicRmwOr(Ordered>) : [0xFE, 0x63] : "struct.atomic.rmw.or", + StructAtomicRmwXor(Ordered>) : [0xFE, 0x64] : "struct.atomic.rmw.xor", + StructAtomicRmwXchg(Ordered>) : [0xFE, 0x65] : "struct.atomic.rmw.xchg", + StructAtomicRmwCmpxchg(Ordered>) : [0xFE, 0x66] : "struct.atomic.rmw.cmpxchg", + ArrayAtomicGet(Ordered>) : [0xFE, 0x67] : "array.atomic.get", + ArrayAtomicGetS(Ordered>) : [0xFE, 0x68] : "array.atomic.get_s", + ArrayAtomicGetU(Ordered>) : [0xFE, 0x69] : "array.atomic.get_u", + ArrayAtomicSet(Ordered>) : [0xFE, 0x6A] : "array.atomic.set", + ArrayAtomicRmwAdd(Ordered>) : [0xFE, 0x6B] : "array.atomic.rmw.add", + ArrayAtomicRmwSub(Ordered>) : [0xFE, 0x6C] : "array.atomic.rmw.sub", + ArrayAtomicRmwAnd(Ordered>) : [0xFE, 0x6D] : "array.atomic.rmw.and", + ArrayAtomicRmwOr(Ordered>) : [0xFE, 0x6E] : "array.atomic.rmw.or", + ArrayAtomicRmwXor(Ordered>) : [0xFE, 0x6F] : "array.atomic.rmw.xor", + ArrayAtomicRmwXchg(Ordered>) : [0xFE, 0x70] : "array.atomic.rmw.xchg", + ArrayAtomicRmwCmpxchg(Ordered>) : [0xFE, 0x71] : "array.atomic.rmw.cmpxchg", + RefI31Shared : [0xFE, 0x72] : "ref.i31_shared", // proposal: simd // @@ -1531,6 +1558,8 @@ pub struct TableArg<'a> { pub dst: Index<'a>, } +// `TableArg` could be an unwrapped as an `Index` if not for this custom parse +// behavior: if we cannot parse a table index, we default to table `0`. impl<'a> Parse<'a> for TableArg<'a> { fn parse(parser: Parser<'a>) -> Result { let dst = if let Some(dst) = parser.parse()? { @@ -1831,20 +1860,27 @@ impl<'a> Parse<'a> for Ordering { } } -/// Extra data associated with the `global.atomic.*` instructions. +/// Add a memory [`Ordering`] to the argument `T` of some instruction. +/// +/// This is helpful for many kinds of `*.atomic.*` instructions introduced by +/// the shared-everything-threads proposal. Many of these instructions "build +/// on" existing instructions by simply adding a memory order to them. #[derive(Clone, Debug)] -pub struct OrderedAccess<'a> { +pub struct Ordered { /// The memory ordering for this atomic instruction. pub ordering: Ordering, - /// The index of the global to access. - pub index: Index<'a>, + /// The original argument type. + pub inner: T, } -impl<'a> Parse<'a> for OrderedAccess<'a> { +impl<'a, T> Parse<'a> for Ordered +where + T: Parse<'a>, +{ fn parse(parser: Parser<'a>) -> Result { let ordering = parser.parse()?; - let index = parser.parse()?; - Ok(OrderedAccess { ordering, index }) + let inner = parser.parse()?; + Ok(Ordered { ordering, inner }) } } diff --git a/crates/wast/src/core/resolve/names.rs b/crates/wast/src/core/resolve/names.rs index d2b7eb1db4..c0c5e5b586 100644 --- a/crates/wast/src/core/resolve/names.rs +++ b/crates/wast/src/core/resolve/names.rs @@ -453,6 +453,13 @@ impl<'a, 'b> ExprResolver<'a, 'b> { self.resolver.resolve(&mut i.dst, Ns::Table)?; } + TableAtomicGet(i) + | TableAtomicSet(i) + | TableAtomicRmwXchg(i) + | TableAtomicRmwCmpxchg(i) => { + self.resolver.resolve(&mut i.inner.dst, Ns::Table)?; + } + GlobalSet(i) | GlobalGet(i) => { self.resolver.resolve(i, Ns::Global)?; } @@ -466,7 +473,7 @@ impl<'a, 'b> ExprResolver<'a, 'b> { | GlobalAtomicRmwXor(i) | GlobalAtomicRmwXchg(i) | GlobalAtomicRmwCmpxchg(i) => { - self.resolver.resolve(&mut i.index, Ns::Global)?; + self.resolver.resolve(&mut i.inner, Ns::Global)?; } LocalSet(i) | LocalGet(i) | LocalTee(i) => { @@ -614,14 +621,21 @@ impl<'a, 'b> ExprResolver<'a, 'b> { } StructSet(s) | StructGet(s) | StructGetS(s) | StructGetU(s) => { - let type_index = self.resolver.resolve(&mut s.r#struct, Ns::Type)?; - if let Index::Id(field_id) = s.field { - self.resolver - .fields - .get(&type_index) - .ok_or(Error::new(field_id.span(), format!("accessing a named field `{}` in a struct without named fields, type index {}", field_id.name(), type_index)))? - .resolve(&mut s.field, "field")?; - } + self.resolve_field(s)?; + } + + StructAtomicGet(s) + | StructAtomicGetS(s) + | StructAtomicGetU(s) + | StructAtomicSet(s) + | StructAtomicRmwAdd(s) + | StructAtomicRmwSub(s) + | StructAtomicRmwAnd(s) + | StructAtomicRmwOr(s) + | StructAtomicRmwXor(s) + | StructAtomicRmwXchg(s) + | StructAtomicRmwCmpxchg(s) => { + self.resolve_field(&mut s.inner)?; } ArrayNewFixed(a) => { @@ -651,6 +665,20 @@ impl<'a, 'b> ExprResolver<'a, 'b> { self.resolver.elems.resolve(&mut a.segment, "elem")?; } + ArrayAtomicGet(i) + | ArrayAtomicGetS(i) + | ArrayAtomicGetU(i) + | ArrayAtomicSet(i) + | ArrayAtomicRmwAdd(i) + | ArrayAtomicRmwSub(i) + | ArrayAtomicRmwAnd(i) + | ArrayAtomicRmwOr(i) + | ArrayAtomicRmwXor(i) + | ArrayAtomicRmwXchg(i) + | ArrayAtomicRmwCmpxchg(i) => { + self.resolver.resolve(&mut i.inner, Ns::Type)?; + } + RefNull(ty) => self.resolver.resolve_heaptype(ty)?, _ => {} @@ -678,6 +706,18 @@ impl<'a, 'b> ExprResolver<'a, 'b> { None => Err(resolve_error(id, "label")), } } + + fn resolve_field(&self, s: &mut StructAccess<'a>) -> Result<(), Error> { + let type_index = self.resolver.resolve(&mut s.r#struct, Ns::Type)?; + if let Index::Id(field_id) = s.field { + self.resolver + .fields + .get(&type_index) + .ok_or(Error::new(field_id.span(), format!("accessing a named field `{}` in a struct without named fields, type index {}", field_id.name(), type_index)))? + .resolve(&mut s.field, "field")?; + } + Ok(()) + } } enum TypeInfo<'a> { diff --git a/tests/local/shared-everything-threads/array.wast b/tests/local/shared-everything-threads/array.wast index e3fb3adbad..064fcecf80 100644 --- a/tests/local/shared-everything-threads/array.wast +++ b/tests/local/shared-everything-threads/array.wast @@ -1,4 +1,4 @@ -;; Shared array declaration syntax +;; Shared array declaration syntax. (module (type (shared (array i8))) (type (sub final (shared (array i8)))) @@ -11,7 +11,7 @@ (global (ref 2) (array.new_default 0 (i32.const 1))) ) -;; Shared arrays are distinct from non-shared arrays +;; Shared arrays are distinct from non-shared arrays. (assert_invalid (module (type (shared (array i8))) @@ -32,7 +32,7 @@ "type mismatch" ) -;; Shared arrays may not be subtypes of non-shared arrays +;; Shared arrays may not be subtypes of non-shared arrays. (assert_invalid (module (type (sub (array i8))) @@ -41,7 +41,7 @@ "sub type must match super type" ) -;; Non-shared arrays may not be subtypes of shared arrays +;; Non-shared arrays may not be subtypes of shared arrays. (assert_invalid (module (type (sub (shared (array i8)))) @@ -50,7 +50,7 @@ "sub type must match super type" ) -;; Shared arrays may not contain non-shared references +;; Shared arrays may not contain non-shared references. (assert_invalid (module (type (shared (array anyref))) @@ -58,12 +58,12 @@ "must contain shared type" ) -;; But they may contain shared references +;; But they may contain shared references. (module (type (shared (array (ref null (shared any))))) ) -;; Non-shared arrays may contain shared references +;; Non-shared arrays may contain shared references. (module (type (array (ref null (shared any)))) ) @@ -113,3 +113,641 @@ (func (param (ref null $i8)) (array.init_data $i8 0 (local.get 0) (i32.const 0) (i32.const 0) (i32.const 0))) ) + +;; Check `array.atomic.rmw.*` instructions. +(module (; get, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-get-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get seq_cst $a) +) + +(module (; get, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-get-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (result i64) + local.get $x + local.get $y + array.atomic.get seq_cst $a) +) + +(module (; get, anyref, seq_cst ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-get-anyref-seq_cst") (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get seq_cst $a) +) + +(module (; get, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-get-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get acq_rel $a) +) + +(module (; get, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-get-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (result i64) + local.get $x + local.get $y + array.atomic.get acq_rel $a) +) + +(module (; get, anyref, acq_rel ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-get-anyref-acq_rel") (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get acq_rel $a) +) + +(module (; get_s, i8, seq_cst ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-get_s-i8-seq_cst") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a) +) + +(module (; get_s, i16, seq_cst ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-get_s-i16-seq_cst") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a) +) + +(module (; get_s, i8, acq_rel ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-get_s-i8-acq_rel") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s acq_rel $a) +) + +(module (; get_s, i16, acq_rel ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-get_s-i16-acq_rel") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s acq_rel $a) +) + +(module (; get_u, i8, seq_cst ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-get_u-i8-seq_cst") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a) +) + +(module (; get_u, i16, seq_cst ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-get_u-i16-seq_cst") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a) +) + +(module (; get_u, i8, acq_rel ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-get_u-i8-acq_rel") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u acq_rel $a) +) + +(module (; get_u, i16, acq_rel ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-get_u-i16-acq_rel") (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u acq_rel $a) +) + +(module (; set, i8, seq_cst ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-set-i8-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a) +) + +(module (; set, i16, seq_cst ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-set-i16-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a) +) + +(module (; set, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-set-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a) +) + +(module (; set, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-set-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a) +) + +(module (; set, anyref, seq_cst ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-set-anyref-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a) +) + +(module (; set, i8, acq_rel ;) + (type $a (shared (array (mut i8)))) + (func (export "array-atomic-set-i8-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a) +) + +(module (; set, i16, acq_rel ;) + (type $a (shared (array (mut i16)))) + (func (export "array-atomic-set-i16-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a) +) + +(module (; set, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-set-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a) +) + +(module (; set, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-set-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a) +) + +(module (; set, anyref, acq_rel ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-set-anyref-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a) +) + +(module (; rmw.add, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.add-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add seq_cst $a) +) + +(module (; rmw.add, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.add-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add seq_cst $a) +) + +(module (; rmw.add, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.add-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add acq_rel $a) +) + +(module (; rmw.add, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.add-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add acq_rel $a) +) + +(module (; rmw.sub, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.sub-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub seq_cst $a) +) + +(module (; rmw.sub, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.sub-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub seq_cst $a) +) + +(module (; rmw.sub, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.sub-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub acq_rel $a) +) + +(module (; rmw.sub, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.sub-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub acq_rel $a) +) + +(module (; rmw.and, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.and-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and seq_cst $a) +) + +(module (; rmw.and, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.and-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and seq_cst $a) +) + +(module (; rmw.and, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.and-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and acq_rel $a) +) + +(module (; rmw.and, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.and-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and acq_rel $a) +) + +(module (; rmw.or, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.or-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or seq_cst $a) +) + +(module (; rmw.or, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.or-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or seq_cst $a) +) + +(module (; rmw.or, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.or-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or acq_rel $a) +) + +(module (; rmw.or, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.or-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or acq_rel $a) +) + +(module (; rmw.xor, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.xor-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor seq_cst $a) +) + +(module (; rmw.xor, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.xor-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor seq_cst $a) +) + +(module (; rmw.xor, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.xor-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor acq_rel $a) +) + +(module (; rmw.xor, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.xor-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor acq_rel $a) +) + +(module (; rmw.xchg, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.xchg-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a) +) + +(module (; rmw.xchg, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.xchg-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a) +) + +(module (; rmw.xchg, anyref, seq_cst ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-rmw.xchg-anyref-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a) +) + +(module (; rmw.xchg, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.xchg-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a) +) + +(module (; rmw.xchg, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.xchg-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a) +) + +(module (; rmw.xchg, anyref, acq_rel ;) + (type $a (shared (array (mut (ref null (shared any)))))) + (func (export "array-atomic-rmw.xchg-anyref-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a) +) + +(module (; rmw.cmpxchg, i32, seq_cst ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.cmpxchg-i32-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i32) (param $A i32) (result i32) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a) +) + +(module (; rmw.cmpxchg, i64, seq_cst ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.cmpxchg-i64-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z i64) (param $A i64) (result i64) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a) +) + +(module (; rmw.cmpxchg, eqref, seq_cst ;) + (type $a (shared (array (mut (ref null (shared eq)))))) + (func (export "array-atomic-rmw.cmpxchg-eqref-seq_cst") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared eq))) (param $A (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a) +) + +(module (; rmw.cmpxchg, i32, acq_rel ;) + (type $a (shared (array (mut i32)))) + (func (export "array-atomic-rmw.cmpxchg-i32-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i32) (param $A i32) (result i32) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a) +) + +(module (; rmw.cmpxchg, i64, acq_rel ;) + (type $a (shared (array (mut i64)))) + (func (export "array-atomic-rmw.cmpxchg-i64-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z i64) (param $A i64) (result i64) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a) +) + +(module (; rmw.cmpxchg, eqref, acq_rel ;) + (type $a (shared (array (mut (ref null (shared eq)))))) + (func (export "array-atomic-rmw.cmpxchg-eqref-acq_rel") (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared eq))) (param $A (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a) +) + +(assert_invalid (; get, i8 ;) + (module + (type $a (shared (array (mut i8)))) + (func (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get seq_cst $a) + ) + "packed storage type" +) +(assert_invalid (; get_s, i32 ;) + (module + (type $a (shared (array (mut i32)))) + (func (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a) + ) + "non-packed storage type" +) +(assert_invalid (; get_s, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a) + ) + "non-packed storage type" +) +(assert_invalid (; get_u, i32 ;) + (module + (type $a (shared (array (mut i32)))) + (func (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a) + ) + "non-packed storage type" +) +(assert_invalid (; get_u, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a) + ) + "non-packed storage type" +) +(assert_invalid (; rmw.add, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.sub, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.and, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.or, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.xor, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.xchg, i8 ;) + (module + (type $a (shared (array (mut i8)))) + (func (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.cmpxchg, i8 ;) + (module + (type $a (shared (array (mut i8)))) + (func (param $x (ref null $a)) (param $y i32) (param $z i32) (param $A i32) (result i32) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a) + ) + "invalid type" +) +(assert_invalid (; rmw.cmpxchg, anyref ;) + (module + (type $a (shared (array (mut (ref null (shared any)))))) + (func (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (param $A (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a) + ) + "invalid type" +) diff --git a/tests/local/shared-everything-threads/struct.wast b/tests/local/shared-everything-threads/struct.wast index 91b1cec268..cd6664631a 100644 --- a/tests/local/shared-everything-threads/struct.wast +++ b/tests/local/shared-everything-threads/struct.wast @@ -1,4 +1,4 @@ -;; Shared struct declaration syntax +;; Shared struct declaration syntax. (module (type (shared (struct))) (type (sub final (shared (struct)))) @@ -11,7 +11,7 @@ (global (ref 2) (struct.new 0)) ) -;; Shared structs are distinct from non-shared structs +;; Shared structs are distinct from non-shared structs. (assert_invalid (module (type (shared (struct))) @@ -32,7 +32,7 @@ "type mismatch" ) -;; Shared structs may not be subtypes of non-shared structs +;; Shared structs may not be subtypes of non-shared structs. (assert_invalid (module (type (sub (struct))) @@ -41,7 +41,7 @@ "must match super type" ) -;; Non-shared structs may not be subtypes of shared structs +;; Non-shared structs may not be subtypes of shared structs. (assert_invalid (module (type (sub (shared (struct)))) @@ -50,7 +50,7 @@ "must match super type" ) -;; Shared structs may not contain non-shared references +;; Shared structs may not contain non-shared references. (assert_invalid (module (type (shared (struct (field anyref)))) @@ -58,12 +58,12 @@ "must contain shared type" ) -;; But they may contain shared references +;; But they may contain shared references. (module (type (shared (struct (field (ref null (shared any)))))) ) -;; Non-shared structs may contain shared references +;; Non-shared structs may contain shared references. (module (type (struct (field (ref null (shared any))))) ) @@ -90,3 +90,358 @@ (func (param (ref null $i8)) (struct.set $i8 0 (local.get 0) (i32.const 0))) ) + +;; Check struct.atomic.rmw.* instructions +(module + (type $s (shared (struct + (field $i8 (mut i8)) + (field $i16 (mut i16)) + (field $i32 (mut i32)) + (field $i64 (mut i64)) + (field $anyref (mut (ref null (shared any)))) + (field $eqref (mut (ref null (shared eq))))))) + (func (export "struct-atomic-get-i32-seq_cst") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get seq_cst $s $i32) + (func (export "struct-atomic-get-i64-seq_cst") (param $x (ref null $s)) (result i64) + local.get $x + struct.atomic.get seq_cst $s $i64) + (func (export "struct-atomic-get-anyref-seq_cst") (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get seq_cst $s $anyref) + (func (export "struct-atomic-get-i32-acq_rel") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get acq_rel $s $i32) + (func (export "struct-atomic-get-i64-acq_rel") (param $x (ref null $s)) (result i64) + local.get $x + struct.atomic.get acq_rel $s $i64) + (func (export "struct-atomic-get-anyref-acq_rel") (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get acq_rel $s $anyref) + (func (export "struct-atomic-get_s-i8-seq_cst") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s seq_cst $s $i8) + (func (export "struct-atomic-get_s-i16-seq_cst") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s seq_cst $s $i16) + (func (export "struct-atomic-get_s-i8-acq_rel") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s acq_rel $s $i8) + (func (export "struct-atomic-get_s-i16-acq_rel") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s acq_rel $s $i16) + (func (export "struct-atomic-get_u-i8-seq_cst") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u seq_cst $s $i8) + (func (export "struct-atomic-get_u-i16-seq_cst") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u seq_cst $s $i16) + (func (export "struct-atomic-get_u-i8-acq_rel") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u acq_rel $s $i8) + (func (export "struct-atomic-get_u-i16-acq_rel") (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u acq_rel $s $i16) + (func (export "struct-atomic-set-i8-seq_cst") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i8) + (func (export "struct-atomic-set-i16-seq_cst") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i16) + (func (export "struct-atomic-set-i32-seq_cst") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i32) + (func (export "struct-atomic-set-i64-seq_cst") (param $x (ref null $s)) (param $y i64) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i64) + (func (export "struct-atomic-set-anyref-seq_cst") (param $x (ref null $s)) (param $y (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $anyref) + (func (export "struct-atomic-set-i8-acq_rel") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i8) + (func (export "struct-atomic-set-i16-acq_rel") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i16) + (func (export "struct-atomic-set-i32-acq_rel") (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i32) + (func (export "struct-atomic-set-i64-acq_rel") (param $x (ref null $s)) (param $y i64) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i64) + (func (export "struct-atomic-set-anyref-acq_rel") (param $x (ref null $s)) (param $y (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $anyref) + (func (export "struct-atomic-rmw.add-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.add seq_cst $s $i32) + (func (export "struct-atomic-rmw.add-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.add seq_cst $s $i64) + (func (export "struct-atomic-rmw.add-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.add acq_rel $s $i32) + (func (export "struct-atomic-rmw.add-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.add acq_rel $s $i64) + (func (export "struct-atomic-rmw.sub-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.sub seq_cst $s $i32) + (func (export "struct-atomic-rmw.sub-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.sub seq_cst $s $i64) + (func (export "struct-atomic-rmw.sub-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.sub acq_rel $s $i32) + (func (export "struct-atomic-rmw.sub-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.sub acq_rel $s $i64) + (func (export "struct-atomic-rmw.and-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.and seq_cst $s $i32) + (func (export "struct-atomic-rmw.and-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.and seq_cst $s $i64) + (func (export "struct-atomic-rmw.and-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.and acq_rel $s $i32) + (func (export "struct-atomic-rmw.and-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.and acq_rel $s $i64) + (func (export "struct-atomic-rmw.or-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.or seq_cst $s $i32) + (func (export "struct-atomic-rmw.or-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.or seq_cst $s $i64) + (func (export "struct-atomic-rmw.or-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.or acq_rel $s $i32) + (func (export "struct-atomic-rmw.or-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.or acq_rel $s $i64) + (func (export "struct-atomic-rmw.xor-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xor seq_cst $s $i32) + (func (export "struct-atomic-rmw.xor-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xor seq_cst $s $i64) + (func (export "struct-atomic-rmw.xor-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xor acq_rel $s $i32) + (func (export "struct-atomic-rmw.xor-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xor acq_rel $s $i64) + (func (export "struct-atomic-rmw.xchg-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $i32) + (func (export "struct-atomic-rmw.xchg-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $i64) + (func (export "struct-atomic-rmw.xchg-anyref-seq_cst") (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $anyref) + (func (export "struct-atomic-rmw.xchg-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $i32) + (func (export "struct-atomic-rmw.xchg-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $i64) + (func (export "struct-atomic-rmw.xchg-anyref-acq_rel") (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $anyref) + (func (export "struct-atomic-rmw.cmpxchg-i32-seq_cst") (param $x (ref null $s)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $i32) + (func (export "struct-atomic-rmw.cmpxchg-i64-seq_cst") (param $x (ref null $s)) (param $y i64) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $i64) + (func (export "struct-atomic-rmw.cmpxchg-eqref-seq_cst") (param $x (ref null $s)) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $eqref) + (func (export "struct-atomic-rmw.cmpxchg-i32-acq_rel") (param $x (ref null $s)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $i32) + (func (export "struct-atomic-rmw.cmpxchg-i64-acq_rel") (param $x (ref null $s)) (param $y i64) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $i64) + (func (export "struct-atomic-rmw.cmpxchg-eqref-acq_rel") (param $x (ref null $s)) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $eqref) +) + +(assert_invalid (; get, i8 ;) + (module + (type $s (shared (struct (field $i8 (mut i8))))) + (func (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get seq_cst $s $i8) + ) + "non-packed storage type" +) +(assert_invalid (; get_s, i32 ;) + (module + (type $s (shared (struct (field $i32 (mut i32))))) + (func (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s seq_cst $s $i32) + ) + "non-packed storage types" +) +(assert_invalid (; get_s, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get_s seq_cst $s $anyref) + ) + "non-packed storage types" +) +(assert_invalid (; get_u, i32 ;) + (module + (type $s (shared (struct (field $i32 (mut i32))))) + (func (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u seq_cst $s $i32) + ) + "non-packed storage types" +) +(assert_invalid (; get_u, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get_u seq_cst $s $anyref) + ) + "non-packed storage types" +) +(assert_invalid (; rmw.add, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.add seq_cst $s $anyref) + ) + "invalid type" +) +(assert_invalid (; rmw.sub, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.sub seq_cst $s $anyref) + ) + "invalid type" +) +(assert_invalid (; rmw.and, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.and seq_cst $s $anyref) + ) + "invalid type" +) +(assert_invalid (; rmw.or, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.or seq_cst $s $anyref) + ) + "invalid type" +) +(assert_invalid (; rmw.xor, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.xor seq_cst $s $anyref) + ) + "invalid type" +) +(assert_invalid (; rmw.xchg, i8 ;) + (module + (type $s (shared (struct (field $i8 (mut i8))))) + (func (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $i8) + ) + "invalid type" +) +(assert_invalid (; rmw.cmpxchg, i8 ;) + (module + (type $s (shared (struct (field $i8 (mut i8))))) + (func (param $x (ref null $s)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $i8) + ) + "invalid type" +) +(assert_invalid (; rmw.cmpxchg, anyref ;) + (module + (type $s (shared (struct (field $anyref (mut (ref null (shared any))))))) + (func (param $x (ref null $s)) (param $y (ref null (shared any))) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $anyref) + ) + "invalid type" +) diff --git a/tests/local/shared-everything-threads/table.wast b/tests/local/shared-everything-threads/table.wast index 0b4eedc2ce..b733ec4c2b 100644 --- a/tests/local/shared-everything-threads/table.wast +++ b/tests/local/shared-everything-threads/table.wast @@ -41,3 +41,134 @@ (type $t (func)) (table shared 0 (ref $t))) "shared tables must have a shared element type") + +;; Check `table.atomic.*` instructions. +(module (;eq;) + (table $a (import "spectest" "table_eq") shared 1 (ref null (shared eq))) + (table $b shared 1 (ref null (shared eq))) + (func (export "table-atomic-get-eq-seq_cst-$a") (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get seq_cst $a) + (func (export "table-atomic-get-eq-seq_cst-$b") (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get seq_cst $b) + (func (export "table-atomic-get-eq-acq_rel-$a") (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get acq_rel $a) + (func (export "table-atomic-get-eq-acq_rel-$b") (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get acq_rel $b) + (func (export "table-atomic-set-eq-seq_cst-$a") (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set seq_cst $a) + (func (export "table-atomic-set-eq-seq_cst-$b") (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set seq_cst $b) + (func (export "table-atomic-set-eq-acq_rel-$a") (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set acq_rel $a) + (func (export "table-atomic-set-eq-acq_rel-$b") (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set acq_rel $b) + (func (export "table-atomic-rmw.xchg-eq-seq_cst-$a") (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $a) + (func (export "table-atomic-rmw.xchg-eq-seq_cst-$b") (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $b) + (func (export "table-atomic-rmw.xchg-eq-acq_rel-$a") (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $a) + (func (export "table-atomic-rmw.xchg-eq-acq_rel-$b") (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $b) + (func (export "table-atomic-rmw.cmpxchg-eq-seq_cst-$a") (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg seq_cst $a) + (func (export "table-atomic-rmw.cmpxchg-eq-seq_cst-$b") (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg seq_cst $b) + (func (export "table-atomic-rmw.cmpxchg-eq-acq_rel-$a") (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg acq_rel $a) + (func (export "table-atomic-rmw.cmpxchg-eq-acq_rel-$b") (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg acq_rel $b) +) + +(module (;any;) + (table $a (import "spectest" "table_any") shared 1 (ref null (shared any))) + (table $b shared 1 (ref null (shared any))) + (func (export "table-atomic-get-any-seq_cst-$a") (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get seq_cst $a) + (func (export "table-atomic-get-any-seq_cst-$b") (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get seq_cst $b) + (func (export "table-atomic-get-any-acq_rel-$a") (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get acq_rel $a) + (func (export "table-atomic-get-any-acq_rel-$b") (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get acq_rel $b) + (func (export "table-atomic-set-any-seq_cst-$a") (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set seq_cst $a) + (func (export "table-atomic-set-any-seq_cst-$b") (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set seq_cst $b) + (func (export "table-atomic-set-any-acq_rel-$a") (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set acq_rel $a) + (func (export "table-atomic-set-any-acq_rel-$b") (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set acq_rel $b) + (func (export "table-atomic-rmw.xchg-any-seq_cst-$a") (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $a) + (func (export "table-atomic-rmw.xchg-any-seq_cst-$b") (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $b) + (func (export "table-atomic-rmw.xchg-any-acq_rel-$a") (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $a) + (func (export "table-atomic-rmw.xchg-any-acq_rel-$b") (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $b) + ;; table.atomic.rmw.cmpxchg only works with subtypes of eqref. +) + +;; Check that cmpxchg only works with eqref subtypes. +(assert_invalid + (module + (table $a shared 0 (ref null (shared any))) + (func (param $x i32) (param $y (ref null (shared any))) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg seq_cst $a)) + "invalid type") diff --git a/tests/snapshots/local/shared-everything-threads/array.wast.json b/tests/snapshots/local/shared-everything-threads/array.wast.json index 03bf81d778..5118986647 100644 --- a/tests/snapshots/local/shared-everything-threads/array.wast.json +++ b/tests/snapshots/local/shared-everything-threads/array.wast.json @@ -55,6 +55,377 @@ "type": "module", "line": 72, "filename": "array.8.wasm" + }, + { + "type": "module", + "line": 118, + "filename": "array.9.wasm" + }, + { + "type": "module", + "line": 126, + "filename": "array.10.wasm" + }, + { + "type": "module", + "line": 134, + "filename": "array.11.wasm" + }, + { + "type": "module", + "line": 142, + "filename": "array.12.wasm" + }, + { + "type": "module", + "line": 150, + "filename": "array.13.wasm" + }, + { + "type": "module", + "line": 158, + "filename": "array.14.wasm" + }, + { + "type": "module", + "line": 166, + "filename": "array.15.wasm" + }, + { + "type": "module", + "line": 174, + "filename": "array.16.wasm" + }, + { + "type": "module", + "line": 182, + "filename": "array.17.wasm" + }, + { + "type": "module", + "line": 190, + "filename": "array.18.wasm" + }, + { + "type": "module", + "line": 198, + "filename": "array.19.wasm" + }, + { + "type": "module", + "line": 206, + "filename": "array.20.wasm" + }, + { + "type": "module", + "line": 214, + "filename": "array.21.wasm" + }, + { + "type": "module", + "line": 222, + "filename": "array.22.wasm" + }, + { + "type": "module", + "line": 230, + "filename": "array.23.wasm" + }, + { + "type": "module", + "line": 239, + "filename": "array.24.wasm" + }, + { + "type": "module", + "line": 248, + "filename": "array.25.wasm" + }, + { + "type": "module", + "line": 257, + "filename": "array.26.wasm" + }, + { + "type": "module", + "line": 266, + "filename": "array.27.wasm" + }, + { + "type": "module", + "line": 275, + "filename": "array.28.wasm" + }, + { + "type": "module", + "line": 284, + "filename": "array.29.wasm" + }, + { + "type": "module", + "line": 293, + "filename": "array.30.wasm" + }, + { + "type": "module", + "line": 302, + "filename": "array.31.wasm" + }, + { + "type": "module", + "line": 311, + "filename": "array.32.wasm" + }, + { + "type": "module", + "line": 320, + "filename": "array.33.wasm" + }, + { + "type": "module", + "line": 329, + "filename": "array.34.wasm" + }, + { + "type": "module", + "line": 338, + "filename": "array.35.wasm" + }, + { + "type": "module", + "line": 347, + "filename": "array.36.wasm" + }, + { + "type": "module", + "line": 356, + "filename": "array.37.wasm" + }, + { + "type": "module", + "line": 365, + "filename": "array.38.wasm" + }, + { + "type": "module", + "line": 374, + "filename": "array.39.wasm" + }, + { + "type": "module", + "line": 383, + "filename": "array.40.wasm" + }, + { + "type": "module", + "line": 392, + "filename": "array.41.wasm" + }, + { + "type": "module", + "line": 401, + "filename": "array.42.wasm" + }, + { + "type": "module", + "line": 410, + "filename": "array.43.wasm" + }, + { + "type": "module", + "line": 419, + "filename": "array.44.wasm" + }, + { + "type": "module", + "line": 428, + "filename": "array.45.wasm" + }, + { + "type": "module", + "line": 437, + "filename": "array.46.wasm" + }, + { + "type": "module", + "line": 446, + "filename": "array.47.wasm" + }, + { + "type": "module", + "line": 455, + "filename": "array.48.wasm" + }, + { + "type": "module", + "line": 464, + "filename": "array.49.wasm" + }, + { + "type": "module", + "line": 473, + "filename": "array.50.wasm" + }, + { + "type": "module", + "line": 482, + "filename": "array.51.wasm" + }, + { + "type": "module", + "line": 491, + "filename": "array.52.wasm" + }, + { + "type": "module", + "line": 500, + "filename": "array.53.wasm" + }, + { + "type": "module", + "line": 509, + "filename": "array.54.wasm" + }, + { + "type": "module", + "line": 518, + "filename": "array.55.wasm" + }, + { + "type": "module", + "line": 527, + "filename": "array.56.wasm" + }, + { + "type": "module", + "line": 536, + "filename": "array.57.wasm" + }, + { + "type": "module", + "line": 545, + "filename": "array.58.wasm" + }, + { + "type": "module", + "line": 554, + "filename": "array.59.wasm" + }, + { + "type": "module", + "line": 564, + "filename": "array.60.wasm" + }, + { + "type": "module", + "line": 574, + "filename": "array.61.wasm" + }, + { + "type": "module", + "line": 584, + "filename": "array.62.wasm" + }, + { + "type": "module", + "line": 594, + "filename": "array.63.wasm" + }, + { + "type": "module", + "line": 604, + "filename": "array.64.wasm" + }, + { + "type": "assert_invalid", + "line": 615, + "filename": "array.65.wasm", + "text": "packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 625, + "filename": "array.66.wasm", + "text": "non-packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 635, + "filename": "array.67.wasm", + "text": "non-packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 645, + "filename": "array.68.wasm", + "text": "non-packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 655, + "filename": "array.69.wasm", + "text": "non-packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 665, + "filename": "array.70.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 676, + "filename": "array.71.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 687, + "filename": "array.72.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 698, + "filename": "array.73.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 709, + "filename": "array.74.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 720, + "filename": "array.75.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 731, + "filename": "array.76.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 743, + "filename": "array.77.wasm", + "text": "invalid type", + "module_type": "binary" } ] } \ No newline at end of file diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/10.print b/tests/snapshots/local/shared-everything-threads/array.wast/10.print new file mode 100644 index 0000000000..f733e00572 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/10.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i64) + local.get $x + local.get $y + array.atomic.get seq_cst $a + ) + (export "array-atomic-get-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/11.print b/tests/snapshots/local/shared-everything-threads/array.wast/11.print new file mode 100644 index 0000000000..76dbd3ecb7 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/11.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32) (result (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get seq_cst $a + ) + (export "array-atomic-get-anyref-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/12.print b/tests/snapshots/local/shared-everything-threads/array.wast/12.print new file mode 100644 index 0000000000..5cf5608397 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/12.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get acq_rel $a + ) + (export "array-atomic-get-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/13.print b/tests/snapshots/local/shared-everything-threads/array.wast/13.print new file mode 100644 index 0000000000..b4b3919e6f --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/13.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i64) + local.get $x + local.get $y + array.atomic.get acq_rel $a + ) + (export "array-atomic-get-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/14.print b/tests/snapshots/local/shared-everything-threads/array.wast/14.print new file mode 100644 index 0000000000..189c2ea090 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/14.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32) (result (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result (ref null (shared any))) + local.get $x + local.get $y + array.atomic.get acq_rel $a + ) + (export "array-atomic-get-anyref-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/15.print b/tests/snapshots/local/shared-everything-threads/array.wast/15.print new file mode 100644 index 0000000000..00e0b30082 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/15.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a + ) + (export "array-atomic-get_s-i8-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/16.print b/tests/snapshots/local/shared-everything-threads/array.wast/16.print new file mode 100644 index 0000000000..82d7db16b1 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/16.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s seq_cst $a + ) + (export "array-atomic-get_s-i16-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/17.print b/tests/snapshots/local/shared-everything-threads/array.wast/17.print new file mode 100644 index 0000000000..0794e77851 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/17.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s acq_rel $a + ) + (export "array-atomic-get_s-i8-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/18.print b/tests/snapshots/local/shared-everything-threads/array.wast/18.print new file mode 100644 index 0000000000..f7a27cdcd8 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/18.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_s acq_rel $a + ) + (export "array-atomic-get_s-i16-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/19.print b/tests/snapshots/local/shared-everything-threads/array.wast/19.print new file mode 100644 index 0000000000..2ccc59945c --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/19.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a + ) + (export "array-atomic-get_u-i8-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/20.print b/tests/snapshots/local/shared-everything-threads/array.wast/20.print new file mode 100644 index 0000000000..144068c536 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/20.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u seq_cst $a + ) + (export "array-atomic-get_u-i16-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/21.print b/tests/snapshots/local/shared-everything-threads/array.wast/21.print new file mode 100644 index 0000000000..e5bed640b9 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/21.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u acq_rel $a + ) + (export "array-atomic-get_u-i8-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/22.print b/tests/snapshots/local/shared-everything-threads/array.wast/22.print new file mode 100644 index 0000000000..069d3eb673 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/22.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get_u acq_rel $a + ) + (export "array-atomic-get_u-i16-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/23.print b/tests/snapshots/local/shared-everything-threads/array.wast/23.print new file mode 100644 index 0000000000..b1727c3227 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/23.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a + ) + (export "array-atomic-set-i8-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/24.print b/tests/snapshots/local/shared-everything-threads/array.wast/24.print new file mode 100644 index 0000000000..95641f947b --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/24.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a + ) + (export "array-atomic-set-i16-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/25.print b/tests/snapshots/local/shared-everything-threads/array.wast/25.print new file mode 100644 index 0000000000..b8e21b1aa8 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/25.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a + ) + (export "array-atomic-set-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/26.print b/tests/snapshots/local/shared-everything-threads/array.wast/26.print new file mode 100644 index 0000000000..6e11fb3a41 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/26.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a + ) + (export "array-atomic-set-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/27.print b/tests/snapshots/local/shared-everything-threads/array.wast/27.print new file mode 100644 index 0000000000..db65bed132 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/27.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.set seq_cst $a + ) + (export "array-atomic-set-anyref-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/28.print b/tests/snapshots/local/shared-everything-threads/array.wast/28.print new file mode 100644 index 0000000000..941e3f0d84 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/28.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i8)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a + ) + (export "array-atomic-set-i8-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/29.print b/tests/snapshots/local/shared-everything-threads/array.wast/29.print new file mode 100644 index 0000000000..4e3d7c91cd --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/29.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i16)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a + ) + (export "array-atomic-set-i16-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/30.print b/tests/snapshots/local/shared-everything-threads/array.wast/30.print new file mode 100644 index 0000000000..17aec3ab82 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/30.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a + ) + (export "array-atomic-set-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/31.print b/tests/snapshots/local/shared-everything-threads/array.wast/31.print new file mode 100644 index 0000000000..43139589ed --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/31.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a + ) + (export "array-atomic-set-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/32.print b/tests/snapshots/local/shared-everything-threads/array.wast/32.print new file mode 100644 index 0000000000..ed1acbaf33 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/32.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.set acq_rel $a + ) + (export "array-atomic-set-anyref-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/33.print b/tests/snapshots/local/shared-everything-threads/array.wast/33.print new file mode 100644 index 0000000000..d230670ccd --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/33.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add seq_cst $a + ) + (export "array-atomic-rmw.add-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/34.print b/tests/snapshots/local/shared-everything-threads/array.wast/34.print new file mode 100644 index 0000000000..28ea109420 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/34.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add seq_cst $a + ) + (export "array-atomic-rmw.add-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/35.print b/tests/snapshots/local/shared-everything-threads/array.wast/35.print new file mode 100644 index 0000000000..8cc27f279f --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/35.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add acq_rel $a + ) + (export "array-atomic-rmw.add-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/36.print b/tests/snapshots/local/shared-everything-threads/array.wast/36.print new file mode 100644 index 0000000000..3be7d18db2 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/36.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.add acq_rel $a + ) + (export "array-atomic-rmw.add-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/37.print b/tests/snapshots/local/shared-everything-threads/array.wast/37.print new file mode 100644 index 0000000000..36af9d868b --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/37.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub seq_cst $a + ) + (export "array-atomic-rmw.sub-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/38.print b/tests/snapshots/local/shared-everything-threads/array.wast/38.print new file mode 100644 index 0000000000..5bb94f29a1 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/38.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub seq_cst $a + ) + (export "array-atomic-rmw.sub-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/39.print b/tests/snapshots/local/shared-everything-threads/array.wast/39.print new file mode 100644 index 0000000000..0b4badbb86 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/39.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub acq_rel $a + ) + (export "array-atomic-rmw.sub-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/40.print b/tests/snapshots/local/shared-everything-threads/array.wast/40.print new file mode 100644 index 0000000000..ba01772628 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/40.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.sub acq_rel $a + ) + (export "array-atomic-rmw.sub-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/41.print b/tests/snapshots/local/shared-everything-threads/array.wast/41.print new file mode 100644 index 0000000000..5c61030757 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/41.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and seq_cst $a + ) + (export "array-atomic-rmw.and-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/42.print b/tests/snapshots/local/shared-everything-threads/array.wast/42.print new file mode 100644 index 0000000000..2edfd317cf --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/42.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and seq_cst $a + ) + (export "array-atomic-rmw.and-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/43.print b/tests/snapshots/local/shared-everything-threads/array.wast/43.print new file mode 100644 index 0000000000..9a6e89fc15 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/43.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and acq_rel $a + ) + (export "array-atomic-rmw.and-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/44.print b/tests/snapshots/local/shared-everything-threads/array.wast/44.print new file mode 100644 index 0000000000..f82346cddb --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/44.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.and acq_rel $a + ) + (export "array-atomic-rmw.and-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/45.print b/tests/snapshots/local/shared-everything-threads/array.wast/45.print new file mode 100644 index 0000000000..59adfe733b --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/45.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or seq_cst $a + ) + (export "array-atomic-rmw.or-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/46.print b/tests/snapshots/local/shared-everything-threads/array.wast/46.print new file mode 100644 index 0000000000..13dd111893 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/46.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or seq_cst $a + ) + (export "array-atomic-rmw.or-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/47.print b/tests/snapshots/local/shared-everything-threads/array.wast/47.print new file mode 100644 index 0000000000..ffca25c496 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/47.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or acq_rel $a + ) + (export "array-atomic-rmw.or-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/48.print b/tests/snapshots/local/shared-everything-threads/array.wast/48.print new file mode 100644 index 0000000000..94fbc49ce6 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/48.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.or acq_rel $a + ) + (export "array-atomic-rmw.or-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/49.print b/tests/snapshots/local/shared-everything-threads/array.wast/49.print new file mode 100644 index 0000000000..0e6016a7ab --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/49.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor seq_cst $a + ) + (export "array-atomic-rmw.xor-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/50.print b/tests/snapshots/local/shared-everything-threads/array.wast/50.print new file mode 100644 index 0000000000..446233a0e1 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/50.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor seq_cst $a + ) + (export "array-atomic-rmw.xor-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/51.print b/tests/snapshots/local/shared-everything-threads/array.wast/51.print new file mode 100644 index 0000000000..7867026121 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/51.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor acq_rel $a + ) + (export "array-atomic-rmw.xor-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/52.print b/tests/snapshots/local/shared-everything-threads/array.wast/52.print new file mode 100644 index 0000000000..1e8eb5b9ef --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/52.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xor acq_rel $a + ) + (export "array-atomic-rmw.xor-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/53.print b/tests/snapshots/local/shared-everything-threads/array.wast/53.print new file mode 100644 index 0000000000..71e2c7a8c2 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/53.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a + ) + (export "array-atomic-rmw.xchg-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/54.print b/tests/snapshots/local/shared-everything-threads/array.wast/54.print new file mode 100644 index 0000000000..1770c9685c --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/54.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a + ) + (export "array-atomic-rmw.xchg-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/55.print b/tests/snapshots/local/shared-everything-threads/array.wast/55.print new file mode 100644 index 0000000000..6ca3ea8062 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/55.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared any))) (result (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg seq_cst $a + ) + (export "array-atomic-rmw.xchg-anyref-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/56.print b/tests/snapshots/local/shared-everything-threads/array.wast/56.print new file mode 100644 index 0000000000..2a03171eae --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/56.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a + ) + (export "array-atomic-rmw.xchg-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/57.print b/tests/snapshots/local/shared-everything-threads/array.wast/57.print new file mode 100644 index 0000000000..618521206b --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/57.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a + ) + (export "array-atomic-rmw.xchg-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/58.print b/tests/snapshots/local/shared-everything-threads/array.wast/58.print new file mode 100644 index 0000000000..2670aba692 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/58.print @@ -0,0 +1,11 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared any)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared any))) (result (ref null (shared any))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + local.get $z + array.atomic.rmw.xchg acq_rel $a + ) + (export "array-atomic-rmw.xchg-anyref-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/59.print b/tests/snapshots/local/shared-everything-threads/array.wast/59.print new file mode 100644 index 0000000000..9b4ed0eced --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/59.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (param $A i32) (result i32) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a + ) + (export "array-atomic-rmw.cmpxchg-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/60.print b/tests/snapshots/local/shared-everything-threads/array.wast/60.print new file mode 100644 index 0000000000..f485f7a7e3 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/60.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (param $A i64) (result i64) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a + ) + (export "array-atomic-rmw.cmpxchg-i64-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/61.print b/tests/snapshots/local/shared-everything-threads/array.wast/61.print new file mode 100644 index 0000000000..c9be7ed8c2 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/61.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared eq)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared eq)) (ref null (shared eq))) (result (ref null (shared eq))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared eq))) (param $A (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg seq_cst $a + ) + (export "array-atomic-rmw.cmpxchg-eqref-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/62.print b/tests/snapshots/local/shared-everything-threads/array.wast/62.print new file mode 100644 index 0000000000..15e7ca30d3 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/62.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32 i32 i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i32) (param $A i32) (result i32) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a + ) + (export "array-atomic-rmw.cmpxchg-i32-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/63.print b/tests/snapshots/local/shared-everything-threads/array.wast/63.print new file mode 100644 index 0000000000..7bce20ede1 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/63.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut i64)))) + (type (;1;) (func (param (ref null $a) i32 i64 i64) (result i64))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z i64) (param $A i64) (result i64) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a + ) + (export "array-atomic-rmw.cmpxchg-i64-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/64.print b/tests/snapshots/local/shared-everything-threads/array.wast/64.print new file mode 100644 index 0000000000..d61185983f --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/64.print @@ -0,0 +1,12 @@ +(module + (type $a (;0;) (shared(array (mut (ref null (shared eq)))))) + (type (;1;) (func (param (ref null $a) i32 (ref null (shared eq)) (ref null (shared eq))) (result (ref null (shared eq))))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (param $z (ref null (shared eq))) (param $A (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + local.get $A + array.atomic.rmw.cmpxchg acq_rel $a + ) + (export "array-atomic-rmw.cmpxchg-eqref-acq_rel" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/array.wast/9.print b/tests/snapshots/local/shared-everything-threads/array.wast/9.print new file mode 100644 index 0000000000..f3d308bd71 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/array.wast/9.print @@ -0,0 +1,10 @@ +(module + (type $a (;0;) (shared(array (mut i32)))) + (type (;1;) (func (param (ref null $a) i32) (result i32))) + (func (;0;) (type 1) (param $x (ref null $a)) (param $y i32) (result i32) + local.get $x + local.get $y + array.atomic.get seq_cst $a + ) + (export "array-atomic-get-i32-seq_cst" (func 0)) +) diff --git a/tests/snapshots/local/shared-everything-threads/struct.wast.json b/tests/snapshots/local/shared-everything-threads/struct.wast.json index 97900a0eba..106b265ca1 100644 --- a/tests/snapshots/local/shared-everything-threads/struct.wast.json +++ b/tests/snapshots/local/shared-everything-threads/struct.wast.json @@ -55,6 +55,102 @@ "type": "module", "line": 72, "filename": "struct.8.wasm" + }, + { + "type": "module", + "line": 95, + "filename": "struct.9.wasm" + }, + { + "type": "assert_invalid", + "line": 322, + "filename": "struct.10.wasm", + "text": "non-packed storage type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 331, + "filename": "struct.11.wasm", + "text": "non-packed storage types", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 340, + "filename": "struct.12.wasm", + "text": "non-packed storage types", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 349, + "filename": "struct.13.wasm", + "text": "non-packed storage types", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 358, + "filename": "struct.14.wasm", + "text": "non-packed storage types", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 367, + "filename": "struct.15.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 377, + "filename": "struct.16.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 387, + "filename": "struct.17.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 397, + "filename": "struct.18.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 407, + "filename": "struct.19.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 417, + "filename": "struct.20.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 427, + "filename": "struct.21.wasm", + "text": "invalid type", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 438, + "filename": "struct.22.wasm", + "text": "invalid type", + "module_type": "binary" } ] } \ No newline at end of file diff --git a/tests/snapshots/local/shared-everything-threads/struct.wast/9.print b/tests/snapshots/local/shared-everything-threads/struct.wast/9.print new file mode 100644 index 0000000000..7987e5e408 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/struct.wast/9.print @@ -0,0 +1,343 @@ +(module + (type $s (;0;) (shared(struct (field $i8 (mut i8)) (field $i16 (mut i16)) (field $i32 (mut i32)) (field $i64 (mut i64)) (field $anyref (mut (ref null (shared any)))) (field $eqref (mut (ref null (shared eq))))))) + (type (;1;) (func (param (ref null $s)) (result i32))) + (type (;2;) (func (param (ref null $s)) (result i64))) + (type (;3;) (func (param (ref null $s)) (result (ref null (shared any))))) + (type (;4;) (func (param (ref null $s) i32))) + (type (;5;) (func (param (ref null $s) i64))) + (type (;6;) (func (param (ref null $s) (ref null (shared any))))) + (type (;7;) (func (param (ref null $s) i32) (result i32))) + (type (;8;) (func (param (ref null $s) i64) (result i64))) + (type (;9;) (func (param (ref null $s) (ref null (shared any))) (result (ref null (shared any))))) + (type (;10;) (func (param (ref null $s) i32 i32) (result i32))) + (type (;11;) (func (param (ref null $s) i64 i64) (result i64))) + (type (;12;) (func (param (ref null $s) (ref null (shared eq)) (ref null (shared eq))) (result (ref null (shared eq))))) + (func (;0;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get seq_cst $s $i32 + ) + (func (;1;) (type 2) (param $x (ref null $s)) (result i64) + local.get $x + struct.atomic.get seq_cst $s $i64 + ) + (func (;2;) (type 3) (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get seq_cst $s $anyref + ) + (func (;3;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get acq_rel $s $i32 + ) + (func (;4;) (type 2) (param $x (ref null $s)) (result i64) + local.get $x + struct.atomic.get acq_rel $s $i64 + ) + (func (;5;) (type 3) (param $x (ref null $s)) (result (ref null (shared any))) + local.get $x + struct.atomic.get acq_rel $s $anyref + ) + (func (;6;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s seq_cst $s $i8 + ) + (func (;7;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s seq_cst $s $i16 + ) + (func (;8;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s acq_rel $s $i8 + ) + (func (;9;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_s acq_rel $s $i16 + ) + (func (;10;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u seq_cst $s $i8 + ) + (func (;11;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u seq_cst $s $i16 + ) + (func (;12;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u acq_rel $s $i8 + ) + (func (;13;) (type 1) (param $x (ref null $s)) (result i32) + local.get $x + struct.atomic.get_u acq_rel $s $i16 + ) + (func (;14;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i8 + ) + (func (;15;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i16 + ) + (func (;16;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i32 + ) + (func (;17;) (type 5) (param $x (ref null $s)) (param $y i64) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $i64 + ) + (func (;18;) (type 6) (param $x (ref null $s)) (param $y (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.set seq_cst $s $anyref + ) + (func (;19;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i8 + ) + (func (;20;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i16 + ) + (func (;21;) (type 4) (param $x (ref null $s)) (param $y i32) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i32 + ) + (func (;22;) (type 5) (param $x (ref null $s)) (param $y i64) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $i64 + ) + (func (;23;) (type 6) (param $x (ref null $s)) (param $y (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.set acq_rel $s $anyref + ) + (func (;24;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.add seq_cst $s $i32 + ) + (func (;25;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.add seq_cst $s $i64 + ) + (func (;26;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.add acq_rel $s $i32 + ) + (func (;27;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.add acq_rel $s $i64 + ) + (func (;28;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.sub seq_cst $s $i32 + ) + (func (;29;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.sub seq_cst $s $i64 + ) + (func (;30;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.sub acq_rel $s $i32 + ) + (func (;31;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.sub acq_rel $s $i64 + ) + (func (;32;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.and seq_cst $s $i32 + ) + (func (;33;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.and seq_cst $s $i64 + ) + (func (;34;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.and acq_rel $s $i32 + ) + (func (;35;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.and acq_rel $s $i64 + ) + (func (;36;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.or seq_cst $s $i32 + ) + (func (;37;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.or seq_cst $s $i64 + ) + (func (;38;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.or acq_rel $s $i32 + ) + (func (;39;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.or acq_rel $s $i64 + ) + (func (;40;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xor seq_cst $s $i32 + ) + (func (;41;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xor seq_cst $s $i64 + ) + (func (;42;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xor acq_rel $s $i32 + ) + (func (;43;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xor acq_rel $s $i64 + ) + (func (;44;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $i32 + ) + (func (;45;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $i64 + ) + (func (;46;) (type 9) (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.xchg seq_cst $s $anyref + ) + (func (;47;) (type 7) (param $x (ref null $s)) (param $y i32) (result i32) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $i32 + ) + (func (;48;) (type 8) (param $x (ref null $s)) (param $y i64) (result i64) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $i64 + ) + (func (;49;) (type 9) (param $x (ref null $s)) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + struct.atomic.rmw.xchg acq_rel $s $anyref + ) + (func (;50;) (type 10) (param $x (ref null $s)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $i32 + ) + (func (;51;) (type 11) (param $x (ref null $s)) (param $y i64) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $i64 + ) + (func (;52;) (type 12) (param $x (ref null $s)) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg seq_cst $s $eqref + ) + (func (;53;) (type 10) (param $x (ref null $s)) (param $y i32) (param $z i32) (result i32) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $i32 + ) + (func (;54;) (type 11) (param $x (ref null $s)) (param $y i64) (param $z i64) (result i64) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $i64 + ) + (func (;55;) (type 12) (param $x (ref null $s)) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + struct.atomic.rmw.cmpxchg acq_rel $s $eqref + ) + (export "struct-atomic-get-i32-seq_cst" (func 0)) + (export "struct-atomic-get-i64-seq_cst" (func 1)) + (export "struct-atomic-get-anyref-seq_cst" (func 2)) + (export "struct-atomic-get-i32-acq_rel" (func 3)) + (export "struct-atomic-get-i64-acq_rel" (func 4)) + (export "struct-atomic-get-anyref-acq_rel" (func 5)) + (export "struct-atomic-get_s-i8-seq_cst" (func 6)) + (export "struct-atomic-get_s-i16-seq_cst" (func 7)) + (export "struct-atomic-get_s-i8-acq_rel" (func 8)) + (export "struct-atomic-get_s-i16-acq_rel" (func 9)) + (export "struct-atomic-get_u-i8-seq_cst" (func 10)) + (export "struct-atomic-get_u-i16-seq_cst" (func 11)) + (export "struct-atomic-get_u-i8-acq_rel" (func 12)) + (export "struct-atomic-get_u-i16-acq_rel" (func 13)) + (export "struct-atomic-set-i8-seq_cst" (func 14)) + (export "struct-atomic-set-i16-seq_cst" (func 15)) + (export "struct-atomic-set-i32-seq_cst" (func 16)) + (export "struct-atomic-set-i64-seq_cst" (func 17)) + (export "struct-atomic-set-anyref-seq_cst" (func 18)) + (export "struct-atomic-set-i8-acq_rel" (func 19)) + (export "struct-atomic-set-i16-acq_rel" (func 20)) + (export "struct-atomic-set-i32-acq_rel" (func 21)) + (export "struct-atomic-set-i64-acq_rel" (func 22)) + (export "struct-atomic-set-anyref-acq_rel" (func 23)) + (export "struct-atomic-rmw.add-i32-seq_cst" (func 24)) + (export "struct-atomic-rmw.add-i64-seq_cst" (func 25)) + (export "struct-atomic-rmw.add-i32-acq_rel" (func 26)) + (export "struct-atomic-rmw.add-i64-acq_rel" (func 27)) + (export "struct-atomic-rmw.sub-i32-seq_cst" (func 28)) + (export "struct-atomic-rmw.sub-i64-seq_cst" (func 29)) + (export "struct-atomic-rmw.sub-i32-acq_rel" (func 30)) + (export "struct-atomic-rmw.sub-i64-acq_rel" (func 31)) + (export "struct-atomic-rmw.and-i32-seq_cst" (func 32)) + (export "struct-atomic-rmw.and-i64-seq_cst" (func 33)) + (export "struct-atomic-rmw.and-i32-acq_rel" (func 34)) + (export "struct-atomic-rmw.and-i64-acq_rel" (func 35)) + (export "struct-atomic-rmw.or-i32-seq_cst" (func 36)) + (export "struct-atomic-rmw.or-i64-seq_cst" (func 37)) + (export "struct-atomic-rmw.or-i32-acq_rel" (func 38)) + (export "struct-atomic-rmw.or-i64-acq_rel" (func 39)) + (export "struct-atomic-rmw.xor-i32-seq_cst" (func 40)) + (export "struct-atomic-rmw.xor-i64-seq_cst" (func 41)) + (export "struct-atomic-rmw.xor-i32-acq_rel" (func 42)) + (export "struct-atomic-rmw.xor-i64-acq_rel" (func 43)) + (export "struct-atomic-rmw.xchg-i32-seq_cst" (func 44)) + (export "struct-atomic-rmw.xchg-i64-seq_cst" (func 45)) + (export "struct-atomic-rmw.xchg-anyref-seq_cst" (func 46)) + (export "struct-atomic-rmw.xchg-i32-acq_rel" (func 47)) + (export "struct-atomic-rmw.xchg-i64-acq_rel" (func 48)) + (export "struct-atomic-rmw.xchg-anyref-acq_rel" (func 49)) + (export "struct-atomic-rmw.cmpxchg-i32-seq_cst" (func 50)) + (export "struct-atomic-rmw.cmpxchg-i64-seq_cst" (func 51)) + (export "struct-atomic-rmw.cmpxchg-eqref-seq_cst" (func 52)) + (export "struct-atomic-rmw.cmpxchg-i32-acq_rel" (func 53)) + (export "struct-atomic-rmw.cmpxchg-i64-acq_rel" (func 54)) + (export "struct-atomic-rmw.cmpxchg-eqref-acq_rel" (func 55)) +) diff --git a/tests/snapshots/local/shared-everything-threads/table.wast.json b/tests/snapshots/local/shared-everything-threads/table.wast.json index 8c2bc6b10f..13a852f325 100644 --- a/tests/snapshots/local/shared-everything-threads/table.wast.json +++ b/tests/snapshots/local/shared-everything-threads/table.wast.json @@ -45,6 +45,23 @@ "filename": "table.6.wasm", "text": "shared tables must have a shared element type", "module_type": "binary" + }, + { + "type": "module", + "line": 46, + "filename": "table.7.wasm" + }, + { + "type": "module", + "line": 115, + "filename": "table.8.wasm" + }, + { + "type": "assert_invalid", + "line": 167, + "filename": "table.9.wasm", + "text": "invalid type", + "module_type": "binary" } ] } \ No newline at end of file diff --git a/tests/snapshots/local/shared-everything-threads/table.wast/7.print b/tests/snapshots/local/shared-everything-threads/table.wast/7.print new file mode 100644 index 0000000000..033089a8b9 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/table.wast/7.print @@ -0,0 +1,104 @@ +(module + (type (;0;) (func (param i32) (result (ref null (shared eq))))) + (type (;1;) (func (param i32 (ref null (shared eq))))) + (type (;2;) (func (param i32 (ref null (shared eq))) (result (ref null (shared eq))))) + (type (;3;) (func (param i32 (ref null (shared eq)) (ref null (shared eq))) (result (ref null (shared eq))))) + (import "spectest" "table_eq" (table $a (;0;) shared 1 (ref null (shared eq)))) + (func (;0;) (type 0) (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get seq_cst $a + ) + (func (;1;) (type 0) (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get seq_cst $b + ) + (func (;2;) (type 0) (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get acq_rel $a + ) + (func (;3;) (type 0) (param $x i32) (result (ref null (shared eq))) + local.get $x + table.atomic.get acq_rel $b + ) + (func (;4;) (type 1) (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set seq_cst $a + ) + (func (;5;) (type 1) (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set seq_cst $b + ) + (func (;6;) (type 1) (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set acq_rel $a + ) + (func (;7;) (type 1) (param $x i32) (param $y (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.set acq_rel $b + ) + (func (;8;) (type 2) (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $a + ) + (func (;9;) (type 2) (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $b + ) + (func (;10;) (type 2) (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $a + ) + (func (;11;) (type 2) (param $x i32) (param $y (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $b + ) + (func (;12;) (type 3) (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg seq_cst $a + ) + (func (;13;) (type 3) (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg seq_cst $b + ) + (func (;14;) (type 3) (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg acq_rel $a + ) + (func (;15;) (type 3) (param $x i32) (param $y (ref null (shared eq))) (param $z (ref null (shared eq))) (result (ref null (shared eq))) + local.get $x + local.get $y + local.get $z + table.atomic.rmw.cmpxchg acq_rel $b + ) + (table $b (;1;) shared 1 (ref null (shared eq))) + (export "table-atomic-get-eq-seq_cst-$a" (func 0)) + (export "table-atomic-get-eq-seq_cst-$b" (func 1)) + (export "table-atomic-get-eq-acq_rel-$a" (func 2)) + (export "table-atomic-get-eq-acq_rel-$b" (func 3)) + (export "table-atomic-set-eq-seq_cst-$a" (func 4)) + (export "table-atomic-set-eq-seq_cst-$b" (func 5)) + (export "table-atomic-set-eq-acq_rel-$a" (func 6)) + (export "table-atomic-set-eq-acq_rel-$b" (func 7)) + (export "table-atomic-rmw.xchg-eq-seq_cst-$a" (func 8)) + (export "table-atomic-rmw.xchg-eq-seq_cst-$b" (func 9)) + (export "table-atomic-rmw.xchg-eq-acq_rel-$a" (func 10)) + (export "table-atomic-rmw.xchg-eq-acq_rel-$b" (func 11)) + (export "table-atomic-rmw.cmpxchg-eq-seq_cst-$a" (func 12)) + (export "table-atomic-rmw.cmpxchg-eq-seq_cst-$b" (func 13)) + (export "table-atomic-rmw.cmpxchg-eq-acq_rel-$a" (func 14)) + (export "table-atomic-rmw.cmpxchg-eq-acq_rel-$b" (func 15)) +) diff --git a/tests/snapshots/local/shared-everything-threads/table.wast/8.print b/tests/snapshots/local/shared-everything-threads/table.wast/8.print new file mode 100644 index 0000000000..e921f4e848 --- /dev/null +++ b/tests/snapshots/local/shared-everything-threads/table.wast/8.print @@ -0,0 +1,75 @@ +(module + (type (;0;) (func (param i32) (result (ref null (shared any))))) + (type (;1;) (func (param i32 (ref null (shared any))))) + (type (;2;) (func (param i32 (ref null (shared any))) (result (ref null (shared any))))) + (import "spectest" "table_any" (table $a (;0;) shared 1 (ref null (shared any)))) + (func (;0;) (type 0) (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get seq_cst $a + ) + (func (;1;) (type 0) (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get seq_cst $b + ) + (func (;2;) (type 0) (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get acq_rel $a + ) + (func (;3;) (type 0) (param $x i32) (result (ref null (shared any))) + local.get $x + table.atomic.get acq_rel $b + ) + (func (;4;) (type 1) (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set seq_cst $a + ) + (func (;5;) (type 1) (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set seq_cst $b + ) + (func (;6;) (type 1) (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set acq_rel $a + ) + (func (;7;) (type 1) (param $x i32) (param $y (ref null (shared any))) + local.get $x + local.get $y + table.atomic.set acq_rel $b + ) + (func (;8;) (type 2) (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $a + ) + (func (;9;) (type 2) (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg seq_cst $b + ) + (func (;10;) (type 2) (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $a + ) + (func (;11;) (type 2) (param $x i32) (param $y (ref null (shared any))) (result (ref null (shared any))) + local.get $x + local.get $y + table.atomic.rmw.xchg acq_rel $b + ) + (table $b (;1;) shared 1 (ref null (shared any))) + (export "table-atomic-get-any-seq_cst-$a" (func 0)) + (export "table-atomic-get-any-seq_cst-$b" (func 1)) + (export "table-atomic-get-any-acq_rel-$a" (func 2)) + (export "table-atomic-get-any-acq_rel-$b" (func 3)) + (export "table-atomic-set-any-seq_cst-$a" (func 4)) + (export "table-atomic-set-any-seq_cst-$b" (func 5)) + (export "table-atomic-set-any-acq_rel-$a" (func 6)) + (export "table-atomic-set-any-acq_rel-$b" (func 7)) + (export "table-atomic-rmw.xchg-any-seq_cst-$a" (func 8)) + (export "table-atomic-rmw.xchg-any-seq_cst-$b" (func 9)) + (export "table-atomic-rmw.xchg-any-acq_rel-$a" (func 10)) + (export "table-atomic-rmw.xchg-any-acq_rel-$b" (func 11)) +)