Skip to content

Commit 947c152

Browse files
authored
threads: add shared tables (#1649)
* threads: add `shared` tables This change spreads `shared` attributes on to tables. As with #1480, this does not yet turn on fuzzing for `shared` things so the only checking is via the in-progress test suite in `tests/local/shared-everything-threads`. Implementing this raises an issue with the spec: the addition of `shared` in the text format means that inline table expressions (e.g., `(table <type> (elem ...))`) are difficult to parse: the parser would potentially have to look past two tokens now, `shared` and `i32|i64` to see if a type appears that indicates we should be parsing an inline format. There are multiple options for what to do here; I opened an issue to figure this out at the spec level first ([#71]). [proposal]: https://github.com/WebAssembly/shared-everything-threads [#71]: WebAssembly/shared-everything-threads#71 * Add a 'missing-features' test for `shared` tables * Add a negative test for indexed types
1 parent ccbe057 commit 947c152

File tree

30 files changed

+220
-32
lines changed

30 files changed

+220
-32
lines changed

crates/wasm-encoder/src/core/elements.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId};
1818
/// minimum: 128,
1919
/// maximum: None,
2020
/// table64: false,
21+
/// shared: false,
2122
/// });
2223
///
2324
/// let mut elements = ElementSection::new();

crates/wasm-encoder/src/core/tables.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId, ValT
1515
/// minimum: 128,
1616
/// maximum: None,
1717
/// table64: false,
18+
/// shared: false,
1819
/// });
1920
///
2021
/// let mut module = Module::new();
@@ -87,6 +88,10 @@ pub struct TableType {
8788
pub minimum: u64,
8889
/// Maximum size, in elements, of this table
8990
pub maximum: Option<u64>,
91+
/// Whether this table is shared or not.
92+
///
93+
/// This is included the shared-everything-threads proposal.
94+
pub shared: bool,
9095
}
9196

9297
impl TableType {
@@ -106,6 +111,9 @@ impl Encode for TableType {
106111
if self.maximum.is_some() {
107112
flags |= 0b001;
108113
}
114+
if self.shared {
115+
flags |= 0b010;
116+
}
109117
if self.table64 {
110118
flags |= 0b100;
111119
}

crates/wasm-encoder/src/reencode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ pub mod utils {
11541154
minimum: table_ty.initial,
11551155
maximum: table_ty.maximum,
11561156
table64: table_ty.table64,
1157+
shared: table_ty.shared,
11571158
})
11581159
}
11591160

crates/wasm-mutate/src/mutators/translate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ pub fn table_type(
156156
minimum: ty.initial,
157157
maximum: ty.maximum,
158158
table64: ty.table64,
159+
shared: ty.shared,
159160
})
160161
}
161162

crates/wasm-smith/src/core.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,7 @@ pub(crate) fn arbitrary_table_type(
25422542
minimum,
25432543
maximum,
25442544
table64,
2545+
shared: false, // TODO: handle shared
25452546
})
25462547
}
25472548

crates/wasmparser/src/readers/core/tables.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ impl<'a> FromReader<'a> for TableType {
6868
let element_type = reader.read()?;
6969
let pos = reader.original_position();
7070
let flags = reader.read_u8()?;
71-
if (flags & !0b101) != 0 {
71+
if (flags & !0b111) != 0 {
7272
bail!(pos, "invalid table resizable limits flags");
7373
}
7474
let has_max = (flags & 0b001) != 0;
75+
let shared = (flags & 0b010) != 0;
7576
let table64 = (flags & 0b100) != 0;
7677
Ok(TableType {
7778
element_type,
@@ -88,6 +89,7 @@ impl<'a> FromReader<'a> for TableType {
8889
} else {
8990
Some(reader.read_var_u32()?.into())
9091
},
92+
shared,
9193
})
9294
}
9395
}

