diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index ae5bf04699..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,21 +1279,21 @@ 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), ) }; 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 +1359,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!() }; @@ -1609,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, }; @@ -1639,96 +1620,76 @@ 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)) } - 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, )), - 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)) } - 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, )), - 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)) } @@ -1783,7 +1744,6 @@ impl<'a> EncodingState<'a> { &mut self, shims: &Shims<'_>, for_module: CustomModule<'_>, - async_: bool, info: &PayloadInfo, kind: PayloadFuncKind, ) -> (ExportKind, u32) { @@ -1791,7 +1751,6 @@ impl<'a> EncodingState<'a> { shims, &ShimKind::PayloadFunc { for_module, - async_, info, kind, }, @@ -2033,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 @@ -2387,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 88a4e8eeb9..9dbf5aa5e7 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. /// @@ -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. /// @@ -548,29 +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)) - } 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() { @@ -637,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) { @@ -652,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); } } @@ -667,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 \ @@ -724,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 resource. + /// * `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<'_>, @@ -1043,7 +1207,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. @@ -1211,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, @@ -1318,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, @@ -1526,215 +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> { - 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) - } 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, - 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_, - ty: info.ty, - imported: info.imported, - } - } 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_, - ty: info.ty, - imported: info.imported, - } - } 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 { - ty: info.ty, - imported: info.imported, - } - } 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 { - ty: info.ty, - imported: info.imported, - } - } 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_, - ty: info.ty, - imported: info.imported, - } - } 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_, - ty: info.ty, - imported: info.imported, - } - } 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 { - ty: info.ty, - imported: info.imported, - } - } 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 { - ty: info.ty, - imported: info.imported, - } - } else { - bail!("unrecognized payload import: {name}"); - }, - ) - } else { - None - }, - ) - } fn module_to_interface( &self, module: &str, @@ -2020,55 +1956,22 @@ 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( - resolve: &Resolve, - world: &World, - (name, index): &(String, usize), - interface: Option, - imported: bool, -) -> Result<(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"); 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)