Repository: bytecodealliance/wasm-tools
Pull request #2162 (2025-04-28 20:29:20)

Align cancellation with upstream specification
* Adjust binary opcodes for `task.cancel` and `subtask.cancel`
* Adjust the core signature for the `yield` intrinsic.


Patch:
diff --git a/crates/wasm-encoder/src/component/canonicals.rs b/crates/wasm-encoder/src/component/canonicals.rs
index bd1c4ba0..acf2713b 100644
--- a/crates/wasm-encoder/src/component/canonicals.rs
+++ b/crates/wasm-encoder/src/component/canonicals.rs
@@ -212,7 +212,7 @@ impl CanonicalFunctionSection {
 
     /// Defines a function to acknowledge cancellation of the current task.
     pub fn task_cancel(&mut self) -> &mut Self {
-        self.bytes.push(0x25);
+        self.bytes.push(0x05);
         self.num_added += 1;
         self
     }
@@ -255,7 +255,7 @@ impl CanonicalFunctionSection {
 
     /// Defines a function to cancel an in-progress task.
     pub fn subtask_cancel(&mut self, async_: bool) -> &mut Self {
-        self.bytes.push(0x24);
+        self.bytes.push(0x06);
         self.bytes.push(if async_ { 1 } else { 0 });
         self.num_added += 1;
         self
diff --git a/crates/wasmparser/src/readers/component/canonicals.rs b/crates/wasmparser/src/readers/component/canonicals.rs
index f7160544..083167cd 100644
--- a/crates/wasmparser/src/readers/component/canonicals.rs
+++ b/crates/wasmparser/src/readers/component/canonicals.rs
@@ -367,10 +367,10 @@ impl<'a> FromReader<'a> for CanonicalFunction {
             },
             0x22 => CanonicalFunction::WaitableSetDrop,
             0x23 => CanonicalFunction::WaitableJoin,
-            0x24 => CanonicalFunction::SubtaskCancel {
+            0x06 => CanonicalFunction::SubtaskCancel {
                 async_: reader.read()?,
             },
-            0x25 => CanonicalFunction::TaskCancel,
+            0x05 => CanonicalFunction::TaskCancel,
             0x40 => CanonicalFunction::ThreadSpawnRef {
                 func_ty_index: reader.read()?,
             },
diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs
index 514198af..6e5000f9 100644
--- a/crates/wasmparser/src/validator/component.rs
+++ b/crates/wasmparser/src/validator/component.rs
@@ -1268,7 +1268,7 @@ impl ComponentState {
         }
 
         self.core_funcs
-            .push(types.intern_func_type(FuncType::new([], []), offset));
+            .push(types.intern_func_type(FuncType::new([], [ValType::I32]), offset));
         Ok(())
     }
 
diff --git a/crates/wit-component/src/dummy.rs b/crates/wit-component/src/dummy.rs
index 003bed34..0cccff00 100644
--- a/crates/wit-component/src/dummy.rs
+++ b/crates/wit-component/src/dummy.rs
@@ -379,7 +379,7 @@ fn push_root_async_intrinsics(dst: &mut String) {
 (import "$root" "[waitable-set-poll]" (func (param i32 i32) (result i32)))
 (import "$root" "[waitable-set-drop]" (func (param i32)))
 (import "$root" "[waitable-join]" (func (param i32 i32)))
-(import "$root" "[yield]" (func))
+(import "$root" "[yield]" (func (result i32)))
 (import "$root" "[subtask-drop]" (func (param i32)))
 (import "$root" "[subtask-cancel]" (func (param i32) (result i32)))
 (import "$root" "[error-context-new-utf8]" (func (param i32 i32) (result i32)))
@@ -395,7 +395,7 @@ fn push_root_async_intrinsics(dst: &mut String) {
 ;; deferred behind 🚝 or 🚟 upstream
 ;;(import "$root" "[async-lower][waitable-set-wait]" (func (param i32 i32) (result i32)))
 ;;(import "$root" "[async-lower][waitable-set-poll]" (func (param i32 i32) (result i32)))
-;;(import "$root" "[async-lower][yield]" (func))
+;;(import "$root" "[async-lower][yield]" (func (result i32)))
 "#,
     );
 }
diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs
index 211a774a..8e2d81cf 100644
--- a/crates/wit-component/src/validation.rs
+++ b/crates/wit-component/src/validation.rs
@@ -607,7 +607,7 @@ impl ImportMap {
             }
 
             if Some(name) == names.yield_() {
-                let expected = FuncType::new([], []);
+                let expected = FuncType::new([], [ValType::I32]);
                 validate_func_sig(name, &expected, ty)?;
                 return Ok(Import::Yield { async_ });
             }


Test patch:
diff --git a/crates/wit-component/tests/components/async-builtins/component.wat b/crates/wit-component/tests/components/async-builtins/component.wat
index ff4caf87..e84346ac 100644
--- a/crates/wit-component/tests/components/async-builtins/component.wat
+++ b/crates/wit-component/tests/components/async-builtins/component.wat
@@ -16,7 +16,7 @@
     (import "$root" "[waitable-set-poll]" (func (;6;) (type 4)))
     (import "$root" "[waitable-set-drop]" (func (;7;) (type 0)))
     (import "$root" "[waitable-join]" (func (;8;) (type 2)))
-    (import "$root" "[yield]" (func (;9;) (type 1)))
+    (import "$root" "[yield]" (func (;9;) (type 3)))
     (import "$root" "[subtask-drop]" (func (;10;) (type 0)))
     (import "$root" "[subtask-cancel]" (func (;11;) (type 5)))
     (import "$root" "[error-context-new-utf8]" (func (;12;) (type 4)))
diff --git a/crates/wit-component/tests/components/async-builtins/module.wat b/crates/wit-component/tests/components/async-builtins/module.wat
index ba3fadc7..adb7a582 100644
--- a/crates/wit-component/tests/components/async-builtins/module.wat
+++ b/crates/wit-component/tests/components/async-builtins/module.wat
@@ -8,7 +8,7 @@
   (import "$root" "[waitable-set-poll]" (func (param i32 i32) (result i32)))
   (import "$root" "[waitable-set-drop]" (func (param i32)))
   (import "$root" "[waitable-join]" (func (param i32 i32)))
-  (import "$root" "[yield]" (func))
+  (import "$root" "[yield]" (func (result i32)))
   (import "$root" "[subtask-drop]" (func (param i32)))
   (import "$root" "[subtask-cancel]" (func (param i32) (result i32)))
   (import "$root" "[error-context-new-utf8]" (func (param i32 i32) (result i32)))
diff --git a/tests/cli/component-model-async/task-builtins.wast b/tests/cli/component-model-async/task-builtins.wast
index f1bca5d9..2cb8ed64 100644
--- a/tests/cli/component-model-async/task-builtins.wast
+++ b/tests/cli/component-model-async/task-builtins.wast
@@ -182,7 +182,7 @@
 ;; yield
 (component
   (core module $m
-    (import "" "yield" (func $yield))
+    (import "" "yield" (func $yield (result i32)))
   )
   (core func $yield (canon yield async))
   (core instance $i (instantiate $m (with "" (instance (export "yield" (func $yield))))))
diff --git a/tests/snapshots/cli/component-model-async/task-builtins.wast/19.print b/tests/snapshots/cli/component-model-async/task-builtins.wast/19.print
index 7034e8c4..d99f410b 100644
--- a/tests/snapshots/cli/component-model-async/task-builtins.wast/19.print
+++ b/tests/snapshots/cli/component-model-async/task-builtins.wast/19.print
@@ -1,6 +1,6 @@
 (component
   (core module $m (;0;)
-    (type (;0;) (func))
+    (type (;0;) (func (result i32)))
     (import "" "yield" (func $yield (;0;) (type 0)))
   )
   (core func $yield (;0;) (canon yield async))