crates/wasmparser/src/readers/core/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,10 @@ pub struct TableType {
17001700
/// For 32-bit tables (when `table64` is `false`) this is guaranteed to
17011701
/// be at most `u32::MAX` for valid types.
17021702
pub maximum: Option<u64>,
1703+
/// Whether this table is shared or not.
1704+
///
1705+
/// This is included the shared-everything-threads proposal.
1706+
pub shared: bool,
17031707
}
17041708

17051709
impl TableType {

crates/wasmparser/src/validator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,7 @@ mod tests {
15371537
maximum: None,
15381538
element_type: RefType::FUNCREF,
15391539
table64: false,
1540+
shared: false,
15401541
}
15411542
);
15421543

crates/wasmparser/src/validator/core.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl ModuleState {
146146
offset: usize,
147147
) -> Result<()> {
148148
self.module
149-
.check_table_type(&mut table.ty, features, offset)?;
149+
.check_table_type(&mut table.ty, features, types, offset)?;
150150

151151
match &table.init {
152152
TableInit::RefNull => {
@@ -870,7 +870,7 @@ impl Module {
870870
EntityType::Func(self.types[*type_index as usize])
871871
}
872872
TypeRef::Table(t) => {
873-
self.check_table_type(t, features, offset)?;
873+
self.check_table_type(t, features, types, offset)?;
874874
EntityType::Table(*t)
875875
}
876876
TypeRef::Memory(t) => {
@@ -892,10 +892,11 @@ impl Module {
892892
&self,
893893
ty: &mut TableType,
894894
features: &WasmFeatures,
895+
types: &TypeList,
895896
offset: usize,
896897
) -> Result<()> {
897-
// the `funcref` value type is allowed all the way back to the MVP, so
898-
// don't check it here
898+
// The `funcref` value type is allowed all the way back to the MVP, so
899+
// don't check it here.
899900
if ty.element_type != RefType::FUNCREF {
900901
self.check_ref_type(&mut ty.element_type, features, offset)?
901902
}
@@ -914,6 +915,23 @@ impl Module {
914915
offset,
915916
));
916917
}
918+
919+
if ty.shared {
920+
if !features.shared_everything_threads() {
921+
return Err(BinaryReaderError::new(
922+
"shared tables require the shared-everything-threads proposal",
923+
offset,
924+
));
925+
}
926+
927+
if !types.reftype_is_shared(ty.element_type) {
928+
return Err(BinaryReaderError::new(
929+
"shared tables must have a shared element type",
930+
offset,
931+
));
932+
}
933+
}
934+
917935
Ok(())
918936
}
919937

crates/wasmparser/src/validator/types.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,19 +2834,23 @@ impl TypeList {
28342834
}
28352835

28362836
/// Is `ty` shared?
2837-
///
2838-
/// This is complicated by reference types, since they may have concrete
2839-
/// heap types whose shared-ness must be checked by looking at the type they
2840-
/// point to.
28412837
pub fn valtype_is_shared(&self, ty: ValType) -> bool {
28422838
match ty {
28432839
ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => true,
2844-
ValType::Ref(rt) => match rt.heap_type() {
2845-
HeapType::Abstract { shared, .. } => shared,
2846-
HeapType::Concrete(index) => {
2847-
self[index.as_core_type_id().unwrap()].composite_type.shared
2848-
}
2849-
},
2840+
ValType::Ref(rt) => self.reftype_is_shared(rt),
2841+
}
2842+
}
2843+
2844+
/// Is the reference type `ty` shared?
2845+
///
2846+
/// This is complicated by concrete heap types whose shared-ness must be
2847+
/// checked by looking at the type they point to.
2848+
pub fn reftype_is_shared(&self, ty: RefType) -> bool {
2849+
match ty.heap_type() {
2850+
HeapType::Abstract { shared, .. } => shared,
2851+
HeapType::Concrete(index) => {
2852+
self[index.as_core_type_id().unwrap()].composite_type.shared
2853+
}
28502854
}
28512855
}
28522856

0 commit comments

Comments
 (0)