Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit af0bc4a

Browse files
committed
add plumbing for subtask.cancel intrinisic
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 2d6ba48 commit af0bc4a

11 files changed

Lines changed: 128 additions & 24 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -595,18 +595,18 @@ lto = true
595595

596596
# TODO: remove this once we've switched to a wasm-tools/wit-bindgen release:
597597
[patch.crates-io]
598-
wasmparser = { git = "https://github.com/bytecodealliance/wasm-tools" }
599-
wat = { git = "https://github.com/bytecodealliance/wasm-tools" }
600-
wast = { git = "https://github.com/bytecodealliance/wasm-tools" }
601-
wasmprinter = { git = "https://github.com/bytecodealliance/wasm-tools" }
602-
wasm-encoder = { git = "https://github.com/bytecodealliance/wasm-tools" }
603-
wasm-smith = { git = "https://github.com/bytecodealliance/wasm-tools" }
604-
wasm-mutate = { git = "https://github.com/bytecodealliance/wasm-tools" }
605-
wit-parser = { git = "https://github.com/bytecodealliance/wasm-tools" }
606-
wit-component = { git = "https://github.com/bytecodealliance/wasm-tools" }
607-
wasm-wave = { git = "https://github.com/bytecodealliance/wasm-tools" }
608-
wasm-compose = { git = "https://github.com/bytecodealliance/wasm-tools" }
609-
wasm-metadata = { git = "https://github.com/bytecodealliance/wasm-tools" }
598+
wasmparser = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
599+
wat = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
600+
wast = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
601+
wasmprinter = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
602+
wasm-encoder = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
603+
wasm-smith = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
604+
wasm-mutate = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
605+
wit-parser = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
606+
wit-component = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
607+
wasm-wave = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
608+
wasm-compose = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
609+
wasm-metadata = { git = "https://github.com/dicej/wasm-tools", branch = "subtask-cancel" }
610610
wit-bindgen = { git = "https://github.com/bytecodealliance/witx-bindgen" }
611611
wit-bindgen-rt = { git = "https://github.com/bytecodealliance/witx-bindgen" }
612612
wit-bindgen-rust-macro = { git = "https://github.com/bytecodealliance/witx-bindgen" }

