Skip to content

Commit 6fc1601

Browse files
authored
threads: add shared composite types (#1646)
* threads: add `shared` composite types This continues the work of #1600 to expand the surface area of a WebAssembly module that can be marked `shared`. This is for support of the shared-everything-threads [proposal]. The key change is to convert `CompositeType` in each of the crates from an `enum` to a `struct` in order to add a `shared` boolean field. The original variants (`Func`, `Array`, `Struct`) are moved to a separate `enum` and fill an `inner` field. Propagating this throughout the code base is the bulk of this PR, with occasional, small refactors to avoid larger match patterns. [proposal]: https://github.com/WebAssembly/shared-everything-threads * Add `wast` parsing of shared composite types This finishes the work of the previous commit, allowing us to express shared composite types in the text format: `(type $t (shared (...)))`. This also finishes up the heap type testing by allowing the tests to express concrete heap types (e.g., `ref $t`). * Fix some un-formatted files * Add shared check to rec groups For now, this explicitly checks that both subtypes are shared. But it isn't yet clear whether an shared type might be able to match an unshared one. Once that is resolved, this might need to be updated. * Add @tlively `struct` and `array` tests These proposed spec tests are slightly modified from @tlively's originals: - they use this crate's choice of error message - they avoid the shorthand form of a single-field struct, ~(struct <type>)` because this crate does not yet know how to parse that - they avoid the shorthand form for `(elem)` for the same reason All of these minor issues can be resolved later.
1 parent 3ca2d7c commit 6fc1601

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1281
-437
lines changed

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

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,46 @@ impl Encode for SubType {
2525

2626
/// Represents a composite type in a WebAssembly module.
2727
#[derive(Debug, Clone)]
28-
pub enum CompositeType {
29-
/// The type is for a function.
30-
Func(FuncType),
31-
/// The type is for an array.
32-
Array(ArrayType),
33-
/// The type is for a struct.
34-
Struct(StructType),
28+
pub struct CompositeType {
29+
/// The type defined inside the composite type.
30+
pub inner: CompositeInnerType,
31+
/// Whether the type is shared. This is part of the
32+
/// shared-everything-threads proposal.
33+
pub shared: bool,
3534
}
3635

3736
impl Encode for CompositeType {
3837
fn encode(&self, sink: &mut Vec<u8>) {
39-
match self {
40-
CompositeType::Func(ty) => TypeSection::encode_function(
38+
if self.shared {
39+
sink.push(0x65);
40+
}
41+
match &self.inner {
42+
CompositeInnerType::Func(ty) => TypeSection::encode_function(
4143
sink,
4244
ty.params().iter().copied(),
4345
ty.results().iter().copied(),
4446
),
45-
CompositeType::Array(ArrayType(ty)) => {
47+
CompositeInnerType::Array(ArrayType(ty)) => {
4648
TypeSection::encode_array(sink, &ty.element_type, ty.mutable)
4749
}
48-
CompositeType::Struct(ty) => {
50+
CompositeInnerType::Struct(ty) => {
4951
TypeSection::encode_struct(sink, ty.fields.iter().cloned())
5052
}
5153
}
5254
}
5355
}
5456

57+
/// A [`CompositeType`] can contain one of these types.
58+
#[derive(Debug, Clone)]
59+
pub enum CompositeInnerType {
60+
/// The type is for a function.
61+
Func(FuncType),
62+
/// The type is for an array.
63+
Array(ArrayType),
64+
/// The type is for a struct.
65+
Struct(StructType),
66+
}
67+
5568
/// Represents a type of a function in a WebAssembly module.
5669
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
5770
pub struct FuncType {
@@ -635,18 +648,20 @@ impl Section for TypeSection {
635648

636649
#[cfg(test)]
637650
mod tests {
638-
use wasmparser::WasmFeatures;
639-
640651
use super::*;
641652
use crate::Module;
653+
use wasmparser::WasmFeatures;
642654

643655
#[test]
644656
fn func_types_dont_require_wasm_gc() {
645657
let mut types = TypeSection::new();
646658
types.subtype(&SubType {
647659
is_final: true,
648660
supertype_idx: None,
649-
composite_type: CompositeType::Func(FuncType::new([], [])),
661+
composite_type: CompositeType {
662+
inner: CompositeInnerType::Func(FuncType::new([], [])),
663+
shared: false,
664+
},
650665
});
651666

652667
let mut module = Module::new();

crates/wasm-encoder/src/reencode.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,16 +1001,20 @@ pub mod utils {
10011001
reencoder: &mut T,
10021002
composite_ty: wasmparser::CompositeType,
10031003
) -> Result<crate::CompositeType, Error<T::Error>> {
1004-
Ok(match composite_ty {
1005-
wasmparser::CompositeType::Func(f) => {
1006-
crate::CompositeType::Func(reencoder.func_type(f)?)
1004+
let inner = match composite_ty.inner {
1005+
wasmparser::CompositeInnerType::Func(f) => {
1006+
crate::CompositeInnerType::Func(reencoder.func_type(f)?)
10071007
}
1008-
wasmparser::CompositeType::Array(a) => {
1009-
crate::CompositeType::Array(reencoder.array_type(a)?)
1008+
wasmparser::CompositeInnerType::Array(a) => {
1009+
crate::CompositeInnerType::Array(reencoder.array_type(a)?)
10101010
}
1011-
wasmparser::CompositeType::Struct(s) => {
1012-
crate::CompositeType::Struct(reencoder.struct_type(s)?)
1011+
wasmparser::CompositeInnerType::Struct(s) => {
1012+
crate::CompositeInnerType::Struct(reencoder.struct_type(s)?)
10131013
}
1014+
};
1015+
Ok(crate::CompositeType {
1016+
inner,
1017+
shared: composite_ty.shared,
10141018
})
10151019
}
10161020

crates/wasm-smith/src/component.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,12 @@ impl ComponentBuilder {
714714
});
715715
let ty_idx = u32::try_from(types.len()).unwrap();
716716
types.push(realloc_ty.clone());
717-
defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(
718-
realloc_ty.clone(),
719-
)));
717+
defs.push(ModuleTypeDef::TypeDef(
718+
crate::core::CompositeType::new_func(
719+
realloc_ty.clone(),
720+
false, // TODO: handle shared
721+
),
722+
));
720723
defs.push(ModuleTypeDef::Export(
721724
"canonical_abi_realloc".into(),
722725
crate::core::EntityType::Func(ty_idx, realloc_ty),
@@ -737,9 +740,12 @@ impl ComponentBuilder {
737740
});
738741
let ty_idx = u32::try_from(types.len()).unwrap();
739742
types.push(free_ty.clone());
740-
defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(
741-
free_ty.clone(),
742-
)));
743+
defs.push(ModuleTypeDef::TypeDef(
744+
crate::core::CompositeType::new_func(
745+
free_ty.clone(),
746+
false, // TODO: handle shared
747+
),
748+
));
743749
defs.push(ModuleTypeDef::Export(
744750
"canonical_abi_free".into(),
745751
crate::core::EntityType::Func(ty_idx, free_ty),
@@ -832,7 +838,9 @@ impl ComponentBuilder {
832838
0,
833839
)?;
834840
types.push(ty.clone());
835-
defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(ty)));
841+
defs.push(ModuleTypeDef::TypeDef(
842+
crate::core::CompositeType::new_func(ty, false),
843+
)); // TODO: handle shared
836844
}
837845

838846
// Alias

crates/wasm-smith/src/component/encode.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::borrow::Cow;
22

3+
use crate::core::{CompositeInnerType, CompositeType};
4+
35
use super::*;
46
use wasm_encoder::{ComponentExportKind, ComponentOuterAliasKind, ExportKind};
57

@@ -124,7 +126,10 @@ impl CoreType {
124126
let mut enc_mod_ty = wasm_encoder::ModuleType::new();
125127
for def in &mod_ty.defs {
126128
match def {
127-
ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(func_ty)) => {
129+
ModuleTypeDef::TypeDef(CompositeType {
130+
inner: CompositeInnerType::Func(func_ty),
131+
..
132+
}) => {
128133
enc_mod_ty.ty().function(
129134
func_ty.params.iter().copied(),
130135
func_ty.results.iter().copied(),

0 commit comments

Comments
 (0)