From e64d89bb89fe3e1b1a9ce48ca2593ddd45869425 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Feb 2025 09:46:06 -0800 Subject: [PATCH 1/5] Plumb `PayloadInfo` through more locations Simplify some callers/accessors by plumbing around this whole structure instead of having some intrinsics just have portions where others have more. --- crates/wit-component/src/encoding.rs | 82 ++++++++------------------ crates/wit-component/src/validation.rs | 76 +++++------------------- 2 files changed, 40 insertions(+), 118 deletions(-) diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index ae5bf04699..1727ef5040 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -1294,7 +1294,7 @@ impl<'a> EncodingState<'a> { let encoding = encoding.unwrap_or(StringEncoding::UTF8); let realloc_index = realloc .map(|name| self.core_alias_export(instance_index, name, ExportKind::Func)); - let type_index = self.payload_type_index(info.ty, info.imported)?; + let type_index = self.payload_type_index(info)?; let options = shim.options .into_iter(encoding, self.memory_index, realloc_index)?; @@ -1360,32 +1360,14 @@ impl<'a> EncodingState<'a> { /// Note that the payload type `T` of `stream` or `future` may be an /// imported or exported type, and that determines the appropriate type /// encoder to use. - fn payload_type_index(&mut self, ty: TypeId, imported: bool) -> Result { - // `stream` and `future` types don't have owners, but their payload - // types (or the payload type of the payload type, etc. in the case of - // nesting) might have an owner, in which case we need to find that in - // order to make the types match up e.g. when we're exporting a resource - // that's used as a payload type. - fn owner(resolve: &Resolve, ty: TypeId) -> Option { - let def = &resolve.types[ty]; - match &def.kind { - TypeDefKind::Future(Some(Type::Id(ty))) - | TypeDefKind::Stream(Some(Type::Id(ty))) => owner(resolve, *ty), - _ => match &def.owner { - TypeOwner::World(_) | TypeOwner::None => None, - TypeOwner::Interface(id) => Some(*id), - }, - } - } - + fn payload_type_index(&mut self, info: &PayloadInfo) -> Result { let resolve = &self.info.encoder.metadata.resolve; - let ComponentValType::Type(type_index) = if imported { - self.root_import_type_encoder(None) + let ComponentValType::Type(type_index) = if info.imported { + self.root_import_type_encoder(info.interface) } else { - let owner = owner(resolve, ty); - self.root_export_type_encoder(owner) + self.root_export_type_encoder(info.interface) } - .encode_valtype(resolve, &Type::Id(ty))? + .encode_valtype(resolve, &Type::Id(info.ty))? else { unreachable!() }; @@ -1639,7 +1621,7 @@ impl<'a> EncodingState<'a> { Ok((ExportKind::Func, index)) } Import::StreamNew(info) => { - let ty = self.payload_type_index(info.ty, info.imported)?; + let ty = self.payload_type_index(info)?; let index = self.component.stream_new(ty); Ok((ExportKind::Func, index)) } @@ -1657,36 +1639,28 @@ impl<'a> EncodingState<'a> { info, PayloadFuncKind::StreamWrite, )), - Import::StreamCancelRead { - ty, - imported, - async_, - } => { - let ty = self.payload_type_index(*ty, *imported)?; + Import::StreamCancelRead { info, async_ } => { + let ty = self.payload_type_index(info)?; let index = self.component.stream_cancel_read(ty, *async_); Ok((ExportKind::Func, index)) } - Import::StreamCancelWrite { - ty, - imported, - async_, - } => { - let ty = self.payload_type_index(*ty, *imported)?; + Import::StreamCancelWrite { info, async_ } => { + let ty = self.payload_type_index(info)?; let index = self.component.stream_cancel_write(ty, *async_); Ok((ExportKind::Func, index)) } - Import::StreamCloseReadable { ty, imported } => { - let type_index = self.payload_type_index(*ty, *imported)?; + Import::StreamCloseReadable(info) => { + let type_index = self.payload_type_index(info)?; let index = self.component.stream_close_readable(type_index); Ok((ExportKind::Func, index)) } - Import::StreamCloseWritable { ty, imported } => { - let type_index = self.payload_type_index(*ty, *imported)?; + Import::StreamCloseWritable(info) => { + let type_index = self.payload_type_index(info)?; let index = self.component.stream_close_writable(type_index); Ok((ExportKind::Func, index)) } Import::FutureNew(info) => { - let ty = self.payload_type_index(info.ty, info.imported)?; + let ty = self.payload_type_index(info)?; let index = self.component.future_new(ty); Ok((ExportKind::Func, index)) } @@ -1704,31 +1678,23 @@ impl<'a> EncodingState<'a> { info, PayloadFuncKind::FutureWrite, )), - Import::FutureCancelRead { - ty, - imported, - async_, - } => { - let ty = self.payload_type_index(*ty, *imported)?; + Import::FutureCancelRead { info, async_ } => { + let ty = self.payload_type_index(info)?; let index = self.component.future_cancel_read(ty, *async_); Ok((ExportKind::Func, index)) } - Import::FutureCancelWrite { - ty, - imported, - async_, - } => { - let ty = self.payload_type_index(*ty, *imported)?; + Import::FutureCancelWrite { info, async_ } => { + let ty = self.payload_type_index(info)?; let index = self.component.future_cancel_write(ty, *async_); Ok((ExportKind::Func, index)) } - Import::FutureCloseReadable { ty, imported } => { - let type_index = self.payload_type_index(*ty, *imported)?; + Import::FutureCloseReadable(info) => { + let type_index = self.payload_type_index(info)?; let index = self.component.future_close_readable(type_index); Ok((ExportKind::Func, index)) } - Import::FutureCloseWritable { ty, imported } => { - let type_index = self.payload_type_index(*ty, *imported)?; + Import::FutureCloseWritable(info) => { + let type_index = self.payload_type_index(info)?; let index = self.component.future_close_writable(type_index); Ok((ExportKind::Func, index)) } diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index 88a4e8eeb9..61d7706ef1 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -307,31 +307,23 @@ pub enum Import { /// /// This allows the guest to cancel a pending read it initiated earlier (but /// which may have already partially or entirely completed). - StreamCancelRead { - ty: TypeId, - imported: bool, - async_: bool, - }, + StreamCancelRead { info: PayloadInfo, async_: bool }, /// A `canon stream.cancel-write` intrinsic. /// /// This allows the guest to cancel a pending write it initiated earlier /// (but which may have already partially or entirely completed). - StreamCancelWrite { - ty: TypeId, - imported: bool, - async_: bool, - }, + StreamCancelWrite { info: PayloadInfo, async_: bool }, /// A `canon stream.close-readable` intrinsic. /// /// This allows the guest to close the readable end of a `stream`. - StreamCloseReadable { ty: TypeId, imported: bool }, + StreamCloseReadable(PayloadInfo), /// A `canon stream.close-writable` intrinsic. /// /// This allows the guest to close the writable end of a `stream`. - StreamCloseWritable { ty: TypeId, imported: bool }, + StreamCloseWritable(PayloadInfo), /// A `canon future.new` intrinsic. /// @@ -353,31 +345,23 @@ pub enum Import { /// /// This allows the guest to cancel a pending read it initiated earlier (but /// which may have already completed). - FutureCancelRead { - ty: TypeId, - imported: bool, - async_: bool, - }, + FutureCancelRead { info: PayloadInfo, async_: bool }, /// A `canon future.cancel-write` intrinsic. /// /// This allows the guest to cancel a pending write it initiated earlier /// (but which may have already completed). - FutureCancelWrite { - ty: TypeId, - imported: bool, - async_: bool, - }, + FutureCancelWrite { info: PayloadInfo, async_: bool }, /// A `canon future.close-readable` intrinsic. /// /// This allows the guest to close the readable end of a `future`. - FutureCloseReadable { ty: TypeId, imported: bool }, + FutureCloseReadable(PayloadInfo), /// A `canon future.close-writable` intrinsic. /// /// This allows the guest to close the writable end of a `future`. - FutureCloseWritable { ty: TypeId, imported: bool }, + FutureCloseWritable(PayloadInfo), /// A `canon error-context.new` intrinsic. /// @@ -1615,11 +1599,7 @@ impl NameMangling for Legacy { ty, )?; let info = info(key)?; - Import::FutureCancelWrite { - async_, - ty: info.ty, - imported: info.imported, - } + Import::FutureCancelWrite { async_, info } } else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") { validate_func_sig( name, @@ -1627,11 +1607,7 @@ impl NameMangling for Legacy { ty, )?; let info = info(key)?; - Import::FutureCancelRead { - async_, - ty: info.ty, - imported: info.imported, - } + Import::FutureCancelRead { async_, info } } else if let Some(key) = match_payload_prefix(name, "[future-close-writable-") { if async_ { @@ -1639,10 +1615,7 @@ impl NameMangling for Legacy { } validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; let info = info(key)?; - Import::FutureCloseWritable { - ty: info.ty, - imported: info.imported, - } + Import::FutureCloseWritable(info) } else if let Some(key) = match_payload_prefix(name, "[future-close-readable-") { if async_ { @@ -1650,10 +1623,7 @@ impl NameMangling for Legacy { } validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; let info = info(key)?; - Import::FutureCloseReadable { - ty: info.ty, - imported: info.imported, - } + Import::FutureCloseReadable(info) } else if let Some(key) = match_payload_prefix(name, "[stream-new-") { if async_ { bail!("async `stream.new` calls not supported"); @@ -1687,11 +1657,7 @@ impl NameMangling for Legacy { ty, )?; let info = info(key)?; - Import::StreamCancelWrite { - async_, - ty: info.ty, - imported: info.imported, - } + Import::StreamCancelWrite { async_, info } } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") { validate_func_sig( name, @@ -1699,11 +1665,7 @@ impl NameMangling for Legacy { ty, )?; let info = info(key)?; - Import::StreamCancelRead { - async_, - ty: info.ty, - imported: info.imported, - } + Import::StreamCancelRead { async_, info } } else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-") { if async_ { @@ -1711,10 +1673,7 @@ impl NameMangling for Legacy { } validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; let info = info(key)?; - Import::StreamCloseWritable { - ty: info.ty, - imported: info.imported, - } + Import::StreamCloseWritable(info) } else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-") { if async_ { @@ -1722,10 +1681,7 @@ impl NameMangling for Legacy { } validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; let info = info(key)?; - Import::StreamCloseReadable { - ty: info.ty, - imported: info.imported, - } + Import::StreamCloseReadable(info) } else { bail!("unrecognized payload import: {name}"); }, From 8be21d36922ba4a5ddca1ab7fa7a3cb18cc2c54e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Feb 2025 11:18:27 -0800 Subject: [PATCH 2/5] Reduce amount of data passed around in wit-component Refactor some internals of async stream/future read/write and `task.return` to avoid passing `Function` and instead just pass then name around. --- crates/wit-component/src/encoding.rs | 30 ++++++---------- crates/wit-component/src/validation.rs | 47 ++++++++++++-------------- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 1727ef5040..628befe7ee 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -1042,7 +1042,7 @@ impl<'a> EncodingState<'a> { .unwrap(); let exports = self.info.exports_for(module); let realloc_index = exports - .export_realloc_for(key, func) + .export_realloc_for(key, &func.name) .map(|name| self.core_alias_export(instance_index, name, ExportKind::Func)); let mut options = options .into_iter(encoding, self.memory_index, realloc_index)? @@ -1271,7 +1271,6 @@ impl<'a> EncodingState<'a> { for_module, info, kind, - async_: _, } => { let metadata = self.info.module_metadata_for(*for_module); let exports = self.info.exports_for(*for_module); @@ -1280,14 +1279,14 @@ impl<'a> EncodingState<'a> { ( metadata .import_encodings - .get(resolve, &info.key, &info.function.name), - exports.import_realloc_for(info.interface, &info.function.name), + .get(resolve, &info.key, &info.function), + exports.import_realloc_for(info.interface, &info.function), ) } else { ( metadata .export_encodings - .get(resolve, &info.key, &info.function.name), + .get(resolve, &info.key, &info.function), exports.export_realloc_for(&info.key, &info.function), ) }; @@ -1591,10 +1590,10 @@ impl<'a> EncodingState<'a> { AbiVariant::GuestImport, ) } - Import::ExportedTaskReturn(interface, function) => { + Import::ExportedTaskReturn(interface, _function, result) => { let mut encoder = self.root_export_type_encoder(*interface); - let result = match &function.result { + let result = match result { Some(ty) => Some(encoder.encode_valtype(resolve, ty)?), None => None, }; @@ -1625,17 +1624,15 @@ impl<'a> EncodingState<'a> { let index = self.component.stream_new(ty); Ok((ExportKind::Func, index)) } - Import::StreamRead { async_, info } => Ok(self.materialize_payload_import( + Import::StreamRead { info, .. } => Ok(self.materialize_payload_import( shims, for_module, - *async_, info, PayloadFuncKind::StreamRead, )), - Import::StreamWrite { async_, info } => Ok(self.materialize_payload_import( + Import::StreamWrite { info, .. } => Ok(self.materialize_payload_import( shims, for_module, - *async_, info, PayloadFuncKind::StreamWrite, )), @@ -1664,17 +1661,15 @@ impl<'a> EncodingState<'a> { let index = self.component.future_new(ty); Ok((ExportKind::Func, index)) } - Import::FutureRead { async_, info } => Ok(self.materialize_payload_import( + Import::FutureRead { info, .. } => Ok(self.materialize_payload_import( shims, for_module, - *async_, info, PayloadFuncKind::FutureRead, )), - Import::FutureWrite { async_, info } => Ok(self.materialize_payload_import( + Import::FutureWrite { info, .. } => Ok(self.materialize_payload_import( shims, for_module, - *async_, info, PayloadFuncKind::FutureWrite, )), @@ -1749,7 +1744,6 @@ impl<'a> EncodingState<'a> { &mut self, shims: &Shims<'_>, for_module: CustomModule<'_>, - async_: bool, info: &PayloadInfo, kind: PayloadFuncKind, ) -> (ExportKind, u32) { @@ -1757,7 +1751,6 @@ impl<'a> EncodingState<'a> { shims, &ShimKind::PayloadFunc { for_module, - async_, info, kind, }, @@ -1999,8 +1992,6 @@ enum ShimKind<'a> { /// Which instance to pull the `realloc` function and string encoding /// from, if necessary. for_module: CustomModule<'a>, - /// Whether this read/write call is using the `async` option. - async_: bool, /// Additional information regarding the function where this `stream` or /// `future` type appeared, which we use in combination with /// `for_module` to determine which `realloc` and string encoding to @@ -2353,7 +2344,6 @@ impl<'a> Shims<'a> { ), kind: ShimKind::PayloadFunc { for_module, - async_, info, kind, }, diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index 61d7706ef1..d899813a38 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -1,6 +1,6 @@ use crate::encoding::{Instance, Item, LibraryInfo, MainOrAdapter}; use crate::{ComponentEncoder, StringEncoding}; -use anyhow::{bail, Context, Result}; +use anyhow::{anyhow, bail, Context, Result}; use indexmap::{map::Entry, IndexMap, IndexSet}; use std::hash::{Hash, Hasher}; use std::mem; @@ -142,7 +142,7 @@ pub struct PayloadInfo { pub ty: TypeId, /// The component-level function import or export where the type appeared as /// a parameter or result type. - pub function: Function, + pub function: String, /// The world key representing the import or export context of `function`. pub key: WorldKey, /// The interface that `function` was imported from or exported in, if any. @@ -253,7 +253,7 @@ pub enum Import { /// As of this writing, only async-lifted exports use `task.return`, but the /// plan is to also support it for sync-lifted exports in the future as /// well. - ExportedTaskReturn(Option, Function), + ExportedTaskReturn(Option, String, Option), /// A `canon task.backpressure` intrinsic. /// @@ -545,7 +545,11 @@ impl ImportMap { // it's associated with in general. Instead, the host will // compare it with the expected type at runtime and trap if // necessary. - Some(Import::ExportedTaskReturn(interface_id, func)) + Some(Import::ExportedTaskReturn( + interface_id, + func.name.clone(), + func.result, + )) } else { None }) @@ -1027,7 +1031,7 @@ impl ExportMap { /// Returns the realloc that the exported function `interface` and `func` /// are using. - pub fn export_realloc_for(&self, key: &WorldKey, func: &Function) -> Option<&str> { + pub fn export_realloc_for(&self, key: &WorldKey, func: &str) -> Option<&str> { // TODO: This realloc detection should probably be improved with // some sort of scheme to have per-function reallocs like // `cabi_realloc_{name}` or something like that. @@ -1558,7 +1562,7 @@ impl NameMangling for Legacy { Ok::<_, anyhow::Error>(PayloadInfo { name: orig_name.to_string(), ty, - function, + function: function.name.clone(), key: key.clone(), interface, imported, @@ -1990,41 +1994,34 @@ fn match_payload_prefix(name: &str, prefix: &str) -> Option<(String, usize)> { /// /// The index refers to the entry in the list returned by /// `Function::find_futures_and_streams`. -fn get_future_or_stream_type( - resolve: &Resolve, - world: &World, +fn get_future_or_stream_type<'a>( + resolve: &'a Resolve, + world: &'a World, (name, index): &(String, usize), interface: Option, imported: bool, -) -> Result<(Function, TypeId)> { +) -> Result<(&'a Function, TypeId)> { let function = get_function(resolve, world, name, interface, imported)?; let ty = function.find_futures_and_streams(resolve)[*index]; Ok((function, ty)) } -fn get_function( - resolve: &Resolve, - world: &World, +fn get_function<'a>( + resolve: &'a Resolve, + world: &'a World, name: &str, interface: Option, imported: bool, -) -> Result { +) -> Result<&'a Function> { let function = if let Some(id) = interface { - resolve.interfaces[id] + return resolve.interfaces[id] .functions .get(name) - .cloned() - .map(WorldItem::Function) + .ok_or_else(|| anyhow!("no export `{name}` found")); } else if imported { - world - .imports - .get(&WorldKey::Name(name.to_string())) - .cloned() + world.imports.get(&WorldKey::Name(name.to_string())) } else { - world - .exports - .get(&WorldKey::Name(name.to_string())) - .cloned() + world.exports.get(&WorldKey::Name(name.to_string())) }; let Some(WorldItem::Function(function)) = function else { bail!("no export `{name}` found"); From d7aa774ec53abf1ca219f776daa7af88d7b684fe Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Feb 2025 11:54:32 -0800 Subject: [PATCH 3/5] Reduce some indentation in wit-component Don't so heavily nest the variables here indentation-wise. --- crates/wit-component/src/validation.rs | 289 +++++++++++-------------- 1 file changed, 122 insertions(+), 167 deletions(-) diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index d899813a38..c269078e41 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -1522,178 +1522,133 @@ impl NameMangling for Legacy { world: &World, ty: &FuncType, ) -> Result> { - Ok( - if let Some((suffix, imported)) = module - .strip_prefix("[import-payload]") - .map(|v| (v, true)) - .or_else(|| module.strip_prefix("[export-payload]").map(|v| (v, false))) - { - let (key, interface) = if suffix == self.import_root() { - (WorldKey::Name(name.to_string()), None) + let Some((suffix, imported)) = module + .strip_prefix("[import-payload]") + .map(|v| (v, true)) + .or_else(|| module.strip_prefix("[export-payload]").map(|v| (v, false))) + else { + return Ok(None); + }; + let (key, interface) = if suffix == self.import_root() { + (WorldKey::Name(name.to_string()), None) + } else { + let (key, id) = self.module_to_interface( + suffix, + resolve, + if imported { + &world.imports } else { - let (key, id) = self.module_to_interface( - suffix, - resolve, - if imported { - &world.imports - } else { - &world.exports - }, - )?; - (key, Some(id)) - }; + &world.exports + }, + )?; + (key, Some(id)) + }; - let orig_name = name; + let orig_name = name; - let (name, async_) = if let Some(name) = self.async_name(name) { - (name, true) - } else { - (name, false) - }; + let (name, async_) = if let Some(name) = self.async_name(name) { + (name, true) + } else { + (name, false) + }; - let info = |payload_key| { - let (function, ty) = get_future_or_stream_type( - resolve, - world, - &payload_key, - interface, - imported, - )?; - Ok::<_, anyhow::Error>(PayloadInfo { - name: orig_name.to_string(), - ty, - function: function.name.clone(), - key: key.clone(), - interface, - imported, - }) - }; + let info = |payload_key| { + let (function, ty) = + get_future_or_stream_type(resolve, world, &payload_key, interface, imported)?; + Ok::<_, anyhow::Error>(PayloadInfo { + name: orig_name.to_string(), + ty, + function: function.name.clone(), + key: key.clone(), + interface, + imported, + }) + }; - Some( - if let Some(key) = match_payload_prefix(name, "[future-new-") { - if async_ { - bail!("async `future.new` calls not supported"); - } - validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; - Import::FutureNew(info(key)?) - } else if let Some(key) = match_payload_prefix(name, "[future-write-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32; 2], [ValType::I32]), - ty, - )?; - Import::FutureWrite { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[future-read-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32; 2], [ValType::I32]), - ty, - )?; - Import::FutureRead { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[future-cancel-write-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32], [ValType::I32]), - ty, - )?; - let info = info(key)?; - Import::FutureCancelWrite { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32], [ValType::I32]), - ty, - )?; - let info = info(key)?; - Import::FutureCancelRead { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[future-close-writable-") - { - if async_ { - bail!("async `future.close-writable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; - let info = info(key)?; - Import::FutureCloseWritable(info) - } else if let Some(key) = match_payload_prefix(name, "[future-close-readable-") - { - if async_ { - bail!("async `future.close-readable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; - let info = info(key)?; - Import::FutureCloseReadable(info) - } else if let Some(key) = match_payload_prefix(name, "[stream-new-") { - if async_ { - bail!("async `stream.new` calls not supported"); - } - validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; - Import::StreamNew(info(key)?) - } else if let Some(key) = match_payload_prefix(name, "[stream-write-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32; 3], [ValType::I32]), - ty, - )?; - Import::StreamWrite { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[stream-read-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32; 3], [ValType::I32]), - ty, - )?; - Import::StreamRead { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-write-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32], [ValType::I32]), - ty, - )?; - let info = info(key)?; - Import::StreamCancelWrite { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") { - validate_func_sig( - name, - &FuncType::new([ValType::I32], [ValType::I32]), - ty, - )?; - let info = info(key)?; - Import::StreamCancelRead { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-") - { - if async_ { - bail!("async `stream.close-writable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; - let info = info(key)?; - Import::StreamCloseWritable(info) - } else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-") - { - if async_ { - bail!("async `stream.close-readable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; - let info = info(key)?; - Import::StreamCloseReadable(info) - } else { - bail!("unrecognized payload import: {name}"); - }, - ) - } else { - None - }, - ) + let import = if let Some(key) = match_payload_prefix(name, "[future-new-") { + if async_ { + bail!("async `future.new` calls not supported"); + } + validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; + Import::FutureNew(info(key)?) + } else if let Some(key) = match_payload_prefix(name, "[future-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; + Import::FutureWrite { + async_, + info: info(key)?, + } + } else if let Some(key) = match_payload_prefix(name, "[future-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; + Import::FutureRead { + async_, + info: info(key)?, + } + } else if let Some(key) = match_payload_prefix(name, "[future-cancel-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + let info = info(key)?; + Import::FutureCancelWrite { async_, info } + } else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + let info = info(key)?; + Import::FutureCancelRead { async_, info } + } else if let Some(key) = match_payload_prefix(name, "[future-close-writable-") { + if async_ { + bail!("async `future.close-writable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; + let info = info(key)?; + Import::FutureCloseWritable(info) + } else if let Some(key) = match_payload_prefix(name, "[future-close-readable-") { + if async_ { + bail!("async `future.close-readable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; + let info = info(key)?; + Import::FutureCloseReadable(info) + } else if let Some(key) = match_payload_prefix(name, "[stream-new-") { + if async_ { + bail!("async `stream.new` calls not supported"); + } + validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; + Import::StreamNew(info(key)?) + } else if let Some(key) = match_payload_prefix(name, "[stream-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; + Import::StreamWrite { + async_, + info: info(key)?, + } + } else if let Some(key) = match_payload_prefix(name, "[stream-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; + Import::StreamRead { + async_, + info: info(key)?, + } + } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + let info = info(key)?; + Import::StreamCancelWrite { async_, info } + } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + let info = info(key)?; + Import::StreamCancelRead { async_, info } + } else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-") { + if async_ { + bail!("async `stream.close-writable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; + let info = info(key)?; + Import::StreamCloseWritable(info) + } else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-") { + if async_ { + bail!("async `stream.close-readable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; + let info = info(key)?; + Import::StreamCloseReadable(info) + } else { + bail!("unrecognized payload import: {name}"); + }; + Ok(Some(import)) } fn module_to_interface( &self, From a672ef7406dd218980378d7b72269a105c482f06 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Feb 2025 12:02:42 -0800 Subject: [PATCH 4/5] Integrate async intrinsics more tightly in wit-component This commit refactors the integration of async intrinsics into wit-component to support future changes to the `task.return` intrinsic. The refactoring here moves detection of intrinsics to all be in the same path rather than having one path which handles async intrinsics, another patch which handles resource intrinsics, and another path which handles `task.return` intrinsics. By handling everything in one location it's easier to ensure that everything is handled uniformly and various bits and pieces of contextual information are also easily available. This refactoring additionally updates the names recognized for async intrinsics. Previously for example async imports might use `[import-payload]` which is now no longer required. Additionally async imports might use `[export-payload]` too and that's changed to be `[export]` to match how other exports are handled as well. --- crates/wit-component/src/validation.rs | 495 +++++++++--------- .../async-streams-and-futures/component.wat | 414 ++++++++------- .../async-streams-and-futures/module.wat | 168 +++--- 3 files changed, 533 insertions(+), 544 deletions(-) diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index c269078e41..bf3f6dfd8f 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -532,33 +532,15 @@ impl ImportMap { let world_id = encoder.metadata.world; let world = &resolve.worlds[world_id]; - if let Some(import) = names.payload_import(module, name, resolve, world, ty)? { - return Ok(import); - } - - let async_import_for_export = |interface: Option<(WorldKey, InterfaceId)>| { - Ok::<_, anyhow::Error>(if let Some(function_name) = names.task_return_name(name) { - let interface_id = interface.as_ref().map(|(_, id)| *id); - let func = get_function(resolve, world, function_name, interface_id, false)?; - // Note that we can't statically validate the type signature of - // a `task.return` built-in since we can't know which export - // it's associated with in general. Instead, the host will - // compare it with the expected type at runtime and trap if - // necessary. - Some(Import::ExportedTaskReturn( - interface_id, - func.name.clone(), - func.result, - )) - } else { - None - }) + let (async_, name) = if let Some(name) = names.async_name(name) { + (true, name) + } else { + (false, name) }; - - let (abi, name) = if let Some(name) = names.async_name(name) { - (AbiVariant::GuestImportAsync, name) + let abi = if async_ { + AbiVariant::GuestImportAsync } else { - (AbiVariant::GuestImport, name) + AbiVariant::GuestImport }; if module == names.import_root() { @@ -625,13 +607,10 @@ impl ImportMap { return Ok(Import::WorldFunc(key, func.name.clone(), abi)); } - let get_resource = resource_test_for_world(resolve, world_id); - if let Some(resource) = names.resource_drop_name(name) { - if let Some(id) = get_resource(resource) { - let expected = FuncType::new([ValType::I32], []); - validate_func_sig(name, &expected, ty)?; - return Ok(Import::ImportedResourceDrop(key, None, id)); - } + if let Some(import) = + self.maybe_classify_wit_intrinsic(name, None, encoder, ty, async_, true, names)? + { + return Ok(import); } match world.imports.get(&key) { @@ -640,11 +619,14 @@ impl ImportMap { } } + // Check for `[export]$root::[task-return]foo` or similar if matches!( module.strip_prefix(names.import_exported_intrinsic_prefix()), Some(module) if module == names.import_root() ) { - if let Some(import) = async_import_for_export(None)? { + if let Some(import) = + self.maybe_classify_wit_intrinsic(name, None, encoder, ty, async_, false, names)? + { return Ok(import); } } @@ -655,56 +637,42 @@ impl ImportMap { }; if let Some(interface) = interface.strip_prefix(names.import_exported_intrinsic_prefix()) { - if let Some(import) = async_import_for_export(Some(names.module_to_interface( - interface, - resolve, - &world.exports, - )?))? { - return Ok(import); - } - let (key, id) = names.module_to_interface(interface, resolve, &world.exports)?; - let get_resource = resource_test_for_interface(resolve, id); - if let Some(name) = names.resource_drop_name(name) { - if let Some(id) = get_resource(name) { - let expected = FuncType::new([ValType::I32], []); - validate_func_sig(name, &expected, ty)?; - return Ok(Import::ExportedResourceDrop(key, id)); - } - } - if let Some(name) = names.resource_new_name(name) { - if let Some(id) = get_resource(name) { - let expected = FuncType::new([ValType::I32], [ValType::I32]); - validate_func_sig(name, &expected, ty)?; - return Ok(Import::ExportedResourceNew(key, id)); - } - } - if let Some(name) = names.resource_rep_name(name) { - if let Some(id) = get_resource(name) { - let expected = FuncType::new([ValType::I32], [ValType::I32]); - validate_func_sig(name, &expected, ty)?; - return Ok(Import::ExportedResourceRep(key, id)); - } + if let Some(import) = self.maybe_classify_wit_intrinsic( + name, + Some((key, id)), + encoder, + ty, + async_, + false, + names, + )? { + return Ok(import); } bail!("unknown function `{name}`") } let (key, id) = names.module_to_interface(interface, resolve, &world.imports)?; let interface = &resolve.interfaces[id]; - let get_resource = resource_test_for_interface(resolve, id); if let Some(f) = interface.functions.get(name) { validate_func(resolve, ty, f, abi).with_context(|| { let name = resolve.name_world_key(&key); format!("failed to validate import interface `{name}`") })?; return Ok(Import::InterfaceFunc(key, id, f.name.clone(), abi)); - } else if let Some(resource) = names.resource_drop_name(name) { - if let Some(resource) = get_resource(resource) { - let expected = FuncType::new([ValType::I32], []); - validate_func_sig(name, &expected, ty)?; - return Ok(Import::ImportedResourceDrop(key, Some(id), resource)); - } + } + + if let Some(import) = self.maybe_classify_wit_intrinsic( + name, + Some((key, id)), + encoder, + ty, + async_, + true, + names, + )? { + return Ok(import); } bail!( "import interface `{module}` is missing function \ @@ -712,6 +680,214 @@ impl ImportMap { ) } + /// Attempts to detect and classify `name` as a WIT intrinsic. + /// + /// This function is a bit of a sprawling sequence of matches used to + /// detect whether `name` corresponds to a WIT intrinsic, so specifically + /// not a WIT function itself. This is only used for functions imported + /// into a module but the import could be for an imported item in a world + /// or an exported item. + /// + /// ## Parameters + /// + /// * `name` - the core module name which is being pattern-matched. This + /// should be the "field" of the import. This should have the "[async]" + /// prefix stripped out already. + /// * `key_and_id` - this is the inferred "container" for the function + /// being described which is inferred from the module portion of the core + /// wasm import field. This is `None` for root-level function/type + /// imports, such as when referring to `import x: func();`. This is `Some` + /// when an interface is used (either `import x: interface { .. }` or a + /// standalone `interface`) where the world key is specified for the + /// interface in addition to the interface that was identified. + /// * `encoder` - this is the encoder state that contains + /// `Resolve`/metadata information. + /// * `ty` - the core wasm type of this import. + /// * `async_` - whether or not this import had the `[async]` import. Note + /// that such prefix is not present in `name`. + /// * `import` - whether or not this core wasm import is operating on a WIT + /// level import or export. An example of this being an export is when a + /// core module imports a destructor for an exported resourceV + /// * `names` - the name mangling scheme that's configured to be used. + fn maybe_classify_wit_intrinsic( + &self, + name: &str, + key_and_id: Option<(WorldKey, InterfaceId)>, + encoder: &ComponentEncoder, + ty: &FuncType, + async_: bool, + import: bool, + names: &dyn NameMangling, + ) -> Result> { + let resolve = &encoder.metadata.resolve; + let world_id = encoder.metadata.world; + let world = &resolve.worlds[world_id]; + + // Separate out `Option` and `Option`. If an + // interface is NOT specified then the `WorldKey` which is attached to + // imports is going to be calculated based on the name of the item + // extracted, such as the resource or function referenced. + let (key, id) = match key_and_id { + Some((key, id)) => (Some(key), Some(id)), + None => (None, None), + }; + + // Tests whether `name` is a resource within `id` (or `world_id`). + let resource_test = |name: &str| match id { + Some(id) => resource_test_for_interface(resolve, id)(name), + None => resource_test_for_world(resolve, world_id)(name), + }; + + // Test whether this is a `resource.drop` intrinsic. + if let Some(resource) = names.resource_drop_name(name) { + if async_ { + bail!("async `resource.drop` calls not supported"); + } + if let Some(resource_id) = resource_test(resource) { + let key = key.unwrap_or_else(|| WorldKey::Name(resource.to_string())); + let expected = FuncType::new([ValType::I32], []); + validate_func_sig(name, &expected, ty)?; + return Ok(Some(if import { + Import::ImportedResourceDrop(key, id, resource_id) + } else { + Import::ExportedResourceDrop(key, resource_id) + })); + } + } + + // There are some intrinsics which are only applicable to exported + // functions/resources, so check those use cases here. + if !import { + if let Some(name) = names.resource_new_name(name) { + if let Some(id) = resource_test(name) { + let key = key.unwrap_or_else(|| WorldKey::Name(name.to_string())); + let expected = FuncType::new([ValType::I32], [ValType::I32]); + validate_func_sig(name, &expected, ty)?; + return Ok(Some(Import::ExportedResourceNew(key, id))); + } + } + if let Some(name) = names.resource_rep_name(name) { + if let Some(id) = resource_test(name) { + let key = key.unwrap_or_else(|| WorldKey::Name(name.to_string())); + let expected = FuncType::new([ValType::I32], [ValType::I32]); + validate_func_sig(name, &expected, ty)?; + return Ok(Some(Import::ExportedResourceRep(key, id))); + } + } + if let Some(name) = names.task_return_name(name) { + let func = get_function(resolve, world, name, id, import)?; + // TODO: should call `validate_func_sig` but would require + // calculating the expected signature based of `func.result`. + return Ok(Some(Import::ExportedTaskReturn( + None, + func.name.clone(), + func.result, + ))); + } + } + + // Looks for `[$prefix-N]foo` within `name`. If found then `foo` is + // used to find a function within `id` and `world` above. Once found + // then `N` is used to index within that function to extract a + // future/stream type. If that's all found then a `PayloadInfo` is + // returned to get attached to an intrinsic. + let prefixed_payload = |prefix: &str| { + // parse the `prefix` into `func_name` and `type_index`, bailing out + // with `None` if anything doesn't match. + let suffix = name.strip_prefix(prefix)?; + let index = suffix.find(']')?; + let func_name = &suffix[index + 1..]; + let type_index: usize = suffix[..index].parse().ok()?; + + // Double-check that `func_name` is indeed a function name within + // this interface/world. Then additionally double-check that + // `type_index` is indeed a valid index for this function's type + // signature. + let function = get_function(resolve, world, func_name, id, import).ok()?; + let ty = *function.find_futures_and_streams(resolve).get(type_index)?; + + // And if all that passes wrap up everything in a `PayloadInfo`. + Some(PayloadInfo { + name: name.to_string(), + ty, + function: function.name.clone(), + key: key + .clone() + .unwrap_or_else(|| WorldKey::Name(name.to_string())), + interface: id, + imported: import, + }) + }; + + // Test for a number of async-related intrinsics. All intrinsics are + // prefixed with `[...-N]` where `...` is the name of the intrinsic and + // the `N` is the indexed future/stream that is being referred to. + let import = if let Some(info) = prefixed_payload("[future-new-") { + if async_ { + bail!("async `future.new` calls not supported"); + } + validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; + Import::FutureNew(info) + } else if let Some(info) = prefixed_payload("[future-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; + Import::FutureWrite { async_, info } + } else if let Some(info) = prefixed_payload("[future-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; + Import::FutureRead { async_, info } + } else if let Some(info) = prefixed_payload("[future-cancel-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + Import::FutureCancelWrite { async_, info } + } else if let Some(info) = prefixed_payload("[future-cancel-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + Import::FutureCancelRead { async_, info } + } else if let Some(info) = prefixed_payload("[future-close-writable-") { + if async_ { + bail!("async `future.close-writable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; + Import::FutureCloseWritable(info) + } else if let Some(info) = prefixed_payload("[future-close-readable-") { + if async_ { + bail!("async `future.close-readable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; + Import::FutureCloseReadable(info) + } else if let Some(info) = prefixed_payload("[stream-new-") { + if async_ { + bail!("async `stream.new` calls not supported"); + } + validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; + Import::StreamNew(info) + } else if let Some(info) = prefixed_payload("[stream-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; + Import::StreamWrite { async_, info } + } else if let Some(info) = prefixed_payload("[stream-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; + Import::StreamRead { async_, info } + } else if let Some(info) = prefixed_payload("[stream-cancel-write-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + Import::StreamCancelWrite { async_, info } + } else if let Some(info) = prefixed_payload("[stream-cancel-read-") { + validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; + Import::StreamCancelRead { async_, info } + } else if let Some(info) = prefixed_payload("[stream-close-writable-") { + if async_ { + bail!("async `stream.close-writable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; + Import::StreamCloseWritable(info) + } else if let Some(info) = prefixed_payload("[stream-close-readable-") { + if async_ { + bail!("async `stream.close-readable` calls not supported"); + } + validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; + Import::StreamCloseReadable(info) + } else { + return Ok(None); + }; + Ok(Some(import)) + } + fn classify_import_with_library( &mut self, import: wasmparser::Import<'_>, @@ -1199,14 +1375,6 @@ trait NameMangling { fn error_context_new(&self, s: &str) -> Option; fn error_context_debug_message<'a>(&self, s: &'a str) -> Option<(StringEncoding, &'a str)>; fn error_context_drop(&self) -> Option<&str>; - fn payload_import( - &self, - module: &str, - name: &str, - resolve: &Resolve, - world: &World, - ty: &FuncType, - ) -> Result>; fn module_to_interface( &self, module: &str, @@ -1306,17 +1474,6 @@ impl NameMangling for Standard { fn error_context_drop(&self) -> Option<&str> { None } - fn payload_import( - &self, - module: &str, - name: &str, - resolve: &Resolve, - world: &World, - ty: &FuncType, - ) -> Result> { - _ = (module, name, resolve, world, ty); - Ok(None) - } fn module_to_interface( &self, interface: &str, @@ -1514,142 +1671,6 @@ impl NameMangling for Legacy { fn error_context_drop(&self) -> Option<&str> { Some("[error-context-drop]") } - fn payload_import( - &self, - module: &str, - name: &str, - resolve: &Resolve, - world: &World, - ty: &FuncType, - ) -> Result> { - let Some((suffix, imported)) = module - .strip_prefix("[import-payload]") - .map(|v| (v, true)) - .or_else(|| module.strip_prefix("[export-payload]").map(|v| (v, false))) - else { - return Ok(None); - }; - let (key, interface) = if suffix == self.import_root() { - (WorldKey::Name(name.to_string()), None) - } else { - let (key, id) = self.module_to_interface( - suffix, - resolve, - if imported { - &world.imports - } else { - &world.exports - }, - )?; - (key, Some(id)) - }; - - let orig_name = name; - - let (name, async_) = if let Some(name) = self.async_name(name) { - (name, true) - } else { - (name, false) - }; - - let info = |payload_key| { - let (function, ty) = - get_future_or_stream_type(resolve, world, &payload_key, interface, imported)?; - Ok::<_, anyhow::Error>(PayloadInfo { - name: orig_name.to_string(), - ty, - function: function.name.clone(), - key: key.clone(), - interface, - imported, - }) - }; - - let import = if let Some(key) = match_payload_prefix(name, "[future-new-") { - if async_ { - bail!("async `future.new` calls not supported"); - } - validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; - Import::FutureNew(info(key)?) - } else if let Some(key) = match_payload_prefix(name, "[future-write-") { - validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; - Import::FutureWrite { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[future-read-") { - validate_func_sig(name, &FuncType::new([ValType::I32; 2], [ValType::I32]), ty)?; - Import::FutureRead { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[future-cancel-write-") { - validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; - let info = info(key)?; - Import::FutureCancelWrite { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[future-cancel-read-") { - validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; - let info = info(key)?; - Import::FutureCancelRead { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[future-close-writable-") { - if async_ { - bail!("async `future.close-writable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; - let info = info(key)?; - Import::FutureCloseWritable(info) - } else if let Some(key) = match_payload_prefix(name, "[future-close-readable-") { - if async_ { - bail!("async `future.close-readable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; - let info = info(key)?; - Import::FutureCloseReadable(info) - } else if let Some(key) = match_payload_prefix(name, "[stream-new-") { - if async_ { - bail!("async `stream.new` calls not supported"); - } - validate_func_sig(name, &FuncType::new([], [ValType::I32]), ty)?; - Import::StreamNew(info(key)?) - } else if let Some(key) = match_payload_prefix(name, "[stream-write-") { - validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; - Import::StreamWrite { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[stream-read-") { - validate_func_sig(name, &FuncType::new([ValType::I32; 3], [ValType::I32]), ty)?; - Import::StreamRead { - async_, - info: info(key)?, - } - } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-write-") { - validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; - let info = info(key)?; - Import::StreamCancelWrite { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[stream-cancel-read-") { - validate_func_sig(name, &FuncType::new([ValType::I32], [ValType::I32]), ty)?; - let info = info(key)?; - Import::StreamCancelRead { async_, info } - } else if let Some(key) = match_payload_prefix(name, "[stream-close-writable-") { - if async_ { - bail!("async `stream.close-writable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32; 2], []), ty)?; - let info = info(key)?; - Import::StreamCloseWritable(info) - } else if let Some(key) = match_payload_prefix(name, "[stream-close-readable-") { - if async_ { - bail!("async `stream.close-readable` calls not supported"); - } - validate_func_sig(name, &FuncType::new([ValType::I32], []), ty)?; - let info = info(key)?; - Import::StreamCloseReadable(info) - } else { - bail!("unrecognized payload import: {name}"); - }; - Ok(Some(import)) - } fn module_to_interface( &self, module: &str, @@ -1935,32 +1956,6 @@ fn validate_func_sig(name: &str, expected: &FuncType, ty: &wasmparser::FuncType) Ok(()) } -fn match_payload_prefix(name: &str, prefix: &str) -> Option<(String, usize)> { - let suffix = name.strip_prefix(prefix)?; - let index = suffix.find(']')?; - Some(( - suffix[index + 1..].to_owned(), - suffix[..index].parse().ok()?, - )) -} - -/// Retrieve the specified function from the specified world or interface, along -/// with the future or stream type at the specified index. -/// -/// The index refers to the entry in the list returned by -/// `Function::find_futures_and_streams`. -fn get_future_or_stream_type<'a>( - resolve: &'a Resolve, - world: &'a World, - (name, index): &(String, usize), - interface: Option, - imported: bool, -) -> Result<(&'a Function, TypeId)> { - let function = get_function(resolve, world, name, interface, imported)?; - let ty = function.find_futures_and_streams(resolve)[*index]; - Ok((function, ty)) -} - fn get_function<'a>( resolve: &'a Resolve, world: &'a World, diff --git a/crates/wit-component/tests/components/async-streams-and-futures/component.wat b/crates/wit-component/tests/components/async-streams-and-futures/component.wat index d5ee978779..4e0883c60c 100644 --- a/crates/wit-component/tests/components/async-streams-and-futures/component.wat +++ b/crates/wit-component/tests/components/async-streams-and-futures/component.wat @@ -24,90 +24,90 @@ (type (;6;) (func (param i32 i32 i32 i32) (result i32))) (import "$root" "[async]foo" (func (;0;) (type 0))) (import "foo:foo/bar" "[async]foo" (func (;1;) (type 0))) - (import "[import-payload]$root" "[stream-new-2]foo" (func (;2;) (type 1))) - (import "[import-payload]$root" "[stream-read-2]foo" (func (;3;) (type 2))) - (import "[import-payload]$root" "[stream-write-2]foo" (func (;4;) (type 2))) - (import "[import-payload]$root" "[stream-cancel-read-2]foo" (func (;5;) (type 3))) - (import "[import-payload]$root" "[stream-cancel-write-2]foo" (func (;6;) (type 3))) - (import "[import-payload]$root" "[stream-close-readable-2]foo" (func (;7;) (type 4))) - (import "[import-payload]$root" "[stream-close-writable-2]foo" (func (;8;) (type 5))) - (import "[import-payload]foo:foo/bar" "[stream-new-2]foo" (func (;9;) (type 1))) - (import "[import-payload]foo:foo/bar" "[stream-read-2]foo" (func (;10;) (type 2))) - (import "[import-payload]foo:foo/bar" "[stream-write-2]foo" (func (;11;) (type 2))) - (import "[import-payload]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;12;) (type 3))) - (import "[import-payload]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;13;) (type 3))) - (import "[import-payload]foo:foo/bar" "[stream-close-readable-2]foo" (func (;14;) (type 4))) - (import "[import-payload]foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 5))) - (import "[import-payload]$root" "[future-new-0]foo" (func (;16;) (type 1))) - (import "[import-payload]$root" "[future-read-0]foo" (func (;17;) (type 0))) - (import "[import-payload]$root" "[future-write-0]foo" (func (;18;) (type 0))) - (import "[import-payload]$root" "[future-cancel-read-0]foo" (func (;19;) (type 3))) - (import "[import-payload]$root" "[future-cancel-write-0]foo" (func (;20;) (type 3))) - (import "[import-payload]$root" "[future-close-readable-0]foo" (func (;21;) (type 4))) - (import "[import-payload]$root" "[future-close-writable-0]foo" (func (;22;) (type 5))) - (import "[import-payload]foo:foo/bar" "[future-new-0]foo" (func (;23;) (type 1))) - (import "[import-payload]foo:foo/bar" "[future-read-0]foo" (func (;24;) (type 0))) - (import "[import-payload]foo:foo/bar" "[future-write-0]foo" (func (;25;) (type 0))) - (import "[import-payload]foo:foo/bar" "[future-cancel-read-0]foo" (func (;26;) (type 3))) - (import "[import-payload]foo:foo/bar" "[future-cancel-write-0]foo" (func (;27;) (type 3))) - (import "[import-payload]foo:foo/bar" "[future-close-readable-0]foo" (func (;28;) (type 4))) - (import "[import-payload]foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 5))) - (import "[import-payload]$root" "[future-new-1]foo" (func (;30;) (type 1))) - (import "[import-payload]$root" "[future-read-1]foo" (func (;31;) (type 0))) - (import "[import-payload]$root" "[future-write-1]foo" (func (;32;) (type 0))) - (import "[import-payload]$root" "[future-cancel-read-1]foo" (func (;33;) (type 3))) - (import "[import-payload]$root" "[future-cancel-write-1]foo" (func (;34;) (type 3))) - (import "[import-payload]$root" "[future-close-readable-1]foo" (func (;35;) (type 4))) - (import "[import-payload]$root" "[future-close-writable-1]foo" (func (;36;) (type 5))) - (import "[import-payload]foo:foo/bar" "[future-new-1]foo" (func (;37;) (type 1))) - (import "[import-payload]foo:foo/bar" "[future-read-1]foo" (func (;38;) (type 0))) - (import "[import-payload]foo:foo/bar" "[future-write-1]foo" (func (;39;) (type 0))) - (import "[import-payload]foo:foo/bar" "[future-cancel-read-1]foo" (func (;40;) (type 3))) - (import "[import-payload]foo:foo/bar" "[future-cancel-write-1]foo" (func (;41;) (type 3))) - (import "[import-payload]foo:foo/bar" "[future-close-readable-1]foo" (func (;42;) (type 4))) - (import "[import-payload]foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 5))) - (import "[export-payload]$root" "[stream-new-2]foo" (func (;44;) (type 1))) - (import "[export-payload]$root" "[stream-read-2]foo" (func (;45;) (type 2))) - (import "[export-payload]$root" "[stream-write-2]foo" (func (;46;) (type 2))) - (import "[export-payload]$root" "[stream-cancel-read-2]foo" (func (;47;) (type 3))) - (import "[export-payload]$root" "[stream-cancel-write-2]foo" (func (;48;) (type 3))) - (import "[export-payload]$root" "[stream-close-readable-2]foo" (func (;49;) (type 4))) - (import "[export-payload]$root" "[stream-close-writable-2]foo" (func (;50;) (type 5))) - (import "[export-payload]foo:foo/bar" "[stream-new-2]foo" (func (;51;) (type 1))) - (import "[export-payload]foo:foo/bar" "[stream-read-2]foo" (func (;52;) (type 2))) - (import "[export-payload]foo:foo/bar" "[stream-write-2]foo" (func (;53;) (type 2))) - (import "[export-payload]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;54;) (type 3))) - (import "[export-payload]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;55;) (type 3))) - (import "[export-payload]foo:foo/bar" "[stream-close-readable-2]foo" (func (;56;) (type 4))) - (import "[export-payload]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 5))) - (import "[export-payload]$root" "[future-new-0]foo" (func (;58;) (type 1))) - (import "[export-payload]$root" "[future-read-0]foo" (func (;59;) (type 0))) - (import "[export-payload]$root" "[future-write-0]foo" (func (;60;) (type 0))) - (import "[export-payload]$root" "[future-cancel-read-0]foo" (func (;61;) (type 3))) - (import "[export-payload]$root" "[future-cancel-write-0]foo" (func (;62;) (type 3))) - (import "[export-payload]$root" "[future-close-readable-0]foo" (func (;63;) (type 4))) - (import "[export-payload]$root" "[future-close-writable-0]foo" (func (;64;) (type 5))) - (import "[export-payload]foo:foo/bar" "[future-new-0]foo" (func (;65;) (type 1))) - (import "[export-payload]foo:foo/bar" "[future-read-0]foo" (func (;66;) (type 0))) - (import "[export-payload]foo:foo/bar" "[future-write-0]foo" (func (;67;) (type 0))) - (import "[export-payload]foo:foo/bar" "[future-cancel-read-0]foo" (func (;68;) (type 3))) - (import "[export-payload]foo:foo/bar" "[future-cancel-write-0]foo" (func (;69;) (type 3))) - (import "[export-payload]foo:foo/bar" "[future-close-readable-0]foo" (func (;70;) (type 4))) - (import "[export-payload]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 5))) - (import "[export-payload]$root" "[future-new-1]foo" (func (;72;) (type 1))) - (import "[export-payload]$root" "[future-read-1]foo" (func (;73;) (type 0))) - (import "[export-payload]$root" "[future-write-1]foo" (func (;74;) (type 0))) - (import "[export-payload]$root" "[future-cancel-read-1]foo" (func (;75;) (type 3))) - (import "[export-payload]$root" "[future-cancel-write-1]foo" (func (;76;) (type 3))) - (import "[export-payload]$root" "[future-close-readable-1]foo" (func (;77;) (type 4))) - (import "[export-payload]$root" "[future-close-writable-1]foo" (func (;78;) (type 5))) - (import "[export-payload]foo:foo/bar" "[future-new-1]foo" (func (;79;) (type 1))) - (import "[export-payload]foo:foo/bar" "[future-read-1]foo" (func (;80;) (type 0))) - (import "[export-payload]foo:foo/bar" "[future-write-1]foo" (func (;81;) (type 0))) - (import "[export-payload]foo:foo/bar" "[future-cancel-read-1]foo" (func (;82;) (type 3))) - (import "[export-payload]foo:foo/bar" "[future-cancel-write-1]foo" (func (;83;) (type 3))) - (import "[export-payload]foo:foo/bar" "[future-close-readable-1]foo" (func (;84;) (type 4))) - (import "[export-payload]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 5))) + (import "$root" "[stream-new-2]foo" (func (;2;) (type 1))) + (import "$root" "[stream-read-2]foo" (func (;3;) (type 2))) + (import "$root" "[stream-write-2]foo" (func (;4;) (type 2))) + (import "$root" "[stream-cancel-read-2]foo" (func (;5;) (type 3))) + (import "$root" "[stream-cancel-write-2]foo" (func (;6;) (type 3))) + (import "$root" "[stream-close-readable-2]foo" (func (;7;) (type 4))) + (import "$root" "[stream-close-writable-2]foo" (func (;8;) (type 5))) + (import "foo:foo/bar" "[stream-new-2]foo" (func (;9;) (type 1))) + (import "foo:foo/bar" "[stream-read-2]foo" (func (;10;) (type 2))) + (import "foo:foo/bar" "[stream-write-2]foo" (func (;11;) (type 2))) + (import "foo:foo/bar" "[stream-cancel-read-2]foo" (func (;12;) (type 3))) + (import "foo:foo/bar" "[stream-cancel-write-2]foo" (func (;13;) (type 3))) + (import "foo:foo/bar" "[stream-close-readable-2]foo" (func (;14;) (type 4))) + (import "foo:foo/bar" "[stream-close-writable-2]foo" (func (;15;) (type 5))) + (import "$root" "[future-new-0]foo" (func (;16;) (type 1))) + (import "$root" "[future-read-0]foo" (func (;17;) (type 0))) + (import "$root" "[future-write-0]foo" (func (;18;) (type 0))) + (import "$root" "[future-cancel-read-0]foo" (func (;19;) (type 3))) + (import "$root" "[future-cancel-write-0]foo" (func (;20;) (type 3))) + (import "$root" "[future-close-readable-0]foo" (func (;21;) (type 4))) + (import "$root" "[future-close-writable-0]foo" (func (;22;) (type 5))) + (import "foo:foo/bar" "[future-new-0]foo" (func (;23;) (type 1))) + (import "foo:foo/bar" "[future-read-0]foo" (func (;24;) (type 0))) + (import "foo:foo/bar" "[future-write-0]foo" (func (;25;) (type 0))) + (import "foo:foo/bar" "[future-cancel-read-0]foo" (func (;26;) (type 3))) + (import "foo:foo/bar" "[future-cancel-write-0]foo" (func (;27;) (type 3))) + (import "foo:foo/bar" "[future-close-readable-0]foo" (func (;28;) (type 4))) + (import "foo:foo/bar" "[future-close-writable-0]foo" (func (;29;) (type 5))) + (import "$root" "[future-new-1]foo" (func (;30;) (type 1))) + (import "$root" "[future-read-1]foo" (func (;31;) (type 0))) + (import "$root" "[future-write-1]foo" (func (;32;) (type 0))) + (import "$root" "[future-cancel-read-1]foo" (func (;33;) (type 3))) + (import "$root" "[future-cancel-write-1]foo" (func (;34;) (type 3))) + (import "$root" "[future-close-readable-1]foo" (func (;35;) (type 4))) + (import "$root" "[future-close-writable-1]foo" (func (;36;) (type 5))) + (import "foo:foo/bar" "[future-new-1]foo" (func (;37;) (type 1))) + (import "foo:foo/bar" "[future-read-1]foo" (func (;38;) (type 0))) + (import "foo:foo/bar" "[future-write-1]foo" (func (;39;) (type 0))) + (import "foo:foo/bar" "[future-cancel-read-1]foo" (func (;40;) (type 3))) + (import "foo:foo/bar" "[future-cancel-write-1]foo" (func (;41;) (type 3))) + (import "foo:foo/bar" "[future-close-readable-1]foo" (func (;42;) (type 4))) + (import "foo:foo/bar" "[future-close-writable-1]foo" (func (;43;) (type 5))) + (import "[export]$root" "[stream-new-2]foo" (func (;44;) (type 1))) + (import "[export]$root" "[stream-read-2]foo" (func (;45;) (type 2))) + (import "[export]$root" "[stream-write-2]foo" (func (;46;) (type 2))) + (import "[export]$root" "[stream-cancel-read-2]foo" (func (;47;) (type 3))) + (import "[export]$root" "[stream-cancel-write-2]foo" (func (;48;) (type 3))) + (import "[export]$root" "[stream-close-readable-2]foo" (func (;49;) (type 4))) + (import "[export]$root" "[stream-close-writable-2]foo" (func (;50;) (type 5))) + (import "[export]foo:foo/bar" "[stream-new-2]foo" (func (;51;) (type 1))) + (import "[export]foo:foo/bar" "[stream-read-2]foo" (func (;52;) (type 2))) + (import "[export]foo:foo/bar" "[stream-write-2]foo" (func (;53;) (type 2))) + (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo" (func (;54;) (type 3))) + (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo" (func (;55;) (type 3))) + (import "[export]foo:foo/bar" "[stream-close-readable-2]foo" (func (;56;) (type 4))) + (import "[export]foo:foo/bar" "[stream-close-writable-2]foo" (func (;57;) (type 5))) + (import "[export]$root" "[future-new-0]foo" (func (;58;) (type 1))) + (import "[export]$root" "[future-read-0]foo" (func (;59;) (type 0))) + (import "[export]$root" "[future-write-0]foo" (func (;60;) (type 0))) + (import "[export]$root" "[future-cancel-read-0]foo" (func (;61;) (type 3))) + (import "[export]$root" "[future-cancel-write-0]foo" (func (;62;) (type 3))) + (import "[export]$root" "[future-close-readable-0]foo" (func (;63;) (type 4))) + (import "[export]$root" "[future-close-writable-0]foo" (func (;64;) (type 5))) + (import "[export]foo:foo/bar" "[future-new-0]foo" (func (;65;) (type 1))) + (import "[export]foo:foo/bar" "[future-read-0]foo" (func (;66;) (type 0))) + (import "[export]foo:foo/bar" "[future-write-0]foo" (func (;67;) (type 0))) + (import "[export]foo:foo/bar" "[future-cancel-read-0]foo" (func (;68;) (type 3))) + (import "[export]foo:foo/bar" "[future-cancel-write-0]foo" (func (;69;) (type 3))) + (import "[export]foo:foo/bar" "[future-close-readable-0]foo" (func (;70;) (type 4))) + (import "[export]foo:foo/bar" "[future-close-writable-0]foo" (func (;71;) (type 5))) + (import "[export]$root" "[future-new-1]foo" (func (;72;) (type 1))) + (import "[export]$root" "[future-read-1]foo" (func (;73;) (type 0))) + (import "[export]$root" "[future-write-1]foo" (func (;74;) (type 0))) + (import "[export]$root" "[future-cancel-read-1]foo" (func (;75;) (type 3))) + (import "[export]$root" "[future-cancel-write-1]foo" (func (;76;) (type 3))) + (import "[export]$root" "[future-close-readable-1]foo" (func (;77;) (type 4))) + (import "[export]$root" "[future-close-writable-1]foo" (func (;78;) (type 5))) + (import "[export]foo:foo/bar" "[future-new-1]foo" (func (;79;) (type 1))) + (import "[export]foo:foo/bar" "[future-read-1]foo" (func (;80;) (type 0))) + (import "[export]foo:foo/bar" "[future-write-1]foo" (func (;81;) (type 0))) + (import "[export]foo:foo/bar" "[future-cancel-read-1]foo" (func (;82;) (type 3))) + (import "[export]foo:foo/bar" "[future-cancel-write-1]foo" (func (;83;) (type 3))) + (import "[export]foo:foo/bar" "[future-close-readable-1]foo" (func (;84;) (type 4))) + (import "[export]foo:foo/bar" "[future-close-writable-1]foo" (func (;85;) (type 5))) (memory (;0;) 1) (export "[async-stackful]foo" (func 86)) (export "[async-stackful]foo:foo/bar#foo" (func 87)) @@ -133,31 +133,31 @@ (type (;2;) (func (param i32 i32) (result i32))) (table (;0;) 26 26 funcref) (export "0" (func $"indirect-$root-[async]foo")) - (export "1" (func $"indirect-foo:foo/bar-[async]foo")) - (export "2" (func $"[import-payload]$root-[stream-read-2]foo")) - (export "3" (func $"[import-payload]$root-[stream-write-2]foo")) - (export "4" (func $"[import-payload]$root-[future-read-0]foo")) - (export "5" (func $"[import-payload]$root-[future-write-0]foo")) - (export "6" (func $"[import-payload]$root-[future-read-1]foo")) - (export "7" (func $"[import-payload]$root-[future-write-1]foo")) - (export "8" (func $"[import-payload]foo:foo/bar-[stream-read-2]foo")) - (export "9" (func $"[import-payload]foo:foo/bar-[stream-write-2]foo")) - (export "10" (func $"[import-payload]foo:foo/bar-[future-read-0]foo")) - (export "11" (func $"[import-payload]foo:foo/bar-[future-write-0]foo")) - (export "12" (func $"[import-payload]foo:foo/bar-[future-read-1]foo")) - (export "13" (func $"[import-payload]foo:foo/bar-[future-write-1]foo")) - (export "14" (func $"[export-payload]$root-[stream-read-2]foo")) - (export "15" (func $"[export-payload]$root-[stream-write-2]foo")) - (export "16" (func $"[export-payload]$root-[future-read-0]foo")) - (export "17" (func $"[export-payload]$root-[future-write-0]foo")) - (export "18" (func $"[export-payload]$root-[future-read-1]foo")) - (export "19" (func $"[export-payload]$root-[future-write-1]foo")) - (export "20" (func $"[export-payload]foo:foo/bar-[stream-read-2]foo")) - (export "21" (func $"[export-payload]foo:foo/bar-[stream-write-2]foo")) - (export "22" (func $"[export-payload]foo:foo/bar-[future-read-0]foo")) - (export "23" (func $"[export-payload]foo:foo/bar-[future-write-0]foo")) - (export "24" (func $"[export-payload]foo:foo/bar-[future-read-1]foo")) - (export "25" (func $"[export-payload]foo:foo/bar-[future-write-1]foo")) + (export "1" (func $"$root-[stream-read-2]foo")) + (export "2" (func $"$root-[stream-write-2]foo")) + (export "3" (func $"$root-[future-read-0]foo")) + (export "4" (func $"$root-[future-write-0]foo")) + (export "5" (func $"$root-[future-read-1]foo")) + (export "6" (func $"$root-[future-write-1]foo")) + (export "7" (func $"indirect-foo:foo/bar-[async]foo")) + (export "8" (func $"foo:foo/bar-[stream-read-2]foo")) + (export "9" (func $"foo:foo/bar-[stream-write-2]foo")) + (export "10" (func $"foo:foo/bar-[future-read-0]foo")) + (export "11" (func $"foo:foo/bar-[future-write-0]foo")) + (export "12" (func $"foo:foo/bar-[future-read-1]foo")) + (export "13" (func $"foo:foo/bar-[future-write-1]foo")) + (export "14" (func $"[export]$root-[stream-read-2]foo")) + (export "15" (func $"[export]$root-[stream-write-2]foo")) + (export "16" (func $"[export]$root-[future-read-0]foo")) + (export "17" (func $"[export]$root-[future-write-0]foo")) + (export "18" (func $"[export]$root-[future-read-1]foo")) + (export "19" (func $"[export]$root-[future-write-1]foo")) + (export "20" (func $"[export]foo:foo/bar-[stream-read-2]foo")) + (export "21" (func $"[export]foo:foo/bar-[stream-write-2]foo")) + (export "22" (func $"[export]foo:foo/bar-[future-read-0]foo")) + (export "23" (func $"[export]foo:foo/bar-[future-write-0]foo")) + (export "24" (func $"[export]foo:foo/bar-[future-read-1]foo")) + (export "25" (func $"[export]foo:foo/bar-[future-write-1]foo")) (export "$imports" (table 0)) (func $"indirect-$root-[async]foo" (;0;) (type 0) (param i32 i32) (result i32) local.get 0 @@ -165,159 +165,159 @@ i32.const 0 call_indirect (type 0) ) - (func $"indirect-foo:foo/bar-[async]foo" (;1;) (type 0) (param i32 i32) (result i32) + (func $"$root-[stream-read-2]foo" (;1;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 + local.get 2 i32.const 1 - call_indirect (type 0) + call_indirect (type 1) ) - (func $"[import-payload]$root-[stream-read-2]foo" (;2;) (type 1) (param i32 i32 i32) (result i32) + (func $"$root-[stream-write-2]foo" (;2;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 2 call_indirect (type 1) ) - (func $"[import-payload]$root-[stream-write-2]foo" (;3;) (type 1) (param i32 i32 i32) (result i32) + (func $"$root-[future-read-0]foo" (;3;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 - local.get 2 i32.const 3 - call_indirect (type 1) + call_indirect (type 2) ) - (func $"[import-payload]$root-[future-read-0]foo" (;4;) (type 2) (param i32 i32) (result i32) + (func $"$root-[future-write-0]foo" (;4;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 4 call_indirect (type 2) ) - (func $"[import-payload]$root-[future-write-0]foo" (;5;) (type 2) (param i32 i32) (result i32) + (func $"$root-[future-read-1]foo" (;5;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 5 call_indirect (type 2) ) - (func $"[import-payload]$root-[future-read-1]foo" (;6;) (type 2) (param i32 i32) (result i32) + (func $"$root-[future-write-1]foo" (;6;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 6 call_indirect (type 2) ) - (func $"[import-payload]$root-[future-write-1]foo" (;7;) (type 2) (param i32 i32) (result i32) + (func $"indirect-foo:foo/bar-[async]foo" (;7;) (type 0) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 7 - call_indirect (type 2) + call_indirect (type 0) ) - (func $"[import-payload]foo:foo/bar-[stream-read-2]foo" (;8;) (type 1) (param i32 i32 i32) (result i32) + (func $"foo:foo/bar-[stream-read-2]foo" (;8;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 8 call_indirect (type 1) ) - (func $"[import-payload]foo:foo/bar-[stream-write-2]foo" (;9;) (type 1) (param i32 i32 i32) (result i32) + (func $"foo:foo/bar-[stream-write-2]foo" (;9;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 9 call_indirect (type 1) ) - (func $"[import-payload]foo:foo/bar-[future-read-0]foo" (;10;) (type 2) (param i32 i32) (result i32) + (func $"foo:foo/bar-[future-read-0]foo" (;10;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 10 call_indirect (type 2) ) - (func $"[import-payload]foo:foo/bar-[future-write-0]foo" (;11;) (type 2) (param i32 i32) (result i32) + (func $"foo:foo/bar-[future-write-0]foo" (;11;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 11 call_indirect (type 2) ) - (func $"[import-payload]foo:foo/bar-[future-read-1]foo" (;12;) (type 2) (param i32 i32) (result i32) + (func $"foo:foo/bar-[future-read-1]foo" (;12;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 12 call_indirect (type 2) ) - (func $"[import-payload]foo:foo/bar-[future-write-1]foo" (;13;) (type 2) (param i32 i32) (result i32) + (func $"foo:foo/bar-[future-write-1]foo" (;13;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 13 call_indirect (type 2) ) - (func $"[export-payload]$root-[stream-read-2]foo" (;14;) (type 1) (param i32 i32 i32) (result i32) + (func $"[export]$root-[stream-read-2]foo" (;14;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 14 call_indirect (type 1) ) - (func $"[export-payload]$root-[stream-write-2]foo" (;15;) (type 1) (param i32 i32 i32) (result i32) + (func $"[export]$root-[stream-write-2]foo" (;15;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 15 call_indirect (type 1) ) - (func $"[export-payload]$root-[future-read-0]foo" (;16;) (type 2) (param i32 i32) (result i32) + (func $"[export]$root-[future-read-0]foo" (;16;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 16 call_indirect (type 2) ) - (func $"[export-payload]$root-[future-write-0]foo" (;17;) (type 2) (param i32 i32) (result i32) + (func $"[export]$root-[future-write-0]foo" (;17;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 17 call_indirect (type 2) ) - (func $"[export-payload]$root-[future-read-1]foo" (;18;) (type 2) (param i32 i32) (result i32) + (func $"[export]$root-[future-read-1]foo" (;18;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 18 call_indirect (type 2) ) - (func $"[export-payload]$root-[future-write-1]foo" (;19;) (type 2) (param i32 i32) (result i32) + (func $"[export]$root-[future-write-1]foo" (;19;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 19 call_indirect (type 2) ) - (func $"[export-payload]foo:foo/bar-[stream-read-2]foo" (;20;) (type 1) (param i32 i32 i32) (result i32) + (func $"[export]foo:foo/bar-[stream-read-2]foo" (;20;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 20 call_indirect (type 1) ) - (func $"[export-payload]foo:foo/bar-[stream-write-2]foo" (;21;) (type 1) (param i32 i32 i32) (result i32) + (func $"[export]foo:foo/bar-[stream-write-2]foo" (;21;) (type 1) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 i32.const 21 call_indirect (type 1) ) - (func $"[export-payload]foo:foo/bar-[future-read-0]foo" (;22;) (type 2) (param i32 i32) (result i32) + (func $"[export]foo:foo/bar-[future-read-0]foo" (;22;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 22 call_indirect (type 2) ) - (func $"[export-payload]foo:foo/bar-[future-write-0]foo" (;23;) (type 2) (param i32 i32) (result i32) + (func $"[export]foo:foo/bar-[future-write-0]foo" (;23;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 23 call_indirect (type 2) ) - (func $"[export-payload]foo:foo/bar-[future-read-1]foo" (;24;) (type 2) (param i32 i32) (result i32) + (func $"[export]foo:foo/bar-[future-read-1]foo" (;24;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 24 call_indirect (type 2) ) - (func $"[export-payload]foo:foo/bar-[future-write-1]foo" (;25;) (type 2) (param i32 i32) (result i32) + (func $"[export]foo:foo/bar-[future-write-1]foo" (;25;) (type 2) (param i32 i32) (result i32) local.get 0 local.get 1 i32.const 25 @@ -332,13 +332,13 @@ (type (;1;) (func (param i32 i32 i32) (result i32))) (type (;2;) (func (param i32 i32) (result i32))) (import "" "0" (func (;0;) (type 0))) - (import "" "1" (func (;1;) (type 0))) + (import "" "1" (func (;1;) (type 1))) (import "" "2" (func (;2;) (type 1))) - (import "" "3" (func (;3;) (type 1))) + (import "" "3" (func (;3;) (type 2))) (import "" "4" (func (;4;) (type 2))) (import "" "5" (func (;5;) (type 2))) (import "" "6" (func (;6;) (type 2))) - (import "" "7" (func (;7;) (type 2))) + (import "" "7" (func (;7;) (type 0))) (import "" "8" (func (;8;) (type 1))) (import "" "9" (func (;9;) (type 1))) (import "" "10" (func (;10;) (type 2))) @@ -365,57 +365,52 @@ ) (core instance (;0;) (instantiate 1)) (alias core export 0 "0" (core func (;0;))) - (core instance (;1;) - (export "[async]foo" (func 0)) - ) - (alias core export 0 "1" (core func (;1;))) - (core instance (;2;) - (export "[async]foo" (func 1)) - ) - (core func (;2;) (canon stream.new 3)) + (core func (;1;) (canon stream.new 3)) + (alias core export 0 "1" (core func (;2;))) (alias core export 0 "2" (core func (;3;))) - (alias core export 0 "3" (core func (;4;))) - (core func (;5;) (canon stream.cancel-read 3)) - (core func (;6;) (canon stream.cancel-write 3)) - (core func (;7;) (canon stream.close-readable 3)) - (core func (;8;) (canon stream.close-writable 3)) - (core func (;9;) (canon future.new 1)) + (core func (;4;) (canon stream.cancel-read 3)) + (core func (;5;) (canon stream.cancel-write 3)) + (core func (;6;) (canon stream.close-readable 3)) + (core func (;7;) (canon stream.close-writable 3)) + (core func (;8;) (canon future.new 1)) + (alias core export 0 "3" (core func (;9;))) (alias core export 0 "4" (core func (;10;))) - (alias core export 0 "5" (core func (;11;))) - (core func (;12;) (canon future.cancel-read 1)) - (core func (;13;) (canon future.cancel-write 1)) - (core func (;14;) (canon future.close-readable 1)) - (core func (;15;) (canon future.close-writable 1)) - (core func (;16;) (canon future.new 2)) + (core func (;11;) (canon future.cancel-read 1)) + (core func (;12;) (canon future.cancel-write 1)) + (core func (;13;) (canon future.close-readable 1)) + (core func (;14;) (canon future.close-writable 1)) + (core func (;15;) (canon future.new 2)) + (alias core export 0 "5" (core func (;16;))) (alias core export 0 "6" (core func (;17;))) - (alias core export 0 "7" (core func (;18;))) - (core func (;19;) (canon future.cancel-read 2)) - (core func (;20;) (canon future.cancel-write 2)) - (core func (;21;) (canon future.close-readable 2)) - (core func (;22;) (canon future.close-writable 2)) - (core instance (;3;) - (export "[stream-new-2]foo" (func 2)) - (export "[stream-read-2]foo" (func 3)) - (export "[stream-write-2]foo" (func 4)) - (export "[stream-cancel-read-2]foo" (func 5)) - (export "[stream-cancel-write-2]foo" (func 6)) - (export "[stream-close-readable-2]foo" (func 7)) - (export "[stream-close-writable-2]foo" (func 8)) - (export "[future-new-0]foo" (func 9)) - (export "[future-read-0]foo" (func 10)) - (export "[future-write-0]foo" (func 11)) - (export "[future-cancel-read-0]foo" (func 12)) - (export "[future-cancel-write-0]foo" (func 13)) - (export "[future-close-readable-0]foo" (func 14)) - (export "[future-close-writable-0]foo" (func 15)) - (export "[future-new-1]foo" (func 16)) - (export "[future-read-1]foo" (func 17)) - (export "[future-write-1]foo" (func 18)) - (export "[future-cancel-read-1]foo" (func 19)) - (export "[future-cancel-write-1]foo" (func 20)) - (export "[future-close-readable-1]foo" (func 21)) - (export "[future-close-writable-1]foo" (func 22)) + (core func (;18;) (canon future.cancel-read 2)) + (core func (;19;) (canon future.cancel-write 2)) + (core func (;20;) (canon future.close-readable 2)) + (core func (;21;) (canon future.close-writable 2)) + (core instance (;1;) + (export "[async]foo" (func 0)) + (export "[stream-new-2]foo" (func 1)) + (export "[stream-read-2]foo" (func 2)) + (export "[stream-write-2]foo" (func 3)) + (export "[stream-cancel-read-2]foo" (func 4)) + (export "[stream-cancel-write-2]foo" (func 5)) + (export "[stream-close-readable-2]foo" (func 6)) + (export "[stream-close-writable-2]foo" (func 7)) + (export "[future-new-0]foo" (func 8)) + (export "[future-read-0]foo" (func 9)) + (export "[future-write-0]foo" (func 10)) + (export "[future-cancel-read-0]foo" (func 11)) + (export "[future-cancel-write-0]foo" (func 12)) + (export "[future-close-readable-0]foo" (func 13)) + (export "[future-close-writable-0]foo" (func 14)) + (export "[future-new-1]foo" (func 15)) + (export "[future-read-1]foo" (func 16)) + (export "[future-write-1]foo" (func 17)) + (export "[future-cancel-read-1]foo" (func 18)) + (export "[future-cancel-write-1]foo" (func 19)) + (export "[future-close-readable-1]foo" (func 20)) + (export "[future-close-writable-1]foo" (func 21)) ) + (alias core export 0 "7" (core func (;22;))) (type (;5;) (stream string)) (core func (;23;) (canon stream.new 5)) (alias core export 0 "8" (core func (;24;))) @@ -440,7 +435,8 @@ (core func (;41;) (canon future.cancel-write 7)) (core func (;42;) (canon future.close-readable 7)) (core func (;43;) (canon future.close-writable 7)) - (core instance (;4;) + (core instance (;2;) + (export "[async]foo" (func 22)) (export "[stream-new-2]foo" (func 23)) (export "[stream-read-2]foo" (func 24)) (export "[stream-write-2]foo" (func 25)) @@ -487,7 +483,7 @@ (core func (;62;) (canon future.cancel-write 10)) (core func (;63;) (canon future.close-readable 10)) (core func (;64;) (canon future.close-writable 10)) - (core instance (;5;) + (core instance (;3;) (export "[stream-new-2]foo" (func 44)) (export "[stream-read-2]foo" (func 45)) (export "[stream-write-2]foo" (func 46)) @@ -534,7 +530,7 @@ (core func (;83;) (canon future.cancel-write 13)) (core func (;84;) (canon future.close-readable 13)) (core func (;85;) (canon future.close-writable 13)) - (core instance (;6;) + (core instance (;4;) (export "[stream-new-2]foo" (func 65)) (export "[stream-read-2]foo" (func 66)) (export "[stream-write-2]foo" (func 67)) @@ -557,27 +553,25 @@ (export "[future-close-readable-1]foo" (func 84)) (export "[future-close-writable-1]foo" (func 85)) ) - (core instance (;7;) (instantiate 0 + (core instance (;5;) (instantiate 0 (with "$root" (instance 1)) (with "foo:foo/bar" (instance 2)) - (with "[import-payload]$root" (instance 3)) - (with "[import-payload]foo:foo/bar" (instance 4)) - (with "[export-payload]$root" (instance 5)) - (with "[export-payload]foo:foo/bar" (instance 6)) + (with "[export]$root" (instance 3)) + (with "[export]foo:foo/bar" (instance 4)) ) ) - (alias core export 7 "memory" (core memory (;0;))) + (alias core export 5 "memory" (core memory (;0;))) (alias core export 0 "$imports" (core table (;0;))) - (alias core export 7 "cabi_realloc" (core func (;86;))) + (alias core export 5 "cabi_realloc" (core func (;86;))) (core func (;87;) (canon lower (func 0) (memory 0) async)) + (core func (;88;) (canon stream.read 3 (memory 0) (realloc 86) string-encoding=utf8)) + (core func (;89;) (canon stream.write 3 (memory 0) string-encoding=utf8)) + (core func (;90;) (canon future.read 1 (memory 0))) + (core func (;91;) (canon future.write 1 (memory 0))) + (core func (;92;) (canon future.read 2 (memory 0))) + (core func (;93;) (canon future.write 2 (memory 0))) (alias export 0 "foo" (func (;1;))) - (core func (;88;) (canon lower (func 1) (memory 0) async)) - (core func (;89;) (canon stream.read 3 (memory 0) (realloc 86) string-encoding=utf8)) - (core func (;90;) (canon stream.write 3 (memory 0) string-encoding=utf8)) - (core func (;91;) (canon future.read 1 (memory 0))) - (core func (;92;) (canon future.write 1 (memory 0))) - (core func (;93;) (canon future.read 2 (memory 0))) - (core func (;94;) (canon future.write 2 (memory 0))) + (core func (;94;) (canon lower (func 1) (memory 0) async)) (core func (;95;) (canon stream.read 5 (memory 0) (realloc 86) string-encoding=utf8)) (core func (;96;) (canon stream.write 5 (memory 0) string-encoding=utf8)) (core func (;97;) (canon future.read 6 (memory 0))) @@ -596,7 +590,7 @@ (core func (;110;) (canon future.write 12 (memory 0))) (core func (;111;) (canon future.read 13 (memory 0))) (core func (;112;) (canon future.write 13 (memory 0))) - (core instance (;8;) + (core instance (;6;) (export "$imports" (table 0)) (export "0" (func 87)) (export "1" (func 88)) @@ -625,15 +619,15 @@ (export "24" (func 111)) (export "25" (func 112)) ) - (core instance (;9;) (instantiate 2 - (with "" (instance 8)) + (core instance (;7;) (instantiate 2 + (with "" (instance 6)) ) ) - (alias core export 7 "[async-stackful]foo" (core func (;113;))) + (alias core export 5 "[async-stackful]foo" (core func (;113;))) (func (;2;) (type 4) (canon lift (core func 113) async)) (export (;3;) "foo" (func 2)) (type (;14;) (func (param "x" 13) (param "y" u32) (result 11))) - (alias core export 7 "[async-stackful]foo:foo/bar#foo" (core func (;114;))) + (alias core export 5 "[async-stackful]foo:foo/bar#foo" (core func (;114;))) (func (;4;) (type 14) (canon lift (core func 114) async)) (component (;0;) (type (;0;) (future u32)) diff --git a/crates/wit-component/tests/components/async-streams-and-futures/module.wat b/crates/wit-component/tests/components/async-streams-and-futures/module.wat index a62c67a051..934fa4bb48 100644 --- a/crates/wit-component/tests/components/async-streams-and-futures/module.wat +++ b/crates/wit-component/tests/components/async-streams-and-futures/module.wat @@ -1,90 +1,90 @@ (module (func (import "$root" "[async]foo") (param i32 i32) (result i32)) (func (import "foo:foo/bar" "[async]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]$root" "[stream-new-2]foo") (result i32)) - (func (import "[import-payload]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[import-payload]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[import-payload]$root" "[stream-cancel-read-2]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[stream-cancel-write-2]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[stream-close-readable-2]foo") (param i32)) - (func (import "[import-payload]$root" "[stream-close-writable-2]foo") (param i32 i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-new-2]foo") (result i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-close-readable-2]foo") (param i32)) - (func (import "[import-payload]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32)) - (func (import "[import-payload]$root" "[future-new-0]foo") (result i32)) - (func (import "[import-payload]$root" "[future-read-0]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]$root" "[future-write-0]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]$root" "[future-cancel-read-0]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[future-cancel-write-0]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[future-close-readable-0]foo") (param i32)) - (func (import "[import-payload]$root" "[future-close-writable-0]foo") (param i32 i32)) - (func (import "[import-payload]foo:foo/bar" "[future-new-0]foo") (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-close-readable-0]foo") (param i32)) - (func (import "[import-payload]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32)) - (func (import "[import-payload]$root" "[future-new-1]foo") (result i32)) - (func (import "[import-payload]$root" "[future-read-1]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]$root" "[future-write-1]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]$root" "[future-cancel-read-1]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[future-cancel-write-1]foo") (param i32) (result i32)) - (func (import "[import-payload]$root" "[future-close-readable-1]foo") (param i32)) - (func (import "[import-payload]$root" "[future-close-writable-1]foo") (param i32 i32)) - (func (import "[import-payload]foo:foo/bar" "[future-new-1]foo") (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32)) - (func (import "[import-payload]foo:foo/bar" "[future-close-readable-1]foo") (param i32)) - (func (import "[import-payload]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32)) - (func (import "[export-payload]$root" "[stream-new-2]foo") (result i32)) - (func (import "[export-payload]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[export-payload]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[export-payload]$root" "[stream-cancel-read-2]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[stream-cancel-write-2]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[stream-close-readable-2]foo") (param i32)) - (func (import "[export-payload]$root" "[stream-close-writable-2]foo") (param i32 i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-new-2]foo") (result i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-close-readable-2]foo") (param i32)) - (func (import "[export-payload]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32)) - (func (import "[export-payload]$root" "[future-new-0]foo") (result i32)) - (func (import "[export-payload]$root" "[future-read-0]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]$root" "[future-write-0]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]$root" "[future-cancel-read-0]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[future-cancel-write-0]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[future-close-readable-0]foo") (param i32)) - (func (import "[export-payload]$root" "[future-close-writable-0]foo") (param i32 i32)) - (func (import "[export-payload]foo:foo/bar" "[future-new-0]foo") (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-close-readable-0]foo") (param i32)) - (func (import "[export-payload]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32)) - (func (import "[export-payload]$root" "[future-new-1]foo") (result i32)) - (func (import "[export-payload]$root" "[future-read-1]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]$root" "[future-write-1]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]$root" "[future-cancel-read-1]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[future-cancel-write-1]foo") (param i32) (result i32)) - (func (import "[export-payload]$root" "[future-close-readable-1]foo") (param i32)) - (func (import "[export-payload]$root" "[future-close-writable-1]foo") (param i32 i32)) - (func (import "[export-payload]foo:foo/bar" "[future-new-1]foo") (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32)) - (func (import "[export-payload]foo:foo/bar" "[future-close-readable-1]foo") (param i32)) - (func (import "[export-payload]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32)) + (func (import "$root" "[stream-new-2]foo") (result i32)) + (func (import "$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) + (func (import "$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) + (func (import "$root" "[stream-cancel-read-2]foo") (param i32) (result i32)) + (func (import "$root" "[stream-cancel-write-2]foo") (param i32) (result i32)) + (func (import "$root" "[stream-close-readable-2]foo") (param i32)) + (func (import "$root" "[stream-close-writable-2]foo") (param i32 i32)) + (func (import "foo:foo/bar" "[stream-new-2]foo") (result i32)) + (func (import "foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) + (func (import "foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) + (func (import "foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[stream-close-readable-2]foo") (param i32)) + (func (import "foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32)) + (func (import "$root" "[future-new-0]foo") (result i32)) + (func (import "$root" "[future-read-0]foo") (param i32 i32) (result i32)) + (func (import "$root" "[future-write-0]foo") (param i32 i32) (result i32)) + (func (import "$root" "[future-cancel-read-0]foo") (param i32) (result i32)) + (func (import "$root" "[future-cancel-write-0]foo") (param i32) (result i32)) + (func (import "$root" "[future-close-readable-0]foo") (param i32)) + (func (import "$root" "[future-close-writable-0]foo") (param i32 i32)) + (func (import "foo:foo/bar" "[future-new-0]foo") (result i32)) + (func (import "foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32)) + (func (import "foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32)) + (func (import "foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[future-close-readable-0]foo") (param i32)) + (func (import "foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32)) + (func (import "$root" "[future-new-1]foo") (result i32)) + (func (import "$root" "[future-read-1]foo") (param i32 i32) (result i32)) + (func (import "$root" "[future-write-1]foo") (param i32 i32) (result i32)) + (func (import "$root" "[future-cancel-read-1]foo") (param i32) (result i32)) + (func (import "$root" "[future-cancel-write-1]foo") (param i32) (result i32)) + (func (import "$root" "[future-close-readable-1]foo") (param i32)) + (func (import "$root" "[future-close-writable-1]foo") (param i32 i32)) + (func (import "foo:foo/bar" "[future-new-1]foo") (result i32)) + (func (import "foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32)) + (func (import "foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32)) + (func (import "foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32)) + (func (import "foo:foo/bar" "[future-close-readable-1]foo") (param i32)) + (func (import "foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32)) + (func (import "[export]$root" "[stream-new-2]foo") (result i32)) + (func (import "[export]$root" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) + (func (import "[export]$root" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) + (func (import "[export]$root" "[stream-cancel-read-2]foo") (param i32) (result i32)) + (func (import "[export]$root" "[stream-cancel-write-2]foo") (param i32) (result i32)) + (func (import "[export]$root" "[stream-close-readable-2]foo") (param i32)) + (func (import "[export]$root" "[stream-close-writable-2]foo") (param i32 i32)) + (func (import "[export]foo:foo/bar" "[stream-new-2]foo") (result i32)) + (func (import "[export]foo:foo/bar" "[stream-read-2]foo") (param i32 i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[stream-write-2]foo") (param i32 i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[stream-cancel-read-2]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[stream-cancel-write-2]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[stream-close-readable-2]foo") (param i32)) + (func (import "[export]foo:foo/bar" "[stream-close-writable-2]foo") (param i32 i32)) + (func (import "[export]$root" "[future-new-0]foo") (result i32)) + (func (import "[export]$root" "[future-read-0]foo") (param i32 i32) (result i32)) + (func (import "[export]$root" "[future-write-0]foo") (param i32 i32) (result i32)) + (func (import "[export]$root" "[future-cancel-read-0]foo") (param i32) (result i32)) + (func (import "[export]$root" "[future-cancel-write-0]foo") (param i32) (result i32)) + (func (import "[export]$root" "[future-close-readable-0]foo") (param i32)) + (func (import "[export]$root" "[future-close-writable-0]foo") (param i32 i32)) + (func (import "[export]foo:foo/bar" "[future-new-0]foo") (result i32)) + (func (import "[export]foo:foo/bar" "[future-read-0]foo") (param i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-write-0]foo") (param i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-cancel-read-0]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-cancel-write-0]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-close-readable-0]foo") (param i32)) + (func (import "[export]foo:foo/bar" "[future-close-writable-0]foo") (param i32 i32)) + (func (import "[export]$root" "[future-new-1]foo") (result i32)) + (func (import "[export]$root" "[future-read-1]foo") (param i32 i32) (result i32)) + (func (import "[export]$root" "[future-write-1]foo") (param i32 i32) (result i32)) + (func (import "[export]$root" "[future-cancel-read-1]foo") (param i32) (result i32)) + (func (import "[export]$root" "[future-cancel-write-1]foo") (param i32) (result i32)) + (func (import "[export]$root" "[future-close-readable-1]foo") (param i32)) + (func (import "[export]$root" "[future-close-writable-1]foo") (param i32 i32)) + (func (import "[export]foo:foo/bar" "[future-new-1]foo") (result i32)) + (func (import "[export]foo:foo/bar" "[future-read-1]foo") (param i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-write-1]foo") (param i32 i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-cancel-read-1]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-cancel-write-1]foo") (param i32) (result i32)) + (func (import "[export]foo:foo/bar" "[future-close-readable-1]foo") (param i32)) + (func (import "[export]foo:foo/bar" "[future-close-writable-1]foo") (param i32 i32)) (func (export "[async-stackful]foo") (param i32 i32) unreachable) (func (export "[async-stackful]foo:foo/bar#foo") (param i32 i32) unreachable) (memory (export "memory") 1) From 9c9a0573326249f19e2c9dd3a45442b9c62a7b85 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Feb 2025 12:19:55 -0600 Subject: [PATCH 5/5] Update crates/wit-component/src/validation.rs Co-authored-by: Joel Dice --- crates/wit-component/src/validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index bf3f6dfd8f..9dbf5aa5e7 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -707,7 +707,7 @@ impl ImportMap { /// that such prefix is not present in `name`. /// * `import` - whether or not this core wasm import is operating on a WIT /// level import or export. An example of this being an export is when a - /// core module imports a destructor for an exported resourceV + /// core module imports a destructor for an exported resource. /// * `names` - the name mangling scheme that's configured to be used. fn maybe_classify_wit_intrinsic( &self,