crates/cranelift/src/compiler/component.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ impl<'a> TrampolineCompiler<'a> {
133133
Trampoline::WaitableJoin { instance } => self.translate_waitable_join(*instance),
134134
Trampoline::Yield { async_ } => self.translate_yield_call(*async_),
135135
Trampoline::SubtaskDrop { instance } => self.translate_subtask_drop_call(*instance),
136+
Trampoline::SubtaskCancel { instance, async_ } => {
137+
self.translate_subtask_cancel_call(*instance, *async_)
138+
}
136139
Trampoline::StreamNew { ty } => self.translate_future_or_stream_call(
137140
&[ty.as_u32()],
138141
None,
@@ -1180,6 +1183,33 @@ impl<'a> TrampolineCompiler<'a> {
11801183
);
11811184
}
11821185

1186+
fn translate_subtask_cancel_call(
1187+
&mut self,
1188+
caller_instance: RuntimeComponentInstanceIndex,
1189+
async_: bool,
1190+
) {
1191+
let args = self.builder.func.dfg.block_params(self.block0).to_vec();
1192+
let vmctx = args[0];
1193+
let mut callee_args = vec![
1194+
vmctx,
1195+
self.builder
1196+
.ins()
1197+
.iconst(ir::types::I32, i64::from(caller_instance.as_u32())),
1198+
self.builder
1199+
.ins()
1200+
.iconst(ir::types::I8, if async_ { 1 } else { 0 }),
1201+
];
1202+
1203+
callee_args.extend(args[2..].iter().copied());
1204+
1205+
self.translate_intrinsic_libcall(
1206+
vmctx,
1207+
host::subtask_cancel,
1208+
&callee_args,
1209+
TrapSentinel::NegativeOne,
1210+
);
1211+
}
1212+
11831213
fn load_optional_memory(
11841214
&mut self,
11851215
vmctx: ir::Value,

crates/environ/src/component.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ macro_rules! foreach_builtin_component_function {
102102
#[cfg(feature = "component-model-async")]
103103
subtask_drop(vmctx: vmctx, caller_instance: u32, task_id: u32) -> bool;
104104
#[cfg(feature = "component-model-async")]
105+
subtask_cancel(vmctx: vmctx, caller_instance: u32, async_: u8, task_id: u32) -> bool;
106+
#[cfg(feature = "component-model-async")]
105107
sync_enter(vmctx: vmctx, memory: ptr_u8, start: ptr_u8, return_: ptr_u8, caller_instance: u32, task_return_type: u32, string_encoding: u32, result_count: u32, storage: ptr_u8, storage_len: size) -> bool;
106108
#[cfg(feature = "component-model-async")]
107109
sync_exit(vmctx: vmctx, callback: ptr_u8, caller_instance: u32, callee: ptr_u8, callee_instance: u32, param_count: u32, storage: ptr_u8, storage_len: size) -> bool;

crates/environ/src/component/dfg.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ pub enum Trampoline {
316316
SubtaskDrop {
317317
instance: RuntimeComponentInstanceIndex,
318318
},
319+
SubtaskCancel {
320+
instance: RuntimeComponentInstanceIndex,
321+
async_: bool,
322+
},
319323
StreamNew {
320324
ty: TypeStreamTableIndex,
321325
},
@@ -826,6 +830,10 @@ impl LinearizeDfg<'_> {
826830
Trampoline::SubtaskDrop { instance } => info::Trampoline::SubtaskDrop {
827831
instance: *instance,
828832
},
833+
Trampoline::SubtaskCancel { instance, async_ } => info::Trampoline::SubtaskCancel {
834+
instance: *instance,
835+
async_: *async_,
836+
},
829837
Trampoline::StreamNew { ty } => info::Trampoline::StreamNew { ty: *ty },
830838
Trampoline::StreamRead { ty, options } => info::Trampoline::StreamRead {
831839
ty: *ty,

crates/environ/src/component/info.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,15 @@ pub enum Trampoline {
775775
instance: RuntimeComponentInstanceIndex,
776776
},
777777

778+
/// A `subtask.cancel` intrinsic to drop an in-progress task.
779+
SubtaskCancel {
780+
/// The specific component instance which is calling the intrinsic.
781+
instance: RuntimeComponentInstanceIndex,
782+
/// If `false`, block until cancellation completes rather than return
783+
/// `BLOCKED`.
784+
async_: bool,
785+
},
786+
778787
/// A `stream.new` intrinsic to create a new `stream` handle of the
779788
/// specified type.
780789
StreamNew {
@@ -1049,6 +1058,7 @@ impl Trampoline {
10491058
WaitableJoin { .. } => format!("waitable-join"),
10501059
Yield { .. } => format!("yield"),
10511060
SubtaskDrop { .. } => format!("subtask-drop"),
1061+
SubtaskCancel { .. } => format!("subtask-cancel"),
10521062
StreamNew { .. } => format!("stream-new"),
10531063
StreamRead { .. } => format!("stream-read"),
10541064
StreamWrite { .. } => format!("stream-write"),

crates/environ/src/component/translate.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ enum LocalInitializer<'data> {
222222
SubtaskDrop {
223223
func: ModuleInternedTypeIndex,
224224
},
225+
SubtaskCancel {
226+
func: ModuleInternedTypeIndex,
227+
async_: bool,
228+
},
225229
StreamNew {
226230
ty: ComponentDefinedTypeId,
227231
func: ModuleInternedTypeIndex,
@@ -718,6 +722,11 @@ impl<'a, 'data> Translator<'a, 'data> {
718722
core_func_index += 1;
719723
LocalInitializer::SubtaskDrop { func }
720724
}
725+
wasmparser::CanonicalFunction::SubtaskCancel { async_ } => {
726+
let func = self.core_func_signature(core_func_index)?;
727+
core_func_index += 1;
728+
LocalInitializer::SubtaskCancel { func, async_ }
729+
}
721730
wasmparser::CanonicalFunction::StreamNew { ty } => {
722731
let ty = types.component_defined_type_at(ty);
723732
let func = self.core_func_signature(core_func_index)?;

crates/environ/src/component/translate/inline.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,16 @@ impl<'a> Inliner<'a> {
775775
));
776776
frame.funcs.push(dfg::CoreDef::Trampoline(index));
777777
}
778+
SubtaskCancel { func, async_ } => {
779+
let index = self.result.trampolines.push((
780+
*func,
781+
dfg::Trampoline::SubtaskCancel {
782+
instance: frame.instance,
783+
async_: *async_,
784+
},
785+
));
786+
frame.funcs.push(dfg::CoreDef::Trampoline(index));
787+
}
778788
StreamNew { ty, func } => {
779789
let InterfaceType::Stream(ty) =
780790
types.defined_type(frame.translation.types_ref(), *ty)?

crates/wasmtime/src/runtime/component/concurrent.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,16 @@ impl ComponentInstance {
22622262
Ok(())
22632263
}
22642264

2265+
pub(crate) fn subtask_cancel(
2266+
&mut self,
2267+
caller_instance: RuntimeComponentInstanceIndex,
2268+
async_: bool,
2269+
task_id: u32,
2270+
) -> Result<()> {
2271+
_ = (caller_instance, async_, task_id);
2272+
todo!()
2273+
}
2274+
22652275
pub(crate) fn context_get(&mut self, slot: u32) -> Result<u32> {
22662276
let task = self.guest_task().unwrap();
22672277
Ok(self.get(task)?.context[usize::try_from(slot).unwrap()])

crates/wasmtime/src/runtime/vm/component/libcalls.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,22 @@ unsafe fn subtask_drop(
716716
})
717717
}
718718

719+
#[cfg(feature = "component-model-async")]
720+
unsafe fn subtask_cancel(
721+
vmctx: NonNull<VMComponentContext>,
722+
caller_instance: u32,
723+
async_: u8,
724+
task_id: u32,
725+
) -> Result<()> {
726+
ComponentInstance::from_vmctx(vmctx, |instance| {
727+
instance.subtask_cancel(
728+
wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32(caller_instance),
729+
async_ != 0,
730+
task_id,
731+
)
732+
})
733+
}
734+
719735
#[cfg(feature = "component-model-async")]
720736
unsafe fn sync_enter(
721737
vmctx: NonNull<VMComponentContext>,

0 commit comments

Comments
 (0)