diff --git a/Cargo.lock b/Cargo.lock index a3926cab2137..3f46d4672f3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,18 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "auditable-serde" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7bf8143dfc3c0258df908843e169b5cc5fcf76c7718bd66135ef4a9cd558c5" +dependencies = [ + "semver", + "serde", + "serde_json", + "topological-sort", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -187,7 +199,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.0", + "miniz_oxide 0.8.5", "object", "rustc-demangle", "windows-targets 0.52.6", @@ -1399,12 +1411,12 @@ checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" [[package]] name = "flate2" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", - "miniz_oxide 0.7.4", + "miniz_oxide 0.8.5", ] [[package]] @@ -2336,9 +2348,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] @@ -3436,7 +3448,7 @@ dependencies = [ "cargo_metadata", "heck 0.5.0", "wasmtime", - "wit-component 0.226.0", + "wit-component 0.227.0", ] [[package]] @@ -3604,6 +3616,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "topological-sort" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" + [[package]] name = "torch-sys" version = "0.17.0" @@ -3837,7 +3855,7 @@ name = "verify-component-adapter" version = "32.0.0" dependencies = [ "anyhow", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wat", ] @@ -3938,7 +3956,7 @@ dependencies = [ "byte-array-literals", "object", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-encoder 0.226.0", + "wasm-encoder 0.227.0", "wit-bindgen-rust-macro", ] @@ -4009,12 +4027,12 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d81b727619aec227dce83e7f7420d4e56c79acd044642a356ea045b98d4e13" +checksum = "829806010c17fa417fa56a42b76efadb35d70dbd972de9f07373b87d2729b698" dependencies = [ "leb128fmt", - "wasmparser 0.226.0", + "wasmparser 0.227.0", ] [[package]] @@ -4036,45 +4054,47 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47bb07c03240e9129676fbf24bc7783140f802102a88e133b7588a33d4a90d68" +checksum = "220471107952f7a42f71d95627deede9a4183e6c7744ad189d4f8c383f397689" dependencies = [ "anyhow", + "auditable-serde", + "flate2", "indexmap 2.7.0", "serde", "serde_derive", "serde_json", "spdx", "url", - "wasm-encoder 0.226.0", - "wasmparser 0.226.0", + "wasm-encoder 0.227.0", + "wasmparser 0.227.0", ] [[package]] name = "wasm-mutate" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1266f9da0874ddc43e76c7345323682f2f5d0b011c9e477497a3908fff26882" +checksum = "588c770cad1f7dd3acbf5d39c0cfd8375fa1b4fe29f9c0141c833c7ca9308b6d" dependencies = [ "egg", "log", "rand", "thiserror", - "wasm-encoder 0.226.0", - "wasmparser 0.226.0", + "wasm-encoder 0.227.0", + "wasmparser 0.227.0", ] [[package]] name = "wasm-smith" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261eaed66714e040f1be171696d88c1b560137760886edfef49ea8d0e51ccd00" +checksum = "c69cad1b21b938a76e88788dc96828e404d33d205f38db52b74adf05a48269f1" dependencies = [ "anyhow", "arbitrary", "flagset", - "wasm-encoder 0.226.0", + "wasm-encoder 0.227.0", ] [[package]] @@ -4087,14 +4107,14 @@ dependencies = [ [[package]] name = "wasm-wave" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b5d555c04eef216db9a4b059be3f8be605e71128225701d84c2a6aad862298" +checksum = "3c6463c8be4f494f627ac1b07138cea94781bf2029402afb9c08e4f58c8307f4" dependencies = [ "indexmap 2.7.0", "logos", "thiserror", - "wit-parser 0.226.0", + "wit-parser 0.227.0", ] [[package]] @@ -4155,9 +4175,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc28600dcb2ba68d7e5f1c3ba4195c2bddc918c0243fd702d0b6dbd05689b681" +checksum = "c15e32b1ab55e5e112f7c1dabd0d3f57c61992bfb0c4d4a6f141fe65c10ba750" dependencies = [ "bitflags 2.6.0", "hashbrown 0.15.2", @@ -4177,13 +4197,13 @@ dependencies = [ [[package]] name = "wasmprinter" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "753a0516fa6c01756ee861f36878dfd9875f273aea9409d9ea390a333c5bcdc2" +checksum = "30699079c5fe7fa8abf77baf9ee7f639f0642259637d4d9030b1f4112acc8447" dependencies = [ "anyhow", "termcolor", - "wasmparser 0.226.0", + "wasmparser 0.227.0", ] [[package]] @@ -4231,9 +4251,9 @@ dependencies = [ "tempfile", "trait-variant", "wasi-common", - "wasm-encoder 0.226.0", + "wasm-encoder 0.227.0", "wasm-wave", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmtime-asm-macros", "wasmtime-cache", "wasmtime-component-macro", @@ -4377,8 +4397,8 @@ dependencies = [ "trait-variant", "walkdir", "wasi-common", - "wasm-encoder 0.226.0", - "wasmparser 0.226.0", + "wasm-encoder 0.227.0", + "wasmparser 0.227.0", "wasmtime", "wasmtime-cache", "wasmtime-cli-flags", @@ -4395,10 +4415,10 @@ dependencies = [ "wasmtime-wasi-threads", "wasmtime-wast", "wasmtime-wast-util", - "wast 226.0.0", + "wast 227.0.0", "wat", "windows-sys 0.59.0", - "wit-component 0.226.0", + "wit-component 0.227.0", ] [[package]] @@ -4434,7 +4454,7 @@ dependencies = [ "wasmtime", "wasmtime-component-util", "wasmtime-wit-bindgen", - "wit-parser 0.226.0", + "wit-parser 0.227.0", ] [[package]] @@ -4460,7 +4480,7 @@ dependencies = [ "smallvec", "target-lexicon", "thiserror", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmtime-environ", "wasmtime-versioned-export-macros", ] @@ -4486,8 +4506,8 @@ dependencies = [ "serde_derive", "smallvec", "target-lexicon", - "wasm-encoder 0.226.0", - "wasmparser 0.226.0", + "wasm-encoder 0.227.0", + "wasmparser 0.227.0", "wasmprinter", "wasmtime-component-util", "wat", @@ -4501,7 +4521,7 @@ dependencies = [ "component-fuzz-util", "env_logger 0.11.5", "libfuzzer-sys", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmprinter", "wasmtime-environ", "wat", @@ -4560,7 +4580,7 @@ dependencies = [ "rand", "smallvec", "target-lexicon", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmtime", "wasmtime-fuzzing", ] @@ -4581,12 +4601,12 @@ dependencies = [ "target-lexicon", "tempfile", "v8", - "wasm-encoder 0.226.0", + "wasm-encoder 0.227.0", "wasm-mutate", "wasm-smith", "wasm-spec-interpreter", "wasmi", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmprinter", "wasmtime", "wasmtime-cli-flags", @@ -4778,7 +4798,7 @@ dependencies = [ "anyhow", "log", "wasmtime", - "wast 226.0.0", + "wast 227.0.0", ] [[package]] @@ -4800,7 +4820,7 @@ dependencies = [ "gimli", "object", "target-lexicon", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmtime-cranelift", "wasmtime-environ", "winch-codegen", @@ -4813,7 +4833,7 @@ dependencies = [ "anyhow", "heck 0.5.0", "indexmap 2.7.0", - "wit-parser 0.226.0", + "wit-parser 0.227.0", ] [[package]] @@ -4831,24 +4851,24 @@ dependencies = [ [[package]] name = "wast" -version = "226.0.0" +version = "227.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb903956d0151eabb6c30a2304dd61e5c8d7182805226120c2b6d611fb09a26" +checksum = "5f9ba0f7fe54ce2895314110aac579043d43175f66201153a0549badfa0fb04e" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.0", - "wasm-encoder 0.226.0", + "wasm-encoder 0.227.0", ] [[package]] name = "wat" -version = "1.226.0" +version = "1.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89a90ef2c401b8b5b2b704020bfa7a7f69b93c3034c7a4b4a88e21e9966581" +checksum = "ddc4d0762d835bf25be727f4320a8b08ce4451fb1e5868940ad7708503c6a6c9" dependencies = [ - "wast 226.0.0", + "wast 227.0.0", ] [[package]] @@ -4990,7 +5010,7 @@ dependencies = [ "smallvec", "target-lexicon", "thiserror", - "wasmparser 0.226.0", + "wasmparser 0.227.0", "wasmtime-cranelift", "wasmtime-environ", ] @@ -5304,9 +5324,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020c1e9da25465fd89003174a0d5ff7b6d61ccbbbd786f471cda04855215b981" +checksum = "0b77d5d7ce899af259d77309a5c9d54fc450c43d7014d08e0eccaf742fd582c1" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -5315,10 +5335,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.226.0", - "wasm-metadata 0.226.0", - "wasmparser 0.226.0", - "wit-parser 0.226.0", + "wasm-encoder 0.227.0", + "wasm-metadata 0.227.0", + "wasmparser 0.227.0", + "wit-parser 0.227.0", ] [[package]] @@ -5341,9 +5361,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.226.0" +version = "0.227.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33f007722bfd43a2978c5b8b90f02c927dddf0f11c5f5b50929816b3358718cd" +checksum = "bdd02ebcfdbbe83a4fc20991c31e8408a1dbb895194c81191e431f7bd0639545" dependencies = [ "anyhow", "id-arena", @@ -5354,7 +5374,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.226.0", + "wasmparser 0.227.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 60542a4687f0..969c50e6e01b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -303,16 +303,16 @@ wit-bindgen = { version = "0.39.0", default-features = false } wit-bindgen-rust-macro = { version = "0.39.0", default-features = false } # wasm-tools family: -wasmparser = { version = "0.226.0", default-features = false, features = ['simd'] } -wat = "1.226.0" -wast = "226.0.0" -wasmprinter = "0.226.0" -wasm-encoder = "0.226.0" -wasm-smith = "0.226.0" -wasm-mutate = "0.226.0" -wit-parser = "0.226.0" -wit-component = "0.226.0" -wasm-wave = "0.226.0" +wasmparser = { version = "0.227.0", default-features = false, features = ['simd'] } +wat = "1.227.0" +wast = "227.0.0" +wasmprinter = "0.227.0" +wasm-encoder = "0.227.0" +wasm-smith = "0.227.0" +wasm-mutate = "0.227.0" +wit-parser = "0.227.0" +wit-component = "0.227.0" +wasm-wave = "0.227.0" # Non-Bytecode Alliance maintained dependencies: # -------------------------- diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs index 24a197fd2507..755da1cc5153 100644 --- a/crates/cranelift/src/compiler/component.rs +++ b/crates/cranelift/src/compiler/component.rs @@ -103,25 +103,36 @@ impl<'a> TrampolineCompiler<'a> { Trampoline::ResourceNew(ty) => self.translate_resource_new(*ty), Trampoline::ResourceRep(ty) => self.translate_resource_rep(*ty), Trampoline::ResourceDrop(ty) => self.translate_resource_drop(*ty), - Trampoline::TaskBackpressure { instance } => { - self.translate_task_backpressure_call(*instance) + Trampoline::BackpressureSet { instance } => { + self.translate_backpressure_set_call(*instance) } - Trampoline::TaskReturn { results } => self.translate_task_return_call(*results), - Trampoline::TaskWait { + Trampoline::TaskReturn { results, options } => { + self.translate_task_return_call(*results, options) + } + Trampoline::WaitableSetNew { instance } => self.translate_waitable_set_new(*instance), + Trampoline::WaitableSetWait { instance, async_, memory, - } => { - self.translate_task_wait_or_poll_call(*instance, *async_, *memory, host::task_wait) - } - Trampoline::TaskPoll { + } => self.translate_task_wait_or_poll_call( + *instance, + *async_, + *memory, + host::waitable_set_wait, + ), + Trampoline::WaitableSetPoll { instance, async_, memory, - } => { - self.translate_task_wait_or_poll_call(*instance, *async_, *memory, host::task_poll) - } - Trampoline::TaskYield { async_ } => self.translate_task_yield_call(*async_), + } => self.translate_task_wait_or_poll_call( + *instance, + *async_, + *memory, + host::waitable_set_poll, + ), + Trampoline::WaitableSetDrop { instance } => self.translate_waitable_set_drop(*instance), + Trampoline::WaitableJoin { instance } => self.translate_waitable_join(*instance), + Trampoline::Yield { async_ } => self.translate_yield_call(*async_), Trampoline::SubtaskDrop { instance } => self.translate_subtask_drop_call(*instance), Trampoline::StreamNew { ty } => self.translate_future_or_stream_call( &[ty.as_u32()], @@ -375,7 +386,9 @@ impl<'a> TrampolineCompiler<'a> { } } - fn translate_task_return_call(&mut self, results: TypeTupleIndex) { + fn translate_task_return_call(&mut self, results: TypeTupleIndex, options: &CanonicalOptions) { + // FIXME(#10338) shouldn't ignore options here. + let _ = options; let args = self.builder.func.dfg.block_params(self.block0).to_vec(); let vmctx = args[0]; @@ -394,6 +407,60 @@ impl<'a> TrampolineCompiler<'a> { ); } + fn translate_waitable_set_new(&mut self, instance: RuntimeComponentInstanceIndex) { + let args = self.builder.func.dfg.block_params(self.block0).to_vec(); + let vmctx = args[0]; + + let instance = self + .builder + .ins() + .iconst(ir::types::I32, i64::from(instance.as_u32())); + + self.translate_intrinsic_libcall( + vmctx, + host::waitable_set_new, + &[vmctx, instance], + TrapSentinel::NegativeOne, + ); + } + + fn translate_waitable_set_drop(&mut self, instance: RuntimeComponentInstanceIndex) { + let args = self.builder.func.dfg.block_params(self.block0).to_vec(); + let vmctx = args[0]; + let set = args[2]; + + let instance = self + .builder + .ins() + .iconst(ir::types::I32, i64::from(instance.as_u32())); + + self.translate_intrinsic_libcall( + vmctx, + host::waitable_set_drop, + &[vmctx, instance, set], + TrapSentinel::Falsy, + ); + } + + fn translate_waitable_join(&mut self, instance: RuntimeComponentInstanceIndex) { + let args = self.builder.func.dfg.block_params(self.block0).to_vec(); + let vmctx = args[0]; + let set = args[2]; + let waitable = args[3]; + + let instance = self + .builder + .ins() + .iconst(ir::types::I32, i64::from(instance.as_u32())); + + self.translate_intrinsic_libcall( + vmctx, + host::waitable_join, + &[vmctx, instance, set, waitable], + TrapSentinel::Falsy, + ); + } + fn translate_sync_enter(&mut self) { match self.abi { Abi::Wasm => {} @@ -534,7 +601,7 @@ impl<'a> TrampolineCompiler<'a> { self.translate_intrinsic_libcall(vmctx, get_libcall, &callee_args, sentinel); } - fn translate_task_backpressure_call(&mut self, caller_instance: RuntimeComponentInstanceIndex) { + fn translate_backpressure_set_call(&mut self, caller_instance: RuntimeComponentInstanceIndex) { let args = self.builder.func.dfg.block_params(self.block0).to_vec(); let vmctx = args[0]; @@ -549,7 +616,7 @@ impl<'a> TrampolineCompiler<'a> { self.translate_intrinsic_libcall( vmctx, - host::task_backpressure, + host::backpressure_set, &callee_args, TrapSentinel::Falsy, ); @@ -586,7 +653,7 @@ impl<'a> TrampolineCompiler<'a> { ); } - fn translate_task_yield_call(&mut self, async_: bool) { + fn translate_yield_call(&mut self, async_: bool) { let args = self.builder.func.dfg.block_params(self.block0).to_vec(); let vmctx = args[0]; @@ -597,12 +664,7 @@ impl<'a> TrampolineCompiler<'a> { .iconst(ir::types::I8, if async_ { 1 } else { 0 }), ]; - self.translate_intrinsic_libcall( - vmctx, - host::task_yield, - &callee_args, - TrapSentinel::Falsy, - ); + self.translate_intrinsic_libcall(vmctx, host::yield_, &callee_args, TrapSentinel::Falsy); } fn translate_subtask_drop_call(&mut self, caller_instance: RuntimeComponentInstanceIndex) { diff --git a/crates/environ/src/component.rs b/crates/environ/src/component.rs index f19d2a69fdf0..a185cb852e0a 100644 --- a/crates/environ/src/component.rs +++ b/crates/environ/src/component.rs @@ -84,15 +84,21 @@ macro_rules! foreach_builtin_component_function { resource_exit_call(vmctx: vmctx) -> bool; #[cfg(feature = "component-model-async")] - task_backpressure(vmctx: vmctx, caller_instance: u32, enabled: u32) -> bool; + backpressure_set(vmctx: vmctx, caller_instance: u32, enabled: u32) -> bool; #[cfg(feature = "component-model-async")] task_return(vmctx: vmctx, ty: u32, storage: ptr_u8, storage_len: size) -> bool; #[cfg(feature = "component-model-async")] - task_wait(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64; + waitable_set_new(vmctx: vmctx, caller_instance: u32) -> u64; #[cfg(feature = "component-model-async")] - task_poll(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64; + waitable_set_wait(vmctx: vmctx, caller_instance: u32, set: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64; #[cfg(feature = "component-model-async")] - task_yield(vmctx: vmctx, async_: u8) -> bool; + waitable_set_poll(vmctx: vmctx, caller_instance: u32, set: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64; + #[cfg(feature = "component-model-async")] + waitable_set_drop(vmctx: vmctx, caller_instance: u32, set: u32) -> bool; + #[cfg(feature = "component-model-async")] + waitable_join(vmctx: vmctx, caller_instance: u32, set: u32, waitable: u32) -> bool; + #[cfg(feature = "component-model-async")] + yield_(vmctx: vmctx, async_: u8) -> bool; #[cfg(feature = "component-model-async")] subtask_drop(vmctx: vmctx, caller_instance: u32, task_id: u32) -> bool; #[cfg(feature = "component-model-async")] @@ -116,7 +122,7 @@ macro_rules! foreach_builtin_component_function { #[cfg(feature = "component-model-async")] future_close_writable(vmctx: vmctx, ty: u32, err_ctx_ty: u32, writer: u32, error: u32) -> bool; #[cfg(feature = "component-model-async")] - future_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool; + future_close_readable(vmctx: vmctx, ty: u32, reader: u32, error: u32) -> bool; #[cfg(feature = "component-model-async")] stream_new(vmctx: vmctx, ty: u32) -> u64; #[cfg(feature = "component-model-async")] @@ -130,7 +136,7 @@ macro_rules! foreach_builtin_component_function { #[cfg(feature = "component-model-async")] stream_close_writable(vmctx: vmctx, ty: u32, err_ctx_ty: u32, writer: u32, error: u32) -> bool; #[cfg(feature = "component-model-async")] - stream_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool; + stream_close_readable(vmctx: vmctx, ty: u32, reader: u32, error: u32) -> bool; #[cfg(feature = "component-model-async")] flat_stream_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, ty: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64; #[cfg(feature = "component-model-async")] diff --git a/crates/environ/src/component/dfg.rs b/crates/environ/src/component/dfg.rs index 1a20f7a8541d..70a651e02110 100644 --- a/crates/environ/src/component/dfg.rs +++ b/crates/environ/src/component/dfg.rs @@ -283,23 +283,33 @@ pub enum Trampoline { ResourceNew(TypeResourceTableIndex), ResourceRep(TypeResourceTableIndex), ResourceDrop(TypeResourceTableIndex), - TaskBackpressure { + BackpressureSet { instance: RuntimeComponentInstanceIndex, }, TaskReturn { results: TypeTupleIndex, + options: CanonicalOptions, + }, + WaitableSetNew { + instance: RuntimeComponentInstanceIndex, }, - TaskWait { + WaitableSetWait { instance: RuntimeComponentInstanceIndex, async_: bool, memory: MemoryId, }, - TaskPoll { + WaitableSetPoll { instance: RuntimeComponentInstanceIndex, async_: bool, memory: MemoryId, }, - TaskYield { + WaitableSetDrop { + instance: RuntimeComponentInstanceIndex, + }, + WaitableJoin { + instance: RuntimeComponentInstanceIndex, + }, + Yield { async_: bool, }, SubtaskDrop { @@ -772,31 +782,41 @@ impl LinearizeDfg<'_> { Trampoline::ResourceNew(ty) => info::Trampoline::ResourceNew(*ty), Trampoline::ResourceDrop(ty) => info::Trampoline::ResourceDrop(*ty), Trampoline::ResourceRep(ty) => info::Trampoline::ResourceRep(*ty), - Trampoline::TaskBackpressure { instance } => info::Trampoline::TaskBackpressure { + Trampoline::BackpressureSet { instance } => info::Trampoline::BackpressureSet { instance: *instance, }, - Trampoline::TaskReturn { results } => { - info::Trampoline::TaskReturn { results: *results } - } - Trampoline::TaskWait { + Trampoline::TaskReturn { results, options } => info::Trampoline::TaskReturn { + results: *results, + options: self.options(options), + }, + Trampoline::WaitableSetNew { instance } => info::Trampoline::WaitableSetNew { + instance: *instance, + }, + Trampoline::WaitableSetWait { instance, async_, memory, - } => info::Trampoline::TaskWait { + } => info::Trampoline::WaitableSetWait { instance: *instance, async_: *async_, memory: self.runtime_memory(*memory), }, - Trampoline::TaskPoll { + Trampoline::WaitableSetPoll { instance, async_, memory, - } => info::Trampoline::TaskPoll { + } => info::Trampoline::WaitableSetPoll { instance: *instance, async_: *async_, memory: self.runtime_memory(*memory), }, - Trampoline::TaskYield { async_ } => info::Trampoline::TaskYield { async_: *async_ }, + Trampoline::WaitableSetDrop { instance } => info::Trampoline::WaitableSetDrop { + instance: *instance, + }, + Trampoline::WaitableJoin { instance } => info::Trampoline::WaitableJoin { + instance: *instance, + }, + Trampoline::Yield { async_ } => info::Trampoline::Yield { async_: *async_ }, Trampoline::SubtaskDrop { instance } => info::Trampoline::SubtaskDrop { instance: *instance, }, diff --git a/crates/environ/src/component/info.rs b/crates/environ/src/component/info.rs index 6bc07660504f..2a27d3275a31 100644 --- a/crates/environ/src/component/info.rs +++ b/crates/environ/src/component/info.rs @@ -679,9 +679,9 @@ pub enum Trampoline { /// Same as `ResourceNew`, but for the `resource.drop` intrinsic. ResourceDrop(TypeResourceTableIndex), - /// A `task.backpressure` intrinsic, which tells the host to enable or + /// A `backpressure.set` intrinsic, which tells the host to enable or /// disable backpressure for the caller's instance. - TaskBackpressure { + BackpressureSet { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, }, @@ -692,11 +692,21 @@ pub enum Trampoline { TaskReturn { /// Tuple representing the result types this intrinsic accepts. results: TypeTupleIndex, + + /// The canonical ABI options specified for this intrinsic. + options: CanonicalOptions, }, - /// A `task.wait` intrinsic, which waits for at least one outstanding async - /// task/stream/future to make progress, returning the first such event. - TaskWait { + /// A `waitable-set.new` intrinsic. + WaitableSetNew { + /// The specific component instance which is calling the intrinsic. + instance: RuntimeComponentInstanceIndex, + }, + + /// A `waitable-set.wait` intrinsic, which waits for at least one + /// outstanding async task/stream/future to make progress, returning the + /// first such event. + WaitableSetWait { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, /// If `true`, indicates the caller instance maybe reentered. @@ -705,10 +715,10 @@ pub enum Trampoline { memory: RuntimeMemoryIndex, }, - /// A `task.poll` intrinsic, which checks whether any outstanding async - /// task/stream/future has made progress. Unlike `task.wait`, this does not - /// block and may return nothing if no such event has occurred. - TaskPoll { + /// A `waitable-set.poll` intrinsic, which checks whether any outstanding + /// async task/stream/future has made progress. Unlike `task.wait`, this + /// does not block and may return nothing if no such event has occurred. + WaitableSetPoll { /// The specific component instance which is calling the intrinsic. instance: RuntimeComponentInstanceIndex, /// If `true`, indicates the caller instance maybe reentered. @@ -717,9 +727,21 @@ pub enum Trampoline { memory: RuntimeMemoryIndex, }, - /// A `task.yield` intrinsic, which yields control to the host so that other + /// A `waitable-set.drop` intrinsic. + WaitableSetDrop { + /// The specific component instance which is calling the intrinsic. + instance: RuntimeComponentInstanceIndex, + }, + + /// A `waitable.join` intrinsic. + WaitableJoin { + /// The specific component instance which is calling the intrinsic. + instance: RuntimeComponentInstanceIndex, + }, + + /// A `yield` intrinsic, which yields control to the host so that other /// tasks are able to make progress, if any. - TaskYield { + Yield { /// If `true`, indicates the caller instance maybe reentered. async_: bool, }, @@ -983,11 +1005,14 @@ impl Trampoline { ResourceNew(i) => format!("component-resource-new[{}]", i.as_u32()), ResourceRep(i) => format!("component-resource-rep[{}]", i.as_u32()), ResourceDrop(i) => format!("component-resource-drop[{}]", i.as_u32()), - TaskBackpressure { .. } => format!("task-backpressure"), + BackpressureSet { .. } => format!("backpressure-set"), TaskReturn { .. } => format!("task-return"), - TaskWait { .. } => format!("task-wait"), - TaskPoll { .. } => format!("task-poll"), - TaskYield { .. } => format!("task-yield"), + WaitableSetNew { .. } => format!("waitable-set-new"), + WaitableSetWait { .. } => format!("waitable-set-wait"), + WaitableSetPoll { .. } => format!("waitable-set-poll"), + WaitableSetDrop { .. } => format!("waitable-set-drop"), + WaitableJoin { .. } => format!("waitable-join"), + Yield { .. } => format!("yield"), SubtaskDrop { .. } => format!("subtask-drop"), StreamNew { .. } => format!("stream-new"), StreamRead { .. } => format!("stream-read"), diff --git a/crates/environ/src/component/translate.rs b/crates/environ/src/component/translate.rs index 3e9d7a687e69..9d952ac2b148 100644 --- a/crates/environ/src/component/translate.rs +++ b/crates/environ/src/component/translate.rs @@ -188,24 +188,34 @@ enum LocalInitializer<'data> { ResourceRep(AliasableResourceId, ModuleInternedTypeIndex), ResourceDrop(AliasableResourceId, ModuleInternedTypeIndex), - TaskBackpressure { + BackpressureSet { func: ModuleInternedTypeIndex, }, TaskReturn { func: ModuleInternedTypeIndex, result: Option, + options: LocalCanonicalOptions, + }, + WaitableSetNew { + func: ModuleInternedTypeIndex, }, - TaskWait { + WaitableSetWait { func: ModuleInternedTypeIndex, async_: bool, memory: MemoryIndex, }, - TaskPoll { + WaitableSetPoll { func: ModuleInternedTypeIndex, async_: bool, memory: MemoryIndex, }, - TaskYield { + WaitableSetDrop { + func: ModuleInternedTypeIndex, + }, + WaitableJoin { + func: ModuleInternedTypeIndex, + }, + Yield { func: ModuleInternedTypeIndex, async_: bool, }, @@ -618,6 +628,10 @@ impl<'a, 'data> Translator<'a, 'data> { core_func_index += 1; LocalInitializer::ResourceDrop(resource, ty) } + wasmparser::CanonicalFunction::ResourceDropAsync { resource } => { + let _ = resource; + bail!("support for `resource.drop async` not implemented yet") + } wasmparser::CanonicalFunction::ResourceRep { resource } => { let resource = types.component_any_type_at(resource).unwrap_resource(); let ty = self.core_func_signature(core_func_index)?; @@ -628,12 +642,12 @@ impl<'a, 'data> Translator<'a, 'data> { | wasmparser::CanonicalFunction::ThreadAvailableParallelism => { bail!("unsupported intrinsic") } - wasmparser::CanonicalFunction::TaskBackpressure => { + wasmparser::CanonicalFunction::BackpressureSet => { let core_type = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::TaskBackpressure { func: core_type } + LocalInitializer::BackpressureSet { func: core_type } } - wasmparser::CanonicalFunction::TaskReturn { result } => { + wasmparser::CanonicalFunction::TaskReturn { result, options } => { let result = result.map(|ty| match ty { wasmparser::ComponentValType::Primitive(ty) => { ComponentValType::Primitive(ty) @@ -642,32 +656,52 @@ impl<'a, 'data> Translator<'a, 'data> { ComponentValType::Type(types.component_defined_type_at(ty)) } }); + let options = self.canonical_options(&options); let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::TaskReturn { func, result } + LocalInitializer::TaskReturn { + func, + result, + options, + } } - wasmparser::CanonicalFunction::TaskWait { async_, memory } => { + wasmparser::CanonicalFunction::WaitableSetNew => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::TaskWait { + LocalInitializer::WaitableSetNew { func } + } + wasmparser::CanonicalFunction::WaitableSetWait { async_, memory } => { + let func = self.core_func_signature(core_func_index)?; + core_func_index += 1; + LocalInitializer::WaitableSetWait { func, async_, memory: MemoryIndex::from_u32(memory), } } - wasmparser::CanonicalFunction::TaskPoll { async_, memory } => { + wasmparser::CanonicalFunction::WaitableSetPoll { async_, memory } => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::TaskPoll { + LocalInitializer::WaitableSetPoll { func, async_, memory: MemoryIndex::from_u32(memory), } } - wasmparser::CanonicalFunction::TaskYield { async_ } => { + wasmparser::CanonicalFunction::WaitableSetDrop => { + let func = self.core_func_signature(core_func_index)?; + core_func_index += 1; + LocalInitializer::WaitableSetDrop { func } + } + wasmparser::CanonicalFunction::WaitableJoin => { + let func = self.core_func_signature(core_func_index)?; + core_func_index += 1; + LocalInitializer::WaitableJoin { func } + } + wasmparser::CanonicalFunction::Yield { async_ } => { let func = self.core_func_signature(core_func_index)?; core_func_index += 1; - LocalInitializer::TaskYield { func, async_ } + LocalInitializer::Yield { func, async_ } } wasmparser::CanonicalFunction::SubtaskDrop => { let func = self.core_func_signature(core_func_index)?; diff --git a/crates/environ/src/component/translate/inline.rs b/crates/environ/src/component/translate/inline.rs index c0c0417c57d3..6b8a8ad05b2f 100644 --- a/crates/environ/src/component/translate/inline.rs +++ b/crates/environ/src/component/translate/inline.rs @@ -670,28 +670,43 @@ impl<'a> Inliner<'a> { .push((*ty, dfg::Trampoline::ResourceDrop(id))); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } - TaskBackpressure { func } => { + BackpressureSet { func } => { let index = self.result.trampolines.push(( *func, - dfg::Trampoline::TaskBackpressure { + dfg::Trampoline::BackpressureSet { instance: frame.instance, }, )); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } - TaskReturn { func, result } => { + TaskReturn { + func, + result, + options, + } => { let results = result .iter() .map(|ty| types.valtype(frame.translation.types_ref(), ty)) .collect::>()?; let results = types.new_tuple_type(results); + let options = self.adapter_options(frame, types, options); + let options = self.canonical_options(options); let index = self .result .trampolines - .push((*func, dfg::Trampoline::TaskReturn { results })); + .push((*func, dfg::Trampoline::TaskReturn { results, options })); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } - TaskWait { + WaitableSetNew { func } => { + let index = self.result.trampolines.push(( + *func, + dfg::Trampoline::WaitableSetNew { + instance: frame.instance, + }, + )); + frame.funcs.push(dfg::CoreDef::Trampoline(index)); + } + WaitableSetWait { func, async_, memory, @@ -700,7 +715,7 @@ impl<'a> Inliner<'a> { let memory = self.result.memories.push(memory); let index = self.result.trampolines.push(( *func, - dfg::Trampoline::TaskWait { + dfg::Trampoline::WaitableSetWait { instance: frame.instance, async_: *async_, memory, @@ -708,7 +723,7 @@ impl<'a> Inliner<'a> { )); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } - TaskPoll { + WaitableSetPoll { func, async_, memory, @@ -717,7 +732,7 @@ impl<'a> Inliner<'a> { let memory = self.result.memories.push(memory); let index = self.result.trampolines.push(( *func, - dfg::Trampoline::TaskPoll { + dfg::Trampoline::WaitableSetPoll { instance: frame.instance, async_: *async_, memory, @@ -725,11 +740,29 @@ impl<'a> Inliner<'a> { )); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } - TaskYield { func, async_ } => { + WaitableSetDrop { func } => { + let index = self.result.trampolines.push(( + *func, + dfg::Trampoline::WaitableSetDrop { + instance: frame.instance, + }, + )); + frame.funcs.push(dfg::CoreDef::Trampoline(index)); + } + WaitableJoin { func } => { + let index = self.result.trampolines.push(( + *func, + dfg::Trampoline::WaitableJoin { + instance: frame.instance, + }, + )); + frame.funcs.push(dfg::CoreDef::Trampoline(index)); + } + Yield { func, async_ } => { let index = self .result .trampolines - .push((*func, dfg::Trampoline::TaskYield { async_: *async_ })); + .push((*func, dfg::Trampoline::Yield { async_: *async_ })); frame.funcs.push(dfg::CoreDef::Trampoline(index)); } SubtaskDrop { func } => { diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs index 2915bcd680d2..20d2d1423600 100644 --- a/crates/environ/src/component/types.rs +++ b/crates/environ/src/component/types.rs @@ -576,26 +576,6 @@ pub enum InterfaceType { ErrorContext(TypeComponentLocalErrorContextTableIndex), } -impl From<&wasmparser::PrimitiveValType> for InterfaceType { - fn from(ty: &wasmparser::PrimitiveValType) -> InterfaceType { - match ty { - wasmparser::PrimitiveValType::Bool => InterfaceType::Bool, - wasmparser::PrimitiveValType::S8 => InterfaceType::S8, - wasmparser::PrimitiveValType::U8 => InterfaceType::U8, - wasmparser::PrimitiveValType::S16 => InterfaceType::S16, - wasmparser::PrimitiveValType::U16 => InterfaceType::U16, - wasmparser::PrimitiveValType::S32 => InterfaceType::S32, - wasmparser::PrimitiveValType::U32 => InterfaceType::U32, - wasmparser::PrimitiveValType::S64 => InterfaceType::S64, - wasmparser::PrimitiveValType::U64 => InterfaceType::U64, - wasmparser::PrimitiveValType::F32 => InterfaceType::Float32, - wasmparser::PrimitiveValType::F64 => InterfaceType::Float64, - wasmparser::PrimitiveValType::Char => InterfaceType::Char, - wasmparser::PrimitiveValType::String => InterfaceType::String, - } - } -} - /// Bye information about a type in the canonical ABI, with metadata for both /// memory32 and memory64-based types. #[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)] diff --git a/crates/environ/src/component/types_builder.rs b/crates/environ/src/component/types_builder.rs index 0128ff27b4ff..3655361fd238 100644 --- a/crates/environ/src/component/types_builder.rs +++ b/crates/environ/src/component/types_builder.rs @@ -16,7 +16,7 @@ use wasmparser::component_types::{ }; use wasmparser::names::KebabString; use wasmparser::types::TypesRef; -use wasmparser::Validator; +use wasmparser::{PrimitiveValType, Validator}; use wasmtime_component_util::FlagsSize; mod resources; @@ -395,7 +395,7 @@ impl ComponentTypesBuilder { ) -> Result { assert_eq!(types.id(), self.module_types.validator_id()); let ret = match &types[id] { - ComponentDefinedType::Primitive(ty) => ty.into(), + ComponentDefinedType::Primitive(ty) => self.primitive_type(ty)?, ComponentDefinedType::Record(e) => InterfaceType::Record(self.record_type(types, e)?), ComponentDefinedType::Variant(e) => { InterfaceType::Variant(self.variant_type(types, e)?) @@ -418,9 +418,6 @@ impl ComponentTypesBuilder { ComponentDefinedType::Stream(ty) => { InterfaceType::Stream(self.stream_table_type(types, ty)?) } - ComponentDefinedType::ErrorContext => { - InterfaceType::ErrorContext(self.error_context_table_type()?) - } }; let info = self.type_information(&ret); if info.depth > MAX_TYPE_DEPTH { @@ -441,11 +438,32 @@ impl ComponentTypesBuilder { ) -> Result { assert_eq!(types.id(), self.module_types.validator_id()); match ty { - ComponentValType::Primitive(p) => Ok(p.into()), + ComponentValType::Primitive(p) => self.primitive_type(p), ComponentValType::Type(id) => self.defined_type(types, *id), } } + fn primitive_type(&mut self, ty: &PrimitiveValType) -> Result { + match ty { + wasmparser::PrimitiveValType::Bool => Ok(InterfaceType::Bool), + wasmparser::PrimitiveValType::S8 => Ok(InterfaceType::S8), + wasmparser::PrimitiveValType::U8 => Ok(InterfaceType::U8), + wasmparser::PrimitiveValType::S16 => Ok(InterfaceType::S16), + wasmparser::PrimitiveValType::U16 => Ok(InterfaceType::U16), + wasmparser::PrimitiveValType::S32 => Ok(InterfaceType::S32), + wasmparser::PrimitiveValType::U32 => Ok(InterfaceType::U32), + wasmparser::PrimitiveValType::S64 => Ok(InterfaceType::S64), + wasmparser::PrimitiveValType::U64 => Ok(InterfaceType::U64), + wasmparser::PrimitiveValType::F32 => Ok(InterfaceType::Float32), + wasmparser::PrimitiveValType::F64 => Ok(InterfaceType::Float64), + wasmparser::PrimitiveValType::Char => Ok(InterfaceType::Char), + wasmparser::PrimitiveValType::String => Ok(InterfaceType::String), + wasmparser::PrimitiveValType::ErrorContext => Ok(InterfaceType::ErrorContext( + self.error_context_table_type()?, + )), + } + } + fn record_type(&mut self, types: TypesRef<'_>, ty: &RecordType) -> Result { assert_eq!(types.id(), self.module_types.validator_id()); let fields = ty diff --git a/crates/wasmtime/src/compile.rs b/crates/wasmtime/src/compile.rs index 2e42e0032c8f..0012823fa52a 100644 --- a/crates/wasmtime/src/compile.rs +++ b/crates/wasmtime/src/compile.rs @@ -373,7 +373,8 @@ impl<'a> CompileInputs<'a> { symbol: trampoline.symbol_name(), function: compiler .component_compiler() - .compile_trampoline(component, types, idx, tunables)? + .compile_trampoline(component, types, idx, tunables) + .with_context(|| format!("failed to compile {}", trampoline.symbol_name()))? .into(), info: None, }) @@ -389,12 +390,14 @@ impl<'a> CompileInputs<'a> { if component.component.num_resources > 0 { if let Some(sig) = types.find_resource_drop_signature() { ret.push_input(move |compiler| { - let trampoline = - compiler.compile_wasm_to_array_trampoline(types[sig].unwrap_func())?; + let symbol = "resource_drop_trampoline".to_string(); + let trampoline = compiler + .compile_wasm_to_array_trampoline(types[sig].unwrap_func()) + .with_context(|| format!("failed to compile `{symbol}`"))?; Ok(CompileOutput { key: CompileKey::resource_drop_wasm_to_array_trampoline(), - symbol: "resource_drop_trampoline".to_string(), function: CompiledFunction::Function(trampoline), + symbol, info: None, }) }); @@ -449,8 +452,6 @@ impl<'a> CompileInputs<'a> { for (def_func_index, func_body) in functions { self.push_input(move |compiler| { let func_index = translation.module.func_index(def_func_index); - let (info, function) = - compiler.compile_function(translation, def_func_index, func_body, types)?; let symbol = match translation .debuginfo .name_section @@ -469,6 +470,9 @@ impl<'a> CompileInputs<'a> { func_index.as_u32() ), }; + let (info, function) = compiler + .compile_function(translation, def_func_index, func_body, types) + .with_context(|| format!("failed to compile: {symbol}"))?; Ok(CompileOutput { key: CompileKey::wasm_function(module, def_func_index), @@ -482,18 +486,17 @@ impl<'a> CompileInputs<'a> { if translation.module.functions[func_index].is_escaping() { self.push_input(move |compiler| { let func_index = translation.module.func_index(def_func_index); - let trampoline = compiler.compile_array_to_wasm_trampoline( - translation, - types, - def_func_index, - )?; + let symbol = format!( + "wasm[{}]::array_to_wasm_trampoline[{}]", + module.as_u32(), + func_index.as_u32() + ); + let trampoline = compiler + .compile_array_to_wasm_trampoline(translation, types, def_func_index) + .with_context(|| format!("failed to compile: {symbol}"))?; Ok(CompileOutput { key: CompileKey::array_to_wasm_trampoline(module, def_func_index), - symbol: format!( - "wasm[{}]::array_to_wasm_trampoline[{}]", - module.as_u32(), - func_index.as_u32() - ), + symbol, function: CompiledFunction::Function(trampoline), info: None, }) @@ -510,14 +513,17 @@ impl<'a> CompileInputs<'a> { } let trampoline_func_ty = types[trampoline_type_index].unwrap_func(); self.push_input(move |compiler| { - let trampoline = compiler.compile_wasm_to_array_trampoline(trampoline_func_ty)?; + let symbol = format!( + "signatures[{}]::wasm_to_array_trampoline", + trampoline_type_index.as_u32() + ); + let trampoline = compiler + .compile_wasm_to_array_trampoline(trampoline_func_ty) + .with_context(|| format!("failed to compile: {symbol}"))?; Ok(CompileOutput { key: CompileKey::wasm_to_array_trampoline(trampoline_type_index), - symbol: format!( - "signatures[{}]::wasm_to_array_trampoline", - trampoline_type_index.as_u32() - ), function: CompiledFunction::Function(trampoline), + symbol, info: None, }) }); @@ -558,8 +564,12 @@ fn compile_required_builtins(engine: &Engine, raw_outputs: &mut Vec PromisesUnordered { /// Trait representing component model ABI async intrinsics and fused adapter /// helper functions. pub unsafe trait VMComponentAsyncStore { - /// The `task.backpressure` intrinsic. - fn task_backpressure( + /// The `backpressure.set` intrinsic. + fn backpressure_set( &mut self, caller_instance: RuntimeComponentInstanceIndex, enabled: u32, @@ -100,28 +100,54 @@ pub unsafe trait VMComponentAsyncStore { storage_len: usize, ) -> Result<()>; - /// The `task.wait` intrinsic. - fn task_wait( + /// The `waitable-set.new` intrinsic. + fn waitable_set_new( &mut self, instance: &mut ComponentInstance, caller_instance: RuntimeComponentInstanceIndex, + ) -> Result; + + /// The `waitable-set.wait` intrinsic. + fn waitable_set_wait( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, async_: bool, memory: *mut VMMemoryDefinition, payload: u32, ) -> Result; - /// The `task.poll` intrinsic. - fn task_poll( + /// The `waitable-set.poll` intrinsic. + fn waitable_set_poll( &mut self, instance: &mut ComponentInstance, caller_instance: RuntimeComponentInstanceIndex, + set: u32, async_: bool, memory: *mut VMMemoryDefinition, payload: u32, ) -> Result; - /// The `task.yield` intrinsic. - fn task_yield(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()>; + /// The `waitable-set.drop` intrinsic. + fn waitable_set_drop( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, + ) -> Result<()>; + + /// The `waitable.join` intrinsic. + fn waitable_join( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, + waitable: u32, + ) -> Result<()>; + + /// The `yield` intrinsic. + fn yield_(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()>; /// The `subtask.drop` intrinsic. fn subtask_drop( @@ -251,6 +277,7 @@ pub unsafe trait VMComponentAsyncStore { instance: &mut ComponentInstance, ty: TypeFutureTableIndex, reader: u32, + error: u32, ) -> Result<()>; /// The `stream.new` intrinsic. @@ -321,6 +348,7 @@ pub unsafe trait VMComponentAsyncStore { instance: &mut ComponentInstance, ty: TypeStreamTableIndex, reader: u32, + error: u32, ) -> Result<()>; /// The "fast-path" implementation of the `stream.write` intrinsic for @@ -388,7 +416,7 @@ pub unsafe trait VMComponentAsyncStore { } unsafe impl VMComponentAsyncStore for StoreInner { - fn task_backpressure( + fn backpressure_set( &mut self, caller_instance: RuntimeComponentInstanceIndex, enabled: u32, @@ -408,31 +436,63 @@ unsafe impl VMComponentAsyncStore for StoreInner { todo!() } - fn task_wait( + fn waitable_set_new( &mut self, instance: &mut ComponentInstance, caller_instance: RuntimeComponentInstanceIndex, + ) -> Result { + _ = (instance, caller_instance); + todo!(); + } + + fn waitable_set_wait( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, async_: bool, memory: *mut VMMemoryDefinition, payload: u32, ) -> Result { - _ = (instance, caller_instance, async_, memory, payload); - todo!() + _ = (instance, caller_instance, set, async_, memory, payload); + todo!(); } - fn task_poll( + fn waitable_set_poll( &mut self, instance: &mut ComponentInstance, caller_instance: RuntimeComponentInstanceIndex, + set: u32, async_: bool, memory: *mut VMMemoryDefinition, payload: u32, ) -> Result { - _ = (instance, caller_instance, async_, memory, payload); - todo!() + _ = (instance, caller_instance, set, async_, memory, payload); + todo!(); } - fn task_yield(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()> { + fn waitable_set_drop( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, + ) -> Result<()> { + _ = (instance, caller_instance, set); + todo!(); + } + + fn waitable_join( + &mut self, + instance: &mut ComponentInstance, + caller_instance: RuntimeComponentInstanceIndex, + set: u32, + waitable: u32, + ) -> Result<()> { + _ = (instance, caller_instance, set, waitable); + todo!(); + } + + fn yield_(&mut self, instance: &mut ComponentInstance, async_: bool) -> Result<()> { _ = (instance, async_); todo!() } @@ -633,8 +693,9 @@ unsafe impl VMComponentAsyncStore for StoreInner { instance: &mut ComponentInstance, ty: TypeFutureTableIndex, reader: u32, + error: u32, ) -> Result<()> { - _ = (instance, ty, reader); + _ = (instance, ty, reader, error); todo!() } @@ -736,8 +797,9 @@ unsafe impl VMComponentAsyncStore for StoreInner { instance: &mut ComponentInstance, ty: TypeStreamTableIndex, reader: u32, + error: u32, ) -> Result<()> { - _ = (instance, ty, reader); + _ = (instance, ty, reader, error); todo!() } diff --git a/crates/wasmtime/src/runtime/vm/component/libcalls.rs b/crates/wasmtime/src/runtime/vm/component/libcalls.rs index 9705249697ba..013790bde66e 100644 --- a/crates/wasmtime/src/runtime/vm/component/libcalls.rs +++ b/crates/wasmtime/src/runtime/vm/component/libcalls.rs @@ -580,7 +580,7 @@ unsafe fn trap(_vmctx: NonNull, code: u8) -> Result, caller_instance: u32, enabled: u32, @@ -588,7 +588,7 @@ unsafe fn task_backpressure( ComponentInstance::from_vmctx(vmctx, |instance| { (*instance.store()) .component_async_store() - .task_backpressure( + .backpressure_set( wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32( caller_instance, ), @@ -615,49 +615,114 @@ unsafe fn task_return( } #[cfg(feature = "component-model-async")] -unsafe fn task_wait( +unsafe fn waitable_set_new( vmctx: NonNull, caller_instance: u32, +) -> Result { + ComponentInstance::from_vmctx(vmctx, |instance| { + (*instance.store()) + .component_async_store() + .waitable_set_new( + instance, + wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32( + caller_instance, + ), + ) + }) +} + +#[cfg(feature = "component-model-async")] +unsafe fn waitable_set_wait( + vmctx: NonNull, + caller_instance: u32, + set: u32, async_: u8, memory: *mut u8, payload: u32, ) -> Result { ComponentInstance::from_vmctx(vmctx, |instance| { - (*instance.store()).component_async_store().task_wait( - instance, - wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32(caller_instance), - async_ != 0, - memory.cast::(), - payload, - ) + (*instance.store()) + .component_async_store() + .waitable_set_wait( + instance, + wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32( + caller_instance, + ), + set, + async_ != 0, + memory.cast::(), + payload, + ) }) } #[cfg(feature = "component-model-async")] -unsafe fn task_poll( +unsafe fn waitable_set_poll( vmctx: NonNull, caller_instance: u32, + set: u32, async_: u8, memory: *mut u8, payload: u32, ) -> Result { ComponentInstance::from_vmctx(vmctx, |instance| { - (*instance.store()).component_async_store().task_poll( + (*instance.store()) + .component_async_store() + .waitable_set_poll( + instance, + wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32( + caller_instance, + ), + set, + async_ != 0, + memory.cast::(), + payload, + ) + }) +} + +#[cfg(feature = "component-model-async")] +unsafe fn waitable_set_drop( + vmctx: NonNull, + caller_instance: u32, + set: u32, +) -> Result<()> { + ComponentInstance::from_vmctx(vmctx, |instance| { + (*instance.store()) + .component_async_store() + .waitable_set_drop( + instance, + wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32( + caller_instance, + ), + set, + ) + }) +} + +#[cfg(feature = "component-model-async")] +unsafe fn waitable_join( + vmctx: NonNull, + caller_instance: u32, + set: u32, + waitable: u32, +) -> Result<()> { + ComponentInstance::from_vmctx(vmctx, |instance| { + (*instance.store()).component_async_store().waitable_join( instance, wasmtime_environ::component::RuntimeComponentInstanceIndex::from_u32(caller_instance), - async_ != 0, - memory.cast::(), - payload, + set, + waitable, ) }) } #[cfg(feature = "component-model-async")] -unsafe fn task_yield(vmctx: NonNull, async_: u8) -> Result<()> { +unsafe fn yield_(vmctx: NonNull, async_: u8) -> Result<()> { ComponentInstance::from_vmctx(vmctx, |instance| { (*instance.store()) .component_async_store() - .task_yield(instance, async_ != 0) + .yield_(instance, async_ != 0) }) } @@ -944,6 +1009,7 @@ unsafe fn future_close_readable( vmctx: NonNull, ty: u32, reader: u32, + error: u32, ) -> Result<()> { ComponentInstance::from_vmctx(vmctx, |instance| { (*instance.store()) @@ -952,6 +1018,7 @@ unsafe fn future_close_readable( instance, wasmtime_environ::component::TypeFutureTableIndex::from_u32(ty), reader, + error, ) }) } @@ -1086,6 +1153,7 @@ unsafe fn stream_close_readable( vmctx: NonNull, ty: u32, reader: u32, + error: u32, ) -> Result<()> { ComponentInstance::from_vmctx(vmctx, |instance| { (*instance.store()) @@ -1094,6 +1162,7 @@ unsafe fn stream_close_readable( instance, wasmtime_environ::component::TypeStreamTableIndex::from_u32(ty), reader, + error, ) }) } diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs index 0b70f20246e2..a04e1faa1d73 100644 --- a/crates/wit-bindgen/src/lib.rs +++ b/crates/wit-bindgen/src/lib.rs @@ -269,12 +269,10 @@ impl Opts { // TODO: Should we refine this test to inspect only types reachable from // the specified world? if !cfg!(feature = "component-model-async") - && resolve.types.iter().any(|(_, ty)| { - matches!( - ty.kind, - TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext - ) - }) + && resolve + .types + .iter() + .any(|(_, ty)| matches!(ty.kind, TypeDefKind::Future(_) | TypeDefKind::Stream(_))) { anyhow::bail!( "must enable `component-model-async` feature when using WIT files \ @@ -767,13 +765,11 @@ fn _new( let mut resource_methods = IndexMap::new(); for (_, func) in iface.functions.iter() { - match func.kind { - FunctionKind::Freestanding => { + match func.kind.resource() { + None => { generator.define_rust_guest_export(resolve, Some(name), func); } - FunctionKind::Method(id) - | FunctionKind::Constructor(id) - | FunctionKind::Static(id) => { + Some(id) => { resource_methods.entry(id).or_insert(Vec::new()).push(func); } } @@ -1849,7 +1845,6 @@ impl<'a> InterfaceGenerator<'a> { TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs), TypeDefKind::Future(t) => self.type_future(id, name, t.as_ref(), &ty.docs), TypeDefKind::Stream(t) => self.type_stream(id, name, t.as_ref(), &ty.docs), - TypeDefKind::ErrorContext => self.type_error_context(id, name, &ty.docs), TypeDefKind::Handle(handle) => self.type_handle(id, name, handle, &ty.docs), TypeDefKind::Resource => self.type_resource(id, name, ty, &ty.docs), TypeDefKind::Unknown => unreachable!(), @@ -1923,12 +1918,7 @@ impl<'a> InterfaceGenerator<'a> { } }; - functions.retain(|func| match func.kind { - FunctionKind::Freestanding => false, - FunctionKind::Method(resource) - | FunctionKind::Static(resource) - | FunctionKind::Constructor(resource) => id == resource, - }); + functions.retain(|func| func.kind.resource() == Some(id)); let has_concurrent_function = functions.iter().any(|func| { matches!( @@ -2564,15 +2554,6 @@ impl<'a> InterfaceGenerator<'a> { self.assert_type(id, &name); } - fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) { - self.rustdoc(docs); - self.push_str(&format!("pub type {name}")); - self.push_str(" = "); - self.print_error_context(); - self.push_str(";\n"); - self.assert_type(id, &name); - } - fn print_result_ty(&mut self, result: Option, mode: TypeMode) { match result { Some(ty) => self.print_ty(&ty, mode), @@ -3008,15 +2989,15 @@ impl<'a> InterfaceGenerator<'a> { "let host = &mut host_getter(caller.data_mut());\n" }); let func_name = rust_function_name(func); - let host_trait = match func.kind { - FunctionKind::Freestanding => match owner { + let host_trait = match func.kind.resource() { + None => match owner { TypeOwner::World(id) => format!( "{}Imports", rust::to_rust_upper_camel_case(&self.resolve.worlds[id].name) ), _ => "Host".to_string(), }, - FunctionKind::Method(id) | FunctionKind::Static(id) | FunctionKind::Constructor(id) => { + Some(id) => { let resource = self.resolve.types[id] .name .as_ref() @@ -3646,8 +3627,7 @@ fn type_contains_lists(ty: Type, resolve: &Resolve) -> bool { | TypeDefKind::Handle(_) | TypeDefKind::Enum(_) | TypeDefKind::Stream(_) - | TypeDefKind::Future(_) - | TypeDefKind::ErrorContext => false, + | TypeDefKind::Future(_) => false, TypeDefKind::Option(ty) => type_contains_lists(*ty, resolve), TypeDefKind::Result(Result_ { ok, err }) => { option_type_contains_lists(*ok, resolve) @@ -3696,21 +3676,25 @@ fn resolve_type_definition_id(resolve: &Resolve, mut id: TypeId) -> TypeId { fn rust_function_name(func: &Function) -> String { match func.kind { - FunctionKind::Method(_) | FunctionKind::Static(_) => to_rust_ident(func.item_name()), FunctionKind::Constructor(_) => "new".to_string(), - FunctionKind::Freestanding => to_rust_ident(&func.name), + FunctionKind::Method(_) + | FunctionKind::Static(_) + | FunctionKind::AsyncMethod(_) + | FunctionKind::AsyncStatic(_) + | FunctionKind::Freestanding + | FunctionKind::AsyncFreestanding => to_rust_ident(func.item_name()), } } fn func_field_name(resolve: &Resolve, func: &Function) -> String { let mut name = String::new(); match func.kind { - FunctionKind::Method(id) => { + FunctionKind::Method(id) | FunctionKind::AsyncMethod(id) => { name.push_str("method-"); name.push_str(resolve.types[id].name.as_ref().unwrap()); name.push_str("-"); } - FunctionKind::Static(id) => { + FunctionKind::Static(id) | FunctionKind::AsyncStatic(id) => { name.push_str("static-"); name.push_str(resolve.types[id].name.as_ref().unwrap()); name.push_str("-"); @@ -3720,7 +3704,7 @@ fn func_field_name(resolve: &Resolve, func: &Function) -> String { name.push_str(resolve.types[id].name.as_ref().unwrap()); name.push_str("-"); } - FunctionKind::Freestanding => {} + FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => {} } name.push_str(func.item_name()); name.to_snake_case() @@ -3777,21 +3761,18 @@ fn concurrent_constraints<'a>( .iter() .filter_map(|(name, ty)| match resolve.types[*ty].kind { TypeDefKind::Resource - if resolve.interfaces[id] - .functions - .values() - .any(|func| match func.kind { - FunctionKind::Freestanding => false, - FunctionKind::Method(resource) - | FunctionKind::Static(resource) - | FunctionKind::Constructor(resource) => { + if resolve.interfaces[id].functions.values().any(|func| { + match func.kind.resource() { + None => false, + Some(resource) => { *ty == resource && matches!( opts.import_call_style(qualifier, &func.name), CallStyle::Concurrent ) } - }) => + } + }) => { Some(format!("{}Data", name.to_upper_camel_case())) } @@ -3845,11 +3826,9 @@ fn world_imports_concurrent_constraints<'a>( .imports .values() .any(|item| match item { - WorldItem::Function(func) => match func.kind { - FunctionKind::Freestanding => false, - FunctionKind::Method(resource) - | FunctionKind::Static(resource) - | FunctionKind::Constructor(resource) => { + WorldItem::Function(func) => match func.kind.resource() { + None => false, + Some(resource) => { *ty == resource && matches!( opts.import_call_style(None, &func.name), diff --git a/crates/wit-bindgen/src/rust.rs b/crates/wit-bindgen/src/rust.rs index 7e7a67fecfdc..41e1f2ee20d5 100644 --- a/crates/wit-bindgen/src/rust.rs +++ b/crates/wit-bindgen/src/rust.rs @@ -57,6 +57,9 @@ pub trait RustGenerator<'a> { self.push_str(&format!("{wt}::component::__internal::String")) } }, + Type::ErrorContext => { + self.push_str("wasmtime::component::ErrorContext"); + } } } @@ -120,7 +123,7 @@ pub trait RustGenerator<'a> { needs_generics(resolve, &resolve.types[*t].kind) } TypeDefKind::Type(Type::String) => true, - TypeDefKind::Type(_) | TypeDefKind::ErrorContext => false, + TypeDefKind::Type(_) => false, TypeDefKind::Unknown => unreachable!(), } } @@ -175,9 +178,6 @@ pub trait RustGenerator<'a> { self.print_optional_ty(ty.as_ref(), TypeMode::Owned); self.push_str(">"); } - TypeDefKind::ErrorContext => { - self.push_str("wasmtime::component::ErrorContext"); - } TypeDefKind::Handle(handle) => { self.print_handle(handle); } @@ -238,11 +238,6 @@ pub trait RustGenerator<'a> { self.push_str(">"); } - fn print_error_context(&mut self) { - let wt = self.wasmtime_path(); - self.push_str(&format!("{wt}::component::ErrorContext")); - } - fn print_handle(&mut self, handle: &Handle) { // Handles are either printed as `ResourceAny` for any guest-defined // resource or `Resource` for all host-defined resources. This means diff --git a/crates/wit-bindgen/src/types.rs b/crates/wit-bindgen/src/types.rs index 3b9c1aa98d7a..8b36ce05dac7 100644 --- a/crates/wit-bindgen/src/types.rs +++ b/crates/wit-bindgen/src/types.rs @@ -155,7 +155,7 @@ impl Types { info = self.optional_type_info(resolve, ty.as_ref()); } TypeDefKind::Handle(_) => info.has_handle = true, - TypeDefKind::Resource | TypeDefKind::ErrorContext => {} + TypeDefKind::Resource => {} TypeDefKind::Unknown => unreachable!(), } self.type_info.insert(ty, info); diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 7c708bf2e64c..f4088c27a66a 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -1063,6 +1063,12 @@ the environment's terminal information when asked. Does its stated purpose and no more. """ +[[audits.auditable-serde]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +version = "0.8.0" +notes = "No `unsafe` code in this crate, small crate, only working with JSON and some serde data structures." + [[audits.backtrace]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -1734,6 +1740,15 @@ criteria = "safe-to-deploy" delta = "1.0.26 -> 1.0.28" notes = "No new `unsafe` and no large changes in function. This diff is mostly refactoring with a lot of docs, CI, test changes. Adds some defensive clearing out of certain variables as a safeguard." +[[audits.flate2]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "1.0.30 -> 1.1.0" +notes = """ +Minor updates, mostly a new changelog with many lines. No new `unsafe` code and +mostly just updating Rust idioms. +""" + [[audits.foldhash]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -2420,6 +2435,16 @@ criteria = "safe-to-deploy" delta = "0.8.0 -> 0.7.4" notes = "Very few changes here, only minor updates here and there." +[[audits.miniz_oxide]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.8.0 -> 0.8.5" +notes = """ +Lots of small updates here and there, for example around modernizing Rust +idioms. No new `unsafe` code and everything looks like what you'd expect a +compression library to be doing. +""" + [[audits.mio]] who = "Alex Crichton " criteria = "safe-to-deploy" @@ -3148,6 +3173,15 @@ criteria = "safe-to-deploy" version = "0.7.4" notes = "Alex Crichton audited the safety of src/sync/reusable_box.rs, I audited the remainder of the crate." +[[audits.topological-sort]] +who = "Alex Crichton " +criteria = "safe-to-deploy" +delta = "0.1.0 -> 0.2.2" +notes = """ +No major changes, mostly CI changes in this update. A new `Default` impl +and a new test. +""" + [[audits.torch-sys]] who = "Andrew Brown " criteria = "safe-to-deploy" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index d9eaf6c06c2c..cba0989a131d 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -1806,8 +1806,8 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wasm-encoder]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -1818,14 +1818,14 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wasm-metadata]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" [[publisher.wasm-wave]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -1836,14 +1836,14 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wasmparser]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" [[publisher.wasmprinter]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -2004,14 +2004,14 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wast]] -version = "226.0.0" -when = "2025-02-19" +version = "227.0.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" [[publisher.wat]] -version = "1.226.0" -when = "2025-02-19" +version = "1.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -2278,8 +2278,8 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wit-component]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -2290,8 +2290,8 @@ user-id = 73222 user-login = "wasmtime-publish" [[publisher.wit-parser]] -version = "0.226.0" -when = "2025-02-19" +version = "0.227.0" +when = "2025-03-05" user-id = 73222 user-login = "wasmtime-publish" @@ -3341,6 +3341,13 @@ criteria = "safe-to-deploy" delta = "0.7.4 -> 0.7.6" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" +[[audits.mozilla.audits.topological-sort]] +who = "Bobby Holley " +criteria = "safe-to-deploy" +version = "0.1.0" +notes = "Simple algorithm crate with no unsafe code or capability usage." +aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" + [[audits.mozilla.audits.tracing]] who = "Alex Franchuk " criteria = "safe-to-deploy" diff --git a/tests/all/code_too_large.rs b/tests/all/code_too_large.rs index 5c71a518734c..e0093f907e47 100644 --- a/tests/all/code_too_large.rs +++ b/tests/all/code_too_large.rs @@ -55,9 +55,9 @@ fn code_too_large_without_panic() -> Result<()> { let store = Store::new(&engine, ()); let result = Module::new(store.engine(), &module.finish()); match result { - Err(e) => assert!(e - .to_string() - .starts_with("Compilation error: Code for function is too large")), + Err(e) => { + assert!(format!("{e:?}").contains("Compilation error: Code for function is too large")) + } Ok(_) => panic!("Please adjust limits to make the module too large to compile!"), } Ok(()) diff --git a/tests/misc_testsuite/component-model-async/futures.wast b/tests/misc_testsuite/component-model-async/futures.wast index f1e4d4d5b940..0c36849ebdbb 100644 --- a/tests/misc_testsuite/component-model-async/futures.wast +++ b/tests/misc_testsuite/component-model-async/futures.wast @@ -72,7 +72,7 @@ ;; future.close-readable (component (core module $m - (import "" "future.close-readable" (func $future-close-readable (param i32))) + (import "" "future.close-readable" (func $future-close-readable (param i32 i32))) ) (type $future-type (future u8)) (core func $future-close-readable (canon future.close-readable $future-type)) diff --git a/tests/misc_testsuite/component-model-async/streams.wast b/tests/misc_testsuite/component-model-async/streams.wast index 790ddec7e5f8..28a21ef33781 100644 --- a/tests/misc_testsuite/component-model-async/streams.wast +++ b/tests/misc_testsuite/component-model-async/streams.wast @@ -72,7 +72,7 @@ ;; stream.close-readable (component (core module $m - (import "" "stream.close-readable" (func $stream-close-readable (param i32))) + (import "" "stream.close-readable" (func $stream-close-readable (param i32 i32))) ) (type $stream-type (stream u8)) (core func $stream-close-readable (canon stream.close-readable $stream-type))