Skip to content

Commit 803b5cf

Browse files
committed
Gate synchronous future/stream read/write separately
This commit renames the previous `CM_ASYNC_BUILTINS` feature to `CM_MORE_ASYNC_BUILTINS` and then moves synchronous future/stream reads/writes behind this feature. This is inspired by bytecodealliance/wasmtime#13212 and corresponds to WebAssembly/component-model#641.
1 parent 7478232 commit 803b5cf

19 files changed

Lines changed: 169 additions & 70 deletions

File tree

crates/wasmparser/src/features.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,12 @@ define_wasm_features! {
259259
/// Corresponds to the 🚟 character in
260260
/// <https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md>.
261261
pub cm_async_stackful: CM_ASYNC_STACKFUL(1 << 28) = false;
262-
/// Gates some intrinsics being marked with `async` in the component
262+
/// Gates some intrinsics and options on intrinsics in the component
263263
/// model async proposal.
264264
///
265265
/// Corresponds to the 🚝 character in
266266
/// <https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md>.
267-
pub cm_async_builtins: CM_ASYNC_BUILTINS(1 << 29) = false;
267+
pub cm_more_async_builtins: CM_MORE_ASYNC_BUILTINS(1 << 29) = false;
268268
/// Support for threading in the component model proposal.
269269
///
270270
/// Corresponds to the 🧵 character in

crates/wasmparser/src/validator/component.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ impl ComponentState {
12341234
self.future_read(ty, &options, types, offset)
12351235
}
12361236
CanonicalFunction::FutureWrite { ty, options } => {
1237-
self.future_write(ty, options.into_vec(), types, offset)
1237+
self.future_write(ty, &options, types, offset)
12381238
}
12391239
CanonicalFunction::FutureCancelRead { ty, async_ } => {
12401240
self.future_cancel_read(ty, async_, types, offset)
@@ -1386,10 +1386,10 @@ impl ComponentState {
13861386
types: &mut TypeAlloc,
13871387
offset: usize,
13881388
) -> Result<()> {
1389-
if !self.features.cm_async_builtins() {
1389+
if !self.features.cm_more_async_builtins() {
13901390
bail!(
13911391
offset,
1392-
"`resource.drop` as `async` requires the component model async builtins feature"
1392+
"`resource.drop` as `async` requires the component model more async builtins feature"
13931393
)
13941394
}
13951395
self.resource_at(resource, types, offset)?;
@@ -1608,10 +1608,10 @@ impl ComponentState {
16081608
"`subtask.cancel` requires the component model async feature"
16091609
)
16101610
}
1611-
if async_ && !self.features.cm_async_builtins() {
1611+
if async_ && !self.features.cm_more_async_builtins() {
16121612
bail!(
16131613
offset,
1614-
"async `subtask.cancel` requires the component model async builtins feature"
1614+
"async `subtask.cancel` requires the component model more async builtins feature"
16151615
)
16161616
}
16171617

@@ -1657,8 +1657,14 @@ impl ComponentState {
16571657
bail!(offset, "`stream.read` requires a stream type")
16581658
};
16591659

1660-
let ty_id = self
1661-
.check_options(types, options, offset)?
1660+
let options = self.check_options(types, options, offset)?;
1661+
if options.concurrency.is_sync() && !self.features.cm_more_async_builtins() {
1662+
bail!(
1663+
offset,
1664+
"synchronous `stream.read` requires the component model more async builtins feature"
1665+
);
1666+
}
1667+
let ty_id = options
16621668
.require_memory_if(offset, || elem_ty.is_some())?
16631669
.require_realloc_if(offset, || elem_ty.is_some_and(|ty| ty.contains_ptr(types)))?
16641670
.check_lower(offset)?
@@ -1691,8 +1697,14 @@ impl ComponentState {
16911697
bail!(offset, "`stream.write` requires a stream type")
16921698
};
16931699

1694-
let ty_id = self
1695-
.check_options(types, options, offset)?
1700+
let options = self.check_options(types, options, offset)?;
1701+
if options.concurrency.is_sync() && !self.features.cm_more_async_builtins() {
1702+
bail!(
1703+
offset,
1704+
"synchronous `stream.write` requires the component model more async builtins feature"
1705+
);
1706+
}
1707+
let ty_id = options
16961708
.require_memory_if(offset, || elem_ty.is_some())?
16971709
.check_lower(offset)?
16981710
.check_core_type(
@@ -1718,10 +1730,10 @@ impl ComponentState {
17181730
"`stream.cancel-read` requires the component model async feature"
17191731
)
17201732
}
1721-
if cancellable && !self.features.cm_async_builtins() {
1733+
if cancellable && !self.features.cm_more_async_builtins() {
17221734
bail!(
17231735
offset,
1724-
"async `stream.cancel-read` requires the component model async builtins feature"
1736+
"async `stream.cancel-read` requires the component model more async builtins feature"
17251737
)
17261738
}
17271739

@@ -1748,10 +1760,10 @@ impl ComponentState {
17481760
"`stream.cancel-write` requires the component model async feature"
17491761
)
17501762
}
1751-
if cancellable && !self.features.cm_async_builtins() {
1763+
if cancellable && !self.features.cm_more_async_builtins() {
17521764
bail!(
17531765
offset,
1754-
"async `stream.cancel-write` requires the component model async builtins feature"
1766+
"async `stream.cancel-write` requires the component model more async builtins feature"
17551767
)
17561768
}
17571769

@@ -1848,8 +1860,14 @@ impl ComponentState {
18481860
bail!(offset, "`future.read` requires a future type")
18491861
};
18501862

1851-
let ty_id = self
1852-
.check_options(types, options, offset)?
1863+
let options = self.check_options(types, options, offset)?;
1864+
if options.concurrency.is_sync() && !self.features.cm_more_async_builtins() {
1865+
bail!(
1866+
offset,
1867+
"synchronous `future.read` requires the component model more async builtins feature"
1868+
);
1869+
}
1870+
let ty_id = options
18531871
.require_memory_if(offset, || elem_ty.is_some())?
18541872
.require_realloc_if(offset, || elem_ty.is_some_and(|ty| ty.contains_ptr(types)))?
18551873
.check_lower(offset)?
@@ -1866,7 +1884,7 @@ impl ComponentState {
18661884
fn future_write(
18671885
&mut self,
18681886
ty: u32,
1869-
options: Vec<CanonicalOption>,
1887+
options: &[CanonicalOption],
18701888
types: &mut TypeAlloc,
18711889
offset: usize,
18721890
) -> Result<()> {
@@ -1882,8 +1900,14 @@ impl ComponentState {
18821900
bail!(offset, "`future.write` requires a future type")
18831901
};
18841902

1885-
let ty_id = self
1886-
.check_options(types, &options, offset)?
1903+
let options = self.check_options(types, &options, offset)?;
1904+
if options.concurrency.is_sync() && !self.features.cm_more_async_builtins() {
1905+
bail!(
1906+
offset,
1907+
"synchronous `future.write` requires the component model more async builtins feature"
1908+
);
1909+
}
1910+
let ty_id = options
18871911
.require_memory_if(offset, || elem_ty.is_some())?
18881912
.check_core_type(
18891913
types,
@@ -1908,10 +1932,10 @@ impl ComponentState {
19081932
"`future.cancel-read` requires the component model async feature"
19091933
)
19101934
}
1911-
if cancellable && !self.features.cm_async_builtins() {
1935+
if cancellable && !self.features.cm_more_async_builtins() {
19121936
bail!(
19131937
offset,
1914-
"async `future.cancel-read` requires the component model async builtins feature"
1938+
"async `future.cancel-read` requires the component model more async builtins feature"
19151939
)
19161940
}
19171941

@@ -1938,10 +1962,10 @@ impl ComponentState {
19381962
"`future.cancel-write` requires the component model async feature"
19391963
)
19401964
}
1941-
if cancellable && !self.features.cm_async_builtins() {
1965+
if cancellable && !self.features.cm_more_async_builtins() {
19421966
bail!(
19431967
offset,
1944-
"async `future.cancel-write` requires the component model async builtins feature"
1968+
"async `future.cancel-write` requires the component model more async builtins feature"
19451969
)
19461970
}
19471971

crates/wit-component/src/dummy.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ fn push_imported_future_and_stream_intrinsics(
208208
wat.push_str(&format!(
209209
r#"
210210
(import {module:?} {new:?} (func (result i64)))
211-
(import {module:?} {read:?} (func (param i32 i32) (result i32)))
212-
(import {module:?} {write:?} (func (param i32 i32) (result i32)))
213211
(import {module:?} {cancel_read:?} (func (param i32) (result i32)))
214212
(import {module:?} {cancel_write:?} (func (param i32) (result i32)))
215213
(import {module:?} {drop_readable:?} (func (param i32)))
@@ -218,6 +216,8 @@ fn push_imported_future_and_stream_intrinsics(
218216
(import {module:?} {async_write:?} (func (param i32 i32) (result i32)))
219217
220218
;; deferred behind 🚝
219+
;;(import {module:?} {read:?} (func (param i32 i32) (result i32)))
220+
;;(import {module:?} {write:?} (func (param i32 i32) (result i32)))
221221
;;(import {module:?} {async_cancel_read:?} (func (param i32) (result i32)))
222222
;;(import {module:?} {async_cancel_write:?} (func (param i32) (result i32)))
223223
"#
@@ -261,8 +261,6 @@ fn push_imported_future_and_stream_intrinsics(
261261
wat.push_str(&format!(
262262
r#"
263263
(import {module:?} {new:?} (func (result i64)))
264-
(import {module:?} {read:?} (func (param i32 i32 i32) (result i32)))
265-
(import {module:?} {write:?} (func (param i32 i32 i32) (result i32)))
266264
(import {module:?} {cancel_read:?} (func (param i32) (result i32)))
267265
(import {module:?} {cancel_write:?} (func (param i32) (result i32)))
268266
(import {module:?} {drop_readable:?} (func (param i32)))
@@ -271,6 +269,8 @@ fn push_imported_future_and_stream_intrinsics(
271269
(import {module:?} {async_write:?} (func (param i32 i32 i32) (result i32)))
272270
273271
;; deferred behind 🚝
272+
;;(import {module:?} {read:?} (func (param i32 i32 i32) (result i32)))
273+
;;(import {module:?} {write:?} (func (param i32 i32 i32) (result i32)))
274274
;;(import {module:?} {async_cancel_read:?} (func (param i32) (result i32)))
275275
;;(import {module:?} {async_cancel_write:?} (func (param i32) (result i32)))
276276
"#

crates/wit-parser/tests/ui/parse-fail/bad-include1.wit.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ interface or world `non-existence` does not exist
22
--> tests/ui/parse-fail/bad-include1.wit:4:11
33
|
44
4 | include non-existence;
5-
| ^------------
5+
| ^------------

tests/cli/component-model/async/async-builtins.wast

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;; RUN: wast --assert default --snapshot tests/snapshots % -f cm-async,cm-async-builtins
1+
;; RUN: wast --assert default --snapshot tests/snapshots % -f cm-async,cm-more-async-builtins
22

33
;; stream.cancel-read
44
(component
@@ -101,3 +101,13 @@
101101
)
102102
"type mismatch for export `future.cancel-write` of module instantiation argument ``"
103103
)
104+
105+
;; synchronous future/stream read/write
106+
(component
107+
(type $f (future))
108+
(type $s (stream))
109+
(core func (canon future.read $f))
110+
(core func (canon future.write $f))
111+
(core func (canon stream.read $s))
112+
(core func (canon stream.write $s))
113+
)

tests/cli/component-model/async/futures.wast

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@
161161
(core func $future-cancel-read (canon future.cancel-read $future-type async))
162162
(core instance $i (instantiate $m (with "" (instance (export "future.cancel-read" (func $future-cancel-read))))))
163163
)
164-
"requires the component model async builtins feature")
164+
"requires the component model more async builtins feature")
165165

166166
;; future.cancel-read; incorrect type
167167
(assert_invalid
@@ -195,7 +195,7 @@
195195
(core func $future-cancel-write (canon future.cancel-write $future-type async))
196196
(core instance $i (instantiate $m (with "" (instance (export "future.cancel-write" (func $future-cancel-write))))))
197197
)
198-
"requires the component model async builtins feature"
198+
"requires the component model more async builtins feature"
199199
)
200200

201201
;; future.cancel-write; incorrect type

tests/cli/component-model/async/streams.wast

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
(core func $stream-cancel-read (canon stream.cancel-read $stream-type async))
153153
(core instance $i (instantiate $m (with "" (instance (export "stream.cancel-read" (func $stream-cancel-read))))))
154154
)
155-
"requires the component model async builtins feature")
155+
"requires the component model more async builtins feature")
156156

157157
;; stream.drop-readable
158158
(component
@@ -187,7 +187,7 @@
187187
(core func $stream-cancel-write (canon stream.cancel-write $stream-type async))
188188
(core instance $i (instantiate $m (with "" (instance (export "stream.cancel-write" (func $stream-cancel-write))))))
189189
)
190-
"requires the component model async builtins feature")
190+
"requires the component model more async builtins feature")
191191

192192
;; stream.drop-writable
193193
(component

tests/cli/component-model/async/task-builtins.wast

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,14 @@
425425
(canon stream.drop-readable $s (core func))
426426
(core func (canon stream.drop-writable $s))
427427
(canon stream.drop-writable $s (core func))
428-
(core func (canon future.read $f (memory $m)))
429-
(canon future.read $f (memory $m) (core func))
430-
(core func (canon future.write $f (memory $m)))
431-
(canon future.write $f (memory $m) (core func))
432-
(core func (canon stream.read $s (memory $m)))
433-
(canon stream.read $s (memory $m) (core func))
434-
(core func (canon stream.write $s (memory $m)))
435-
(canon stream.write $s (memory $m) (core func))
428+
(core func (canon future.read $f (memory $m) async))
429+
(canon future.read $f (memory $m) async (core func))
430+
(core func (canon future.write $f (memory $m) async))
431+
(canon future.write $f (memory $m) async (core func))
432+
(core func (canon stream.read $s (memory $m) async))
433+
(canon stream.read $s (memory $m) async (core func))
434+
(core func (canon stream.write $s (memory $m) async))
435+
(canon stream.write $s (memory $m) async (core func))
436436

437437
(core func (canon context.get i32 0))
438438
(canon context.get i32 0 (core func))

tests/cli/missing-features/component-model/async-builtins.wast

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
;; RUN: wast % --assert default --snapshot tests/snapshots \
2-
;; -f=cm-async,-cm-async-builtins
2+
;; -f=cm-async,-cm-more-async-builtins
33

44
;; {future,stream}.cancel-{read,write}
55
(assert_invalid
66
(component
77
(type $t (future))
88
(core func (canon future.cancel-read $t async)))
9-
"requires the component model async builtins feature")
9+
"requires the component model more async builtins feature")
1010
(assert_invalid
1111
(component
1212
(type $t (future))
1313
(core func (canon future.cancel-write $t async)))
14-
"requires the component model async builtins feature")
14+
"requires the component model more async builtins feature")
1515
(assert_invalid
1616
(component
1717
(type $t (stream))
1818
(core func (canon stream.cancel-read $t async)))
19-
"requires the component model async builtins feature")
19+
"requires the component model more async builtins feature")
2020
(assert_invalid
2121
(component
2222
(type $t (stream))
2323
(core func (canon stream.cancel-write $t async)))
24-
"requires the component model async builtins feature")
24+
"requires the component model more async builtins feature")
2525

2626
(component
2727
(type $f (future))
@@ -37,8 +37,31 @@
3737
(component
3838
(type $t (resource (rep i32)))
3939
(core func (canon resource.drop $t async)))
40-
"requires the component model async builtins feature")
40+
"requires the component model more async builtins feature")
4141
(component
4242
(type $t (resource (rep i32)))
4343
(core func (canon resource.drop $t)))
44-
44+
45+
(assert_invalid
46+
(component
47+
(type $t (stream))
48+
(core func (canon stream.write $t)))
49+
"requires the component model more async builtins feature")
50+
51+
(assert_invalid
52+
(component
53+
(type $t (stream))
54+
(core func (canon stream.read $t)))
55+
"requires the component model more async builtins feature")
56+
57+
(assert_invalid
58+
(component
59+
(type $t (future))
60+
(core func (canon future.write $t)))
61+
"requires the component model more async builtins feature")
62+
63+
(assert_invalid
64+
(component
65+
(type $t (future))
66+
(core func (canon future.read $t)))
67+
"requires the component model more async builtins feature")

tests/cli/missing-features/component-model/async-stackful.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
;; RUN: wast % --assert default --snapshot tests/snapshots \
2-
;; -f=cm-async,-cm-async-builtins
2+
;; -f=cm-async,-cm-more-async-builtins
33

44
(assert_invalid
55
(component

0 commit comments

Comments
 (0)