diff --git a/Cargo.lock b/Cargo.lock index 182b5286a4b6..736ff20d7e80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2224,8 +2224,7 @@ dependencies = [ [[package]] name = "json-from-wast" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74cef75a485ea9c18b6f7c1928bda2ef3a5727227fe7ebab4260626bc75f98e" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "serde", @@ -4371,8 +4370,7 @@ dependencies = [ [[package]] name = "wasm-compose" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd08e5283f98238f2f16f5f978188a33af9901b81186bb549faad306a7b5388" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "heck", @@ -4398,8 +4396,7 @@ dependencies = [ [[package]] name = "wasm-encoder" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e974fe6821a8cf64575d51ea2194e2c8f77e7b66e9afe7419ce8a97f9ee0d251" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "leb128fmt", "wasmparser 0.258.0", @@ -4420,8 +4417,7 @@ dependencies = [ [[package]] name = "wasm-metadata" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a11585adb92fe9b55ad1d760e8d8fb5d87e0d2e303cb8eed57f078d54293a2" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "indexmap 2.14.0", @@ -4432,8 +4428,7 @@ dependencies = [ [[package]] name = "wasm-mutate" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ae9cac04ab7c539efa6b4288726ced0d423c95f1bb63659d74506142ff0499b" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "egg", "log", @@ -4446,8 +4441,7 @@ dependencies = [ [[package]] name = "wasm-smith" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84b31d645ea084a94e1a7c410e30219c165a0960b336f535f99162caf2cfd0c" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "arbitrary", @@ -4469,8 +4463,7 @@ dependencies = [ [[package]] name = "wasm-wave" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1d8cbc89bc22dac012f5fd56fca419330cb88d8d2c8f6ccb313f08ec4a6836" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "logos", @@ -4543,8 +4536,7 @@ dependencies = [ [[package]] name = "wasmparser" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a61719f93a87b16d325921e251800c4833f8fab50fa21c7de73aed50086313" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "bitflags 2.11.1", "hashbrown 0.17.0", @@ -4556,8 +4548,7 @@ dependencies = [ [[package]] name = "wasmprinter" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a65e30fb2cd3cc5cb7761a6064787b2abf017e6566d8d0dedf2bb7f55ad5383" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "termcolor", @@ -5311,8 +5302,7 @@ dependencies = [ [[package]] name = "wast" version = "258.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97f7defc7ecca8b19ac7f824598eadd0c53985ee00c74060d65051e9da5b58a1" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "bumpalo", "gimli 0.32.3", @@ -5325,8 +5315,7 @@ dependencies = [ [[package]] name = "wat" version = "1.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7555c008cca87f2ac58d9f83ccda7e7b44611093ce28eb28f052e7c78024b9bf" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "wast 258.0.0", ] @@ -5762,8 +5751,7 @@ dependencies = [ [[package]] name = "wit-component" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "481b5c47b2ecce0389b5e08a05557d6a190c9cd761773b8880a8017ee04dc7ef" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "bitflags 2.11.1", @@ -5799,8 +5787,7 @@ dependencies = [ [[package]] name = "wit-parser" version = "0.258.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4daaa3cd97ae49ecd0a99dc009d453f93e0f083dd3be38c0f24a83a93e37ac" +source = "git+https://github.com/bytecodealliance/wasm-tools#e2d3556ae7aec4acd26a0695c7905930db45753d" dependencies = [ "anyhow", "hashbrown 0.17.0", diff --git a/Cargo.toml b/Cargo.toml index 3c6425c6a2a9..56cb3e2e2e27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -786,3 +786,18 @@ fpr = "fpr" [workspace.metadata.typos.files] extend-exclude = [ "docs/js/mermaid*.js", "crates/wasi-nn/**/*.txt", "*.isle" ] + +[patch.crates-io] +wasmparser = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wat = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wast = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasmprinter = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-encoder = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-smith = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-mutate = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-metadata = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wit-parser = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wit-component = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-wave = { git = 'https://github.com/bytecodealliance/wasm-tools' } +wasm-compose = { git = 'https://github.com/bytecodealliance/wasm-tools' } +json-from-wast = { git = 'https://github.com/bytecodealliance/wasm-tools' } diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs index b32ae9a203b2..168715d22ff5 100644 --- a/crates/cranelift/src/compiler/component.rs +++ b/crates/cranelift/src/compiler/component.rs @@ -742,111 +742,63 @@ impl<'a> TrampolineCompiler<'a> { }, ); } - Trampoline::ThreadSuspend { - instance, - cancellable, - } => { + Trampoline::ThreadSuspend { instance } => { self.translate_libcall( host::thread_suspend, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } - Trampoline::ThreadYield { - instance, - cancellable, - } => { + Trampoline::ThreadYield { instance } => { self.translate_libcall( host::thread_yield, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } - Trampoline::ThreadSuspendThenResume { - instance, - cancellable, - } => { + Trampoline::ThreadSuspendThenResume { instance } => { self.translate_libcall( host::thread_suspend_then_resume, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } - Trampoline::ThreadYieldThenResume { - instance, - cancellable, - } => { + Trampoline::ThreadYieldThenResume { instance } => { self.translate_libcall( host::thread_yield_then_resume, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } - Trampoline::ThreadSuspendThenPromote { - instance, - cancellable, - } => { + Trampoline::ThreadSuspendThenPromote { instance } => { self.translate_libcall( host::thread_suspend_then_promote, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } - Trampoline::ThreadYieldThenPromote { - instance, - cancellable, - } => { + Trampoline::ThreadYieldThenPromote { instance } => { self.translate_libcall( host::thread_yield_then_promote, TrapSentinel::NegativeOne, WasmArgs::InRegisters, |me, params| { params.push(me.index_value(*instance)); - params.push( - me.builder - .ins() - .iconst(ir::types::I8, i64::from(*cancellable)), - ); }, ); } diff --git a/crates/environ/src/component.rs b/crates/environ/src/component.rs index 9e3233209d66..21a32a28f9a3 100644 --- a/crates/environ/src/component.rs +++ b/crates/environ/src/component.rs @@ -190,17 +190,17 @@ macro_rules! foreach_builtin_component_function { #[cfg(feature = "component-model-async")] thread_resume_later(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> bool; #[cfg(feature = "component-model-async")] - thread_suspend(vmctx: vmctx, caller_instance: u32, cancellable: u8) -> u32; + thread_suspend(vmctx: vmctx, caller_instance: u32) -> u32; #[cfg(feature = "component-model-async")] - thread_yield(vmctx: vmctx, caller_instance: u32, cancellable: u8) -> u32; + thread_yield(vmctx: vmctx, caller_instance: u32) -> u32; #[cfg(feature = "component-model-async")] - thread_suspend_then_resume(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; + thread_suspend_then_resume(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> u32; #[cfg(feature = "component-model-async")] - thread_yield_then_resume(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; + thread_yield_then_resume(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> u32; #[cfg(feature = "component-model-async")] - thread_suspend_then_promote(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; + thread_suspend_then_promote(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> u32; #[cfg(feature = "component-model-async")] - thread_yield_then_promote(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; + thread_yield_then_promote(vmctx: vmctx, caller_instance: u32, thread_idx: u32) -> u32; utf8_to_utf8(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool; utf16_to_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> bool; diff --git a/crates/environ/src/component/dfg.rs b/crates/environ/src/component/dfg.rs index 69e456038884..546322e5c599 100644 --- a/crates/environ/src/component/dfg.rs +++ b/crates/environ/src/component/dfg.rs @@ -484,27 +484,21 @@ pub enum Trampoline { }, ThreadSuspend { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, ThreadYield { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, ThreadSuspendThenResume { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, ThreadYieldThenResume { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, ThreadSuspendThenPromote { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, ThreadYieldThenPromote { instance: RuntimeComponentInstanceIndex, - cancellable: bool, }, } @@ -542,7 +536,6 @@ pub struct CanonicalOptions { pub callback: Option, pub post_return: Option, pub async_: bool, - pub cancellable: bool, pub core_type: ModuleInternedTypeIndex, pub data_model: CanonicalOptionsDataModel, } @@ -847,7 +840,6 @@ impl LinearizeDfg<'_> { callback, post_return, async_: options.async_, - cancellable: options.cancellable, core_type: options.core_type, data_model, }; @@ -1171,48 +1163,32 @@ impl LinearizeDfg<'_> { Trampoline::ThreadResumeLater { instance } => info::Trampoline::ThreadResumeLater { instance: *instance, }, - Trampoline::ThreadSuspend { - instance, - cancellable, - } => info::Trampoline::ThreadSuspend { - instance: *instance, - cancellable: *cancellable, - }, - Trampoline::ThreadYield { - instance, - cancellable, - } => info::Trampoline::ThreadYield { - instance: *instance, - cancellable: *cancellable, - }, - Trampoline::ThreadSuspendThenResume { - instance, - cancellable, - } => info::Trampoline::ThreadSuspendThenResume { - instance: *instance, - cancellable: *cancellable, - }, - Trampoline::ThreadYieldThenResume { - instance, - cancellable, - } => info::Trampoline::ThreadYieldThenResume { - instance: *instance, - cancellable: *cancellable, - }, - Trampoline::ThreadSuspendThenPromote { - instance, - cancellable, - } => info::Trampoline::ThreadSuspendThenPromote { + Trampoline::ThreadSuspend { instance } => info::Trampoline::ThreadSuspend { instance: *instance, - cancellable: *cancellable, }, - Trampoline::ThreadYieldThenPromote { - instance, - cancellable, - } => info::Trampoline::ThreadYieldThenPromote { + Trampoline::ThreadYield { instance } => info::Trampoline::ThreadYield { instance: *instance, - cancellable: *cancellable, }, + Trampoline::ThreadSuspendThenResume { instance } => { + info::Trampoline::ThreadSuspendThenResume { + instance: *instance, + } + } + Trampoline::ThreadYieldThenResume { instance } => { + info::Trampoline::ThreadYieldThenResume { + instance: *instance, + } + } + Trampoline::ThreadSuspendThenPromote { instance } => { + info::Trampoline::ThreadSuspendThenPromote { + instance: *instance, + } + } + Trampoline::ThreadYieldThenPromote { instance } => { + info::Trampoline::ThreadYieldThenPromote { + instance: *instance, + } + } }; let i1 = self.trampolines.push(*signature); let i2 = self.trampoline_defs.push(trampoline); diff --git a/crates/environ/src/component/info.rs b/crates/environ/src/component/info.rs index 0e96aa047038..6df332bf4167 100644 --- a/crates/environ/src/component/info.rs +++ b/crates/environ/src/component/info.rs @@ -531,10 +531,6 @@ pub struct CanonicalOptions { /// Whether to use the async ABI for lifting or lowering. pub async_: bool, - /// Whether or not this function can consume a task cancellation - /// notification. - pub cancellable: bool, - /// The core function type that is being lifted from / lowered to. pub core_type: ModuleInternedTypeIndex, @@ -1131,9 +1127,6 @@ pub enum Trampoline { ThreadSuspend { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, /// A `thread.yield` intrinsic, which yields control to the host so that other @@ -1141,9 +1134,6 @@ pub enum Trampoline { ThreadYield { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, /// Intrinsic used to implement the `thread.suspend-then-resume` component @@ -1151,9 +1141,6 @@ pub enum Trampoline { ThreadSuspendThenResume { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, /// Intrinsic used to implement the `thread.yield-then-resume` component @@ -1161,9 +1148,6 @@ pub enum Trampoline { ThreadYieldThenResume { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, /// Intrinsic used to implement the `thread.suspend-then-promote` component @@ -1171,9 +1155,6 @@ pub enum Trampoline { ThreadSuspendThenPromote { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, /// Intrinsic used to implement the `thread.yield-then-promote` component @@ -1181,9 +1162,6 @@ pub enum Trampoline { ThreadYieldThenPromote { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, - /// If `true`, indicates the caller instance may receive notification - /// of task cancellation. - cancellable: bool, }, } diff --git a/crates/environ/src/component/translate.rs b/crates/environ/src/component/translate.rs index 3cbf3d02643d..ffeb40e6aa13 100644 --- a/crates/environ/src/component/translate.rs +++ b/crates/environ/src/component/translate.rs @@ -320,27 +320,21 @@ enum LocalInitializer<'data> { }, ThreadSuspend { func: ModuleInternedTypeIndex, - cancellable: bool, }, ThreadYield { func: ModuleInternedTypeIndex, - cancellable: bool, }, ThreadSuspendThenResume { func: ModuleInternedTypeIndex, - cancellable: bool, }, ThreadYieldThenResume { func: ModuleInternedTypeIndex, - cancellable: bool, }, ThreadSuspendThenPromote { func: ModuleInternedTypeIndex, - cancellable: bool, }, ThreadYieldThenPromote { func: ModuleInternedTypeIndex, - cancellable: bool, }, // core wasm modules @@ -428,7 +422,6 @@ struct LocalCanonicalOptions { string_encoding: StringEncoding, post_return: Option, async_: bool, - cancellable: bool, callback: Option, /// The type index of the core GC types signature. core_type: ModuleInternedTypeIndex, @@ -1050,16 +1043,12 @@ impl<'a, 'data> Translator<'a, 'data> { core_func_index += 1; LocalInitializer::WaitableSetNew { func } } - wasmparser::CanonicalFunction::WaitableSetWait { - cancellable, - memory, - } => { + wasmparser::CanonicalFunction::WaitableSetWait { memory } => { let core_type = self.core_func_signature(core_func_index)?; core_func_index += 1; LocalInitializer::WaitableSetWait { options: LocalCanonicalOptions { core_type, - cancellable, async_: false, data_model: LocalDataModel::LinearMemory { memory: Some(MemoryIndex::from_u32(memory)), @@ -1071,17 +1060,13 @@ impl<'a, 'data> Translator<'a, 'data> { }, } } - wasmparser::CanonicalFunction::WaitableSetPoll { - cancellable, - memory, - } => { + wasmparser::CanonicalFunction::WaitableSetPoll { memory } => { let core_type = self.core_func_signature(core_func_index)?; core_func_index += 1; LocalInitializer::WaitableSetPoll { options: LocalCanonicalOptions { core_type, async_: false, - cancellable, data_model: LocalDataModel::LinearMemory { memory: Some(MemoryIndex::from_u32(memory)), realloc: None, @@ -1305,35 +1290,35 @@ impl<'a, 'data> Translator<'a, 'data> { core_func_index += 1; LocalInitializer::ThreadResumeLater { func } } - wasmparser::CanonicalFunction::ThreadSuspend { cancellable } => { + wasmparser::CanonicalFunction::ThreadSuspend => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadSuspend { func, cancellable } + LocalInitializer::ThreadSuspend { func } } - wasmparser::CanonicalFunction::ThreadYield { cancellable } => { + wasmparser::CanonicalFunction::ThreadYield => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadYield { func, cancellable } + LocalInitializer::ThreadYield { func } } - wasmparser::CanonicalFunction::ThreadSuspendThenResume { cancellable } => { + wasmparser::CanonicalFunction::ThreadSuspendThenResume => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadSuspendThenResume { func, cancellable } + LocalInitializer::ThreadSuspendThenResume { func } } - wasmparser::CanonicalFunction::ThreadYieldThenResume { cancellable } => { + wasmparser::CanonicalFunction::ThreadYieldThenResume => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadYieldThenResume { func, cancellable } + LocalInitializer::ThreadYieldThenResume { func } } - wasmparser::CanonicalFunction::ThreadSuspendThenPromote { cancellable } => { + wasmparser::CanonicalFunction::ThreadSuspendThenPromote => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadSuspendThenPromote { func, cancellable } + LocalInitializer::ThreadSuspendThenPromote { func } } - wasmparser::CanonicalFunction::ThreadYieldThenPromote { cancellable } => { + wasmparser::CanonicalFunction::ThreadYieldThenPromote => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::ThreadYieldThenPromote { func, cancellable } + LocalInitializer::ThreadYieldThenPromote { func } } }; self.result.initializers.push(init); @@ -1773,7 +1758,6 @@ impl<'a, 'data> Translator<'a, 'data> { Ok(LocalCanonicalOptions { string_encoding, post_return, - cancellable: false, async_, callback, core_type, diff --git a/crates/environ/src/component/translate/adapt.rs b/crates/environ/src/component/translate/adapt.rs index 9555adcb7a6c..8b43dbc6db41 100644 --- a/crates/environ/src/component/translate/adapt.rs +++ b/crates/environ/src/component/translate/adapt.rs @@ -172,9 +172,6 @@ pub struct AdapterOptions { pub post_return: Option, /// Whether to use the async ABI for lifting or lowering. pub async_: bool, - /// Whether or not this intrinsic can consume a task cancellation - /// notification. - pub cancellable: bool, /// The core function type that is being lifted from / lowered to. pub core_type: ModuleInternedTypeIndex, /// The data model used by this adapter: linear memory or GC objects. diff --git a/crates/environ/src/component/translate/inline.rs b/crates/environ/src/component/translate/inline.rs index 4fd2f4a55e9b..4f3d7d25664d 100644 --- a/crates/environ/src/component/translate/inline.rs +++ b/crates/environ/src/component/translate/inline.rs @@ -1132,62 +1132,56 @@ impl<'a> Inliner<'a> { )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadSuspend { func, cancellable } => { + ThreadSuspend { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadSuspend { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadYield { func, cancellable } => { + ThreadYield { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadYield { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadSuspendThenResume { func, cancellable } => { + ThreadSuspendThenResume { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadSuspendThenResume { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadYieldThenResume { func, cancellable } => { + ThreadYieldThenResume { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadYieldThenResume { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadSuspendThenPromote { func, cancellable } => { + ThreadSuspendThenPromote { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadSuspendThenPromote { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); } - ThreadYieldThenPromote { func, cancellable } => { + ThreadYieldThenPromote { func } => { let index = self.result.trampolines.push(( *func, dfg::Trampoline::ThreadYieldThenPromote { instance: frame.instance, - cancellable: *cancellable, }, )); frame.funcs.push((*func, dfg::CoreDef::Trampoline(index))); @@ -1587,7 +1581,6 @@ impl<'a> Inliner<'a> { callback, post_return, async_: options.async_, - cancellable: options.cancellable, core_type: options.core_type, data_model, } @@ -1617,7 +1610,6 @@ impl<'a> Inliner<'a> { callback, post_return, async_: options.async_, - cancellable: options.cancellable, core_type: options.core_type, data_model, }) diff --git a/crates/environ/src/fact.rs b/crates/environ/src/fact.rs index 650647decc0a..6003c6bfb72e 100644 --- a/crates/environ/src/fact.rs +++ b/crates/environ/src/fact.rs @@ -352,9 +352,7 @@ impl<'a> Module<'a> { async_, core_type, data_model, - cancellable, } = options; - assert!(!cancellable); let flags = self.import_global( "flags", diff --git a/crates/misc/component-async-tests/tests/scenario/yield_.rs b/crates/misc/component-async-tests/tests/scenario/yield_.rs index 70de715ea3f8..2c05894d08b9 100644 --- a/crates/misc/component-async-tests/tests/scenario/yield_.rs +++ b/crates/misc/component-async-tests/tests/scenario/yield_.rs @@ -18,15 +18,6 @@ pub fn async_yield_caller() {} )] pub fn async_yield_caller_cancel() {} -#[tokio::test] -pub async fn async_yield_callee_synchronous() -> Result<()> { - test_run(&[ - test_programs_artifacts::ASYNC_YIELD_CALLER_COMPONENT, - test_programs_artifacts::ASYNC_YIELD_CALLEE_SYNCHRONOUS_COMPONENT, - ]) - .await -} - #[tokio::test] pub async fn async_yield_callee_stackless() -> Result<()> { test_run(&[ @@ -36,15 +27,6 @@ pub async fn async_yield_callee_stackless() -> Result<()> { .await } -#[tokio::test] -pub async fn async_yield_callee_cancel_synchronous() -> Result<()> { - test_run(&[ - test_programs_artifacts::ASYNC_YIELD_CALLER_CANCEL_COMPONENT, - test_programs_artifacts::ASYNC_YIELD_CALLEE_SYNCHRONOUS_COMPONENT, - ]) - .await -} - #[tokio::test] pub async fn async_yield_callee_cancel_stackless() -> Result<()> { test_run(&[ diff --git a/crates/misc/component-async-tests/tests/test_all.rs b/crates/misc/component-async-tests/tests/test_all.rs index 92ccf5ae77d4..7d030a88a5ad 100644 --- a/crates/misc/component-async-tests/tests/test_all.rs +++ b/crates/misc/component-async-tests/tests/test_all.rs @@ -40,6 +40,5 @@ use scenario::transmit::{ }; use scenario::unit_stream::{async_unit_stream_callee, async_unit_stream_caller}; use scenario::yield_::{ - async_yield_callee_stackless, async_yield_callee_synchronous, async_yield_caller, - async_yield_caller_cancel, + async_yield_callee_stackless, async_yield_caller, async_yield_caller_cancel, }; diff --git a/crates/test-programs/src/bin/async_yield_callee_synchronous.rs b/crates/test-programs/src/bin/async_yield_callee_synchronous.rs deleted file mode 100644 index 5a13243e8cd5..000000000000 --- a/crates/test-programs/src/bin/async_yield_callee_synchronous.rs +++ /dev/null @@ -1,35 +0,0 @@ -mod bindings { - wit_bindgen::generate!({ - path: "../misc/component-async-tests/wit", - world: "yield-callee", - async: ["-local:local/run#run"], - }); - - use super::Component; - export!(Component); -} - -use bindings::{exports::local::local::run::Guest, local::local::continue_}; - -#[cfg(not(target_arch = "wasm32"))] -unsafe fn yield_cancellable() -> bool { - unreachable!(); -} - -#[cfg(target_arch = "wasm32")] -#[link(wasm_import_module = "$root")] -unsafe extern "C" { - #[link_name = "[cancellable][thread-yield]"] - fn yield_cancellable() -> bool; -} - -struct Component; - -impl Guest for Component { - fn run() { - while continue_::get_continue() && unsafe { !yield_cancellable() } {} - } -} - -// Unused function; required since this file is built as a `bin`: -fn main() {} diff --git a/crates/test-util/src/wast.rs b/crates/test-util/src/wast.rs index dd8b301b2db4..ba2e18a6f923 100644 --- a/crates/test-util/src/wast.rs +++ b/crates/test-util/src/wast.rs @@ -525,6 +525,13 @@ impl WastTest { return true; } + // Waiting for WebAssembly/component-model#716 to land + if self.path.ends_with("async/cancellable.wast") + || self.path.ends_with("binary/binary.wast") + { + return true; + } + // Some tests are known to fail with the pooling allocator if config.pooling { // allocates too much memory for the pooling configuration here @@ -692,19 +699,6 @@ impl WastTest { return true; } - // These will require a wasm-tools update: - let need_wasm_tools_updates = [ - "component-model/test/validation/max-value-size.wast", - "component-model/test/validation/kebab.wast", - ]; - - if need_wasm_tools_updates - .iter() - .any(|part| self.path.ends_with(part)) - { - return true; - } - false } } diff --git a/crates/wasmtime/src/runtime/component/concurrent.rs b/crates/wasmtime/src/runtime/component/concurrent.rs index 79be3eb1b85e..4aa7c203de9b 100644 --- a/crates/wasmtime/src/runtime/component/concurrent.rs +++ b/crates/wasmtime/src/runtime/component/concurrent.rs @@ -685,10 +685,7 @@ enum SuspendReason { NeedWork, /// The fiber is yielding and should be resumed once other tasks have had a /// chance to run. - Yielding { - thread: QualifiedThreadId, - cancellable: bool, - }, + Yielding { thread: QualifiedThreadId }, /// The fiber was explicitly suspended with a call to `thread.suspend` or `thread.switch-to`. ExplicitlySuspending { thread: QualifiedThreadId }, } @@ -1792,18 +1789,6 @@ impl StoreOpaque { } } - /// Returns whether there's a pending cancellation on the current guest thread, - /// consuming the event if so. - fn take_pending_cancellation(&mut self) -> Result { - let thread = self.current_guest_thread()?; - let task = self.concurrent_state_mut()?.get_mut(thread.task)?; - if let Some(Event::Cancelled) = task.event { - task.event.take(); - return Ok(true); - } - Ok(false) - } - fn enter_sync_call(&mut self, callee: RuntimeInstance) -> Result<()> { log::trace!("enter sync-typed call {callee:?}"); let state = self.instance_state(callee).concurrent_state(); @@ -2179,12 +2164,8 @@ impl StoreOpaque { fiber.dispose(self); } } - SuspendReason::Yielding { - thread, - cancellable, - } => { - state.get_mut(thread.thread)?.state = - GuestThreadState::Ready { fiber, cancellable }; + SuspendReason::Yielding { thread } => { + state.get_mut(thread.thread)?.state = GuestThreadState::Ready { fiber }; let instance = state.get_mut(thread.task)?.instance; state.push_low_priority(WorkItem::ResumeThread { instance, thread }); } @@ -3762,7 +3743,6 @@ impl Instance { payload: u32, ) -> Result { let &CanonicalOptions { - cancellable, instance: caller_instance, .. } = &self.id().get(store).component().env_component().options[options]; @@ -3775,7 +3755,6 @@ impl Instance { self.waitable_check( store, caller, - cancellable, WaitableCheck::Wait, WaitableCheckParams { set: TableId::new(rep), @@ -3794,7 +3773,6 @@ impl Instance { payload: u32, ) -> Result { let &CanonicalOptions { - cancellable, instance: caller_instance, .. } = &self.id().get(store).component().env_component().options[options]; @@ -3807,7 +3785,6 @@ impl Instance { self.waitable_check( store, caller, - cancellable, WaitableCheck::Poll, WaitableCheckParams { set: TableId::new(rep), @@ -3963,9 +3940,9 @@ impl Instance { priority, )?; } - GuestThreadState::Ready { fiber, cancellable } => { + GuestThreadState::Ready { fiber } => { log::trace!("resuming thread {thread_id:?} that was ready"); - thread.state = GuestThreadState::Ready { fiber, cancellable }; + thread.state = GuestThreadState::Ready { fiber }; store .concurrent_state_mut()? .promote_thread_work_item(guest_thread)?; @@ -4003,15 +3980,9 @@ impl Instance { self, store: &mut StoreOpaque, caller: RuntimeComponentInstanceIndex, - cancellable: bool, yielding: bool, to_thread: SuspensionTarget, ) -> Result { - // There could be a pending cancellation from a previous uncancellable wait - if cancellable && store.take_pending_cancellation()? { - return Ok(WaitResult::Cancelled); - } - let check_suspend = match to_thread { SuspensionTarget::Promote(thread) => { !self.resume_thread(store, caller, thread, ResumeThread::Promote)? @@ -4041,7 +4012,6 @@ impl Instance { let reason = if yielding { SuspendReason::Yielding { thread: guest_thread, - cancellable, } } else { SuspendReason::ExplicitlySuspending { @@ -4051,11 +4021,7 @@ impl Instance { store.suspend(reason)?; - if cancellable && store.take_pending_cancellation()? { - Ok(WaitResult::Cancelled) - } else { - Ok(WaitResult::Completed) - } + Ok(WaitResult::Completed) } /// Helper function for the `waitable-set.wait` and `waitable-set.poll` intrinsics. @@ -4063,7 +4029,6 @@ impl Instance { self, store: &mut StoreOpaque, caller: RuntimeInstance, - cancellable: bool, check: WaitableCheck, params: WaitableCheckParams, ) -> Result { @@ -4080,23 +4045,11 @@ impl Instance { WaitableCheck::Wait => { let set = params.set; - if (task.event.is_none() - || (matches!(task.event, Some(Event::Cancelled)) && !cancellable)) + if (task.event.is_none() || matches!(task.event, Some(Event::Cancelled))) && state.get_mut(set)?.ready.is_empty() { store.switch_or_trap_if_may_not_suspend(caller)?; - if cancellable { - let old = store - .concurrent_state_mut()? - .get_mut(guest_thread.thread)? - .wake_on_cancel - .replace(set); - if !old.is_none() { - bail_bug!("thread unexpectedly in a prior wake_on_cancel set"); - } - } - store.suspend(SuspendReason::Waiting { set, thread: guest_thread, @@ -4112,7 +4065,7 @@ impl Instance { ); // Deliver any pending events to the guest and return. - let event = self.get_event(store, guest_thread.task, Some(params.set), cancellable)?; + let event = self.get_event(store, guest_thread.task, Some(params.set), false)?; let (ordinal, handle, result) = match &check { WaitableCheck::Wait => { @@ -4254,10 +4207,7 @@ impl Instance { let set = state.get_mut(caller.thread)?.sync_call_set; waitable.join(state, Some(set))?; - store.suspend(SuspendReason::Yielding { - thread: caller, - cancellable: false, - })?; + store.suspend(SuspendReason::Yielding { thread: caller })?; let state = store.concurrent_state_mut()?; waitable.join(state, None)?; @@ -4297,19 +4247,6 @@ impl Instance { yield_(store)?; - break; - } else if let GuestThreadState::Ready { - cancellable: true, .. - } = &thread_mut.state - { - // The thread is in a cancellable yield, so yield back - // to it. - if !concurrent_state.promote_thread_work_item(thread)? { - bail_bug!("a ready thread should have been promotable"); - } - - yield_(store)?; - break; } } @@ -4973,7 +4910,6 @@ enum GuestThreadState { Suspended(StoreFiber<'static>), Ready { fiber: StoreFiber<'static>, - cancellable: bool, }, Completed, } diff --git a/crates/wasmtime/src/runtime/vm/component/libcalls.rs b/crates/wasmtime/src/runtime/vm/component/libcalls.rs index 18b881a2e27c..93319119ce4c 100644 --- a/crates/wasmtime/src/runtime/vm/component/libcalls.rs +++ b/crates/wasmtime/src/runtime/vm/component/libcalls.rs @@ -1343,17 +1343,11 @@ fn thread_resume_later( } #[cfg(feature = "component-model-async")] -fn thread_suspend( - store: &mut dyn VMStore, - instance: Instance, - caller: u32, - cancellable: u8, -) -> Result { +fn thread_suspend(store: &mut dyn VMStore, instance: Instance, caller: u32) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller), - cancellable != 0, false, SuspensionTarget::None, ) @@ -1361,17 +1355,11 @@ fn thread_suspend( } #[cfg(feature = "component-model-async")] -fn thread_yield( - store: &mut dyn VMStore, - instance: Instance, - caller_instance: u32, - cancellable: u8, -) -> Result { +fn thread_yield(store: &mut dyn VMStore, instance: Instance, caller_instance: u32) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller_instance), - cancellable != 0, true, SuspensionTarget::None, ) @@ -1383,14 +1371,12 @@ fn thread_suspend_then_resume( store: &mut dyn VMStore, instance: Instance, caller: u32, - cancellable: u8, thread_idx: u32, ) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller), - cancellable != 0, false, SuspensionTarget::Resume(thread_idx), ) @@ -1402,14 +1388,12 @@ fn thread_yield_then_resume( store: &mut dyn VMStore, instance: Instance, caller_instance: u32, - cancellable: u8, thread_idx: u32, ) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller_instance), - cancellable != 0, true, SuspensionTarget::Resume(thread_idx), ) @@ -1421,14 +1405,12 @@ fn thread_suspend_then_promote( store: &mut dyn VMStore, instance: Instance, caller: u32, - cancellable: u8, thread_idx: u32, ) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller), - cancellable != 0, false, SuspensionTarget::Promote(thread_idx), ) @@ -1440,14 +1422,12 @@ fn thread_yield_then_promote( store: &mut dyn VMStore, instance: Instance, caller: u32, - cancellable: u8, thread_idx: u32, ) -> Result { instance .suspension_intrinsic( store, RuntimeComponentInstanceIndex::from_u32(caller), - cancellable != 0, true, SuspensionTarget::Promote(thread_idx), ) diff --git a/tests/misc_testsuite/component-model-threading/stackful-cancellation.wast b/tests/misc_testsuite/component-model-threading/stackful-cancellation.wast deleted file mode 100644 index c1ccd1b12a34..000000000000 --- a/tests/misc_testsuite/component-model-threading/stackful-cancellation.wast +++ /dev/null @@ -1,385 +0,0 @@ -;;! component_model_async = true -;;! component_model_async_stackful = true -;;! component_model_more_async_builtins = true -;;! component_model_threading = true -;;! reference_types = true - -;; Tests that cancellation works with the async threading intrinsics. -;; Consists of two components, C and D. C implements functions that mix cancellable and uncancellable yields and suspensions. -;; D calls these functions and cancels the resulting subtasks, ensuring that cancellation is only seen when expected. - -;; -- Component C -- - -;; `run-yield`: Yields twice, first with an uncancellable yield, then with a cancellable yield. -;; The caller cancels the subtask during the first yield, and ensures that the cancellation only takes effect -;; on the second yield. - -;; `run-yield-then-resume`: Yields twice to a spawned thread, first with an uncancellable yield, then with a cancellable yield. -;; A complication is that we can't guarantee that if the spawned thread yields, the supertask will be scheduled to -;; cancel the subtask before the subtask's implicit thread is rescheduled. To handle this, the subtask's implicit -;; thread first waits on a future to be written by the supertask, then yields to the spawned thread. - -;; `run-suspend`: More complex, because executing an uncancellable suspension requires another -;; thread in the same subtask to explicitly wake it up. This is done by the subtask spawning a new thread that -;; waits on a future to be written by the supertask, and then resumes the main thread once that happens. -;; After setting up this thread, `run-suspend` performs an uncancellable suspend, then a cancellable suspend. -;; The caller cancels the subtask during the first suspend, writes to the future to make the spawned thread -;; resume the implicit thread, and ensures that the cancellation only takes effect on the second suspend. - -;; `run-suspend-then-resume`: Similar to `run-suspend`, but uses `thread.suspend-then-resume` instead of `thread.suspend`. - -;; -- Component D -- - -;; `run-test`: Calls one of the functions in C based on a test id, cancels the resulting subtask, and ensures that -;; cancellation is only seen when expected. - -;; `run`: Calls `run-test` for each of the functions in C. - -(component - (component $C - (type $FT (future)) - (core module $Memory (memory (export "mem") 1)) - (core instance $memory (instantiate $Memory)) - ;; Defines the table for the thread start functions, of which there are two - (core module $libc - (table (export "__indirect_function_table") 2 funcref)) - (core module $CM - (import "" "mem" (memory 1)) - (import "" "task.cancel" (func $task-cancel)) - (import "" "thread.new-indirect" (func $thread-new-indirect (param i32 i32) (result i32))) - (import "" "thread.suspend" (func $thread-suspend (result i32))) - (import "" "thread.suspend-cancellable" (func $thread-suspend-cancellable (result i32))) - (import "" "thread.yield-then-resume" (func $thread-yield-then-resume (param i32) (result i32))) - (import "" "thread.yield-then-resume-cancellable" (func $thread-yield-then-resume-cancellable (param i32) (result i32))) - (import "" "thread.suspend-then-resume" (func $thread-suspend-then-resume (param i32) (result i32))) - (import "" "thread.suspend-then-resume-cancellable" (func $thread-suspend-then-resume-cancellable (param i32) (result i32))) - (import "" "thread.yield" (func $thread-yield (result i32))) - (import "" "thread.yield-cancellable" (func $thread-yield-cancellable (result i32))) - (import "" "thread.index" (func $thread-index (result i32))) - (import "" "thread.resume-later" (func $thread-resume-later (param i32))) - (import "" "future.read" (func $future.read (param i32 i32) (result i32))) - (import "" "waitable.join" (func $waitable.join (param i32 i32))) - (import "" "waitable-set.new" (func $waitable-set.new (result i32))) - (import "" "waitable-set.wait" (func $waitable-set.wait (param i32 i32) (result i32))) - (import "libc" "__indirect_function_table" (table $indirect-function-table 2 funcref)) - - ;; Indices into the function table for the thread start functions - (global $wake-from-suspend-ftbl-idx i32 (i32.const 0)) - (global $just-yield-ftbl-idx i32 (i32.const 1)) - - (func (export "run-yield") - ;; Yield back to the caller, who will attempt to cancel us, but we won't see it - ;; because we're using an uncancellable yield - (if (i32.ne (call $thread-yield) (i32.const 0)) (then unreachable)) - ;; Yield back to the caller again. This time, we should receive the cancellation immediately. - (if (i32.ne (call $thread-yield-cancellable) (i32.const 1)) (then unreachable)) - (call $task-cancel) - ) - - (func $wait-for-future-write (param i32) - (local $ret i32) - ;; Perform a future.read, which will block, waiting for the supertask to write - (local.set $ret (call $future.read (local.get 0) (i32.const 0xba5eba11))) - (if (i32.ne (i32.const 0 (; COMPLETED ;)) (local.get $ret)) - (then unreachable)) - ) - - (func $wake-from-suspend (param i32) - ;; Extract the thread index and future to wait on from the argument structure - (local $thread-index i32) (local $future i32) - (local.set $thread-index (i32.load offset=0 (local.get 0))) - (local.set $future (i32.load offset=4 (local.get 0))) - - ;; Wait for the supertask to signal us to wake up suspended thread. - (call $wait-for-future-write (local.get $future)) - ;; Resume the main thread, which is suspended in an uncancellable suspend - (call $thread-resume-later (local.get $thread-index)) - ) - - (func $just-yield (param $explicit-thread-idx i32) - ;; Yield nondeterministically, either back to the supertask, who will then wait on cancellation to be acknowledged, - ;; or to the implicit thread, who will acknowledge the cancellation. - (if (i32.ne (call $thread-yield) (i32.const 0)) (then unreachable)) - ) - - ;; Initialize the function table that will be used by thread.new-indirect - (elem (table $indirect-function-table) (i32.const 0 (; wake-from-suspend-ftbl-idx ;)) func $wake-from-suspend) - (elem (table $indirect-function-table) (i32.const 1 (; just-yield-ftbl-idx ;)) func $just-yield) - - (func (export "run-yield-then-resume") (param $futr i32) - (local $thread-index i32) - ;; Spawn a new thread that will wake us up from our uncancellable suspend; we'll switch to it next - (local.set $thread-index - (call $thread-new-indirect (global.get $just-yield-ftbl-idx) (call $thread-index))) - - ;; We can't guarantee that the supertask will be scheduled to cancel us before we're rescheduled, so we first - ;; wait on the future to be written, then yield to the spawned thread. This means that cancellation will be - ;; sent while we're waiting on the future rather than at the yield point, but the cancel will still be pending - ;; when we reach the yield point, so it should still be ignored by the uncancellable yield and only take effect - ;; when we reach the second, cancellable yield. - (call $wait-for-future-write (local.get $futr)) - - ;; Yield to the spawned thread uncancellably. We should eventually be rescheduled without being notified - ;; of the pending cancellation. - (if (i32.ne (call $thread-yield-then-resume (local.get $thread-index)) (i32.const 0)) (then unreachable)) - ;; Yield to the spawned thread again. This time we should see the cancellation immediately. - (if (i32.ne (call $thread-yield-then-resume-cancellable (local.get $thread-index)) (i32.const 1)) (then unreachable)) - (call $task-cancel) - ) - - (func (export "run-suspend") (param $futr i32) - ;; Set up the arguments for the wake-for-suspend thread start function. - ;; It expects a pointer to a structure containing the thread index to resume - ;; and the future to wait on before resuming it. - (local $wake-from-suspend-argp i32) - (local.set $wake-from-suspend-argp (i32.const 4)) - (i32.store offset=0 (local.get $wake-from-suspend-argp) (call $thread-index)) - (i32.store offset=4 (local.get $wake-from-suspend-argp) (local.get $futr)) - - ;; Spawn a new thread that will wake us up from our uncancellable suspend and schedule - ;; it to resume after we suspend. - (call $thread-resume-later - (call $thread-new-indirect (global.get $wake-from-suspend-ftbl-idx) (local.get $wake-from-suspend-argp))) - - ;; Request suspension. We will not be woken up by cancellation, because this is an uncancellable - ;; suspend. We will be woken up by the other thread we spawned above, which will be resumed after - ;; the supertask cancels our subtask. - (if (i32.ne (call $thread-suspend) (i32.const 0)) (then unreachable)) - ;; Request suspension again. This time we should see the cancellation immediately. - (if (i32.ne (call $thread-suspend-cancellable) (i32.const 1)) (then unreachable)) - (call $task-cancel) - ) - - (func (export "run-suspend-then-resume") (param $futr i32) - (local $thread-index i32) - ;; Set up the arguments for the wake-for-suspend thread start function. - ;; It expects a pointer to a structure containing the thread index to resume - ;; and the future to wait on before resuming it. - (local $wake-from-suspend-argp i32) - (local.set $wake-from-suspend-argp (i32.const 4)) - (i32.store offset=0 (local.get $wake-from-suspend-argp) (call $thread-index)) - (i32.store offset=4 (local.get $wake-from-suspend-argp) (local.get $futr)) - - ;; Spawn a new thread that will wake us up from our uncancellable suspend; we'll switch to it next - (local.set $thread-index - (call $thread-new-indirect (global.get $wake-from-suspend-ftbl-idx) (local.get $wake-from-suspend-argp))) - - ;; Request suspension by switching to the spawned thread. - ;; We will not be woken up by cancellation, because this is an uncancellable suspend. - ;; We will be woken up by the other thread we spawned above, which will be resumed after - ;; the supertask cancels our subtask. - (if (i32.ne (call $thread-suspend-then-resume (local.get $thread-index)) (i32.const 0)) (then unreachable)) - ;; Request suspension again. This time we should see the cancellation immediately. - (if (i32.ne (call $thread-suspend-then-resume-cancellable (local.get $thread-index)) (i32.const 1)) (then unreachable)) - (call $task-cancel) - ) - ) - - ;; Instantiate the libc module to get the table - (core instance $libc (instantiate $libc)) - ;; Get access to `thread.new-indirect` that uses the table from libc - (core type $start-func-ty (func (param i32))) - (alias core export $libc "__indirect_function_table" (core table $indirect-function-table)) - - (core func $task-cancel (canon task.cancel)) - (core func $thread-new-indirect - (canon thread.new-indirect $start-func-ty (core table $indirect-function-table))) - (core func $thread-yield (canon thread.yield)) - (core func $thread-yield-cancellable (canon thread.yield cancellable)) - (core func $thread-index (canon thread.index)) - (core func $thread-yield-then-resume (canon thread.yield-then-resume)) - (core func $thread-yield-then-resume-cancellable (canon thread.yield-then-resume cancellable)) - (core func $thread-resume-later (canon thread.resume-later)) - (core func $thread-suspend-then-resume (canon thread.suspend-then-resume)) - (core func $thread-suspend-then-resume-cancellable (canon thread.suspend-then-resume cancellable)) - (core func $thread-suspend (canon thread.suspend)) - (core func $thread-suspend-cancellable (canon thread.suspend cancellable)) - (core func $future.read (canon future.read $FT (memory (core memory $memory "mem")))) - (core func $waitable-set.new (canon waitable-set.new)) - (core func $waitable.join (canon waitable.join)) - (core func $waitable-set.wait (canon waitable-set.wait (memory (core memory $memory "mem")))) - - ;; Instantiate the main module - (core instance $cm ( - instantiate $CM - (with "" (instance - (export "mem" (memory $memory "mem")) - (export "task.cancel" (func $task-cancel)) - (export "thread.new-indirect" (func $thread-new-indirect)) - (export "thread.index" (func $thread-index)) - (export "thread.yield-then-resume" (func $thread-yield-then-resume)) - (export "thread.yield-then-resume-cancellable" (func $thread-yield-then-resume-cancellable)) - (export "thread.yield" (func $thread-yield)) - (export "thread.yield-cancellable" (func $thread-yield-cancellable)) - (export "thread.suspend-then-resume" (func $thread-suspend-then-resume)) - (export "thread.suspend-then-resume-cancellable" (func $thread-suspend-then-resume-cancellable)) - (export "thread.suspend" (func $thread-suspend)) - (export "thread.suspend-cancellable" (func $thread-suspend-cancellable)) - (export "thread.resume-later" (func $thread-resume-later)) - (export "future.read" (func $future.read)) - (export "waitable.join" (func $waitable.join)) - (export "waitable-set.wait" (func $waitable-set.wait)) - (export "waitable-set.new" (func $waitable-set.new)))) - (with "libc" (instance $libc)))) - - (func (export "run-yield") async (result u32) (canon lift (core func $cm "run-yield") async)) - (func (export "run-yield-then-resume") async (param "fut" $FT) (result u32) (canon lift (core func $cm "run-yield-then-resume") async)) - (func (export "run-suspend") async (param "fut" $FT) (result u32) (canon lift (core func $cm "run-suspend") async)) - (func (export "run-suspend-then-resume") async (param "fut" $FT) (result u32) (canon lift (core func $cm "run-suspend-then-resume") async)) - ) - - (component $D - (type $FT (future)) - (import "run-yield" (func $run-yield async (result u32))) - (import "run-yield-then-resume" (func $run-yield-then-resume async (param "fut" $FT) (result u32))) - (import "run-suspend" (func $run-suspend async (param "fut" $FT) (result u32))) - (import "run-suspend-then-resume" (func $run-suspend-then-resume async (param "fut" $FT) (result u32))) - - (core module $Memory (memory (export "mem") 1)) - (core instance $memory (instantiate $Memory)) - (core module $DM - (import "" "mem" (memory 1)) - (import "" "subtask.cancel" (func $subtask.cancel (param i32) (result i32))) - (import "" "run-yield" (func $run-yield (param i32) (result i32))) - (import "" "run-yield-then-resume" (func $run-yield-then-resume (param i32 i32) (result i32))) - (import "" "run-suspend" (func $run-suspend (param i32 i32) (result i32))) - (import "" "run-suspend-then-resume" (func $run-suspend-then-resume (param i32 i32) (result i32))) - (import "" "waitable.join" (func $waitable.join (param i32 i32))) - (import "" "waitable-set.new" (func $waitable-set.new (result i32))) - (import "" "waitable-set.wait" (func $waitable-set.wait (param i32 i32) (result i32))) - (import "" "future.new" (func $future.new (result i64))) - (import "" "future.write" (func $future.write (param i32 i32) (result i32))) - (import "" "thread.yield" (func $thread-yield (result i32))) - - (func $run-test (param $test-id i32) (result i32) - (local $ret i32) (local $subtask i32) - (local $ws i32) (local $event_code i32) - (local $run-retp i32) (local $wait-retp i32) - (local $ret64 i64) (local $futr i32) (local $futw i32) - - ;; Set up return value storage for run-suspend/suspend-then-resume and waitable-set.wait - (local.set $run-retp (i32.const 4)) - (local.set $wait-retp (i32.const 8)) - (i32.store (local.get $run-retp) (i32.const 0xbad0bad0)) - (i32.store (local.get $wait-retp) (i32.const 0xbad0bad0)) - - ;; Create a future that the subtask may wait on - (local.set $ret64 (call $future.new)) - (local.set $futr (i32.wrap_i64 (local.get $ret64))) - (local.set $futw (i32.wrap_i64 (i64.shr_u (local.get $ret64) (i64.const 32)))) - - ;; Calling run-suspend/suspend-then-resume will start the thread, which will suspend. - ;; This is basically a switch statement: - ;; 0: run-yield - ;; 1: run-yield-then-resume - ;; 2: run-suspend - ;; 3: run-suspend-then-resume - (if (i32.eq (local.get $test-id) (i32.const 0)) - (then (local.set $ret (call $run-yield (local.get $run-retp)))) - (else (if (i32.eq (local.get $test-id) (i32.const 1)) - (then (local.set $ret (call $run-yield-then-resume (local.get $futr) (local.get $run-retp)))) - (else (if (i32.eq (local.get $test-id) (i32.const 2)) - (then (local.set $ret (call $run-suspend (local.get $futr) (local.get $run-retp)))) - (else (if (i32.eq (local.get $test-id) (i32.const 3)) - (then (local.set $ret (call $run-suspend-then-resume (local.get $futr) (local.get $run-retp)))) - (else unreachable)))))))) - - ;; Ensure that the thread started - (if (i32.ne (i32.and (local.get $ret) (i32.const 0xF)) (i32.const 1 (; STARTED ;))) - (then unreachable)) - ;; Extract the subtask index - (local.set $subtask (i32.shr_u (local.get $ret) (i32.const 4))) - ;; Cancel the subtask, which should block, because the initial suspend/yield is uncancellable - (local.set $ret (call $subtask.cancel (local.get $subtask))) - ;; Ensure the cancellation blocked - (if (i32.ne (local.get $ret) (i32.const -1 (; BLOCKED ;))) - (then unreachable)) - - ;; If we're not testing run-yield, the subtask is expecting a write to our future, so write to it - (if (i32.ne (local.get $test-id) (i32.const 0)) - (then - (local.set $ret (call $future.write (local.get $futw) (i32.const 0xdeadbeef))) - ;; The write should succeed - (if (i32.ne (i32.const 0 (; COMPLETED ;)) (local.get $ret)) - (then unreachable)))) - - ;; Wait on the subtask, which will eventually progress to a cancellable yield/suspend and acknowledge the cancellation - (local.set $ws (call $waitable-set.new)) - (call $waitable.join (local.get $subtask) (local.get $ws)) - (local.set $event_code (call $waitable-set.wait (local.get $ws) (local.get $wait-retp))) - ;; Ensure we got the subtask event - (if (i32.ne (local.get $event_code) (i32.const 1 (; SUBTASK ;))) - (then unreachable)) - ;; Ensure the subtask index matches - (if (i32.ne (local.get $subtask) (i32.load (local.get $wait-retp))) - (then unreachable)) - ;; Ensure the subtask was cancelled before it returned - (if (i32.ne (i32.const 4 (; CANCELLED_BEFORE_RETURNED=4 | (0<<4) ;)) - (i32.load offset=4 (local.get $wait-retp))) - (then unreachable)) - - ;; Return success - (i32.const 42) - ) - - (func $run (export "run") (result i32) - ;; test-id 0: run-yield - (if (i32.ne (call $run-test (i32.const 0)) (i32.const 42)) - (then unreachable)) - - ;; test-id 1: run-yield-then-resume - (if (i32.ne (call $run-test (i32.const 1)) (i32.const 42)) - (then unreachable)) - - ;; test-id 2: run-suspend - (if (i32.ne (call $run-test (i32.const 2)) (i32.const 42)) - (then unreachable)) - - ;; test-id 3: run-suspend-then-resume - (if (i32.ne (call $run-test (i32.const 3)) (i32.const 42)) - (then unreachable)) - - ;; Return success - (i32.const 42) - ) - ) - - (core func $waitable-set.new (canon waitable-set.new)) - (core func $waitable-set.wait (canon waitable-set.wait (memory (core memory $memory "mem")))) - (core func $waitable.join (canon waitable.join)) - (core func $subtask.cancel (canon subtask.cancel async)) - (core func $future.new (canon future.new $FT)) - (core func $future.write (canon future.write $FT (memory (core memory $memory "mem")))) - (core func $thread.yield (canon thread.yield)) - (canon lower (func $run-yield) async (memory (core memory $memory "mem")) (core func $run-yield')) - (canon lower (func $run-suspend) async (memory (core memory $memory "mem")) (core func $run-suspend')) - (canon lower (func $run-suspend-then-resume) async (memory (core memory $memory "mem")) (core func $run-suspend-then-resume')) - (canon lower (func $run-yield-then-resume) async (memory (core memory $memory "mem")) (core func $run-yield-then-resume')) - (core instance $dm (instantiate $DM (with "" (instance - (export "mem" (memory $memory "mem")) - (export "run-yield" (func $run-yield')) - (export "run-suspend" (func $run-suspend')) - (export "run-suspend-then-resume" (func $run-suspend-then-resume')) - (export "run-yield-then-resume" (func $run-yield-then-resume')) - (export "waitable.join" (func $waitable.join)) - (export "waitable-set.new" (func $waitable-set.new)) - (export "waitable-set.wait" (func $waitable-set.wait)) - (export "subtask.cancel" (func $subtask.cancel)) - (export "future.new" (func $future.new)) - (export "future.write" (func $future.write)) - (export "thread.yield" (func $thread.yield)) - )))) - (func (export "run") async (result u32) (canon lift (core func $dm "run"))) - ) - - (instance $c (instantiate $C)) - (instance $d (instantiate $D - (with "run-yield" (func $c "run-yield")) - (with "run-yield-then-resume" (func $c "run-yield-then-resume")) - (with "run-suspend" (func $c "run-suspend")) - (with "run-suspend-then-resume" (func $c "run-suspend-then-resume")) - )) - (func (export "run") (alias export $d "run")) -) - -(assert_return (invoke "run") (u32.const 42)) diff --git a/tests/misc_testsuite/component-model-threading/yield-cancellable.wast b/tests/misc_testsuite/component-model-threading/yield-cancellable.wast index b74efa9f4b64..d6a9f2bb4c25 100644 --- a/tests/misc_testsuite/component-model-threading/yield-cancellable.wast +++ b/tests/misc_testsuite/component-model-threading/yield-cancellable.wast @@ -10,14 +10,14 @@ (canon thread.new-indirect $start-func-ty (core table $libc "t"))) (core func $thread.resume-later (canon thread.resume-later)) (core func $thread.index (canon thread.index)) - (core func $thread.yield-cancellable (canon thread.yield cancellable)) + (core func $thread.yield (canon thread.yield)) (core func $task.return (canon task.return)) (core module $m (import "" "thread.new-indirect" (func $thread.new-indirect (param i32 i32) (result i32))) (import "" "thread.resume-later" (func $thread.resume-later (param i32))) (import "" "thread.index" (func $thread.index (result i32))) - (import "" "thread.yield-cancellable" (func $thread.yield-cancellable (result i32))) + (import "" "thread.yield" (func $thread.yield (result i32))) (import "" "task.return" (func $task.return)) (import "" "tbl" (table $tbl 1 funcref)) @@ -32,7 +32,7 @@ ;; thread: call `thread.yield-cancellable` and double-check it didn't pick ;; up anything (func $explicit-start (param $ctx i32) - (if (call $thread.yield-cancellable) + (if (call $thread.yield) (then (unreachable))) ) (elem (table $tbl) (i32.const 0) func $explicit-start) @@ -48,7 +48,7 @@ (export "thread.new-indirect" (func $thread.new-indirect)) (export "thread.resume-later" (func $thread.resume-later)) (export "thread.index" (func $thread.index)) - (export "thread.yield-cancellable" (func $thread.yield-cancellable)) + (export "thread.yield" (func $thread.yield)) (export "task.return" (func $task.return)) (export "tbl" (table $libc "t")))))) diff --git a/tests/misc_testsuite/component-model/async/stackful.wast b/tests/misc_testsuite/component-model/async/stackful.wast index 6c7712f5fdbb..2edb4f11e2b9 100644 --- a/tests/misc_testsuite/component-model/async/stackful.wast +++ b/tests/misc_testsuite/component-model/async/stackful.wast @@ -113,7 +113,7 @@ (core module $m (import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i32) (result i32))) ) - (core func $waitable-set-wait (canon waitable-set.wait cancellable (memory (core memory $libc "memory")))) + (core func $waitable-set-wait (canon waitable-set.wait (memory (core memory $libc "memory")))) (core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait)))))) ) @@ -124,7 +124,7 @@ (core module $m (import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i32) (result i32))) ) - (core func $waitable-set-poll (canon waitable-set.poll cancellable (memory (core memory $libc "memory")))) + (core func $waitable-set-poll (canon waitable-set.poll (memory (core memory $libc "memory")))) (core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll)))))) ) @@ -133,6 +133,6 @@ (core module $m (import "" "yield" (func $yield (result i32))) ) - (core func $yield (canon thread.yield cancellable)) + (core func $yield (canon thread.yield)) (core instance $i (instantiate $m (with "" (instance (export "yield" (func $yield)))))) ) diff --git a/tests/misc_testsuite/component-model/async/task-deletion.wast b/tests/misc_testsuite/component-model/async/task-deletion.wast index 6e0b73a7d6b8..1bc5ef8b74d0 100644 --- a/tests/misc_testsuite/component-model/async/task-deletion.wast +++ b/tests/misc_testsuite/component-model/async/task-deletion.wast @@ -21,13 +21,9 @@ (import "" "task.cancel" (func $task-cancel)) (import "" "thread.new-indirect" (func $thread-new-indirect (param i32 i32) (result i32))) (import "" "thread.suspend" (func $thread-suspend (result i32))) - (import "" "thread.suspend-cancellable" (func $thread-suspend-cancellable (result i32))) (import "" "thread.yield-then-resume" (func $thread-yield-then-resume (param i32) (result i32))) - (import "" "thread.yield-then-resume-cancellable" (func $thread-yield-then-resume-cancellable (param i32) (result i32))) (import "" "thread.suspend-then-promote" (func $thread-suspend-then-promote (param i32) (result i32))) - (import "" "thread.suspend-then-promote-cancellable" (func $thread-suspend-then-promote-cancellable (param i32) (result i32))) (import "" "thread.yield" (func $thread-yield (result i32))) - (import "" "thread.yield-cancellable" (func $thread-yield-cancellable (result i32))) (import "" "thread.index" (func $thread-index (result i32))) (import "" "thread.resume-later" (func $thread-resume-later (param i32))) (import "" "waitable.join" (func $waitable.join (param i32 i32))) @@ -112,15 +108,11 @@ (core func $thread-new-indirect (canon thread.new-indirect $start-func-ty (core table $indirect-function-table))) (core func $thread-yield (canon thread.yield)) - (core func $thread-yield-cancellable (canon thread.yield cancellable)) (core func $thread-index (canon thread.index)) (core func $thread-yield-then-resume (canon thread.yield-then-resume)) - (core func $thread-yield-then-resume-cancellable (canon thread.yield-then-resume cancellable)) (core func $thread-resume-later (canon thread.resume-later)) (core func $thread-suspend-then-promote (canon thread.suspend-then-promote)) - (core func $thread-suspend-then-promote-cancellable (canon thread.suspend-then-promote cancellable)) (core func $thread-suspend (canon thread.suspend)) - (core func $thread-suspend-cancellable (canon thread.suspend cancellable)) (core func $waitable-set.new (canon waitable-set.new)) (core func $waitable.join (canon waitable.join)) (core func $waitable-set.wait (canon waitable-set.wait (memory (core memory $memory "mem")))) @@ -135,13 +127,9 @@ (export "thread.new-indirect" (func $thread-new-indirect)) (export "thread.index" (func $thread-index)) (export "thread.yield-then-resume" (func $thread-yield-then-resume)) - (export "thread.yield-then-resume-cancellable" (func $thread-yield-then-resume-cancellable)) (export "thread.yield" (func $thread-yield)) - (export "thread.yield-cancellable" (func $thread-yield-cancellable)) (export "thread.suspend-then-promote" (func $thread-suspend-then-promote)) - (export "thread.suspend-then-promote-cancellable" (func $thread-suspend-then-promote-cancellable)) (export "thread.suspend" (func $thread-suspend)) - (export "thread.suspend-cancellable" (func $thread-suspend-cancellable)) (export "thread.resume-later" (func $thread-resume-later)) (export "waitable.join" (func $waitable.join)) (export "waitable-set.wait" (func $waitable-set.wait))