Skip to content

Commit

Permalink
Limit component model flags to 32 (#1635)
Browse files Browse the repository at this point in the history
* Limit component model flags to 32

This commit is an attempt to explore the design space of
WebAssembly/component-model#370. This limits, by default, the number of
flags in a component model type to 32 by default. The hope of this issue
is to be able to ratchet the maximum number of flags to make it easier
on bindings generators to not need to work with arbitrary numbers of
flags. The secondary hope is that we can ratchet flags straight to 32
instead of 64 due to it being unlikely that more than 32 flags are in
use. Once this percolates there can then be a separate feature for
enabling 33-64 flags.

* Drop a link
  • Loading branch information
alexcrichton committed Jun 25, 2024
1 parent 659f4a6 commit 2c6f127
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 174 deletions.
2 changes: 2 additions & 0 deletions crates/wasmparser/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ define_wasm_features! {
pub component_model_values: COMPONENT_MODEL_VALUES(1 << 21) = false;
/// Support for the nested namespaces and projects in component model names.
pub component_model_nested_names: COMPONENT_MODEL_NESTED_NAMES(1 << 22) = false;
/// Support for more than 32 flags per-type in the component model.
pub component_model_more_flags: COMPONENT_MODEL_MORE_FLAGS(1 << 23) = false;
}
}

