Skip to content

Commit 2c6f127

Browse files
authored
Limit component model flags to 32 (#1635)
* 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
1 parent 659f4a6 commit 2c6f127

9 files changed

Lines changed: 130 additions & 174 deletions

File tree

crates/wasmparser/src/features.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ define_wasm_features! {
146146
pub component_model_values: COMPONENT_MODEL_VALUES(1 << 21) = false;
147147
/// Support for the nested namespaces and projects in component model names.
148148
pub component_model_nested_names: COMPONENT_MODEL_NESTED_NAMES(1 << 22) = false;
149+
/// Support for more than 32 flags per-type in the component model.
150+
pub component_model_more_flags: COMPONENT_MODEL_MORE_FLAGS(1 << 23) = false;
149151
}
150152
}
151153

crates/wasmparser/src/validator/component.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl ComponentState {
348348

349349
let id = match ty {
350350
crate::ComponentType::Defined(ty) => {
351-
let ty = current(components).create_defined_type(ty, types, offset)?;
351+
let ty = current(components).create_defined_type(ty, types, features, offset)?;
352352
types.push(ty).into()
353353
}
354354
crate::ComponentType::Func(ty) => {
@@ -2512,6 +2512,7 @@ impl ComponentState {
25122512
&self,
25132513
ty: crate::ComponentDefinedType,
25142514
types: &TypeList,
2515+
features: &WasmFeatures,
25152516
offset: usize,
25162517
) -> Result<ComponentDefinedType> {
25172518
match ty {
@@ -2529,7 +2530,7 @@ impl ComponentState {
25292530
self.create_tuple_type(tys.as_ref(), types, offset)
25302531
}
25312532
crate::ComponentDefinedType::Flags(names) => {
2532-
self.create_flags_type(names.as_ref(), offset)
2533+
self.create_flags_type(names.as_ref(), features, offset)
25332534
}
25342535
crate::ComponentDefinedType::Enum(cases) => {
25352536
self.create_enum_type(cases.as_ref(), offset)
@@ -2681,14 +2682,29 @@ impl ComponentState {
26812682
Ok(ComponentDefinedType::Tuple(TupleType { info, types }))
26822683
}
26832684

2684-
fn create_flags_type(&self, names: &[&str], offset: usize) -> Result<ComponentDefinedType> {
2685+
fn create_flags_type(
2686+
&self,
2687+
names: &[&str],
2688+
features: &WasmFeatures,
2689+
offset: usize,
2690+
) -> Result<ComponentDefinedType> {
26852691
let mut names_set = IndexSet::default();
26862692
names_set.reserve(names.len());
26872693

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

2698+
if names.len() > 32 && !features.component_model_more_flags() {
2699+
bail!(
2700+
offset,
2701+
"cannot have more than 32 flags; this was previously \
2702+
accepted and if this is required for your project please \
2703+
leave a comment on \
2704+
https://github.com/WebAssembly/component-model/issues/370"
2705+
);
2706+
}
2707+
26922708
for name in names {
26932709
let name = to_kebab_str(name, "flag", offset)?;
26942710
if !names_set.insert(name.to_owned()) {

crates/wit-component/tests/interfaces/flags.wat

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,18 @@
1515
(export (;9;) "flag16" (type (eq 8)))
1616
(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"))
1717
(export (;11;) "flag32" (type (eq 10)))
18-
(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"))
19-
(export (;13;) "flag64" (type (eq 12)))
20-
(type (;14;) (func (param "x" 1) (result 1)))
21-
(export (;0;) "roundtrip-flag1" (func (type 14)))
22-
(type (;15;) (func (param "x" 3) (result 3)))
23-
(export (;1;) "roundtrip-flag2" (func (type 15)))
24-
(type (;16;) (func (param "x" 5) (result 5)))
25-
(export (;2;) "roundtrip-flag4" (func (type 16)))
26-
(type (;17;) (func (param "x" 7) (result 7)))
27-
(export (;3;) "roundtrip-flag8" (func (type 17)))
28-
(type (;18;) (func (param "x" 9) (result 9)))
29-
(export (;4;) "roundtrip-flag16" (func (type 18)))
30-
(type (;19;) (func (param "x" 11) (result 11)))
31-
(export (;5;) "roundtrip-flag32" (func (type 19)))
32-
(type (;20;) (func (param "x" 13) (result 13)))
33-
(export (;6;) "roundtrip-flag64" (func (type 20)))
18+
(type (;12;) (func (param "x" 1) (result 1)))
19+
(export (;0;) "roundtrip-flag1" (func (type 12)))
20+
(type (;13;) (func (param "x" 3) (result 3)))
21+
(export (;1;) "roundtrip-flag2" (func (type 13)))
22+
(type (;14;) (func (param "x" 5) (result 5)))
23+
(export (;2;) "roundtrip-flag4" (func (type 14)))
24+
(type (;15;) (func (param "x" 7) (result 7)))
25+
(export (;3;) "roundtrip-flag8" (func (type 15)))
26+
(type (;16;) (func (param "x" 9) (result 9)))
27+
(export (;4;) "roundtrip-flag16" (func (type 16)))
28+
(type (;17;) (func (param "x" 11) (result 11)))
29+
(export (;5;) "roundtrip-flag32" (func (type 17)))
3430
)
3531
)
3632
(export (;0;) "foo:flags/imports" (instance (type 0)))
@@ -55,22 +51,18 @@
5551
(export (;9;) "flag16" (type (eq 8)))
5652
(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"))
5753
(export (;11;) "flag32" (type (eq 10)))
58-
(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"))
59-
(export (;13;) "flag64" (type (eq 12)))
60-
(type (;14;) (func (param "x" 1) (result 1)))
61-
(export (;0;) "roundtrip-flag1" (func (type 14)))
62-
(type (;15;) (func (param "x" 3) (result 3)))
63-
(export (;1;) "roundtrip-flag2" (func (type 15)))
64-
(type (;16;) (func (param "x" 5) (result 5)))
65-
(export (;2;) "roundtrip-flag4" (func (type 16)))
66-
(type (;17;) (func (param "x" 7) (result 7)))
67-
(export (;3;) "roundtrip-flag8" (func (type 17)))
68-
(type (;18;) (func (param "x" 9) (result 9)))
69-
(export (;4;) "roundtrip-flag16" (func (type 18)))
70-
(type (;19;) (func (param "x" 11) (result 11)))
71-
(export (;5;) "roundtrip-flag32" (func (type 19)))
72-
(type (;20;) (func (param "x" 13) (result 13)))
73-
(export (;6;) "roundtrip-flag64" (func (type 20)))
54+
(type (;12;) (func (param "x" 1) (result 1)))
55+
(export (;0;) "roundtrip-flag1" (func (type 12)))
56+
(type (;13;) (func (param "x" 3) (result 3)))
57+
(export (;1;) "roundtrip-flag2" (func (type 13)))
58+
(type (;14;) (func (param "x" 5) (result 5)))
59+
(export (;2;) "roundtrip-flag4" (func (type 14)))
60+
(type (;15;) (func (param "x" 7) (result 7)))
61+
(export (;3;) "roundtrip-flag8" (func (type 15)))
62+
(type (;16;) (func (param "x" 9) (result 9)))
63+
(export (;4;) "roundtrip-flag16" (func (type 16)))
64+
(type (;17;) (func (param "x" 11) (result 11)))
65+
(export (;5;) "roundtrip-flag32" (func (type 17)))
7466
)
7567
)
7668
(import "foo:flags/imports" (instance (;0;) (type 0)))

crates/wit-component/tests/interfaces/flags.wit

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -82,73 +82,6 @@ interface imports {
8282
b31,
8383
}
8484

85-
flags flag64 {
86-
b0,
87-
b1,
88-
b2,
89-
b3,
90-
b4,
91-
b5,
92-
b6,
93-
b7,
94-
b8,
95-
b9,
96-
b10,
97-
b11,
98-
b12,
99-
b13,
100-
b14,
101-
b15,
102-
b16,
103-
b17,
104-
b18,
105-
b19,
106-
b20,
107-
b21,
108-
b22,
109-
b23,
110-
b24,
111-
b25,
112-
b26,
113-
b27,
114-
b28,
115-
b29,
116-
b30,
117-
b31,
118-
b32,
119-
b33,
120-
b34,
121-
b35,
122-
b36,
123-
b37,
124-
b38,
125-
b39,
126-
b40,
127-
b41,
128-
b42,
129-
b43,
130-
b44,
131-
b45,
132-
b46,
133-
b47,
134-
b48,
135-
b49,
136-
b50,
137-
b51,
138-
b52,
139-
b53,
140-
b54,
141-
b55,
142-
b56,
143-
b57,
144-
b58,
145-
b59,
146-
b60,
147-
b61,
148-
b62,
149-
b63,
150-
}
151-
15285
roundtrip-flag1: func(x: flag1) -> flag1;
15386

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

16295
roundtrip-flag32: func(x: flag32) -> flag32;
163-
164-
roundtrip-flag64: func(x: flag64) -> flag64;
16596
}
16697

16798
world flags-world {

crates/wit-component/tests/interfaces/flags.wit.print

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -82,73 +82,6 @@ interface imports {
8282
b31,
8383
}
8484

85-
flags flag64 {
86-
b0,
87-
b1,
88-
b2,
89-
b3,
90-
b4,
91-
b5,
92-
b6,
93-
b7,
94-
b8,
95-
b9,
96-
b10,
97-
b11,
98-
b12,
99-
b13,
100-
b14,
101-
b15,
102-
b16,
103-
b17,
104-
b18,
105-
b19,
106-
b20,
107-
b21,
108-
b22,
109-
b23,
110-
b24,
111-
b25,
112-
b26,
113-
b27,
114-
b28,
115-
b29,
116-
b30,
117-
b31,
118-
b32,
119-
b33,
120-
b34,
121-
b35,
122-
b36,
123-
b37,
124-
b38,
125-
b39,
126-
b40,
127-
b41,
128-
b42,
129-
b43,
130-
b44,
131-
b45,
132-
b46,
133-
b47,
134-
b48,
135-
b49,
136-
b50,
137-
b51,
138-
b52,
139-
b53,
140-
b54,
141-
b55,
142-
b56,
143-
b57,
144-
b58,
145-
b59,
146-
b60,
147-
b61,
148-
b62,
149-
b63,
150-
}
151-
15285
roundtrip-flag1: func(x: flag1) -> flag1;
15386

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

16295
roundtrip-flag32: func(x: flag32) -> flag32;
163-
164-
roundtrip-flag64: func(x: flag64) -> flag64;
16596
}
16697

16798
world flags-world {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
(component
2+
(type (flags
3+
"f1"
4+
"f2"
5+
"f3"
6+
"f4"
7+
"f5"
8+
"f6"
9+
"f7"
10+
"f8"
11+
"f9"
12+
"f10"
13+
"f11"
14+
"f12"
15+
"f13"
16+
"f14"
17+
"f15"
18+
"f16"
19+
"f17"
20+
"f18"
21+
"f19"
22+
"f20"
23+
"f21"
24+
"f22"
25+
"f23"
26+
"f24"
27+
"f25"
28+
"f26"
29+
"f27"
30+
"f28"
31+
"f29"
32+
"f30"
33+
"f31"
34+
"f32"
35+
"f33"
36+
))
37+
)

tests/local/component-model/types.wast

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,43 @@
323323
))
324324
)
325325
)
326+
327+
(assert_invalid
328+
(component
329+
(type (flags
330+
"f1"
331+
"f2"
332+
"f3"
333+
"f4"
334+
"f5"
335+
"f6"
336+
"f7"
337+
"f8"
338+
"f9"
339+
"f10"
340+
"f11"
341+
"f12"
342+
"f13"
343+
"f14"
344+
"f15"
345+
"f16"
346+
"f17"
347+
"f18"
348+
"f19"
349+
"f20"
350+
"f21"
351+
"f22"
352+
"f23"
353+
"f24"
354+
"f25"
355+
"f26"
356+
"f27"
357+
"f28"
358+
"f29"
359+
"f30"
360+
"f31"
361+
"f32"
362+
"f33"
363+
))
364+
)
365+
"cannot have more than 32 flags")

0 commit comments

Comments
 (0)