Skip to content

Commit b91ad7d

Browse files
committed
add wast support for parsing async canon opts
And add tests/local/component-model-async/lift-async.wast for round-trip testing of async lifts (more to come). Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 940de62 commit b91ad7d

File tree

9 files changed

+170
-2
lines changed

9 files changed

+170
-2
lines changed

crates/wast/src/component/binary.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,8 @@ impl From<&CanonOpt<'_>> for wasm_encoder::CanonicalOption {
822822
CanonOpt::Memory(m) => Self::Memory(m.idx.into()),
823823
CanonOpt::Realloc(f) => Self::Realloc(f.idx.into()),
824824
CanonOpt::PostReturn(f) => Self::PostReturn(f.idx.into()),
825+
CanonOpt::Async => Self::Async,
826+
CanonOpt::Callback(f) => Self::Callback(f.idx.into()),
825827
}
826828
}
827829
}

crates/wast/src/component/func.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ pub enum CanonOpt<'a> {
475475
Realloc(CoreItemRef<'a, kw::func>),
476476
/// Call the specified function after the lifted function has returned.
477477
PostReturn(CoreItemRef<'a, kw::func>),
478+
/// Use the async ABI for lifting or lowering.
479+
Async,
480+
/// Use the specified function to deliver async events to stackless coroutines.
481+
Callback(CoreItemRef<'a, kw::func>),
478482
}
479483

480484
impl<'a> Parse<'a> for CanonOpt<'a> {
@@ -489,6 +493,9 @@ impl<'a> Parse<'a> for CanonOpt<'a> {
489493
} else if l.peek::<kw::string_latin1_utf16>()? {
490494
parser.parse::<kw::string_latin1_utf16>()?;
491495
Ok(Self::StringLatin1Utf16)
496+
} else if l.peek::<kw::r#async>()? {
497+
parser.parse::<kw::r#async>()?;
498+
Ok(Self::Async)
492499
} else if l.peek::<LParen>()? {
493500
parser.parens(|parser| {
494501
let mut l = parser.lookahead1();
@@ -508,6 +515,11 @@ impl<'a> Parse<'a> for CanonOpt<'a> {
508515
Ok(CanonOpt::PostReturn(
509516
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
510517
))
518+
} else if l.peek::<kw::callback>()? {
519+
parser.parse::<kw::callback>()?;
520+
Ok(CanonOpt::Callback(
521+
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
522+
))
511523
} else {
512524
Err(l.error())
513525
}

crates/wast/src/component/resolve.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,14 @@ impl<'a> Resolver<'a> {
395395
fn canon_opts(&mut self, opts: &mut [CanonOpt<'a>]) -> Result<(), Error> {
396396
for opt in opts {
397397
match opt {
398-
CanonOpt::StringUtf8 | CanonOpt::StringUtf16 | CanonOpt::StringLatin1Utf16 => {}
398+
CanonOpt::StringUtf8
399+
| CanonOpt::StringUtf16
400+
| CanonOpt::StringLatin1Utf16
401+
| CanonOpt::Async => {}
399402
CanonOpt::Memory(r) => self.core_item_ref(r)?,
400-
CanonOpt::Realloc(r) | CanonOpt::PostReturn(r) => self.core_item_ref(r)?,
403+
CanonOpt::Realloc(r) | CanonOpt::PostReturn(r) | CanonOpt::Callback(r) => {
404+
self.core_item_ref(r)?
405+
}
401406
}
402407
}
403408

crates/wast/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ pub mod kw {
558558
custom_keyword!(thread_hw_concurrency = "thread.hw_concurrency");
559559
custom_keyword!(wait);
560560
custom_keyword!(definition);
561+
custom_keyword!(r#async = "async");
562+
custom_keyword!(callback);
561563
}
562564

563565
/// Common annotations used to parse WebAssembly text files.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
;; async lift; no callback
2+
(component
3+
(core module $m
4+
(func (export "foo") (param i32) (result i32) unreachable)
5+
)
6+
(core instance $i (instantiate $m))
7+
8+
(func (export "foo") (param "p1" u32) (result u32)
9+
(canon lift (core func $i "foo") async)
10+
)
11+
)
12+
13+
;; async lift; with callback
14+
(component
15+
(core module $m
16+
(func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
17+
(func (export "foo") (param i32) (result i32) unreachable)
18+
)
19+
(core instance $i (instantiate $m))
20+
21+
(func (export "foo") (param "p1" u32) (result u32)
22+
(canon lift (core func $i "foo") async (callback (func $i "callback")))
23+
)
24+
)
25+
26+
;; async lift; with incorrectly-typed callback
27+
(assert_invalid
28+
(component
29+
(core module $m
30+
(func (export "callback") (param i32 i32 f32 i32) (result i32) unreachable)
31+
(func (export "foo") (param i32) (result i32) unreachable)
32+
)
33+
(core instance $i (instantiate $m))
34+
35+
(func (export "foo") (param "p1" u32) (result u32)
36+
(canon lift (core func $i "foo") async (callback (func $i "callback")))
37+
)
38+
)
39+
"canonical option `callback` uses a core function with an incorrect signature"
40+
)
41+
42+
;; async lift; with missing callback
43+
(assert_invalid
44+
(component
45+
(core module $m
46+
(func (export "foo") (param i32) (result i32) unreachable)
47+
)
48+
(core instance $i (instantiate $m))
49+
50+
(func (export "foo") (param "p1" u32) (result u32)
51+
(canon lift (core func $i "foo") async (callback (func $i "callback")))
52+
)
53+
)
54+
"core instance 0 has no export named `callback`"
55+
)
56+
57+
;; sync lift; with redundant callback
58+
(assert_invalid
59+
(component
60+
(core module $m
61+
(func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
62+
(func (export "foo") (param i32) (result i32) unreachable)
63+
)
64+
(core instance $i (instantiate $m))
65+
66+
(func (export "foo") (param "p1" u32) (result u32)
67+
(canon lift (core func $i "foo") (callback (func $i "callback")))
68+
)
69+
)
70+
"cannot specify callback without lifting async"
71+
)

tests/roundtrip.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@ impl TestState {
681681
"wide-arithmetic" => {
682682
features.insert(WasmFeatures::WIDE_ARITHMETIC);
683683
}
684+
"component-model-async" => {
685+
features.insert(WasmFeatures::COMPONENT_MODEL);
686+
features.insert(WasmFeatures::COMPONENT_MODEL_ASYNC);
687+
}
684688
_ => {}
685689
}
686690
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"source_filename": "tests/local/component-model-async/lift.wast",
3+
"commands": [
4+
{
5+
"type": "module",
6+
"line": 2,
7+
"filename": "lift.0.wasm",
8+
"module_type": "binary"
9+
},
10+
{
11+
"type": "module",
12+
"line": 14,
13+
"filename": "lift.1.wasm",
14+
"module_type": "binary"
15+
},
16+
{
17+
"type": "assert_invalid",
18+
"line": 28,
19+
"filename": "lift.2.wasm",
20+
"module_type": "binary",
21+
"text": "canonical option `callback` uses a core function with an incorrect signature"
22+
},
23+
{
24+
"type": "assert_invalid",
25+
"line": 44,
26+
"filename": "lift.3.wasm",
27+
"module_type": "binary",
28+
"text": "core instance 0 has no export named `callback`"
29+
},
30+
{
31+
"type": "assert_invalid",
32+
"line": 59,
33+
"filename": "lift.4.wasm",
34+
"module_type": "binary",
35+
"text": "cannot specify callback without lifting async"
36+
}
37+
]
38+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(component
2+
(core module $m (;0;)
3+
(type (;0;) (func (param i32) (result i32)))
4+
(export "foo" (func 0))
5+
(func (;0;) (type 0) (param i32) (result i32)
6+
unreachable
7+
)
8+
)
9+
(core instance $i (;0;) (instantiate $m))
10+
(type (;0;) (func (param "p1" u32) (result u32)))
11+
(alias core export $i "foo" (core func (;0;)))
12+
(func (;0;) (type 0) (canon lift (core func 0) async))
13+
(export (;1;) "foo" (func 0))
14+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(component
2+
(core module $m (;0;)
3+
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
4+
(type (;1;) (func (param i32) (result i32)))
5+
(export "callback" (func 0))
6+
(export "foo" (func 1))
7+
(func (;0;) (type 0) (param i32 i32 i32 i32) (result i32)
8+
unreachable
9+
)
10+
(func (;1;) (type 1) (param i32) (result i32)
11+
unreachable
12+
)
13+
)
14+
(core instance $i (;0;) (instantiate $m))
15+
(type (;0;) (func (param "p1" u32) (result u32)))
16+
(alias core export $i "foo" (core func (;0;)))
17+
(alias core export $i "callback" (core func (;1;)))
18+
(func (;0;) (type 0) (canon lift (core func 0) async (callback 1)))
19+
(export (;1;) "foo" (func 0))
20+
)

0 commit comments

Comments
 (0)