Expand Down
22 changes: 19 additions & 3 deletions crates/wasmparser/src/validator/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ impl ComponentState {

let id = match ty {
crate::ComponentType::Defined(ty) => {
let ty = current(components).create_defined_type(ty, types, offset)?;
let ty = current(components).create_defined_type(ty, types, features, offset)?;
types.push(ty).into()
}
crate::ComponentType::Func(ty) => {
Expand Down Expand Up @@ -2512,6 +2512,7 @@ impl ComponentState {
&self,
ty: crate::ComponentDefinedType,
types: &TypeList,
features: &WasmFeatures,
offset: usize,
) -> Result<ComponentDefinedType> {
match ty {
Expand All @@ -2529,7 +2530,7 @@ impl ComponentState {
self.create_tuple_type(tys.as_ref(), types, offset)
}
crate::ComponentDefinedType::Flags(names) => {
self.create_flags_type(names.as_ref(), offset)
self.create_flags_type(names.as_ref(), features, offset)
}
crate::ComponentDefinedType::Enum(cases) => {
self.create_enum_type(cases.as_ref(), offset)
Expand Down Expand Up @@ -2681,14 +2682,29 @@ impl ComponentState {
Ok(ComponentDefinedType::Tuple(TupleType { info, types }))
}

fn create_flags_type(&self, names: &[&str], offset: usize) -> Result<ComponentDefinedType> {
fn create_flags_type(
&self,
names: &[&str],
features: &WasmFeatures,
offset: usize,
) -> Result<ComponentDefinedType> {
let mut names_set = IndexSet::default();
names_set.reserve(names.len());

if names.is_empty() {
bail!(offset, "flags must have at least one entry");
}

if names.len() > 32 && !features.component_model_more_flags() {
bail!(
offset,
"cannot have more than 32 flags; this was previously \
accepted and if this is required for your project please \
leave a comment on \
https://github.com/WebAssembly/component-model/issues/370"
);
}

for name in names {
let name = to_kebab_str(name, "flag", offset)?;
if !names_set.insert(name.to_owned()) {
Expand Down
56 changes: 24 additions & 32 deletions crates/wit-component/tests/interfaces/flags.wat
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,18 @@
(export (;9;) "flag16" (type (eq 8)))
(type (;10;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31"))
(export (;11;) "flag32" (type (eq 10)))
(type (;12;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31" "b32" "b33" "b34" "b35" "b36" "b37" "b38" "b39" "b40" "b41" "b42" "b43" "b44" "b45" "b46" "b47" "b48" "b49" "b50" "b51" "b52" "b53" "b54" "b55" "b56" "b57" "b58" "b59" "b60" "b61" "b62" "b63"))
(export (;13;) "flag64" (type (eq 12)))
(type (;14;) (func (param "x" 1) (result 1)))
(export (;0;) "roundtrip-flag1" (func (type 14)))
(type (;15;) (func (param "x" 3) (result 3)))
(export (;1;) "roundtrip-flag2" (func (type 15)))
(type (;16;) (func (param "x" 5) (result 5)))
(export (;2;) "roundtrip-flag4" (func (type 16)))
(type (;17;) (func (param "x" 7) (result 7)))
(export (;3;) "roundtrip-flag8" (func (type 17)))
(type (;18;) (func (param "x" 9) (result 9)))
(export (;4;) "roundtrip-flag16" (func (type 18)))
(type (;19;) (func (param "x" 11) (result 11)))
(export (;5;) "roundtrip-flag32" (func (type 19)))
(type (;20;) (func (param "x" 13) (result 13)))
(export (;6;) "roundtrip-flag64" (func (type 20)))
(type (;12;) (func (param "x" 1) (result 1)))
(export (;0;) "roundtrip-flag1" (func (type 12)))
(type (;13;) (func (param "x" 3) (result 3)))
(export (;1;) "roundtrip-flag2" (func (type 13)))
(type (;14;) (func (param "x" 5) (result 5)))
(export (;2;) "roundtrip-flag4" (func (type 14)))
(type (;15;) (func (param "x" 7) (result 7)))
(export (;3;) "roundtrip-flag8" (func (type 15)))
(type (;16;) (func (param "x" 9) (result 9)))
(export (;4;) "roundtrip-flag16" (func (type 16)))
(type (;17;) (func (param "x" 11) (result 11)))
(export (;5;) "roundtrip-flag32" (func (type 17)))
)
)
(export (;0;) "foo:flags/imports" (instance (type 0)))
Expand All @@ -55,22 +51,18 @@
(export (;9;) "flag16" (type (eq 8)))
(type (;10;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31"))
(export (;11;) "flag32" (type (eq 10)))
(type (;12;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31" "b32" "b33" "b34" "b35" "b36" "b37" "b38" "b39" "b40" "b41" "b42" "b43" "b44" "b45" "b46" "b47" "b48" "b49" "b50" "b51" "b52" "b53" "b54" "b55" "b56" "b57" "b58" "b59" "b60" "b61" "b62" "b63"))
(export (;13;) "flag64" (type (eq 12)))
(type (;14;) (func (param "x" 1) (result 1)))
(export (;0;) "roundtrip-flag1" (func (type 14)))
(type (;15;) (func (param "x" 3) (result 3)))
(export (;1;) "roundtrip-flag2" (func (type 15)))
(type (;16;) (func (param "x" 5) (result 5)))
(export (;2;) "roundtrip-flag4" (func (type 16)))
(type (;17;) (func (param "x" 7) (result 7)))
(export (;3;) "roundtrip-flag8" (func (type 17)))
(type (;18;) (func (param "x" 9) (result 9)))
(export (;4;) "roundtrip-flag16" (func (type 18)))
(type (;19;) (func (param "x" 11) (result 11)))
(export (;5;) "roundtrip-flag32" (func (type 19)))
(type (;20;) (func (param "x" 13) (result 13)))
(export (;6;) "roundtrip-flag64" (func (type 20)))
(type (;12;) (func (param "x" 1) (result 1)))
(export (;0;) "roundtrip-flag1" (func (type 12)))
(type (;13;) (func (param "x" 3) (result 3)))
(export (;1;) "roundtrip-flag2" (func (type 13)))
(type (;14;) (func (param "x" 5) (result 5)))
(export (;2;) "roundtrip-flag4" (func (type 14)))
(type (;15;) (func (param "x" 7) (result 7)))
(export (;3;) "roundtrip-flag8" (func (type 15)))
(type (;16;) (func (param "x" 9) (result 9)))
(export (;4;) "roundtrip-flag16" (func (type 16)))
(type (;17;) (func (param "x" 11) (result 11)))
(export (;5;) "roundtrip-flag32" (func (type 17)))
)
)
(import "foo:flags/imports" (instance (;0;) (type 0)))
Expand Down
69 changes: 0 additions & 69 deletions crates/wit-component/tests/interfaces/flags.wit
Original file line number Diff line number Diff line change
Expand Up @@ -82,73 +82,6 @@ interface imports {
b31,
}

flags flag64 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8,
b9,
b10,
b11,
b12,
b13,
b14,
b15,
b16,
b17,
b18,
b19,
b20,
b21,
b22,
b23,
b24,
b25,
b26,
b27,
b28,
b29,
b30,
b31,
b32,
b33,
b34,
b35,
b36,
b37,
b38,
b39,
b40,
b41,
b42,
b43,
b44,
b45,
b46,
b47,
b48,
b49,
b50,
b51,
b52,
b53,
b54,
b55,
b56,
b57,
b58,
b59,
b60,
b61,
b62,
b63,
}

roundtrip-flag1: func(x: flag1) -> flag1;

roundtrip-flag2: func(x: flag2) -> flag2;
Expand All @@ -160,8 +93,6 @@ interface imports {
roundtrip-flag16: func(x: flag16) -> flag16;

roundtrip-flag32: func(x: flag32) -> flag32;

roundtrip-flag64: func(x: flag64) -> flag64;
}

world flags-world {
Expand Down
69 changes: 0 additions & 69 deletions crates/wit-component/tests/interfaces/flags.wit.print
Original file line number Diff line number Diff line change
Expand Up @@ -82,73 +82,6 @@ interface imports {
b31,
}

flags flag64 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8,
b9,
b10,
b11,
b12,
b13,
b14,
b15,
b16,
b17,
b18,
b19,
b20,
b21,
b22,
b23,
b24,
b25,
b26,
b27,
b28,
b29,
b30,
b31,
b32,
b33,
b34,
b35,
b36,
b37,
b38,
b39,
b40,
b41,
b42,
b43,
b44,
b45,
b46,
b47,
b48,
b49,
b50,
b51,
b52,
b53,
b54,
b55,
b56,
b57,
b58,
b59,
b60,
b61,
b62,
b63,
}

roundtrip-flag1: func(x: flag1) -> flag1;

roundtrip-flag2: func(x: flag2) -> flag2;
Expand All @@ -160,8 +93,6 @@ interface imports {
roundtrip-flag16: func(x: flag16) -> flag16;

roundtrip-flag32: func(x: flag32) -> flag32;

roundtrip-flag64: func(x: flag64) -> flag64;
}

world flags-world {
Expand Down
37 changes: 37 additions & 0 deletions tests/local/component-model/more-flags.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(component
(type (flags
"f1"
"f2"
"f3"
"f4"
"f5"
"f6"
"f7"
"f8"
"f9"
"f10"
"f11"
"f12"
"f13"
"f14"
"f15"
"f16"
"f17"
"f18"
"f19"
"f20"
"f21"
"f22"
"f23"
"f24"
"f25"
"f26"
"f27"
"f28"
"f29"
"f30"
"f31"
"f32"
"f33"
))
)
40 changes: 40 additions & 0 deletions tests/local/component-model/types.wast
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,43 @@
))
)
)

(assert_invalid
(component
(type (flags
"f1"
"f2"
"f3"
"f4"
"f5"
"f6"
"f7"
"f8"
"f9"
"f10"
"f11"
"f12"
"f13"
"f14"
"f15"
"f16"
"f17"
"f18"
"f19"
"f20"
"f21"
"f22"
"f23"
"f24"
"f25"
"f26"
"f27"
"f28"
"f29"
"f30"
"f31"
"f32"
"f33"
))
)
"cannot have more than 32 flags")
Loading

0 comments on commit 2c6f127

Please sign in to comment.