From 5870f0d4b45e4a246394840f18df9f4e31a24f92 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Sep 2024 13:10:51 -0700 Subject: [PATCH 1/3] Overhaul and refactor some internals of `wit-component` This commit is a lead-up to the changes proposed in #1774. The `wit-component` crate is quite old and has gone through many iterations of the component model and it's very much showing its age in a few places. Namely the correlation between component model names and core wasm names is open-coded in many places throughout validation and encoding of a component. This makes the changes in #1774 where the names may be different (e.g. core wasm 0.2.0 might import component 0.2.1). Making this change was inevitably going to require quite a lot of refactoring of `wit-component`, so that's what this commit does. It's a pretty large rewrite of the internals of validation of a core wasm module and adapter prior to creating a component. The metadata produced by this pass is now represented in a completely different format. The metadata is extensively used throughout the encoding process so encoding has been heavily refactored as well. The overall idea is that the previous "grab bag" of various items here and there produced from validation are now all unified into a single `ImportMap` and `ExportMap` for a module. These maps track all the various kinds of imports and exports and how they map back to core wasm names. Notably this means that the logic to correlate core wasm names with component model names is now happening in just one location (in theory) as opposed to implicitly all throughout encoding. I've additionally taken this opportunity to subjectively simplify much of the encoding process around managing instantiations of core wasm modules and adapters. One of the main changes in this commit is that it does away with code structure such as "do the thing for WIT" then "do the thing for resources" then "do the thing for other resources" and finally "do the thing for adapters". This was difficult to understand every time I came back to it and I can't imagine was easy for anyone else to understand either. All imports are now handled in a single location and it's intended to be much better separated who's responsible for what. For example the code satisfying an import is decoupled from what the import is going to be named and how it's provided to the main core wasm module. Overall the intention is that this does not either enhance the functionality of wit-component nor regress it. Lots of tests have changed but I've tried to verify it's just things moving around as opposed to anything that has a different semantic meaning. A future PR for #1774 will enhance the logic of connecting core wasm imports to WIT imports but that's deferred for a future PR. --- crates/wasm-encoder/src/component/builder.rs | 14 - crates/wasm-encoder/src/core/exports.rs | 2 +- crates/wit-component/src/encoding.rs | 1012 ++++++------ crates/wit-component/src/encoding/world.rs | 149 +- crates/wit-component/src/validation.rs | 1449 +++++++++-------- .../adapt-export-reallocs/component.wat | 26 +- .../component.wat | 13 +- .../component.wat | 18 +- .../component.wat | 45 +- .../component.wat | 43 +- .../component.wat | 43 +- .../component.wat | 43 +- .../adapt-inject-stack/component.wat | 26 +- .../adapt-list-return/component.wat | 30 +- .../adapt-memory-simple/component.wat | 16 +- .../adapt-stub-wasip2/component.wat | 5 +- .../tests/components/bare-funcs/component.wat | 2 +- .../ensure-default-type-exports/component.wat | 6 +- .../error.txt | 2 +- .../error-empty-module-import/error.txt | 2 +- .../error-export-sig-mismatch/error.txt | 2 +- .../error-import-resource-rep/error.txt | 2 +- .../error.txt | 2 +- .../error-import-sig-mismatch/error.txt | 2 +- .../error-invalid-module-import/error.txt | 2 +- .../error-missing-default-export/error.txt | 2 +- .../components/error-missing-export/error.txt | 2 +- .../error-missing-import-func/error.txt | 2 +- .../components/error-missing-import/error.txt | 2 +- .../components/export-resource/component.wat | 12 +- .../tests/components/exports/component.wat | 10 +- .../import-and-export-resource/component.wat | 14 +- .../components/import-conflict/component.wat | 2 +- .../components/import-export/component.wat | 2 +- .../component.wat | 76 +- .../component.wat | 14 +- .../import-resource-simple/component.wat | 12 +- .../tests/components/imports/component.wat | 2 +- .../components/lift-options/component.wat | 18 +- .../components/link-bare-funcs/component.wat | 24 +- .../components/lower-options/component.wat | 2 +- .../components/post-return/component.wat | 6 +- .../tests/components/simple/component.wat | 8 +- .../worlds-with-type-renamings/component.wat | 6 +- 44 files changed, 1615 insertions(+), 1557 deletions(-) diff --git a/crates/wasm-encoder/src/component/builder.rs b/crates/wasm-encoder/src/component/builder.rs index af4526a3b4..d587ae99f5 100644 --- a/crates/wasm-encoder/src/component/builder.rs +++ b/crates/wasm-encoder/src/component/builder.rs @@ -206,20 +206,6 @@ impl ComponentBuilder { }) } - /// Creates an alias to a previous core instance's exported item. - /// - /// The `instance` provided is the instance to access and the `name` is the - /// item to access. - /// - /// Returns the index of the new item defined. - pub fn alias_core_export(&mut self, instance: u32, name: &str, kind: ExportKind) -> u32 { - self.alias(Alias::CoreInstanceExport { - instance, - kind, - name, - }) - } - fn inc_kind(&mut self, kind: ComponentExportKind) -> u32 { match kind { ComponentExportKind::Func => inc(&mut self.funcs), diff --git a/crates/wasm-encoder/src/core/exports.rs b/crates/wasm-encoder/src/core/exports.rs index 36c7896362..7d78220e28 100644 --- a/crates/wasm-encoder/src/core/exports.rs +++ b/crates/wasm-encoder/src/core/exports.rs @@ -4,7 +4,7 @@ use super::{ use crate::{encode_section, Encode, Section, SectionId}; /// Represents the kind of an export from a WebAssembly module. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[repr(u8)] pub enum ExportKind { /// The export is a function. diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index d609390a7c..26871bb97c 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -71,12 +71,8 @@ //! otherwise there's no way to run a `wasi_snapshot_preview1` module within the //! component model. -use crate::encoding::world::WorldAdapter; use crate::metadata::{self, Bindgen, ModuleMetadata}; -use crate::validation::{ - ResourceInfo, ValidatedModule, BARE_FUNC_MODULE_NAME, MAIN_MODULE_IMPORT_NAME, - POST_RETURN_PREFIX, -}; +use crate::validation::{Export, ExportMap, Import, ImportInstance, ImportMap, RESOURCE_DROP}; use crate::StringEncoding; use anyhow::{anyhow, bail, Context, Result}; use indexmap::{IndexMap, IndexSet}; @@ -338,10 +334,6 @@ pub struct EncodingState<'a> { /// /// If `None`, then the memory has not yet been aliased. memory_index: Option, - /// The index in the core function index space for the realloc function. - /// - /// If `None`, then the realloc function has not yet been aliased. - realloc_index: Option, /// The index of the shim instance used for lowering imports into the core instance. /// /// If `None`, then the shim instance how not yet been encoded. @@ -356,11 +348,6 @@ pub struct EncodingState<'a> { adapter_modules: IndexMap<&'a str, u32>, /// A map of adapter module instances and the index of their instance. adapter_instances: IndexMap<&'a str, u32>, - /// A map of the index of the aliased realloc function for each adapter - /// module. Note that adapters have two realloc functions, one for imports - /// and one for exports. - adapter_import_reallocs: IndexMap<&'a str, Option>, - adapter_export_reallocs: IndexMap<&'a str, Option>, /// Imported instances and what index they were imported as. imported_instances: IndexMap, @@ -376,6 +363,13 @@ pub struct EncodingState<'a> { export_type_map: HashMap, export_func_type_map: HashMap, u32>, + /// Cache of items that have been aliased from core instances. + /// + /// This is a helper to reduce the number of aliases created by ensuring + /// that repeated requests for the same item return the same index of an + /// original `core alias` item. + aliased_core_items: HashMap<(u32, String), u32>, + /// Metadata about the world inferred from the input to `ComponentEncoder`. info: &'a ComponentWorld<'a>, } @@ -549,59 +543,18 @@ impl<'a> EncodingState<'a> { } fn encode_core_instantiation(&mut self) -> Result<()> { - let info = &self.info.info; - // Encode a shim instantiation if needed let shims = self.encode_shim_instantiation()?; - // For each instance import into the main module create a - // pseudo-core-wasm-module via a bag-of-exports. - let mut args = Vec::new(); - for core_wasm_name in info.required_imports.keys() { - let index = self.import_instance_to_lowered_core_instance( - CustomModule::Main, - core_wasm_name, - &shims, - info.metadata, - ); - args.push((*core_wasm_name, ModuleArg::Instance(index))); - } - - // For each adapter module instance imported into the core wasm module - // the appropriate shim is packaged up into a bag-of-exports instance. - // Note that adapter modules currently don't deal with - // indirect-vs-direct lowerings, everything is indirect. - for (adapter, funcs) in info.adapters_required.iter() { - let shim_instance = self - .shim_instance_index - .expect("shim should be instantiated"); - let mut exports = Vec::new(); - - for (func, _ty) in funcs { - let index = self.component.core_alias_export( - shim_instance, - &shims.shim_names[&ShimKind::Adapter { adapter, func }], - ExportKind::Func, - ); - exports.push((*func, ExportKind::Func, index)); - } + // Next declare all exported resource types. This populates + // `export_type_map` and will additionally be used for imports to + // modules instantiated below. + self.declare_exported_resources(&shims); - let index = self.component.core_instantiate_exports(exports); - args.push((*adapter, ModuleArg::Instance(index))); - } - - self.add_resource_funcs( - CustomModule::Main, - &info.required_resource_funcs, - &shims, - &mut args, - ); - - // Instantiate the main module now that all of its arguments have been - // prepared. With this we now have the main linear memory for - // liftings/lowerings later on as well as the adapter modules, if any, - // instantiated after the core wasm module. - self.instantiate_core_module(args, info); + // Next instantiate the main module. This provides the linear memory to + // use for all future adapters and enables creating indirect lowerings + // at the end. + self.instantiate_main_module(&shims)?; // Separate the adapters according which should be instantiated before // and after indirect lowerings are encoded. @@ -619,16 +572,16 @@ impl<'a> EncodingState<'a> { ) }); - for (name, adapter) in before { - self.instantiate_adapter_module(&shims, name, adapter); + for (name, _adapter) in before { + self.instantiate_adapter_module(&shims, name)?; } // With all the relevant core wasm instances in play now the original shim // module, if present, can be filled in with lowerings/adapters/etc. self.encode_indirect_lowerings(&shims)?; - for (name, adapter) in after { - self.instantiate_adapter_module(&shims, name, adapter); + for (name, _adapter) in after { + self.instantiate_adapter_module(&shims, name)?; } self.encode_initialize_with_start()?; @@ -636,86 +589,6 @@ impl<'a> EncodingState<'a> { Ok(()) } - /// Lowers a named imported interface a core wasm instances suitable to - /// provide as an instantiation argument to another core wasm module. - /// - /// * `for_module` the module that this instance is being created for, or - /// otherwise which `realloc` option is used for the lowerings. - /// * `name` - the name of the imported interface that's being lowered. - /// * `imports` - the list of all imports known for this encoding. - /// * `shims` - the indirect/adapter shims created prior, if any. - fn import_instance_to_lowered_core_instance( - &mut self, - for_module: CustomModule<'_>, - core_wasm_name: &str, - shims: &Shims<'_>, - metadata: &ModuleMetadata, - ) -> u32 { - let interface = if core_wasm_name == BARE_FUNC_MODULE_NAME { - None - } else { - Some(core_wasm_name.to_string()) - }; - let import = &self.info.import_map[&interface]; - let required_imports = match for_module { - CustomModule::Main => &self.info.info.required_imports[core_wasm_name], - CustomModule::Adapter(name) => { - &self.info.adapters[name].info.required_imports[core_wasm_name] - } - }; - let mut exports = Vec::with_capacity(import.lowerings.len()); - - for (index, (name, lowering)) in import.lowerings.iter().enumerate() { - if !required_imports.funcs.contains(name.as_str()) { - continue; - } - let index = match lowering { - // All direct lowerings can be `canon lower`'d here immediately - // and passed as arguments. - Lowering::Direct => { - let func_index = match &import.interface { - Some(interface) => { - let instance_index = self.imported_instances[interface]; - self.component.alias_export( - instance_index, - name, - ComponentExportKind::Func, - ) - } - None => self.imported_funcs[name], - }; - self.component.lower_func(func_index, []) - } - - // Add an entry for all indirect lowerings which come as an - // export of the shim module. - Lowering::Indirect { .. } => { - let encoding = - metadata.import_encodings[&(core_wasm_name.to_string(), name.clone())]; - self.component.core_alias_export( - self.shim_instance_index - .expect("shim should be instantiated"), - &shims.shim_names[&ShimKind::IndirectLowering { - interface: interface.clone(), - index, - realloc: for_module, - encoding, - }], - ExportKind::Func, - ) - } - - Lowering::ResourceDrop(id) => { - let resource_idx = self.lookup_resource_index(*id); - self.component.resource_drop(resource_idx) - } - }; - exports.push((name.as_str(), ExportKind::Func, index)); - } - - self.component.core_instantiate_exports(exports) - } - fn lookup_resource_index(&mut self, id: TypeId) -> u32 { let resolve = &self.info.encoder.metadata.resolve; let ty = &resolve.types[id]; @@ -749,7 +622,7 @@ impl<'a> EncodingState<'a> { .root_import_type_encoder(None) .encode_func_type(resolve, func)?; let core_name = func.core_export_name(None); - let idx = self.encode_lift(module, &core_name, func, ty)?; + let idx = self.encode_lift(module, &core_name, None, func, ty)?; self.component .export(&export_string, ComponentExportKind::Func, idx, None); } @@ -783,7 +656,9 @@ impl<'a> EncodingState<'a> { for (_, func) in &resolve.interfaces[export].functions { let core_name = func.core_export_name(Some(export_name)); let ty = root.encode_func_type(resolve, func)?; - let func_index = root.state.encode_lift(module, &core_name, func, ty)?; + let func_index = root + .state + .encode_lift(module, &core_name, Some(export), func, ty)?; imports.push(( import_func_name(func), ComponentExportKind::Func, @@ -1076,45 +951,28 @@ impl<'a> EncodingState<'a> { &mut self, module: CustomModule<'_>, core_name: &str, + interface: Option, func: &Function, ty: u32, ) -> Result { let resolve = &self.info.encoder.metadata.resolve; - let metadata = match module { - CustomModule::Main => &self.info.encoder.metadata.metadata, - CustomModule::Adapter(name) => &self.info.encoder.adapters[name].metadata, - }; - let post_returns = match module { - CustomModule::Main => &self.info.info.post_returns, - CustomModule::Adapter(name) => &self.info.adapters[name].info.post_returns, - }; - let instance_index = match module { - CustomModule::Main => self.instance_index.expect("instantiated by now"), - CustomModule::Adapter(name) => self.adapter_instances[name], - }; - let core_func_index = - self.component - .core_alias_export(instance_index, core_name, ExportKind::Func); + let metadata = self.info.module_metadata_for(module); + let instance_index = self.instance_for(module); + let core_func_index = self.core_alias_export(instance_index, core_name, ExportKind::Func); let options = RequiredOptions::for_export(resolve, func); let encoding = metadata.export_encodings[core_name]; - // 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. - let realloc_index = match module { - CustomModule::Main => self.realloc_index, - CustomModule::Adapter(name) => self.adapter_export_reallocs[name], - }; + let exports = self.info.exports_for(module); + let realloc_index = exports + .export_realloc_for(interface, func) + .map(|name| self.core_alias_export(instance_index, name, ExportKind::Func)); let mut options = options .into_iter(encoding, self.memory_index, realloc_index)? .collect::>(); - let post_return = format!("{POST_RETURN_PREFIX}{core_name}"); - if post_returns.contains(&post_return[..]) { - let post_return = - self.component - .core_alias_export(instance_index, &post_return, ExportKind::Func); + if let Some(post_return) = exports.post_return(interface, func) { + let post_return = self.core_alias_export(instance_index, post_return, ExportKind::Func); options.push(CanonicalOption::PostReturn(post_return)); } let func_index = self.component.lift_func(core_func_index, ty, options); @@ -1124,94 +982,24 @@ impl<'a> EncodingState<'a> { fn encode_shim_instantiation(&mut self) -> Result> { let mut signatures = Vec::new(); let mut ret = Shims::default(); - let info = &self.info.info; - // For all interfaces imported into the main module record all of their - // indirect lowerings into `Shims`. - for (core_wasm_name, required) in info.required_imports.iter() { - let import_name = if *core_wasm_name == BARE_FUNC_MODULE_NAME { - None - } else { - Some(core_wasm_name.to_string()) - }; - let import = &self.info.import_map[&import_name]; - ret.append_indirect( - core_wasm_name, - CustomModule::Main, - import, - &required.funcs, - info.metadata, - &mut signatures, - ) + ret.append_indirect(self.info, CustomModule::Main, &mut signatures) .context("failed to register indirect shims for main module")?; - } // For all required adapter modules a shim is created for each required // function and additionally a set of shims are created for the // interface imported into the shim module itself. - for (adapter_name, adapter) in self.info.adapters.iter() { - for (name, required) in adapter.info.required_imports.iter() { - let import_name = if *name == BARE_FUNC_MODULE_NAME { - None - } else { - Some(name.to_string()) - }; - let import = &self.info.import_map[&import_name]; - ret.append_indirect( - name, - CustomModule::Adapter(adapter_name), - import, - &required.funcs, - adapter.info.metadata, - &mut signatures, - ) - .with_context(|| { - format!("failed to register indirect shims for adapter {adapter_name}") - })?; - } - - self.encode_resource_dtors( + for (adapter_name, _adapter) in self.info.adapters.iter() { + ret.append_indirect( + self.info, CustomModule::Adapter(adapter_name), - &adapter.info.required_resource_funcs, &mut signatures, - &mut ret, - ); - - let funcs = match self.info.info.adapters_required.get(adapter_name) { - Some(funcs) => funcs, - None => continue, - }; - for (func, ty) in funcs { - let name = ret.list.len().to_string(); - log::debug!("shim {name} is adapter `{adapter_name}::{func}`"); - signatures.push(WasmSignature { - params: ty.params().iter().map(to_wasm_type).collect(), - results: ty.results().iter().map(to_wasm_type).collect(), - indirect_params: false, - retptr: false, - }); - ret.list.push(Shim { - name, - debug_name: format!("adapt-{adapter_name}-{func}"), - // Pessimistically assume that all adapters require memory - // in one form or another. While this isn't technically true - // it's true enough for WASI. - options: RequiredOptions::MEMORY, - kind: ShimKind::Adapter { - adapter: adapter_name, - func, - }, - }); - } + ) + .with_context(|| { + format!("failed to register indirect shims for adapter {adapter_name}") + })?; } - self.encode_resource_dtors( - CustomModule::Main, - &self.info.info.required_resource_funcs, - &mut signatures, - &mut ret, - ); - if ret.list.is_empty() { return Ok(ret); } @@ -1313,16 +1101,6 @@ impl<'a> EncodingState<'a> { self.shim_instance_index = Some(self.component.core_instantiate(shim_module_index, [])); return Ok(ret); - - fn to_wasm_type(ty: &wasmparser::ValType) -> WasmType { - match ty { - wasmparser::ValType::I32 => WasmType::I32, - wasmparser::ValType::I64 => WasmType::I64, - wasmparser::ValType::F32 => WasmType::F32, - wasmparser::ValType::F64 => WasmType::F64, - _ => unreachable!(), - } - } } fn encode_shim_function( @@ -1353,11 +1131,8 @@ impl<'a> EncodingState<'a> { .shim_instance_index .expect("must have an instantiated shim"); - let table_index = self.component.core_alias_export( - shim_instance_index, - INDIRECT_TABLE_NAME, - ExportKind::Table, - ); + let table_index = + self.core_alias_export(shim_instance_index, INDIRECT_TABLE_NAME, ExportKind::Table); let mut exports = Vec::new(); exports.push((INDIRECT_TABLE_NAME, ExportKind::Table, table_index)); @@ -1390,10 +1165,14 @@ impl<'a> EncodingState<'a> { None => self.imported_funcs[name], }; - let realloc = match realloc { - CustomModule::Main => self.realloc_index, - CustomModule::Adapter(name) => self.adapter_import_reallocs[name], - }; + let realloc = self + .info + .exports_for(*realloc) + .import_realloc_for(interface.interface, name) + .map(|name| { + let instance = self.instance_for(*realloc); + self.core_alias_export(instance, name, ExportKind::Func) + }); self.component.lower_func( func_index, @@ -1406,33 +1185,16 @@ impl<'a> EncodingState<'a> { // instance, so use the specified name here and the previously // created instances to get the core item that represents the // shim. - ShimKind::Adapter { adapter, func } => self.component.core_alias_export( - self.adapter_instances[adapter], - func, - ExportKind::Func, - ), + ShimKind::Adapter { adapter, func } => { + self.core_alias_export(self.adapter_instances[adapter], func, ExportKind::Func) + } // Resources are required for a module to be instantiated // meaning that any destructor for the resource must be called // indirectly due to the otherwise circular dependency between // the module and the resource itself. - ShimKind::ResourceDtor { - module, - import, - resource, - } => { - let funcs = match module { - CustomModule::Main => &self.info.info.required_resource_funcs, - CustomModule::Adapter(name) => { - &self.info.adapters[name].info.required_resource_funcs - } - }; - - self.component.core_alias_export( - self.instance_index.unwrap(), - funcs[*import][*resource].dtor_export.as_deref().unwrap(), - ExportKind::Func, - ) + ShimKind::ResourceDtor { module, export } => { + self.core_alias_export(self.instance_for(*module), export, ExportKind::Func) } }; @@ -1447,249 +1209,272 @@ impl<'a> EncodingState<'a> { Ok(()) } - fn instantiate_core_module<'b, A>(&mut self, args: A, info: &ValidatedModule<'_>) - where - A: IntoIterator, - A::IntoIter: ExactSizeIterator, - { - assert!(self.instance_index.is_none()); + /// This is a helper function that will declare, in the component itself, + /// all exported resources. + /// + /// These resources later on get packaged up into instances and such. The + /// main thing that this handles is that it registers the right destructor + /// from `shims`, if needed, for each resource. + fn declare_exported_resources(&mut self, shims: &Shims<'_>) { + let resolve = &self.info.encoder.metadata.resolve; + let world = &resolve.worlds[self.info.encoder.metadata.world]; - let instance_index = self - .component - .core_instantiate(self.module_index.expect("core module encoded"), args); + // Iterate over the main module's exports and the exports of all + // adapters. Look for exported interfaces that themselves have + // resources. + let main_module_keys = self.info.encoder.main_module_exports.iter(); + let main_module_keys = main_module_keys.map(|key| (CustomModule::Main, key)); + let adapter_keys = self.info.encoder.adapters.iter().flat_map(|(name, info)| { + info.required_exports + .iter() + .map(move |key| (CustomModule::Adapter(name), key)) + }); + for (for_module, key) in main_module_keys.chain(adapter_keys) { + let id = match &world.exports[key] { + WorldItem::Interface { id, .. } => *id, + WorldItem::Type { .. } => unreachable!(), + WorldItem::Function(_) => continue, + }; - if info.has_memory { - self.memory_index = Some(self.component.core_alias_export( - instance_index, - "memory", - ExportKind::Memory, - )); + for ty in resolve.interfaces[id].types.values() { + match resolve.types[*ty].kind { + TypeDefKind::Resource => {} + _ => continue, + } + + // Load the destructor, previously detected in module + // validation, if one is present. + let exports = self.info.exports_for(for_module); + let dtor = exports.resource_dtor(*ty).map(|name| { + let name = &shims.shim_names[&ShimKind::ResourceDtor { + module: for_module, + export: name, + }]; + let shim = self.shim_instance_index.unwrap(); + self.core_alias_export(shim, name, ExportKind::Func) + }); + + // Declare the resource with this destructor and register it in + // our internal map. This should be the first and only time this + // type is inserted into this map. + let resource_idx = self.component.type_resource(ValType::I32, dtor); + let prev = self.export_type_map.insert(*ty, resource_idx); + assert!(prev.is_none()); + } } + } - if let Some(name) = &info.realloc { - self.realloc_index = Some(self.component.core_alias_export( - instance_index, - name, - ExportKind::Func, - )); + /// Helper to instantiate the main module and record various results of its + /// instantiation within `self`. + fn instantiate_main_module(&mut self, shims: &Shims<'_>) -> Result<()> { + assert!(self.instance_index.is_none()); + + let instance_index = self.instantiate_core_module(shims, CustomModule::Main)?; + + if let Some(memory) = self.info.info.exports.memory() { + self.memory_index = + Some(self.core_alias_export(instance_index, memory, ExportKind::Memory)); } self.instance_index = Some(instance_index); + Ok(()) } - fn encode_resource_dtors<'b>( - &mut self, - module: CustomModule<'b>, - funcs: &'b IndexMap>, - signatures: &mut Vec, - shims: &mut Shims<'b>, - ) { - // Any resource destructors are encoded through the shim module. The - // core wasm probably imports resource intrinsics which requires the - // resource definition, but the resource definition requires - // the destructor to be available. The shim module breaks this - // circular dependency. - for (import, info) in funcs.iter() { - for (resource, info) in info { - if info.dtor_export.is_none() { - continue; - } - signatures.push(WasmSignature { - params: vec![WasmType::I32], - results: Vec::new(), - indirect_params: false, - retptr: false, - }); - let name = shims.list.len().to_string(); - shims.list.push(Shim { - name, - debug_name: format!("dtor-{import}-{resource}"), - options: RequiredOptions::empty(), - kind: ShimKind::ResourceDtor { - module, - import, - resource, - }, - }); - } - } + /// This function will instantiate the specified adapter module, which may + /// depend on previously-instantiated modules. + fn instantiate_adapter_module(&mut self, shims: &Shims<'_>, name: &'a str) -> Result<()> { + let instance = self.instantiate_core_module(shims, CustomModule::Adapter(name))?; + self.adapter_instances.insert(name, instance); + Ok(()) } - fn add_resource_funcs<'b>( + /// Generic helper to instantiate a module. + /// + /// The `for_module` provided will have all of its imports satisfied from + /// either previous instantiations or the `shims` module present. This + /// iterates over the metadata produced during validation to determine what + /// hooks up to what import. + fn instantiate_core_module( &mut self, - module: CustomModule<'b>, - funcs: &'b IndexMap>, shims: &Shims, - args: &mut Vec<(&'b str, ModuleArg)>, - ) { - for (import, info) in funcs { - let mut exports = Vec::new(); - for (resource, info) in info { - // Destructors for resources live on the shim module previously - // created, so if one is specified create the resource with - // the shim module that currently exists. The shim will get - // filled in later with the actual destructor after the main - // module is instantiated. - let dtor = info.dtor_export.as_deref().map(|_| { - self.component.core_alias_export( - self.shim_instance_index.unwrap(), - &shims.shim_names[&ShimKind::ResourceDtor { - module, - import, - resource, - }], - ExportKind::Func, - ) - }); - let resource_idx = self.component.type_resource(ValType::I32, dtor); - let prev = self.export_type_map.insert(info.id, resource_idx); - assert!(prev.is_none()); + for_module: CustomModule<'_>, + ) -> Result { + let module = self.module_for(for_module); - if let Some(name) = info.drop_import.as_deref() { - let index = self.component.resource_drop(resource_idx); - exports.push((name, ExportKind::Func, index)); - } - if let Some(name) = info.rep_import.as_deref() { - let index = self.component.resource_rep(resource_idx); - exports.push((name, ExportKind::Func, index)); + let mut args = Vec::new(); + for (core_wasm_name, instance) in self.info.imports_for(for_module).modules() { + match instance { + // For import modules that are a "bag of names" iterate over + // each name and materialize it into this component with the + // `materialize_import` helper. This is then all bottled up into + // a bag-of-exports instances which is then used for + // instantiation. + ImportInstance::Names(names) => { + let mut exports = Vec::new(); + for (name, import) in names { + let (kind, index) = self + .materialize_import(&shims, for_module, core_wasm_name, name, import) + .with_context(|| { + format!("failed to satisfy import `{core_wasm_name}::{name}`") + })?; + exports.push((name.as_str(), kind, index)); + } + let index = self.component.core_instantiate_exports(exports); + args.push((core_wasm_name.as_str(), ModuleArg::Instance(index))); } - if let Some(name) = info.new_import.as_deref() { - let index = self.component.resource_new(resource_idx); - exports.push((name, ExportKind::Func, index)); + + // Some imports are entire instances, so use the instance for + // the module identifier as the import. + ImportInstance::Whole(which) => { + let instance = self.instance_for(which.to_custom_module()); + args.push((core_wasm_name.as_str(), ModuleArg::Instance(instance))); } } - if !exports.is_empty() { - let index = self.component.core_instantiate_exports(exports); - args.push((import.as_str(), ModuleArg::Instance(index))); - } } + + // And with all arguments prepared now, instantiate the module. + Ok(self.component.core_instantiate(module, args)) } - /// This function will instantiate the specified adapter module, which may - /// depend on previously-instantiated modules. - fn instantiate_adapter_module( + /// Helper function to materialize an import into a core module within the + /// component being built. + /// + /// This function is called for individual imports and uses the results of + /// validation, notably the `Import` type, to determine what WIT-level or + /// component-level construct is being hooked up. + fn materialize_import( &mut self, shims: &Shims<'_>, - name: &'a str, - adapter: &WorldAdapter, - ) { - let mut args = Vec::new(); + for_module: CustomModule<'_>, + module: &str, + field: &str, + import: &Import, + ) -> Result<(ExportKind, u32)> { + log::trace!("attempting to materialize import of `{module}::{field}` for {for_module:?}"); + let resolve = &self.info.encoder.metadata.resolve; + let name_tmp; + let (key, name) = match import { + // Main module dependencies on an adapter in use are done with an + // indirection here, so load the shim function and use that. + Import::AdapterExport(_) => { + assert!(self.info.encoder.adapters.contains_key(module)); + let shim_instance = self + .shim_instance_index + .expect("shim should be instantiated"); + let index = self.core_alias_export( + shim_instance, + &shims.shim_names[&ShimKind::Adapter { + adapter: module, + func: field, + }], + ExportKind::Func, + ); + return Ok((ExportKind::Func, index)); + } - let mut core_exports = Vec::new(); - for export_name in adapter.info.needs_core_exports.iter() { - let mut core_export_name = export_name.as_str(); - // provide cabi_realloc_adapter as cabi_realloc to adapters - // if it exists - if export_name == "cabi_realloc" { - if let Some(adapter_realloc) = self.info.info.adapter_realloc { - core_export_name = adapter_realloc; - } + // Adapters might uset he main module's memory, in which case it + // should have been previously instantiated. + Import::MainModuleMemory => { + let index = self + .memory_index + .ok_or_else(|| anyhow!("main module cannot import memory"))?; + return Ok((ExportKind::Memory, index)); } - let index = self.component.core_alias_export( - self.instance_index - .expect("adaptee index set at this point"), - core_export_name, - ExportKind::Func, - ); - core_exports.push((export_name.as_str(), ExportKind::Func, index)); - } - if !core_exports.is_empty() { - let instance = self.component.core_instantiate_exports(core_exports); - args.push((MAIN_MODULE_IMPORT_NAME, ModuleArg::Instance(instance))); - } - // The adapter may either be a library or a "minimal" adapter. If it's - // the former, we use `LibraryInfo::arguments` to populate inter-module - // instantiation arguments. - if let Some(library_info) = adapter.library_info { - for (import_name, instance) in &library_info.arguments { - let resolve = |which: &_| match which { - MainOrAdapter::Main => self.instance_index.unwrap(), - MainOrAdapter::Adapter(adapter_name) => *self - .adapter_instances - .get(adapter_name.as_str()) - .unwrap_or_else(|| { - panic!( - "adapter {name} needs {adapter_name}, \ - which has not yet been instantiated" - ) - }), - }; - args.push(( - import_name, - ModuleArg::Instance(match instance { - Instance::MainOrAdapter(which) => resolve(which), - Instance::Items(items) => { - let exports = items - .iter() - .map(|item| { - ( - item.alias.as_str(), - item.kind, - self.component.core_alias_export( - resolve(&item.which), - &item.name, - item.kind, - ), - ) - }) - .collect::>(); - self.component.core_instantiate_exports(exports) - } - }), - )); + // Grab-bag of "this adapter wants this thing from the main module". + Import::MainModuleExport { name, kind } => { + let instance = self.instance_index.unwrap(); + let index = self.core_alias_export(instance, name, *kind); + return Ok((*kind, index)); } - } else { - // If the adapter module requires a `memory` import then specify - // that here. For now assume that the module name of the memory is - // different from the imported interface. That's true enough for now - // since it's `env::memory`. - if let Some((module, name)) = &adapter.info.needs_memory { - for (import_name, _) in adapter.info.required_imports.iter() { - assert!(module != import_name); - } - assert!(module != name); - let memory = self.memory_index.unwrap(); - let instance = self.component.core_instantiate_exports([( - name.as_str(), - ExportKind::Memory, - memory, - )]); - args.push((module.as_str(), ModuleArg::Instance(instance))); + + // A similar grab-bag to above but with a slightly different + // structure. Should probably refactor to make these two the same in + // the future. + Import::Item(item) => { + let instance = self.instance_for(item.which.to_custom_module()); + let index = self.core_alias_export(instance, &item.name, item.kind); + return Ok((item.kind, index)); } - } - for (import_name, _) in adapter.info.required_imports.iter() { - let instance = self.import_instance_to_lowered_core_instance( - CustomModule::Adapter(name), - import_name, - shims, - adapter.info.metadata, - ); - args.push((import_name, ModuleArg::Instance(instance))); - } - self.add_resource_funcs( - CustomModule::Adapter(name), - &adapter.info.required_resource_funcs, - shims, - &mut args, - ); + // Resource intrinsics related to exported resources. Despite being + // an exported resource the component still provides necessary + // intrinsics for manipulating resource state. These are all + // handled here using the resource types created during + // `declare_exported_resources` above. + Import::ExportedResourceDrop(_key, id) => { + let index = self.component.resource_drop(self.export_type_map[id]); + return Ok((ExportKind::Func, index)); + } + Import::ExportedResourceRep(_key, id) => { + let index = self.component.resource_rep(self.export_type_map[id]); + return Ok((ExportKind::Func, index)); + } + Import::ExportedResourceNew(_key, id) => { + let index = self.component.resource_new(self.export_type_map[id]); + return Ok((ExportKind::Func, index)); + } - let instance = self - .component - .core_instantiate(self.adapter_modules[name], args); - self.adapter_instances.insert(name, instance); + // And finally here at the end these cases are going to all fall + // through to the code below. This is where these are connected to a + // WIT `ImportedInterface` one way or another with the name that was + // detected during validation. + Import::ImportedResourceDrop(key, id) => { + let ty = &resolve.types[*id]; + let name = ty.name.as_ref().unwrap(); + name_tmp = format!("{RESOURCE_DROP}{name}"); + (key.as_ref(), &name_tmp) + } + Import::WorldFunc(name) => (None, name), + Import::InterfaceFunc(key, _, name) => (Some(key), name), + }; - let realloc = adapter.info.export_realloc.as_ref().map(|name| { - self.component - .core_alias_export(instance, name, ExportKind::Func) - }); - self.adapter_export_reallocs.insert(name, realloc); - let realloc = adapter.info.import_realloc.as_ref().map(|name| { - self.component - .core_alias_export(instance, name, ExportKind::Func) - }); - self.adapter_import_reallocs.insert(name, realloc); + let interface = key.map(|key| resolve.name_world_key(key)); + let import = &self.info.import_map[&interface]; + let (index, _, lowering) = import.lowerings.get_full(name).unwrap(); + let metadata = self.info.module_metadata_for(for_module); + + let index = match lowering { + // All direct lowerings can be `canon lower`'d here immediately + // and passed as arguments. + Lowering::Direct => { + let func_index = match &import.interface { + Some(interface) => { + let instance_index = self.imported_instances[interface]; + self.component + .alias_export(instance_index, name, ComponentExportKind::Func) + } + None => self.imported_funcs[name], + }; + self.component.lower_func(func_index, []) + } + + // Indirect lowerings come from the shim that was previously + // created, so the specific export is loaded here and used as an + // import. + Lowering::Indirect { .. } => { + let encoding = metadata.import_encodings[&(module.to_string(), field.to_string())]; + self.core_alias_export( + self.shim_instance_index + .expect("shim should be instantiated"), + &shims.shim_names[&ShimKind::IndirectLowering { + interface: interface.clone(), + index, + realloc: for_module, + encoding, + }], + ExportKind::Func, + ) + } + + // A "resource drop" intrinsic only needs to find the index of the + // resource type itself and then the intrinsic is declared. + Lowering::ResourceDrop(id) => { + let resource_idx = self.lookup_resource_index(*id); + self.component.resource_drop(resource_idx) + } + }; + Ok((ExportKind::Func, index)) } /// Generates component bits that are responsible for executing @@ -1711,17 +1496,14 @@ impl<'a> EncodingState<'a> { /// Note that at this time `_initialize` is only detected in the "main /// module", not adapters/libraries. fn encode_initialize_with_start(&mut self) -> Result<()> { - let initialize = match self.info.info.initialize { + let initialize = match self.info.info.exports.initialize() { Some(name) => name, // If this core module didn't have `_initialize` or similar, then // there's nothing to do here. None => return Ok(()), }; - let initialize_index = self.component.alias_core_export( - self.instance_index.unwrap(), - initialize, - ExportKind::Func, - ); + let initialize_index = + self.core_alias_export(self.instance_index.unwrap(), initialize, ExportKind::Func); let mut shim = Module::default(); let mut section = TypeSection::new(); section.ty().function([], []); @@ -1745,6 +1527,33 @@ impl<'a> EncodingState<'a> { ); Ok(()) } + + /// Convenience function to go from `CustomModule` to the instance index + /// corresponding to what that points to. + fn instance_for(&self, module: CustomModule) -> u32 { + match module { + CustomModule::Main => self.instance_index.expect("instantiated by now"), + CustomModule::Adapter(name) => self.adapter_instances[name], + } + } + + /// Convenience function to go from `CustomModule` to the module index + /// corresponding to what that points to. + fn module_for(&self, module: CustomModule) -> u32 { + match module { + CustomModule::Main => self.module_index.unwrap(), + CustomModule::Adapter(name) => self.adapter_modules[name], + } + } + + /// Convenience function which caches aliases created so repeated calls to + /// this function will all return the same index. + fn core_alias_export(&mut self, instance: u32, name: &str, kind: ExportKind) -> u32 { + *self + .aliased_core_items + .entry((instance, name.to_string())) + .or_insert_with(|| self.component.core_alias_export(instance, name, kind)) + } } /// A list of "shims" which start out during the component instantiation process @@ -1819,10 +1628,8 @@ enum ShimKind<'a> { ResourceDtor { /// Which instance to pull the destructor function from. module: CustomModule<'a>, - /// The import that the resource was defined for. - import: &'a str, - /// The name of the resource being destroyed. - resource: &'a str, + /// The exported function name of this destructor in the core module. + export: &'a str, }, } @@ -1846,50 +1653,102 @@ enum CustomModule<'a> { } impl<'a> Shims<'a> { - /// Adds all shims necessary for the `import` provided, namely iterating - /// over its indirect lowerings and appending a shim per lowering. + /// Adds all shims necessary for the instantiation of `for_module`. + /// + /// This function will iterate over all the imports required by this module + /// and for those that require a shim they're registered here. fn append_indirect( &mut self, - core_wasm_module: &'a str, + world: &'a ComponentWorld<'a>, for_module: CustomModule<'a>, - import: &ImportedInterface, - required: &IndexSet, - metadata: &ModuleMetadata, sigs: &mut Vec, ) -> Result<()> { - let interface = if core_wasm_module == BARE_FUNC_MODULE_NAME { - None - } else { - Some(core_wasm_module.to_string()) - }; - for (index, (name, lowering)) in import.lowerings.iter().enumerate() { - if !required.contains(name.as_str()) { - continue; - } + let module_imports = world.imports_for(for_module); + let module_exports = world.exports_for(for_module); + let metadata = world.module_metadata_for(for_module); + let resolve = &world.encoder.metadata.resolve; + + for (module, field, import) in module_imports.imports() { + let (key, name) = match import { + // These imports don't require shims, they can be satisfied + // as-needed when required. + Import::ImportedResourceDrop(..) + | Import::MainModuleMemory + | Import::MainModuleExport { .. } + | Import::Item(_) + | Import::ExportedResourceDrop(..) + | Import::ExportedResourceRep(..) + | Import::ExportedResourceNew(..) => continue, + + // Adapter imports into the main module must got through an + // indirection, so that's registered here. + Import::AdapterExport(ty) => { + let name = self.list.len().to_string(); + log::debug!("shim {name} is adapter `{module}::{field}`"); + sigs.push(WasmSignature { + params: ty.params().iter().map(to_wasm_type).collect(), + results: ty.results().iter().map(to_wasm_type).collect(), + indirect_params: false, + retptr: false, + }); + self.list.push(Shim { + name, + debug_name: format!("adapt-{module}-{field}"), + // Pessimistically assume that all adapters require + // memory in one form or another. While this isn't + // technically true it's true enough for WASI. + options: RequiredOptions::MEMORY, + kind: ShimKind::Adapter { + adapter: module, + func: field, + }, + }); + continue; + + fn to_wasm_type(ty: &wasmparser::ValType) -> WasmType { + match ty { + wasmparser::ValType::I32 => WasmType::I32, + wasmparser::ValType::I64 => WasmType::I64, + wasmparser::ValType::F32 => WasmType::F32, + wasmparser::ValType::F64 => WasmType::F64, + _ => unreachable!(), + } + } + } + + // WIT-level functions may require an indirection, so yield some + // metadata out of this `match` to the loop below to figure that + // out. + Import::InterfaceFunc(key, _, name) => (Some(key), name), + Import::WorldFunc(name) => (None, name), + }; + let key = key.map(|key| resolve.name_world_key(key)); + let interface = &world.import_map[&key]; + let (index, _, lowering) = interface.lowerings.get_full(name).unwrap(); let shim_name = self.list.len().to_string(); - log::debug!( - "shim {shim_name} is import `{core_wasm_module}` lowering {index} `{name}`", - ); match lowering { Lowering::Direct | Lowering::ResourceDrop(_) => {} Lowering::Indirect { sig, options } => { + log::debug!( + "shim {shim_name} is import `{module}::{field}` lowering {index} `{name}`", + ); sigs.push(sig.clone()); let encoding = *metadata .import_encodings - .get(&(core_wasm_module.to_string(), name.clone())) + .get(&(module.to_string(), field.to_string())) .ok_or_else(|| { anyhow::anyhow!( "missing component metadata for import of \ - `{core_wasm_module}::{name}`" + `{module}::{field}`" ) })?; self.list.push(Shim { name: shim_name, - debug_name: format!("indirect-{core_wasm_module}-{name}"), + debug_name: format!("indirect-{module}-{field}"), options: *options, kind: ShimKind::IndirectLowering { - interface: interface.clone(), + interface: key, index, realloc: for_module, encoding, @@ -1898,12 +1757,42 @@ impl<'a> Shims<'a> { } } } + + // In addition to all the shims added for imports above this module also + // requires shims for resource destructors that it exports. Resource + // types are declared before the module is instantiated so the actual + // destructor is registered as a shim (defined here) and it's then + // filled in with the module's exports later. + for (export_name, export) in module_exports.iter() { + let id = match export { + Export::ResourceDtor(id) => id, + _ => continue, + }; + sigs.push(WasmSignature { + params: vec![WasmType::I32], + results: Vec::new(), + indirect_params: false, + retptr: false, + }); + let resource = resolve.types[*id].name.as_ref().unwrap(); + let name = self.list.len().to_string(); + self.list.push(Shim { + name, + debug_name: format!("dtor-{resource}"), + options: RequiredOptions::empty(), + kind: ShimKind::ResourceDtor { + module: for_module, + export: export_name, + }, + }); + } + Ok(()) } } /// Alias argument to an instantiation -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Item { pub alias: String, pub kind: ExportKind, @@ -1912,12 +1801,21 @@ pub struct Item { } /// Module argument to an instantiation -#[derive(Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum MainOrAdapter { Main, Adapter(String), } +impl MainOrAdapter { + fn to_custom_module(&self) -> CustomModule<'_> { + match self { + MainOrAdapter::Main => CustomModule::Main, + MainOrAdapter::Adapter(s) => CustomModule::Adapter(s), + } + } +} + /// Module instantiation argument #[derive(Clone)] pub enum Instance { @@ -2144,13 +2042,10 @@ impl ComponentEncoder { module_index: None, instance_index: None, memory_index: None, - realloc_index: None, shim_instance_index: None, fixups_module_index: None, adapter_modules: IndexMap::new(), adapter_instances: IndexMap::new(), - adapter_import_reallocs: IndexMap::new(), - adapter_export_reallocs: IndexMap::new(), import_type_map: HashMap::new(), import_func_type_map: HashMap::new(), export_type_map: HashMap::new(), @@ -2158,6 +2053,7 @@ impl ComponentEncoder { imported_instances: Default::default(), imported_funcs: Default::default(), exported_instances: Default::default(), + aliased_core_items: Default::default(), info: &world, }; state.encode_imports(&self.import_name_map)?; @@ -2182,6 +2078,32 @@ impl ComponentEncoder { } } +impl ComponentWorld<'_> { + /// Convenience function to lookup a module's import map. + fn imports_for(&self, module: CustomModule) -> &ImportMap { + match module { + CustomModule::Main => &self.info.imports, + CustomModule::Adapter(name) => &self.adapters[name].info.imports, + } + } + + /// Convenience function to lookup a module's export map. + fn exports_for(&self, module: CustomModule) -> &ExportMap { + match module { + CustomModule::Main => &self.info.exports, + CustomModule::Adapter(name) => &self.adapters[name].info.exports, + } + } + + /// Convenience function to lookup a module's metadata. + fn module_metadata_for(&self, module: CustomModule) -> &ModuleMetadata { + match module { + CustomModule::Main => &self.encoder.metadata.metadata, + CustomModule::Adapter(name) => &self.encoder.adapters[name].metadata, + } + } +} + #[cfg(all(test, feature = "dummy-module"))] mod test { use super::*; diff --git a/crates/wit-component/src/encoding/world.rs b/crates/wit-component/src/encoding/world.rs index f7cb669d57..d969e39798 100644 --- a/crates/wit-component/src/encoding/world.rs +++ b/crates/wit-component/src/encoding/world.rs @@ -1,13 +1,11 @@ use super::{Adapter, ComponentEncoder, LibraryInfo, RequiredOptions}; use crate::validation::{ - validate_adapter_module, validate_module, RequiredImports, ValidatedAdapter, ValidatedModule, - BARE_FUNC_MODULE_NAME, RESOURCE_DROP, + validate_adapter_module, validate_module, Import, ImportMap, ValidatedModule, RESOURCE_DROP, }; use anyhow::{Context, Result}; use indexmap::{IndexMap, IndexSet}; -use std::borrow::{Borrow, Cow}; +use std::borrow::Cow; use std::collections::{HashMap, HashSet}; -use std::hash::Hash; use wasmparser::FuncType; use wit_parser::{ abi::{AbiVariant, WasmSignature, WasmType}, @@ -17,7 +15,7 @@ use wit_parser::{ pub struct WorldAdapter<'a> { pub wasm: Cow<'a, [u8]>, - pub info: ValidatedAdapter<'a>, + pub info: ValidatedModule, pub library_info: Option<&'a LibraryInfo>, } @@ -31,7 +29,7 @@ pub struct ComponentWorld<'a> { pub encoder: &'a ComponentEncoder, /// Validation information of the input module, or `None` in `--types-only` /// mode. - pub info: ValidatedModule<'a>, + pub info: ValidatedModule, /// Validation information about adapters populated only for required /// adapters. Additionally stores the gc'd wasm for each adapter. pub adapters: IndexMap<&'a str, WorldAdapter<'a>>, @@ -107,14 +105,14 @@ impl<'a> ComponentWorld<'a> { name, Adapter { wasm, - metadata, + metadata: _, required_exports, library_info, }, ) in self.encoder.adapters.iter() { - let required_by_import = self.info.adapters_required.get(name.as_str()); - let no_required_by_import = || required_by_import.map(|m| m.is_empty()).unwrap_or(true); + let required_by_import = self.info.imports.required_from_adapter(name.as_str()); + let no_required_by_import = || required_by_import.is_empty(); let no_required_exports = || { required_exports .iter() @@ -136,7 +134,7 @@ impl<'a> ComponentWorld<'a> { resolve, world, required_exports, - required_by_import, + &required_by_import, ); Cow::Owned( @@ -146,7 +144,7 @@ impl<'a> ComponentWorld<'a> { if self.encoder.realloc_via_memory_grow { None } else { - self.info.realloc + self.info.exports.realloc_to_import_into_adapter() }, ) .context("failed to reduce input adapter module to its minimal size")?, @@ -156,13 +154,14 @@ impl<'a> ComponentWorld<'a> { &wasm, resolve, world, - metadata, - required_by_import, + &required_by_import, required_exports, - library_info.is_some(), + library_info.as_ref(), adapters, ) - .context("failed to validate the imports of the minimized adapter module")?; + .with_context(|| { + format!("failed to validate the imports of the minimized adapter module `{name}`") + })?; self.adapters.insert( name, WorldAdapter { @@ -183,15 +182,13 @@ impl<'a> ComponentWorld<'a> { resolve: &'r Resolve, world: WorldId, required_exports: &IndexSet, - required_by_import: Option<&IndexMap<&str, FuncType>>, + required_by_import: &IndexMap, ) -> IndexMap)> { use wasmparser::ValType; let mut required = IndexMap::new(); - if let Some(imports) = required_by_import { - for (name, ty) in imports { - required.insert(name.to_string(), (ty.clone(), None)); - } + for (name, ty) in required_by_import { + required.insert(name.to_string(), (ty.clone(), None)); } let mut add_func = |func: &'r Function, name: Option<&str>| { let name = func.core_export_name(name); @@ -241,29 +238,40 @@ impl<'a> ComponentWorld<'a> { fn process_imports(&mut self) -> Result<()> { let resolve = &self.encoder.metadata.resolve; let world = self.encoder.metadata.world; - let mut all_required_imports = IndexMap::new(); - for map in self.adapters.values().map(|a| &a.info.required_imports) { - for (k, v) in map { - all_required_imports - .entry(k.as_str()) - .or_insert_with(IndexSet::new) - .extend(v.funcs.iter().map(|v| v.as_str())); + + // Inspect all imports of the main module and adapters to find all + // WIT-looking things and register those as required. This is used to + // prune out unneeded things in the `add_item` function below. + let mut required = Required::default(); + for (_, _, import) in self + .adapters + .values() + .flat_map(|a| a.info.imports.imports()) + .chain(self.info.imports.imports()) + { + match import { + Import::WorldFunc(name) => { + required + .interface_funcs + .entry(None) + .or_default() + .insert(name); + } + Import::InterfaceFunc(_, id, name) => { + required + .interface_funcs + .entry(Some(*id)) + .or_default() + .insert(name); + } + Import::ImportedResourceDrop(_, id) => { + required.resource_drops.insert(*id); + } + _ => {} } } - for (k, v) in self.info.required_imports.iter() { - all_required_imports - .entry(*k) - .or_insert_with(IndexSet::new) - .extend(v.funcs.iter().map(|v| v.as_str())); - } for (name, item) in resolve.worlds[world].imports.iter() { - add_item( - &mut self.import_map, - resolve, - name, - item, - &all_required_imports, - )?; + add_item(&mut self.import_map, resolve, name, item, &required)?; } return Ok(()); @@ -272,11 +280,10 @@ impl<'a> ComponentWorld<'a> { resolve: &Resolve, name: &WorldKey, item: &WorldItem, - required: &IndexMap<&str, IndexSet<&str>>, + required: &Required<'_>, ) -> Result<()> { let name = resolve.name_world_key(name); log::trace!("register import `{name}`"); - let empty = IndexSet::new(); let import_map_key = match item { WorldItem::Function(_) | WorldItem::Type(_) => None, WorldItem::Interface { .. } => Some(name), @@ -285,9 +292,6 @@ impl<'a> ComponentWorld<'a> { WorldItem::Function(_) | WorldItem::Type(_) => None, WorldItem::Interface { id, .. } => Some(*id), }; - let required = required - .get(import_map_key.as_deref().unwrap_or(BARE_FUNC_MODULE_NAME)) - .unwrap_or(&empty); let interface = import_map .entry(import_map_key) .or_insert_with(|| ImportedInterface { @@ -324,10 +328,10 @@ impl<'a> ComponentWorld<'a> { // First use the previously calculated metadata about live imports to // determine the set of live types in those imports. - self.add_live_imports(world, &self.info.required_imports, &mut live); + self.add_live_imports(world, &self.info.imports, &mut live); for (adapter_name, adapter) in self.adapters.iter() { log::trace!("processing adapter `{adapter_name}`"); - self.add_live_imports(world, &adapter.info.required_imports, &mut live); + self.add_live_imports(world, &adapter.info.imports, &mut live); } // Next any imported types used by an export must also be considered @@ -379,43 +383,28 @@ impl<'a> ComponentWorld<'a> { } } - fn add_live_imports( - &self, - world: WorldId, - required: &IndexMap, - live: &mut LiveTypes, - ) where - S: Borrow + Hash + Eq, - { + fn add_live_imports(&self, world: WorldId, imports: &ImportMap, live: &mut LiveTypes) { let resolve = &self.encoder.metadata.resolve; for (name, item) in resolve.worlds[world].imports.iter() { let name = resolve.name_world_key(name); match item { WorldItem::Function(func) => { - let required = match required.get(BARE_FUNC_MODULE_NAME) { - Some(set) => set, - None => continue, - }; - if !required.funcs.contains(name.as_str()) { + if !imports.uses_toplevel_func(name.as_str()) { continue; } log::trace!("add live function import `{name}`"); live.add_func(resolve, func); } WorldItem::Interface { id, .. } => { - let required = match required.get(name.as_str()) { - Some(set) => set, - None => continue, - }; log::trace!("add live interface import `{name}`"); for (name, func) in resolve.interfaces[*id].functions.iter() { - if required.funcs.contains(name.as_str()) { + if imports.uses_interface_func(*id, name.as_str()) { log::trace!("add live func `{name}`"); live.add_func(resolve, func); } } - for (name, ty) in resolve.interfaces[*id].types.iter() { - if required.resources.contains(name.as_str()) { + for (_name, ty) in resolve.interfaces[*id].types.iter() { + if imports.uses_imported_resource_drop(*ty) { live.add_type_id(resolve, *ty); } } @@ -458,10 +447,17 @@ impl<'a> ComponentWorld<'a> { } } +#[derive(Default)] +struct Required<'a> { + interface_funcs: IndexMap, IndexSet<&'a str>>, + resource_drops: IndexSet, +} + impl ImportedInterface { - fn add_func(&mut self, required: &IndexSet<&str>, resolve: &Resolve, func: &Function) { - if !required.contains(func.name.as_str()) { - return; + fn add_func(&mut self, required: &Required<'_>, resolve: &Resolve, func: &Function) { + match required.interface_funcs.get(&self.interface) { + Some(set) if set.contains(func.name.as_str()) => {} + _ => return, } log::trace!("add func {}", func.name); let options = RequiredOptions::for_import(resolve, func); @@ -476,7 +472,7 @@ impl ImportedInterface { assert!(prev.is_none()); } - fn add_type(&mut self, required: &IndexSet<&str>, resolve: &Resolve, id: TypeId) { + fn add_type(&mut self, required: &Required<'_>, resolve: &Resolve, id: TypeId) { let ty = &resolve.types[id]; match &ty.kind { TypeDefKind::Resource => {} @@ -484,13 +480,10 @@ impl ImportedInterface { } let name = ty.name.as_deref().expect("resources must be named"); - let mut maybe_add = |name: String, lowering: Lowering| { - if !required.contains(name.as_str()) { - return; - } - let prev = self.lowerings.insert(name, lowering); + if required.resource_drops.contains(&id) { + let name = format!("{RESOURCE_DROP}{name}"); + let prev = self.lowerings.insert(name, Lowering::ResourceDrop(id)); assert!(prev.is_none()); - }; - maybe_add(format!("{RESOURCE_DROP}{name}"), Lowering::ResourceDrop(id)); + } } } diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index c70e0c8e3b..14c532935e 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -1,10 +1,12 @@ -use crate::metadata::{Bindgen, ModuleMetadata}; +use crate::encoding::{Instance, Item, LibraryInfo, MainOrAdapter}; +use crate::metadata::Bindgen; use anyhow::{bail, Context, Result}; use indexmap::{map::Entry, IndexMap, IndexSet}; use std::mem; +use wasm_encoder::ExportKind; use wasmparser::names::{ComponentName, ComponentNameKind}; use wasmparser::{ - types::Types, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef, ValType, + types::TypesRef, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef, ValType, ValidPayload, Validator, }; use wit_parser::{ @@ -12,10 +14,6 @@ use wit_parser::{ Function, InterfaceId, PackageName, Resolve, TypeDefKind, TypeId, WorldId, WorldItem, WorldKey, }; -fn is_canonical_function(name: &str) -> bool { - name.starts_with("cabi_") || name.starts_with("canonical_abi_") -} - fn wasm_sig_to_func_type(signature: WasmSignature) -> FuncType { fn from_wasm_type(ty: &WasmType) -> ValType { match ty { @@ -52,557 +50,858 @@ pub const POST_RETURN_PREFIX: &str = "cabi_post_"; /// Metadata about a validated module and what was found internally. /// -/// All imports to the module are described by the union of `required_imports` -/// and `adapters_required`. -/// -/// This structure is created by the `validate_module` function. -pub struct ValidatedModule<'a> { - /// The required imports into this module which are to be satisfied by - /// imported component model instances. - /// - /// The key of this map is the name of the interface that the module imports - /// from and the value is the set of functions required from that interface. - /// This is used to generate an appropriate instance import in the generated - /// component which imports only the set of required functions. - pub required_imports: IndexMap<&'a str, RequiredImports>, - - /// This is the set of imports into the module which were not satisfied by - /// imported interfaces but are required to be satisfied by adapter modules. - /// - /// The key of this map is the name of the adapter that was imported into - /// the module and the value is a further map from function to function type - /// as required by this module. This map is used to shrink adapter modules - /// to the precise size required for this module by ensuring it doesn't - /// export (and subsequently import) extraneous functions. - pub adapters_required: IndexMap<&'a str, IndexMap<&'a str, FuncType>>, - - /// Resource-related functions required and imported which work over - /// exported resources from the final component. - /// - /// Note that this is disjoint from `required_imports` which handles - /// imported resources and this is only for exported resources. Exported - /// resources still require intrinsics to be imported into the core module - /// itself. - pub required_resource_funcs: IndexMap>, +/// This structure houses information about `imports` and `exports` to the +/// module. Each of these specialized types contains "connection" information +/// between a module's imports/exports and the WIT or component-level constructs +/// they correspond to. +#[derive(Default)] +pub struct ValidatedModule { + /// Information about a module's imports. + pub imports: ImportMap, - /// Whether or not this module exported a linear memory. - pub has_memory: bool, + /// Information about a module's exports. + pub exports: ExportMap, +} - /// Whether or not this module exported a `cabi_realloc` function. - pub realloc: Option<&'a str>, +impl ValidatedModule { + fn new( + bytes: &[u8], + resolve: &Resolve, + world: WorldId, + exports: &IndexSet, + adapters: &IndexSet<&str>, + info: Option<&LibraryInfo>, + ) -> Result { + let mut validator = Validator::new(); + let mut ret = ValidatedModule::default(); + + for payload in Parser::new(0).parse_all(bytes) { + let payload = payload?; + if let ValidPayload::End(_) = validator.payload(&payload)? { + break; + } - /// Whether or not this module exported a `cabi_realloc_adapter` function. - pub adapter_realloc: Option<&'a str>, + let types = validator.types(0).unwrap(); - /// The original metadata specified for this module. - pub metadata: &'a ModuleMetadata, + match payload { + Payload::Version { encoding, .. } if encoding != Encoding::Module => { + bail!("data is not a WebAssembly module"); + } + Payload::ImportSection(s) => { + for import in s { + let import = import?; + ret.imports + .add(import, resolve, world, adapters, info, types)?; + } + } + Payload::ExportSection(s) => { + for export in s { + let export = export?; + ret.exports.add(export, resolve, world, &exports, types)?; + } + } + _ => continue, + } + } - /// Post-return functions annotated with `cabi_post_*` in their function - /// name. - pub post_returns: IndexSet, + ret.exports.validate(resolve, world, exports)?; - /// Exported function like `_initialize` which needs to be run after - /// everything else has been instantiated. - pub initialize: Option<&'a str>, + Ok(ret) + } } +/// Metadata information about a module's imports. +/// +/// This structure maintains the connection between component model "things" and +/// core wasm "things" by ensuring that all imports to the core wasm module are +/// classified by the `Import` enumeration. #[derive(Default)] -pub struct RequiredImports { - pub funcs: IndexSet, - pub resources: IndexSet, +pub struct ImportMap { + /// The first level of the map here is the module namespace of the import + /// and the second level of the map is the field namespace. The item is then + /// how the import is satisfied. + names: IndexMap, } -pub struct ResourceInfo { - pub drop_import: Option, - pub new_import: Option, - pub rep_import: Option, - pub dtor_export: Option, - pub id: TypeId, +pub enum ImportInstance { + /// This import is satisfied by an entire instance of another + /// adapter/module. + Whole(MainOrAdapter), + + /// This import is satisfied by filling out each name possibly differently. + Names(IndexMap), } -/// This function validates the following: +/// The different kinds of items that a module or an adapter can import. /// -/// * The `bytes` represent a valid core WebAssembly module. -/// * The module's imports are all satisfied by the given `imports` interfaces -/// or the `adapters` set. -/// * The given default and exported interfaces are satisfied by the module's -/// exports. -/// -/// The `ValidatedModule` return value contains the metadata which describes the -/// input module on success. This is then further used to generate a component -/// for this module. -pub fn validate_module<'a>( - bytes: &'a [u8], - metadata: &'a Bindgen, - exports: &IndexSet, - adapters: &IndexSet<&str>, -) -> Result> { - let mut validator = Validator::new(); - let mut types = None; - let mut import_funcs = IndexMap::new(); - let mut export_funcs = IndexMap::new(); - let mut ret = ValidatedModule { - required_imports: Default::default(), - adapters_required: Default::default(), - has_memory: false, - realloc: None, - adapter_realloc: None, - metadata: &metadata.metadata, - required_resource_funcs: Default::default(), - post_returns: Default::default(), - initialize: None, - }; +/// This is intended to be an exhaustive definition of what can be imported into +/// core modules within a component that wit-component supports. +#[derive(Debug, Clone)] +pub enum Import { + /// A top-level world function, with the name provided here, is imported + /// into the module. + WorldFunc(String), + + /// An interface's function is imported into the module. + /// + /// The `WorldKey` here is the name of the interface in the world in + /// question. The `InterfaceId` is the interface that was imported from and + /// `String` is the WIT name of the function. + InterfaceFunc(WorldKey, InterfaceId, String), + + /// An imported resource's destructor is imported. + /// + /// The key provided indicates whether it's for the top-level types of the + /// world (`None`) or an interface (`Some` with the name of the interface). + /// The `TypeId` is what resource is being dropped. + ImportedResourceDrop(Option, TypeId), + + /// A `canon resource.drop` intrinsic for an exported item is being + /// imported. + /// + /// This lists the key of the interface that's exporting the resource plus + /// the id within that interface. + ExportedResourceDrop(WorldKey, TypeId), + + /// A `canon resource.new` intrinsic for an exported item is being + /// imported. + /// + /// This lists the key of the interface that's exporting the resource plus + /// the id within that interface. + ExportedResourceNew(WorldKey, TypeId), + + /// A `canon resource.rep` intrinsic for an exported item is being + /// imported. + /// + /// This lists the key of the interface that's exporting the resource plus + /// the id within that interface. + ExportedResourceRep(WorldKey, TypeId), + + /// An export of an adapter is being imported with the specified type. + /// + /// This is used for when the main module imports an adapter function. The + /// adapter name and function name match the module's own import, and the + /// type must match that listed here. + AdapterExport(FuncType), + + /// An adapter is importing the memory of the main module. + /// + /// (should be combined with `MainModuleExport` below one day) + MainModuleMemory, + + /// An adapter is importing an arbitrary item from the main module. + MainModuleExport { name: String, kind: ExportKind }, + + /// An arbitrary item from either the main module or an adapter is being + /// imported. + /// + /// (should probably subsume `MainModule*` and maybe `AdapterExport` above + /// one day. + Item(Item), +} + +impl ImportMap { + /// Returns whether the top-level world function `func` is imported. + pub fn uses_toplevel_func(&self, func: &str) -> bool { + let item = self + .names + .get(BARE_FUNC_MODULE_NAME) + .and_then(|map| match map { + ImportInstance::Names(names) => names.get(func), + _ => None, + }); + matches!(item, Some(Import::WorldFunc(_))) + } + + /// Returns whether the interface function specified is imported. + pub fn uses_interface_func(&self, interface: InterfaceId, func: &str) -> bool { + self.imports().any(|(_, _, import)| match import { + Import::InterfaceFunc(_, id, name) => *id == interface && name == func, + _ => false, + }) + } + + /// Returns whether the specified resource's drop method is needed to import. + pub fn uses_imported_resource_drop(&self, resource: TypeId) -> bool { + self.imports().any(|(_, _, import)| match import { + Import::ImportedResourceDrop(_, id) => resource == *id, + _ => false, + }) + } - for payload in Parser::new(0).parse_all(bytes) { - let payload = payload?; - if let ValidPayload::End(tys) = validator.payload(&payload)? { - types = Some(tys); - break; + /// Returns the list of items that the adapter named `name` must export. + pub fn required_from_adapter(&self, name: &str) -> IndexMap { + let names = match self.names.get(name) { + Some(ImportInstance::Names(names)) => names, + _ => return IndexMap::new(), + }; + names + .iter() + .map(|(name, import)| { + ( + name.clone(), + match import { + Import::AdapterExport(ty) => ty.clone(), + _ => unreachable!(), + }, + ) + }) + .collect() + } + + /// Returns an iterator over all individual imports registered in this map. + /// + /// Note that this doesn't iterate over the "whole instance" imports. + pub fn imports(&self) -> impl Iterator + '_ { + self.names + .iter() + .filter_map(|(module, m)| match m { + ImportInstance::Names(names) => Some((module, names)), + ImportInstance::Whole(_) => None, + }) + .flat_map(|(module, m)| { + m.iter() + .map(move |(field, import)| (module.as_str(), field.as_str(), import)) + }) + } + + /// Returns the map for how all imports must be satisfied. + pub fn modules(&self) -> &IndexMap { + &self.names + } + + /// Helper function used during validation to build up this `ImportMap`. + fn add( + &mut self, + import: wasmparser::Import<'_>, + resolve: &Resolve, + world: WorldId, + adapters: &IndexSet<&str>, + library_info: Option<&LibraryInfo>, + types: TypesRef<'_>, + ) -> Result<()> { + if self.classify_import_with_library(import, library_info)? { + return Ok(()); + } + let item = self + .classify(import, resolve, world, adapters, types) + .with_context(|| { + format!( + "failed to resolve import `{}::{}`", + import.module, import.name, + ) + })?; + self.insert_import(import, item) + } + + fn classify( + &self, + import: wasmparser::Import<'_>, + resolve: &Resolve, + world_id: WorldId, + adapters: &IndexSet<&str>, + types: TypesRef<'_>, + ) -> Result { + let world = &resolve.worlds[world_id]; + + // Special-case the main module's memory imported into adapters which + // currently with `wasm-ld` is not easily configurable. + if import.module == "env" && import.name == "memory" { + return Ok(Import::MainModuleMemory); } - match payload { - Payload::Version { encoding, .. } if encoding != Encoding::Module => { - bail!("data is not a WebAssembly module"); + // Special-case imports from the main module into adapters. + if import.module == MAIN_MODULE_IMPORT_NAME { + return Ok(Import::MainModuleExport { + name: import.name.to_string(), + kind: match import.ty { + TypeRef::Func(_) => ExportKind::Func, + TypeRef::Table(_) => ExportKind::Table, + TypeRef::Memory(_) => ExportKind::Memory, + TypeRef::Global(_) => ExportKind::Global, + TypeRef::Tag(_) => ExportKind::Tag, + }, + }); + } + + let ty_index = match import.ty { + TypeRef::Func(ty) => ty, + _ => bail!("module is only allowed to import functions"), + }; + let ty = types[types.core_type_at(ty_index).unwrap_sub()].unwrap_func(); + + // Handle top-level function imports if they're going through the "bare + // name" representing the world root. + if import.module == BARE_FUNC_MODULE_NAME { + let name = import.name; + let key = WorldKey::Name(name.to_string()); + if let Some(WorldItem::Function(func)) = world.imports.get(&key) { + validate_func(resolve, ty, func, AbiVariant::GuestImport)?; + return Ok(Import::WorldFunc(func.name.clone())); } - Payload::ImportSection(s) => { - for import in s { - let import = import?; - match import.ty { - TypeRef::Func(ty) => { - let map = match import_funcs.entry(import.module) { - Entry::Occupied(e) => e.into_mut(), - Entry::Vacant(e) => e.insert(IndexMap::new()), - }; - - if map.insert(import.name, ty).is_some() { - bail!( - "module has duplicate import for `{}::{}`", - import.module, - import.name - ); - } - } - _ => bail!("module is only allowed to import functions"), - } - } + + let get_resource = resource_test_for_world(resolve, world_id); + if let Some(id) = valid_resource_drop(name, ty, get_resource)? { + return Ok(Import::ImportedResourceDrop(None, id)); } - Payload::ExportSection(s) => { - for export in s { - let export = export?; - - match export.kind { - ExternalKind::Func => { - if is_canonical_function(export.name) { - // TODO: validate that the cabi_realloc - // function is [i32, i32, i32, i32] -> [i32] - if export.name == "cabi_realloc" - || export.name == "canonical_abi_realloc" - { - ret.realloc = Some(export.name); - } - if export.name == "cabi_realloc_adapter" { - ret.adapter_realloc = Some(export.name); - } - } - - if export.name == "_initialize" { - ret.initialize = Some(export.name); - } else { - assert!(export_funcs.insert(export.name, export.index).is_none()) - } - } - ExternalKind::Memory => { - if export.name == "memory" { - ret.has_memory = true; - } - } - _ => continue, - } - } + + match world.imports.get(&key) { + Some(_) => bail!("expected world top-level import `{name}` to be a function"), + None => bail!("no top-level imported function `{name}` specified"), } - _ => continue, } - } - let types = types.unwrap(); - let world = &metadata.resolve.worlds[metadata.world]; - let mut exported_resource_funcs = Vec::new(); + // Handle main module imports that match known adapters and set it up as + // an import of an adapter export. + if adapters.contains(import.module) { + return Ok(Import::AdapterExport(ty.clone())); + } - for (name, funcs) in &import_funcs { - // An empty module name is indicative of the top-level import namespace, - // so look for top-level functions here. - if *name == BARE_FUNC_MODULE_NAME { - let required = - validate_imports_top_level(&metadata.resolve, metadata.world, funcs, &types)?; - let prev = ret.required_imports.insert(BARE_FUNC_MODULE_NAME, required); - assert!(prev.is_none()); - continue; + // Handle imports which are used to manipulate state for exported + // resources. + if let Some(suffix) = import.module.strip_prefix("[export]") { + let (key, id) = self.module_to_interface(suffix, resolve, &world.exports)?; + let get_resource = resource_test_for_interface(resolve, id); + + return if let Some(ty) = valid_resource_drop(import.name, ty, &get_resource)? { + Ok(Import::ExportedResourceDrop(key, ty)) + } else if let Some(id) = import + .name + .strip_prefix(RESOURCE_NEW) + .and_then(&get_resource) + { + let expected = FuncType::new([ValType::I32], [ValType::I32]); + validate_func_sig(import.name, &expected, ty)?; + Ok(Import::ExportedResourceNew(key, id)) + } else if let Some(id) = import + .name + .strip_prefix(RESOURCE_REP) + .and_then(&get_resource) + { + let expected = FuncType::new([ValType::I32], [ValType::I32]); + validate_func_sig(import.name, &expected, ty)?; + Ok(Import::ExportedResourceRep(key, id)) + } else { + bail!("unknown function `{}`", import.name) + }; } - if let Some(interface_name) = name.strip_prefix("[export]") { - exported_resource_funcs.push((name, interface_name, &import_funcs[name])); - continue; + // And finally handle imports of functions from interfaces here. + let (key, id) = self.module_to_interface(import.module, resolve, &world.imports)?; + let interface = &resolve.interfaces[id]; + let get_resource = resource_test_for_interface(resolve, id); + if let Some(f) = interface.functions.get(import.name) { + validate_func(resolve, ty, f, AbiVariant::GuestImport).with_context(|| { + let name = resolve.name_world_key(&key); + format!("failed to validate import interface `{name}`") + })?; + Ok(Import::InterfaceFunc(key, id, f.name.clone())) + } else if let Some(ty) = valid_resource_drop(import.name, ty, get_resource)? { + Ok(Import::ImportedResourceDrop(Some(key), ty)) + } else { + bail!( + "import interface `{}` is missing function \ + `{}` that is required by the module", + import.module, + import.name, + ) } + } - if adapters.contains(name) { - let map = ret.adapters_required.entry(name).or_default(); - for (func, ty) in funcs { - let ty = types[types.core_type_at(*ty).unwrap_sub()].unwrap_func(); - map.insert(func, ty.clone()); + fn module_to_interface( + &self, + module: &str, + resolve: &Resolve, + items: &IndexMap, + ) -> Result<(WorldKey, InterfaceId)> { + let key = world_key(resolve, module); + match items.get(&key) { + Some(WorldItem::Interface { id, .. }) => Ok((key, *id)), + Some(WorldItem::Function(_) | WorldItem::Type(_)) => { + bail!("import `{module}` is not an interface") } - } else { - match world.imports.get(&world_key(&metadata.resolve, name)) { - Some(WorldItem::Interface { id: interface, .. }) => { - let required = validate_imported_interface( - &metadata.resolve, - *interface, - name, - funcs, - &types, - ) - .with_context(|| format!("failed to validate import interface `{name}`"))?; - let prev = ret.required_imports.insert(name, required); - assert!(prev.is_none()); + None => bail!("module requires an import interface named `{module}`"), + } + } + + fn classify_import_with_library( + &mut self, + import: wasmparser::Import<'_>, + library_info: Option<&LibraryInfo>, + ) -> Result { + let info = match library_info { + Some(info) => info, + None => return Ok(false), + }; + let Some((_, instance)) = info + .arguments + .iter() + .find(|(name, _items)| *name == import.module) + else { + return Ok(false); + }; + match instance { + Instance::MainOrAdapter(module) => match self.names.get(import.module) { + Some(ImportInstance::Whole(which)) => { + if which != module { + bail!("different whole modules imported under the same name"); + } + } + Some(ImportInstance::Names(_)) => { + bail!("cannot mix individual imports and whole module imports") } - Some(WorldItem::Function(_) | WorldItem::Type(_)) => { - bail!("import `{}` is not an interface", name) + None => { + let instance = ImportInstance::Whole(module.clone()); + self.names.insert(import.module.to_string(), instance); } - None => bail!("module requires an import interface named `{name}`"), + }, + Instance::Items(items) => { + let Some(item) = items.iter().find(|i| i.alias == import.name) else { + return Ok(false); + }; + self.insert_import(import, Import::Item(item.clone()))?; } } + Ok(true) } - for name in exports { - validate_exported_item( - &metadata.resolve, - &world.exports[name], - &metadata.resolve.name_world_key(name), - &export_funcs, - &types, - &mut ret.post_returns, - &mut ret.required_resource_funcs, - )?; - } - - for (name, interface_name, funcs) in exported_resource_funcs { - let world_key = world_key(&metadata.resolve, interface_name); - match world.exports.get(&world_key) { - Some(WorldItem::Interface { id, .. }) => { - validate_exported_interface_resource_imports( - &metadata.resolve, - *id, - name, - funcs, - &types, - &mut ret.required_resource_funcs, - )?; + fn insert_import(&mut self, import: wasmparser::Import<'_>, item: Import) -> Result<()> { + let entry = self + .names + .entry(import.module.to_string()) + .or_insert(ImportInstance::Names(IndexMap::default())); + let names = match entry { + ImportInstance::Names(names) => names, + _ => bail!("cannot mix individual imports with module imports"), + }; + let entry = match names.entry(import.name.to_string()) { + Entry::Occupied(_) => { + bail!( + "module has duplicate import for `{}::{}`", + import.module, + import.name + ); } - _ => bail!("import from `{name}` does not correspond to exported interface"), - } + Entry::Vacant(v) => v, + }; + log::trace!( + "classifying import `{}::{} as {item:?}", + import.module, + import.name + ); + entry.insert(item); + Ok(()) } +} - Ok(ret) +/// Dual of `ImportMap` except describes the exports of a module instead of the +/// imports. +#[derive(Default)] +pub struct ExportMap { + names: IndexMap, + raw_exports: IndexMap, } -fn validate_exported_interface_resource_imports<'a>( - resolve: &Resolve, - interface: InterfaceId, - import_module: &str, - funcs: &IndexMap<&'a str, u32>, - types: &Types, - required_resource_funcs: &mut IndexMap>, -) -> Result<()> { - let is_resource = |name: &str| match resolve.interfaces[interface].types.get(name) { - Some(ty) => matches!(resolve.types[*ty].kind, TypeDefKind::Resource), - None => false, - }; - for (func_name, ty) in funcs { - if valid_exported_resource_func(func_name, *ty, types, is_resource)?.is_none() { - bail!("import of `{func_name}` is not a valid resource function"); - } - let info = required_resource_funcs.get_mut(import_module).unwrap(); - if let Some(resource_name) = func_name.strip_prefix(RESOURCE_DROP) { - info[resource_name].drop_import = Some(func_name.to_string()); - continue; - } - if let Some(resource_name) = func_name.strip_prefix(RESOURCE_NEW) { - info[resource_name].new_import = Some(func_name.to_string()); - continue; - } - if let Some(resource_name) = func_name.strip_prefix(RESOURCE_REP) { - info[resource_name].rep_import = Some(func_name.to_string()); - continue; - } +/// All possible (known) exports from a core wasm module that are recognized and +/// handled during the componentization process. +pub enum Export { + /// An export of a top-level function of a world, where the world function + /// is named here. + WorldFunc(String), - unreachable!(); - } - Ok(()) -} + /// A post-return for a top-level function of a world. + WorldFuncPostReturn(String), -/// Validation information from an "adapter module" which is distinct from a -/// "main module" validated above. -/// -/// This is created by the `validate_adapter_module` function. -pub struct ValidatedAdapter<'a> { - /// If specified this is the list of required imports from the original set - /// of possible imports along with the set of functions required from each - /// imported interface. - pub required_imports: IndexMap, - - /// Resource-related functions required and imported which work over - /// exported resources from the final component. - /// - /// Note that this is disjoint from `required_imports` which handles - /// imported resources and this is only for exported resources. Exported - /// resources still require intrinsics to be imported into the core module - /// itself. - pub required_resource_funcs: IndexMap>, - - /// This is the module and field name of the memory import, if one is - /// specified. - /// - /// Due to LLVM codegen this is typically `env::memory` as a totally separate - /// import from the `required_import` above. - pub needs_memory: Option<(String, String)>, + /// An export of a function in an interface. + InterfaceFunc(InterfaceId, String), + + /// A post-return for the above function. + InterfaceFuncPostReturn(InterfaceId, String), + + /// A destructor for an exported resource. + ResourceDtor(TypeId), + + /// Memory, typically for an adapter. + Memory, - /// Set of names required to be exported from the main module which are - /// imported by this adapter through the `__main_module__` synthetic export. - /// This is how the WASI adapter imports `_start`, for example. - pub needs_core_exports: IndexSet, + /// `cabi_realloc` + GeneralPurposeRealloc, - /// Name of the exported function to use for the realloc canonical option - /// for lowering imports. - pub import_realloc: Option, + /// `cabi_export_realloc` + GeneralPurposeExportRealloc, - /// Same as `import_realloc`, but for exported interfaces. - pub export_realloc: Option, + /// `cabi_import_realloc` + GeneralPurposeImportRealloc, - /// Metadata about the original adapter module. - pub metadata: &'a ModuleMetadata, + /// `_initialize` + Initialize, - /// Post-return functions annotated with `cabi_post_*` in their function - /// name. - pub post_returns: IndexSet, + /// `cabi_realloc_adapter` + ReallocForAdapter, } -/// This function will validate the `bytes` provided as a wasm adapter module. -/// Notably this will validate the wasm module itself in addition to ensuring -/// that it has the "shape" of an adapter module. Current constraints are: -/// -/// * The adapter module can import only one memory -/// * The adapter module can only import from the name of `interface` specified, -/// and all function imports must match the `required` types which correspond -/// to the lowered types of the functions in `interface`. -/// -/// The wasm module passed into this function is the output of the GC pass of an -/// adapter module's original source. This means that the adapter module is -/// already minimized and this is a double-check that the minimization pass -/// didn't accidentally break the wasm module. -/// -/// If `is_library` is true, we waive some of the constraints described above, -/// allowing the module to import tables and globals, as well as import -/// functions at the world level, not just at the interface level. -pub fn validate_adapter_module<'a>( - bytes: &[u8], - resolve: &'a Resolve, - world: WorldId, - metadata: &'a ModuleMetadata, - required_by_import: Option<&IndexMap<&str, FuncType>>, - exports: &IndexSet, - is_library: bool, - adapters: &IndexSet<&str>, -) -> Result> { - let mut validator = Validator::new(); - let mut import_funcs = IndexMap::new(); - let mut export_funcs = IndexMap::new(); - let mut types = None; - let mut funcs = Vec::new(); - let mut ret = ValidatedAdapter { - required_imports: Default::default(), - required_resource_funcs: Default::default(), - needs_memory: None, - needs_core_exports: Default::default(), - import_realloc: None, - export_realloc: None, - metadata, - post_returns: Default::default(), - }; +impl ExportMap { + fn add( + &mut self, + export: wasmparser::Export<'_>, + resolve: &Resolve, + world: WorldId, + exports: &IndexSet, + types: TypesRef<'_>, + ) -> Result<()> { + if let Some(item) = self.classify(export, resolve, world, exports, types)? { + let prev = self.names.insert(export.name.to_string(), item); + assert!(prev.is_none()); + } + Ok(()) + } - let mut cabi_realloc = None; - for payload in Parser::new(0).parse_all(bytes) { - let payload = payload?; - match validator.payload(&payload)? { - ValidPayload::End(tys) => { - types = Some(tys); - break; - } - ValidPayload::Func(validator, body) => { - funcs.push((validator, body)); - } - _ => {} + fn classify( + &mut self, + export: wasmparser::Export<'_>, + resolve: &Resolve, + world: WorldId, + exports: &IndexSet, + types: TypesRef<'_>, + ) -> Result> { + match export.kind { + ExternalKind::Func => {} + ExternalKind::Memory => return Ok(Some(Export::Memory)), + _ => return Ok(None), + } + + let ty = types[types.core_function_at(export.index)].unwrap_func(); + self.raw_exports.insert(export.name.to_string(), ty.clone()); + + // Handle a few special-cased names first. + if export.name == "cabi_realloc" || export.name == "canonical_abi_realloc" { + return Ok(Some(Export::GeneralPurposeRealloc)); + } else if export.name == "cabi_import_realloc" { + return Ok(Some(Export::GeneralPurposeImportRealloc)); + } else if export.name == "cabi_export_realloc" { + return Ok(Some(Export::GeneralPurposeExportRealloc)); + } else if export.name == "cabi_realloc_adapter" { + return Ok(Some(Export::ReallocForAdapter)); + } else if export.name == "_initialize" { + return Ok(Some(Export::Initialize)); } - match payload { - Payload::Version { encoding, .. } if encoding != Encoding::Module => { - bail!("data is not a WebAssembly module"); + // Try to match this to a known WIT export that `exports` allows. + if let Some((key, id, f)) = self.match_wit_export(export.name, resolve, world, exports) { + validate_func(resolve, ty, f, AbiVariant::GuestExport).with_context(|| { + let key = resolve.name_world_key(key); + format!("failed to validate export for `{key}`") + })?; + match id { + Some(id) => { + return Ok(Some(Export::InterfaceFunc(id, f.name.clone()))); + } + None => { + return Ok(Some(Export::WorldFunc(f.name.clone()))); + } } + } - Payload::ImportSection(s) => { - for import in s { - let import = import?; - match import.ty { - TypeRef::Func(ty) => { - let map = match import_funcs.entry(import.module) { - Entry::Occupied(e) => e.into_mut(), - Entry::Vacant(e) => e.insert(IndexMap::new()), - }; - - assert!(map.insert(import.name, ty).is_none()); - } + // See if this is a post-return for any known WIT export. + if let Some(suffix) = export.name.strip_prefix(POST_RETURN_PREFIX) { + if let Some((key, id, f)) = self.match_wit_export(suffix, resolve, world, exports) { + validate_post_return(resolve, ty, f).with_context(|| { + let key = resolve.name_world_key(key); + format!("failed to validate export for `{key}`") + })?; + match id { + Some(id) => { + return Ok(Some(Export::InterfaceFuncPostReturn(id, f.name.clone()))); + } + None => { + return Ok(Some(Export::WorldFuncPostReturn(f.name.clone()))); + } + } + } + } - // A memory is allowed to be imported into the adapter - // module so that's skipped here - TypeRef::Memory(_) => { - ret.needs_memory = - Some((import.module.to_string(), import.name.to_string())); - } + // And, finally, see if it matches a known destructor. + if let Some(dtor) = self.match_wit_resource_dtor(export.name, resolve, world, exports) { + let expected = FuncType::new([ValType::I32], []); + validate_func_sig(export.name, &expected, ty)?; + return Ok(Some(Export::ResourceDtor(dtor))); + } - TypeRef::Global(_) | TypeRef::Table(_) if is_library => (), + log::debug!("unknown export `{}`", export.name); + Ok(None) + } - _ => { - bail!("adapter module is only allowed to import functions and memories") - } + fn match_wit_export<'a>( + &self, + export_name: &str, + resolve: &'a Resolve, + world: WorldId, + exports: &'a IndexSet, + ) -> Option<(&'a WorldKey, Option, &'a Function)> { + let world = &resolve.worlds[world]; + for name in exports { + match &world.exports[name] { + WorldItem::Function(f) => { + if f.core_export_name(None) == export_name { + return Some((name, None, f)); } } - } - Payload::ExportSection(s) => { - for export in s { - let export = export?; - - match export.kind { - ExternalKind::Func => { - export_funcs.insert(export.name, export.index); - if export.name == "cabi_export_realloc" { - ret.export_realloc = Some(export.name.to_string()); - } - if export.name == "cabi_import_realloc" { - ret.import_realloc = Some(export.name.to_string()); - } - if export.name == "cabi_realloc" { - cabi_realloc = Some(export.name.to_string()); - } + WorldItem::Interface { id, .. } => { + let string = resolve.name_world_key(name); + for (_, func) in resolve.interfaces[*id].functions.iter() { + if func.core_export_name(Some(&string)) == export_name { + return Some((name, Some(*id), func)); } - _ => continue, } } + + WorldItem::Type(_) => unreachable!(), + } + } + + None + } + + fn match_wit_resource_dtor<'a>( + &self, + export_name: &str, + resolve: &'a Resolve, + world: WorldId, + exports: &'a IndexSet, + ) -> Option { + let world = &resolve.worlds[world]; + for name in exports { + let id = match &world.exports[name] { + WorldItem::Interface { id, .. } => *id, + WorldItem::Function(_) => continue, + WorldItem::Type(_) => unreachable!(), + }; + let name = resolve.name_world_key(name); + let resource = match export_name + .strip_prefix(&name) + .and_then(|s| s.strip_prefix("#[dtor]")) + .and_then(|r| resolve.interfaces[id].types.get(r)) + { + Some(id) => *id, + None => continue, + }; + + match resolve.types[resource].kind { + TypeDefKind::Resource => {} + _ => continue, } - _ => continue, + + return Some(resource); } + + None } - if is_library { - // If we're looking at a library, it may only export the - // `wit-bindgen`-generated `cabi_realloc` rather than the - // `cabi_import_realloc` and `cabi_export_realloc` functions, so we'll - // use whatever's available. - ret.export_realloc = ret.export_realloc.or_else(|| cabi_realloc.clone()); - ret.import_realloc = ret.import_realloc.or_else(|| cabi_realloc); + /// Returns the name of the post-return export, if any, for the `interface` + /// and `func` combo. + pub fn post_return(&self, interface: Option, func: &Function) -> Option<&str> { + self.find(|m| match (m, interface) { + (Export::WorldFuncPostReturn(f), None) => func.name == *f, + (Export::InterfaceFuncPostReturn(i, f), Some(id)) => *i == id && func.name == *f, + _ => false, + }) } - let mut resources = Default::default(); - for (validator, body) in funcs { - let mut validator = validator.into_validator(resources); - validator.validate(&body)?; - resources = validator.into_allocations(); + /// Returns the realloc that the exported function `interface` and `func` + /// are using. + pub fn export_realloc_for( + &self, + interface: Option, + func: &Function, + ) -> 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. + let _ = (interface, func); + + if let Some(name) = self.find(|m| matches!(m, Export::GeneralPurposeExportRealloc)) { + return Some(name); + } + self.general_purpose_realloc() } - let types = types.unwrap(); - let mut exported_resource_funcs = Vec::new(); - for (name, funcs) in &import_funcs { - if *name == MAIN_MODULE_IMPORT_NAME { - ret.needs_core_exports - .extend(funcs.iter().map(|(name, _ty)| name.to_string())); - continue; + /// Returns the realloc that the imported function `interface` and `func` + /// are using. + pub fn import_realloc_for(&self, interface: Option, 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. + let _ = (interface, func); + + if let Some(name) = self.find(|m| matches!(m, Export::GeneralPurposeImportRealloc)) { + return Some(name); } + self.general_purpose_realloc() + } - // An empty module name is indicative of the top-level import namespace, - // so look for top-level functions here. - if *name == BARE_FUNC_MODULE_NAME { - let required = validate_imports_top_level(resolve, world, funcs, &types)?; - ret.required_imports - .insert(BARE_FUNC_MODULE_NAME.to_string(), required); - continue; + /// Returns the realloc that the main module is exporting into the adapter. + pub fn realloc_to_import_into_adapter(&self) -> Option<&str> { + if let Some(name) = self.find(|m| matches!(m, Export::ReallocForAdapter)) { + return Some(name); } + self.general_purpose_realloc() + } + + fn general_purpose_realloc(&self) -> Option<&str> { + self.find(|m| matches!(m, Export::GeneralPurposeRealloc)) + } + + /// Returns the memory, if exported, for this module. + pub fn memory(&self) -> Option<&str> { + self.find(|m| matches!(m, Export::Memory)) + } + + /// Returns the `_initialize` intrinsic, if exported, for this module. + pub fn initialize(&self) -> Option<&str> { + self.find(|m| matches!(m, Export::Initialize)) + } - if let Some(interface_name) = name.strip_prefix("[export]") { - exported_resource_funcs.push((name, interface_name, &import_funcs[name])); - continue; + /// Returns destructor for the exported resource `ty`, if it was listed. + pub fn resource_dtor(&self, ty: TypeId) -> Option<&str> { + self.find(|m| match m { + Export::ResourceDtor(t) => *t == ty, + _ => false, + }) + } + + /// NB: this is a linear search and if that's ever a problem this should + /// build up an inverse map during construction to accelerate it. + fn find(&self, f: impl Fn(&Export) -> bool) -> Option<&str> { + let (name, _) = self.names.iter().filter(|(_, m)| f(m)).next()?; + Some(name) + } + + /// Iterates over all exports of this module. + pub fn iter(&self) -> impl Iterator + '_ { + self.names.iter().map(|(n, e)| (n.as_str(), e)) + } + + fn validate( + &self, + resolve: &Resolve, + world: WorldId, + exports: &IndexSet, + ) -> Result<()> { + // Multi-memory isn't supported because otherwise we don't know what + // memory to put things in. + if self + .names + .values() + .filter(|m| matches!(m, Export::Memory)) + .count() + > 1 + { + bail!("cannot componentize module that exports multiple memories") } - if !(is_library && adapters.contains(name)) { - match resolve.worlds[world].imports.get(&world_key(resolve, name)) { - Some(WorldItem::Interface { id: interface, .. }) => { - let required = - validate_imported_interface(resolve, *interface, name, funcs, &types) - .with_context(|| { - format!("failed to validate import interface `{name}`") - })?; - let prev = ret.required_imports.insert(name.to_string(), required); - assert!(prev.is_none()); + // All of `exports` must be exported and found within this module. + for export in exports { + let require_interface_func = |interface: InterfaceId, name: &str| -> Result<()> { + let result = self.find(|e| match e { + Export::InterfaceFunc(id, s) => interface == *id && name == s, + _ => false, + }); + if result.is_some() { + Ok(()) + } else { + let export = resolve.name_world_key(export); + bail!("failed to find export of interface `{export}` function `{name}`") + } + }; + let require_world_func = |name: &str| -> Result<()> { + let result = self.find(|e| match e { + Export::WorldFunc(s) => name == s, + _ => false, + }); + if result.is_some() { + Ok(()) + } else { + bail!("failed to find export of function `{name}`") } - None | Some(WorldItem::Function(_) | WorldItem::Type(_)) => { - if !is_library { - bail!( - "adapter module requires an import interface named `{}`", - name - ) + }; + match &resolve.worlds[world].exports[export] { + WorldItem::Interface { id, .. } => { + for (name, _) in resolve.interfaces[*id].functions.iter() { + require_interface_func(*id, name)?; } } + WorldItem::Function(f) => { + require_world_func(&f.name)?; + } + WorldItem::Type(_) => unreachable!(), } } - } - if let Some(required) = required_by_import { - for (name, ty) in required { - let idx = match export_funcs.get(name) { - Some(idx) => *idx, - None => bail!("adapter module did not export `{name}`"), - }; - let id = types.core_function_at(idx); - let actual = types[id].unwrap_func(); - validate_func_sig(name, ty, actual)?; - } + Ok(()) } +} - let world = &resolve.worlds[world]; - - for name in exports { - validate_exported_item( - resolve, - &world.exports[name], - &resolve.name_world_key(name), - &export_funcs, - &types, - &mut ret.post_returns, - &mut ret.required_resource_funcs, - )?; - } - - for (name, interface_name, funcs) in exported_resource_funcs { - let world_key = world_key(resolve, interface_name); - match world.exports.get(&world_key) { - Some(WorldItem::Interface { id, .. }) => { - validate_exported_interface_resource_imports( - resolve, - *id, - name, - funcs, - &types, - &mut ret.required_resource_funcs, - )?; - } - _ => bail!("import from `{name}` does not correspond to exported interface"), - } +/// This function validates the following: +/// +/// * The `bytes` represent a valid core WebAssembly module. +/// * The module's imports are all satisfied by the given `imports` interfaces +/// or the `adapters` set. +/// * The given default and exported interfaces are satisfied by the module's +/// exports. +/// +/// The `ValidatedModule` return value contains the metadata which describes the +/// input module on success. This is then further used to generate a component +/// for this module. +pub fn validate_module( + bytes: &[u8], + metadata: &Bindgen, + exports: &IndexSet, + adapters: &IndexSet<&str>, +) -> Result { + ValidatedModule::new( + bytes, + &metadata.resolve, + metadata.world, + exports, + adapters, + None, + ) +} + +/// This function will validate the `bytes` provided as a wasm adapter module. +/// Notably this will validate the wasm module itself in addition to ensuring +/// that it has the "shape" of an adapter module. Current constraints are: +/// +/// * The adapter module can import only one memory +/// * The adapter module can only import from the name of `interface` specified, +/// and all function imports must match the `required` types which correspond +/// to the lowered types of the functions in `interface`. +/// +/// The wasm module passed into this function is the output of the GC pass of an +/// adapter module's original source. This means that the adapter module is +/// already minimized and this is a double-check that the minimization pass +/// didn't accidentally break the wasm module. +/// +/// If `is_library` is true, we waive some of the constraints described above, +/// allowing the module to import tables and globals, as well as import +/// functions at the world level, not just at the interface level. +pub fn validate_adapter_module( + bytes: &[u8], + resolve: &Resolve, + world: WorldId, + required_by_import: &IndexMap, + exports: &IndexSet, + library_info: Option<&LibraryInfo>, + adapters: &IndexSet<&str>, +) -> Result { + let ret = ValidatedModule::new(bytes, resolve, world, exports, adapters, library_info)?; + + for (name, required_ty) in required_by_import { + let actual = match ret.exports.raw_exports.get(name) { + Some(ty) => ty, + None => bail!("adapter module did not export `{name}`"), + }; + validate_func_sig(name, required_ty, &actual)?; } Ok(ret) @@ -631,116 +930,54 @@ fn world_key(resolve: &Resolve, name: &str) -> WorldKey { } } -fn validate_imports_top_level( - resolve: &Resolve, - world: WorldId, - funcs: &IndexMap<&str, u32>, - types: &Types, -) -> Result { - let is_resource = |name: &str| match resolve.worlds[world] - .imports - .get(&WorldKey::Name(name.to_string())) - { - Some(WorldItem::Type(r)) => { - matches!(resolve.types[*r].kind, TypeDefKind::Resource) - } - _ => false, - }; - let mut required = RequiredImports::default(); - for (name, ty) in funcs { - match resolve.worlds[world].imports.get(&world_key(resolve, name)) { - Some(WorldItem::Function(func)) => { - let ty = types[types.core_type_at(*ty).unwrap_sub()].unwrap_func(); - validate_func(resolve, ty, func, AbiVariant::GuestImport)?; - } - Some(_) => bail!("expected world top-level import `{name}` to be a function"), - None => match valid_imported_resource_func(name, *ty, types, is_resource)? { - Some(name) => { - required.resources.insert(name.to_string()); - } - None => bail!("no top-level imported function `{name}` specified"), - }, - } - required.funcs.insert(name.to_string()); - } - Ok(required) -} - -fn valid_imported_resource_func<'a>( - func_name: &'a str, - ty: u32, - types: &Types, - is_resource: impl Fn(&str) -> bool, -) -> Result> { +fn valid_resource_drop( + func_name: &str, + ty: &FuncType, + get_resource: impl Fn(&str) -> Option, +) -> Result> { if let Some(resource_name) = func_name.strip_prefix(RESOURCE_DROP) { - if is_resource(resource_name) { - let ty = types[types.core_type_at(ty).unwrap_sub()].unwrap_func(); + if let Some(id) = get_resource(resource_name) { let expected = FuncType::new([ValType::I32], []); validate_func_sig(func_name, &expected, ty)?; - return Ok(Some(resource_name)); + return Ok(Some(id)); } } Ok(None) } -fn valid_exported_resource_func<'a>( - func_name: &'a str, - ty: u32, - types: &Types, - is_resource: impl Fn(&str) -> bool, -) -> Result> { - if let Some(name) = valid_imported_resource_func(func_name, ty, types, &is_resource)? { - return Ok(Some(name)); - } - if let Some(resource_name) = func_name - .strip_prefix(RESOURCE_REP) - .or_else(|| func_name.strip_prefix(RESOURCE_NEW)) - { - if is_resource(resource_name) { - let ty = types[types.core_type_at(ty).unwrap_sub()].unwrap_func(); - let expected = FuncType::new([ValType::I32], [ValType::I32]); - validate_func_sig(func_name, &expected, ty)?; - return Ok(Some(resource_name)); +fn resource_test_for_interface<'a>( + resolve: &'a Resolve, + id: InterfaceId, +) -> impl Fn(&str) -> Option + 'a { + let interface = &resolve.interfaces[id]; + move |name: &str| { + let ty = match interface.types.get(name) { + Some(ty) => *ty, + None => return None, + }; + if matches!(resolve.types[ty].kind, TypeDefKind::Resource) { + Some(ty) + } else { + None } } - Ok(None) } -fn validate_imported_interface( - resolve: &Resolve, - interface: InterfaceId, - name: &str, - imports: &IndexMap<&str, u32>, - types: &Types, -) -> Result { - let mut required = RequiredImports::default(); - let is_resource = |name: &str| { - let ty = match resolve.interfaces[interface].types.get(name) { - Some(ty) => *ty, - None => return false, - }; - matches!(resolve.types[ty].kind, TypeDefKind::Resource) - }; - for (func_name, ty) in imports { - match resolve.interfaces[interface].functions.get(*func_name) { - Some(f) => { - let ty = types[types.core_type_at(*ty).unwrap_sub()].unwrap_func(); - validate_func(resolve, ty, f, AbiVariant::GuestImport)?; +fn resource_test_for_world<'a>( + resolve: &'a Resolve, + id: WorldId, +) -> impl Fn(&str) -> Option + 'a { + let world = &resolve.worlds[id]; + move |name: &str| match world.imports.get(&WorldKey::Name(name.to_string()))? { + WorldItem::Type(r) => { + if matches!(resolve.types[*r].kind, TypeDefKind::Resource) { + Some(*r) + } else { + None } - None => match valid_imported_resource_func(func_name, *ty, types, is_resource)? { - Some(name) => { - required.resources.insert(name.to_string()); - } - None => bail!( - "import interface `{name}` is missing function \ - `{func_name}` that is required by the module", - ), - }, } - required.funcs.insert(func_name.to_string()); + _ => None, } - - Ok(required) } fn validate_func( @@ -789,77 +1026,3 @@ fn validate_func_sig(name: &str, expected: &FuncType, ty: &wasmparser::FuncType) Ok(()) } - -fn validate_exported_item<'a>( - resolve: &'a Resolve, - item: &'a WorldItem, - export_name: &str, - exports: &IndexMap<&str, u32>, - types: &Types, - post_returns: &mut IndexSet, - required_resource_funcs: &mut IndexMap>, -) -> Result<()> { - let mut validate = |func: &Function, name: Option<&str>| { - let expected_export_name = func.core_export_name(name); - let func_index = match exports.get(expected_export_name.as_ref()) { - Some(func_index) => func_index, - None => bail!( - "module does not export required function `{}`", - expected_export_name - ), - }; - let id = types.core_function_at(*func_index); - let ty = types[id].unwrap_func(); - validate_func(resolve, ty, func, AbiVariant::GuestExport)?; - - let post_return = format!("{POST_RETURN_PREFIX}{expected_export_name}"); - if let Some(index) = exports.get(&post_return[..]) { - let ok = post_returns.insert(post_return); - assert!(ok); - let id = types.core_function_at(*index); - let ty = types[id].unwrap_func(); - validate_post_return(resolve, ty, func)?; - } - Ok(()) - }; - match item { - WorldItem::Function(func) => validate(func, None)?, - WorldItem::Interface { id: interface, .. } => { - let interface = &resolve.interfaces[*interface]; - for (_, f) in interface.functions.iter() { - validate(f, Some(export_name)).with_context(|| { - format!("failed to validate exported interface `{export_name}`") - })?; - } - let mut map = IndexMap::new(); - for (name, id) in interface.types.iter() { - if !matches!(resolve.types[*id].kind, TypeDefKind::Resource) { - continue; - } - let mut info = ResourceInfo { - id: *id, - dtor_export: None, - drop_import: None, - rep_import: None, - new_import: None, - }; - let dtor = format!("{export_name}#[dtor]{name}"); - if let Some((_, name, func_idx)) = exports.get_full(dtor.as_str()) { - let id = types.core_function_at(*func_idx); - let ty = types[id].unwrap_func(); - let expected = FuncType::new([ValType::I32], []); - validate_func_sig(name, &expected, ty)?; - info.dtor_export = Some(name.to_string()); - } - let prev = map.insert(name.to_string(), info); - assert!(prev.is_none()); - } - let prev = required_resource_funcs.insert(format!("[export]{export_name}"), map); - assert!(prev.is_none()); - } - // not required to have anything exported in the core wasm module - WorldItem::Type(_) => {} - } - - Ok(()) -} diff --git a/crates/wit-component/tests/components/adapt-export-reallocs/component.wat b/crates/wit-component/tests/components/adapt-export-reallocs/component.wat index 4c75ab416a..7de26e613b 100644 --- a/crates/wit-component/tests/components/adapt-export-reallocs/component.wat +++ b/crates/wit-component/tests/components/adapt-export-reallocs/component.wat @@ -57,16 +57,16 @@ (type (;0;) (func (param i32 i32))) (type (;1;) (func (param i32 i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-read)) - (export "1" (func $adapt-old-read)) + (export "0" (func $adapt-old-read)) + (export "1" (func $indirect-new-read)) (export "$imports" (table 0)) - (func $indirect-new-read (;0;) (type 0) (param i32 i32) + (func $adapt-old-read (;0;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 0 call_indirect (type 0) ) - (func $adapt-old-read (;1;) (type 1) (param i32 i32) + (func $indirect-new-read (;1;) (type 1) (param i32 i32) local.get 0 local.get 1 i32.const 1 @@ -88,7 +88,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "read" (func 0)) ) @@ -97,7 +97,7 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 0 "0" (core func (;1;))) + (alias core export 0 "1" (core func (;1;))) (core instance (;3;) (export "read" (func 1)) ) @@ -105,16 +105,15 @@ (with "new" (instance 3)) ) ) - (alias core export 4 "cabi_export_realloc" (core func (;2;))) - (alias core export 4 "cabi_import_realloc" (core func (;3;))) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 4 "read" (core func (;2;))) (alias export 0 "read" (func (;0;))) + (alias core export 4 "cabi_import_realloc" (core func (;3;))) (core func (;4;) (canon lower (func 0) (memory 0) (realloc 3))) - (alias core export 4 "read" (core func (;5;))) (core instance (;5;) (export "$imports" (table 0)) - (export "0" (func 4)) - (export "1" (func 5)) + (export "0" (func 2)) + (export "1" (func 4)) ) (core instance (;6;) (instantiate 3 (with "" (instance 5)) @@ -122,8 +121,9 @@ ) (type (;1;) (list string)) (type (;2;) (func (param "args" 1))) - (alias core export 4 "entrypoint" (core func (;6;))) - (func (;1;) (type 2) (canon lift (core func 6) (memory 0) (realloc 2) string-encoding=utf8)) + (alias core export 4 "entrypoint" (core func (;5;))) + (alias core export 4 "cabi_export_realloc" (core func (;6;))) + (func (;1;) (type 2) (canon lift (core func 5) (memory 0) (realloc 6) string-encoding=utf8)) (export (;2;) "entrypoint" (func 1)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat index fda6091bb4..8cde5d448d 100644 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat @@ -71,20 +71,19 @@ (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) (alias core export 0 "canonical_abi_realloc" (core func (;0;))) - (alias core export 0 "canonical_abi_realloc" (core func (;1;))) - (alias core export 0 "canonical_abi_free" (core func (;2;))) + (alias core export 0 "canonical_abi_free" (core func (;1;))) (core instance (;1;) - (export "canonical_abi_realloc" (func 1)) - (export "canonical_abi_free" (func 2)) + (export "canonical_abi_realloc" (func 0)) + (export "canonical_abi_free" (func 1)) ) (core instance (;2;) (instantiate 1 (with "__main_module__" (instance 1)) ) ) (type (;0;) (func (result string))) - (alias core export 2 "foo:foo/new#foo" (core func (;3;))) - (alias core export 2 "cabi_post_foo:foo/new#foo" (core func (;4;))) - (func (;0;) (type 0) (canon lift (core func 3) (memory 0) string-encoding=utf8 (post-return 4))) + (alias core export 2 "foo:foo/new#foo" (core func (;2;))) + (alias core export 2 "cabi_post_foo:foo/new#foo" (core func (;3;))) + (func (;0;) (type 0) (canon lift (core func 2) (memory 0) string-encoding=utf8 (post-return 3))) (component (;0;) (type (;0;) (func (result string))) (import "import-func-foo" (func (;0;) (type 0))) diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat index 71433f932d..cfeae5bdeb 100644 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat @@ -88,26 +88,26 @@ (with "foo:foo/adapter-imports" (instance 3)) ) ) - (alias core export 4 "cabi_export_realloc" (core func (;2;))) (alias core export 0 "$imports" (core table (;0;))) - (core func (;3;) (canon lower (func 0) (memory 0) string-encoding=utf8)) + (core func (;2;) (canon lower (func 0) (memory 0) string-encoding=utf8)) (alias export 0 "foo" (func (;1;))) - (core func (;4;) (canon lower (func 1) (memory 0) string-encoding=utf8)) + (core func (;3;) (canon lower (func 1) (memory 0) string-encoding=utf8)) (core instance (;5;) (export "$imports" (table 0)) - (export "0" (func 3)) - (export "1" (func 4)) + (export "0" (func 2)) + (export "1" (func 3)) ) (core instance (;6;) (instantiate 3 (with "" (instance 5)) ) ) (type (;2;) (func)) - (alias core export 2 "bar" (core func (;5;))) - (func (;2;) (type 2) (canon lift (core func 5))) + (alias core export 2 "bar" (core func (;4;))) + (func (;2;) (type 2) (canon lift (core func 4))) (export (;3;) "bar" (func 2)) - (alias core export 4 "adapter-bar" (core func (;6;))) - (func (;4;) (type 1) (canon lift (core func 6) (memory 0) (realloc 2) string-encoding=utf8)) + (alias core export 4 "adapter-bar" (core func (;5;))) + (alias core export 4 "cabi_export_realloc" (core func (;6;))) + (func (;4;) (type 1) (canon lift (core func 5) (memory 0) (realloc 6) string-encoding=utf8)) (export (;5;) "adapter-bar" (func 4)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wat b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wat index 63b6159356..9642506e48 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wat +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wat @@ -33,7 +33,7 @@ (type (;3;) (func)) (import "env" "memory" (memory (;0;) 0)) (import "new" "get-two" (func $get_two (;0;) (type 0))) - (import "__main_module__" "cabi_realloc" (func $cabi_realloc (;1;) (type 1))) + (import "__main_module__" "cabi_realloc_adapter" (func $cabi_realloc (;1;) (type 1))) (global $__stack_pointer (;0;) (mut i32) i32.const 0) (global $some_other_mutable_global (;1;) (mut i32) i32.const 0) (global $allocation_state (;2;) (mut i32) i32.const 0) @@ -98,18 +98,18 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-get-two)) - (export "1" (func $adapt-old-get_sum)) + (export "0" (func $adapt-old-get_sum)) + (export "1" (func $indirect-new-get-two)) (export "$imports" (table 0)) - (func $indirect-new-get-two (;0;) (type 0) (param i32) - local.get 0 + (func $adapt-old-get_sum (;0;) (type 0) (result i32) i32.const 0 call_indirect (type 0) ) - (func $adapt-old-get_sum (;1;) (type 1) (result i32) + (func $indirect-new-get-two (;1;) (type 1) (param i32) + local.get 0 i32.const 1 call_indirect (type 1) ) @@ -118,8 +118,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -129,7 +129,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "get_sum" (func 0)) ) @@ -138,32 +138,31 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) - (alias core export 2 "cabi_realloc_adapter" (core func (;2;))) (core instance (;3;) - (export "cabi_realloc" (func 2)) + (export "memory" (memory 0)) ) + (alias core export 0 "1" (core func (;1;))) (core instance (;4;) - (export "memory" (memory 0)) + (export "get-two" (func 1)) ) - (alias core export 0 "0" (core func (;3;))) + (alias core export 2 "cabi_realloc_adapter" (core func (;2;))) (core instance (;5;) - (export "get-two" (func 3)) + (export "cabi_realloc_adapter" (func 2)) ) (core instance (;6;) (instantiate 1 - (with "__main_module__" (instance 3)) - (with "env" (instance 4)) - (with "new" (instance 5)) + (with "env" (instance 3)) + (with "new" (instance 4)) + (with "__main_module__" (instance 5)) ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 6 "get_sum" (core func (;3;))) (alias export 0 "get-two" (func (;0;))) (core func (;4;) (canon lower (func 0) (memory 0))) - (alias core export 6 "get_sum" (core func (;5;))) (core instance (;7;) (export "$imports" (table 0)) - (export "0" (func 4)) - (export "1" (func 5)) + (export "0" (func 3)) + (export "1" (func 4)) ) (core instance (;8;) (instantiate 3 (with "" (instance 7)) diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wat b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wat index 203e7fb21b..4a1f093682 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wat +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wat @@ -140,18 +140,18 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-get-two)) - (export "1" (func $adapt-old-get_sum)) + (export "0" (func $adapt-old-get_sum)) + (export "1" (func $indirect-new-get-two)) (export "$imports" (table 0)) - (func $indirect-new-get-two (;0;) (type 0) (param i32) - local.get 0 + (func $adapt-old-get_sum (;0;) (type 0) (result i32) i32.const 0 call_indirect (type 0) ) - (func $adapt-old-get_sum (;1;) (type 1) (result i32) + (func $indirect-new-get-two (;1;) (type 1) (param i32) + local.get 0 i32.const 1 call_indirect (type 1) ) @@ -160,8 +160,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -171,7 +171,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "get_sum" (func 0)) ) @@ -180,32 +180,31 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) - (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;3;) - (export "cabi_realloc" (func 2)) + (export "memory" (memory 0)) ) + (alias core export 0 "1" (core func (;1;))) (core instance (;4;) - (export "memory" (memory 0)) + (export "get-two" (func 1)) ) - (alias core export 0 "0" (core func (;3;))) + (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;5;) - (export "get-two" (func 3)) + (export "cabi_realloc" (func 2)) ) (core instance (;6;) (instantiate 1 - (with "__main_module__" (instance 3)) - (with "env" (instance 4)) - (with "new" (instance 5)) + (with "env" (instance 3)) + (with "new" (instance 4)) + (with "__main_module__" (instance 5)) ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 6 "get_sum" (core func (;3;))) (alias export 0 "get-two" (func (;0;))) (core func (;4;) (canon lower (func 0) (memory 0))) - (alias core export 6 "get_sum" (core func (;5;))) (core instance (;7;) (export "$imports" (table 0)) - (export "0" (func 4)) - (export "1" (func 5)) + (export "0" (func 3)) + (export "1" (func 4)) ) (core instance (;8;) (instantiate 3 (with "" (instance 7)) diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wat b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wat index 742a885bed..0e203d7c4d 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wat +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wat @@ -123,18 +123,18 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-get-two)) - (export "1" (func $adapt-old-get_sum)) + (export "0" (func $adapt-old-get_sum)) + (export "1" (func $indirect-new-get-two)) (export "$imports" (table 0)) - (func $indirect-new-get-two (;0;) (type 0) (param i32) - local.get 0 + (func $adapt-old-get_sum (;0;) (type 0) (result i32) i32.const 0 call_indirect (type 0) ) - (func $adapt-old-get_sum (;1;) (type 1) (result i32) + (func $indirect-new-get-two (;1;) (type 1) (param i32) + local.get 0 i32.const 1 call_indirect (type 1) ) @@ -143,8 +143,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -154,7 +154,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "get_sum" (func 0)) ) @@ -163,32 +163,31 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) - (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;3;) - (export "cabi_realloc" (func 2)) + (export "memory" (memory 0)) ) + (alias core export 0 "1" (core func (;1;))) (core instance (;4;) - (export "memory" (memory 0)) + (export "get-two" (func 1)) ) - (alias core export 0 "0" (core func (;3;))) + (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;5;) - (export "get-two" (func 3)) + (export "cabi_realloc" (func 2)) ) (core instance (;6;) (instantiate 1 - (with "__main_module__" (instance 3)) - (with "env" (instance 4)) - (with "new" (instance 5)) + (with "env" (instance 3)) + (with "new" (instance 4)) + (with "__main_module__" (instance 5)) ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 6 "get_sum" (core func (;3;))) (alias export 0 "get-two" (func (;0;))) (core func (;4;) (canon lower (func 0) (memory 0))) - (alias core export 6 "get_sum" (core func (;5;))) (core instance (;7;) (export "$imports" (table 0)) - (export "0" (func 4)) - (export "1" (func 5)) + (export "0" (func 3)) + (export "1" (func 4)) ) (core instance (;8;) (instantiate 3 (with "" (instance 7)) diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wat b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wat index 3f853cd333..f5bb663626 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wat +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wat @@ -111,18 +111,18 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-get-two)) - (export "1" (func $adapt-old-get_sum)) + (export "0" (func $adapt-old-get_sum)) + (export "1" (func $indirect-new-get-two)) (export "$imports" (table 0)) - (func $indirect-new-get-two (;0;) (type 0) (param i32) - local.get 0 + (func $adapt-old-get_sum (;0;) (type 0) (result i32) i32.const 0 call_indirect (type 0) ) - (func $adapt-old-get_sum (;1;) (type 1) (result i32) + (func $indirect-new-get-two (;1;) (type 1) (param i32) + local.get 0 i32.const 1 call_indirect (type 1) ) @@ -131,8 +131,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -142,7 +142,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "get_sum" (func 0)) ) @@ -151,32 +151,31 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) - (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;3;) - (export "cabi_realloc" (func 2)) + (export "memory" (memory 0)) ) + (alias core export 0 "1" (core func (;1;))) (core instance (;4;) - (export "memory" (memory 0)) + (export "get-two" (func 1)) ) - (alias core export 0 "0" (core func (;3;))) + (alias core export 2 "cabi_realloc" (core func (;2;))) (core instance (;5;) - (export "get-two" (func 3)) + (export "cabi_realloc" (func 2)) ) (core instance (;6;) (instantiate 1 - (with "__main_module__" (instance 3)) - (with "env" (instance 4)) - (with "new" (instance 5)) + (with "env" (instance 3)) + (with "new" (instance 4)) + (with "__main_module__" (instance 5)) ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 6 "get_sum" (core func (;3;))) (alias export 0 "get-two" (func (;0;))) (core func (;4;) (canon lower (func 0) (memory 0))) - (alias core export 6 "get_sum" (core func (;5;))) (core instance (;7;) (export "$imports" (table 0)) - (export "0" (func 4)) - (export "1" (func 5)) + (export "0" (func 3)) + (export "1" (func 4)) ) (core instance (;8;) (instantiate 3 (with "" (instance 7)) diff --git a/crates/wit-component/tests/components/adapt-inject-stack/component.wat b/crates/wit-component/tests/components/adapt-inject-stack/component.wat index e079fa0861..58424fc592 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack/component.wat +++ b/crates/wit-component/tests/components/adapt-inject-stack/component.wat @@ -92,18 +92,18 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-get-two)) - (export "1" (func $adapt-old-get_sum)) + (export "0" (func $adapt-old-get_sum)) + (export "1" (func $indirect-new-get-two)) (export "$imports" (table 0)) - (func $indirect-new-get-two (;0;) (type 0) (param i32) - local.get 0 + (func $adapt-old-get_sum (;0;) (type 0) (result i32) i32.const 0 call_indirect (type 0) ) - (func $adapt-old-get_sum (;1;) (type 1) (result i32) + (func $indirect-new-get-two (;1;) (type 1) (param i32) + local.get 0 i32.const 1 call_indirect (type 1) ) @@ -112,8 +112,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (result i32))) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -123,7 +123,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "get_sum" (func 0)) ) @@ -135,7 +135,7 @@ (core instance (;3;) (export "memory" (memory 0)) ) - (alias core export 0 "0" (core func (;1;))) + (alias core export 0 "1" (core func (;1;))) (core instance (;4;) (export "get-two" (func 1)) ) @@ -145,9 +145,9 @@ ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 5 "get_sum" (core func (;2;))) (alias export 0 "get-two" (func (;0;))) - (core func (;2;) (canon lower (func 0) (memory 0))) - (alias core export 5 "get_sum" (core func (;3;))) + (core func (;3;) (canon lower (func 0) (memory 0))) (core instance (;6;) (export "$imports" (table 0)) (export "0" (func 2)) diff --git a/crates/wit-component/tests/components/adapt-list-return/component.wat b/crates/wit-component/tests/components/adapt-list-return/component.wat index b17f062c44..e20a6fc059 100644 --- a/crates/wit-component/tests/components/adapt-list-return/component.wat +++ b/crates/wit-component/tests/components/adapt-list-return/component.wat @@ -34,20 +34,20 @@ ) ) (core module (;2;) - (type (;0;) (func (param i32))) - (type (;1;) (func (param i32 i32))) + (type (;0;) (func (param i32 i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-read)) - (export "1" (func $adapt-old-read)) + (export "0" (func $adapt-old-read)) + (export "1" (func $indirect-new-read)) (export "$imports" (table 0)) - (func $indirect-new-read (;0;) (type 0) (param i32) + (func $adapt-old-read (;0;) (type 0) (param i32 i32) local.get 0 + local.get 1 i32.const 0 call_indirect (type 0) ) - (func $adapt-old-read (;1;) (type 1) (param i32 i32) + (func $indirect-new-read (;1;) (type 1) (param i32) local.get 0 - local.get 1 i32.const 1 call_indirect (type 1) ) @@ -56,8 +56,8 @@ ) ) (core module (;3;) - (type (;0;) (func (param i32))) - (type (;1;) (func (param i32 i32))) + (type (;0;) (func (param i32 i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -67,7 +67,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "read" (func 0)) ) @@ -76,7 +76,7 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 0 "0" (core func (;1;))) + (alias core export 0 "1" (core func (;1;))) (core instance (;3;) (export "read" (func 1)) ) @@ -84,14 +84,14 @@ (with "new" (instance 3)) ) ) - (alias core export 4 "cabi_import_realloc" (core func (;2;))) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 4 "read" (core func (;2;))) (alias export 0 "read" (func (;0;))) - (core func (;3;) (canon lower (func 0) (memory 0) (realloc 2))) - (alias core export 4 "read" (core func (;4;))) + (alias core export 4 "cabi_import_realloc" (core func (;3;))) + (core func (;4;) (canon lower (func 0) (memory 0) (realloc 3))) (core instance (;5;) (export "$imports" (table 0)) - (export "0" (func 3)) + (export "0" (func 2)) (export "1" (func 4)) ) (core instance (;6;) (instantiate 3 diff --git a/crates/wit-component/tests/components/adapt-memory-simple/component.wat b/crates/wit-component/tests/components/adapt-memory-simple/component.wat index d9c66b07d5..99630efcf6 100644 --- a/crates/wit-component/tests/components/adapt-memory-simple/component.wat +++ b/crates/wit-component/tests/components/adapt-memory-simple/component.wat @@ -25,16 +25,16 @@ (type (;0;) (func (param i32 i32))) (type (;1;) (func (param i32 i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-new-log)) - (export "1" (func $adapt-old-log)) + (export "0" (func $adapt-old-log)) + (export "1" (func $indirect-new-log)) (export "$imports" (table 0)) - (func $indirect-new-log (;0;) (type 0) (param i32 i32) + (func $adapt-old-log (;0;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 0 call_indirect (type 0) ) - (func $adapt-old-log (;1;) (type 1) (param i32 i32) + (func $indirect-new-log (;1;) (type 1) (param i32 i32) local.get 0 local.get 1 i32.const 1 @@ -56,7 +56,7 @@ ) ) (core instance (;0;) (instantiate 2)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "log" (func 0)) ) @@ -65,7 +65,7 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 0 "0" (core func (;1;))) + (alias core export 0 "1" (core func (;1;))) (core instance (;3;) (export "log" (func 1)) ) @@ -74,9 +74,9 @@ ) ) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 4 "log" (core func (;2;))) (alias export 0 "log" (func (;0;))) - (core func (;2;) (canon lower (func 0) (memory 0) string-encoding=utf8)) - (alias core export 4 "log" (core func (;3;))) + (core func (;3;) (canon lower (func 0) (memory 0) string-encoding=utf8)) (core instance (;5;) (export "$imports" (table 0)) (export "0" (func 2)) diff --git a/crates/wit-component/tests/components/adapt-stub-wasip2/component.wat b/crates/wit-component/tests/components/adapt-stub-wasip2/component.wat index d9626c0e18..2aaeb87e35 100644 --- a/crates/wit-component/tests/components/adapt-stub-wasip2/component.wat +++ b/crates/wit-component/tests/components/adapt-stub-wasip2/component.wat @@ -57,13 +57,12 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) (core instance (;3;) (instantiate 1)) (alias core export 0 "$imports" (core table (;0;))) - (alias core export 3 "get-environment" (core func (;2;))) + (alias core export 3 "get-environment" (core func (;1;))) (core instance (;4;) (export "$imports" (table 0)) - (export "0" (func 2)) + (export "0" (func 1)) ) (core instance (;5;) (instantiate 3 (with "" (instance 4)) diff --git a/crates/wit-component/tests/components/bare-funcs/component.wat b/crates/wit-component/tests/components/bare-funcs/component.wat index c29a8722c8..091b823615 100644 --- a/crates/wit-component/tests/components/bare-funcs/component.wat +++ b/crates/wit-component/tests/components/bare-funcs/component.wat @@ -66,8 +66,8 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;2;))) (alias core export 0 "$imports" (core table (;0;))) + (alias core export 2 "cabi_realloc" (core func (;2;))) (core func (;3;) (canon lower (func 1) (memory 0) (realloc 2) string-encoding=utf8)) (core instance (;3;) (export "$imports" (table 0)) diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat index 50cf12585a..38cf03265b 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat +++ b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat @@ -39,10 +39,10 @@ ) ) (alias core export 1 "memory" (core memory (;0;))) - (alias core export 1 "cabi_realloc" (core func (;1;))) (type (;1;) (func (param "b" u8))) - (alias core export 1 "a" (core func (;2;))) - (func (;1;) (type 1) (canon lift (core func 2))) + (alias core export 1 "a" (core func (;1;))) + (alias core export 1 "cabi_realloc" (core func (;2;))) + (func (;1;) (type 1) (canon lift (core func 1))) (export (;2;) "a" (func 1)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt index 72264c4a30..e223246a10 100644 --- a/crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt +++ b/crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: type mismatch for function `a`: expected `[I32, I32] -> [I32]` but found `[] -> []` \ No newline at end of file +failed to decode world from module: module was not valid: failed to validate export for `a`: type mismatch for function `a`: expected `[I32, I32] -> [I32]` but found `[] -> []` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-empty-module-import/error.txt b/crates/wit-component/tests/components/error-empty-module-import/error.txt index f68bb1b668..d19c5d6f44 100644 --- a/crates/wit-component/tests/components/error-empty-module-import/error.txt +++ b/crates/wit-component/tests/components/error-empty-module-import/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: no top-level imported function `foo` specified \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `$root::foo`: no top-level imported function `foo` specified \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-export-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-export-sig-mismatch/error.txt index 3b1c6afaab..548e42b291 100644 --- a/crates/wit-component/tests/components/error-export-sig-mismatch/error.txt +++ b/crates/wit-component/tests/components/error-export-sig-mismatch/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: failed to validate exported interface `foo`: type mismatch for function `a`: expected `[I32, I32] -> [I32]` but found `[] -> []` \ No newline at end of file +failed to decode world from module: module was not valid: failed to validate export for `foo`: type mismatch for function `a`: expected `[I32, I32] -> [I32]` but found `[] -> []` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-import-resource-rep/error.txt b/crates/wit-component/tests/components/error-import-resource-rep/error.txt index 7dd176e603..96ec0d40c9 100644 --- a/crates/wit-component/tests/components/error-import-resource-rep/error.txt +++ b/crates/wit-component/tests/components/error-import-resource-rep/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: no top-level imported function `[resource-rep]a` specified \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `$root::[resource-rep]a`: no top-level imported function `[resource-rep]a` specified \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-import-resource-wrong-signature/error.txt b/crates/wit-component/tests/components/error-import-resource-wrong-signature/error.txt index d7eaac43fa..a79d143c61 100644 --- a/crates/wit-component/tests/components/error-import-resource-wrong-signature/error.txt +++ b/crates/wit-component/tests/components/error-import-resource-wrong-signature/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: type mismatch for function `[resource-drop]a`: expected `[I32] -> []` but found `[I32] -> [I32]` \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `$root::[resource-drop]a`: type mismatch for function `[resource-drop]a`: expected `[I32] -> []` but found `[I32] -> [I32]` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-import-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-import-sig-mismatch/error.txt index 41ba5e7720..3dd7680ff8 100644 --- a/crates/wit-component/tests/components/error-import-sig-mismatch/error.txt +++ b/crates/wit-component/tests/components/error-import-sig-mismatch/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: failed to validate import interface `foo`: type mismatch for function `bar`: expected `[I32, I32] -> []` but found `[] -> []` \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `foo::bar`: failed to validate import interface `foo`: type mismatch for function `bar`: expected `[I32, I32] -> []` but found `[] -> []` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-invalid-module-import/error.txt b/crates/wit-component/tests/components/error-invalid-module-import/error.txt index 4c5195ec6c..83b5393bc8 100644 --- a/crates/wit-component/tests/components/error-invalid-module-import/error.txt +++ b/crates/wit-component/tests/components/error-invalid-module-import/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: module is only allowed to import functions \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `::`: module is only allowed to import functions \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-missing-default-export/error.txt b/crates/wit-component/tests/components/error-missing-default-export/error.txt index cd0b78a041..0c9b4e921b 100644 --- a/crates/wit-component/tests/components/error-missing-default-export/error.txt +++ b/crates/wit-component/tests/components/error-missing-default-export/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: module does not export required function `a` \ No newline at end of file +failed to decode world from module: module was not valid: failed to find export of function `a` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-missing-export/error.txt b/crates/wit-component/tests/components/error-missing-export/error.txt index 0829150ee5..fe3665353b 100644 --- a/crates/wit-component/tests/components/error-missing-export/error.txt +++ b/crates/wit-component/tests/components/error-missing-export/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: failed to validate exported interface `foo`: module does not export required function `foo#a` \ No newline at end of file +failed to decode world from module: module was not valid: failed to find export of interface `foo` function `a` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-missing-import-func/error.txt b/crates/wit-component/tests/components/error-missing-import-func/error.txt index b6f4f0dd5d..c70df83372 100644 --- a/crates/wit-component/tests/components/error-missing-import-func/error.txt +++ b/crates/wit-component/tests/components/error-missing-import-func/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: module requires an import interface named `foo` \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `foo::bar`: module requires an import interface named `foo` \ No newline at end of file diff --git a/crates/wit-component/tests/components/error-missing-import/error.txt b/crates/wit-component/tests/components/error-missing-import/error.txt index b6f4f0dd5d..c70df83372 100644 --- a/crates/wit-component/tests/components/error-missing-import/error.txt +++ b/crates/wit-component/tests/components/error-missing-import/error.txt @@ -1 +1 @@ -failed to decode world from module: module was not valid: module requires an import interface named `foo` \ No newline at end of file +failed to decode world from module: module was not valid: failed to resolve import `foo::bar`: module requires an import interface named `foo` \ No newline at end of file diff --git a/crates/wit-component/tests/components/export-resource/component.wat b/crates/wit-component/tests/components/export-resource/component.wat index 6fa1d68e02..0ae882efbb 100644 --- a/crates/wit-component/tests/components/export-resource/component.wat +++ b/crates/wit-component/tests/components/export-resource/component.wat @@ -26,9 +26,9 @@ (core module (;1;) (type (;0;) (func (param i32))) (table (;0;) 1 1 funcref) - (export "0" (func $"dtor-[export]foo-a")) + (export "0" (func $dtor-a)) (export "$imports" (table 0)) - (func $"dtor-[export]foo-a" (;0;) (type 0) (param i32) + (func $dtor-a (;0;) (type 0) (param i32) local.get 0 i32.const 0 call_indirect (type 0) @@ -49,13 +49,13 @@ (core instance (;0;) (instantiate 1)) (alias core export 0 "0" (core func (;0;))) (type (;0;) (resource (rep i32) (dtor (func 0)))) - (core func (;1;) (canon resource.drop 0)) + (core func (;1;) (canon resource.new 0)) (core func (;2;) (canon resource.rep 0)) - (core func (;3;) (canon resource.new 0)) + (core func (;3;) (canon resource.drop 0)) (core instance (;1;) - (export "[resource-drop]a" (func 1)) + (export "[resource-new]a" (func 1)) (export "[resource-rep]a" (func 2)) - (export "[resource-new]a" (func 3)) + (export "[resource-drop]a" (func 3)) ) (core instance (;2;) (instantiate 0 (with "[export]foo" (instance 1)) diff --git a/crates/wit-component/tests/components/exports/component.wat b/crates/wit-component/tests/components/exports/component.wat index 88a6a82271..1410510fc9 100644 --- a/crates/wit-component/tests/components/exports/component.wat +++ b/crates/wit-component/tests/components/exports/component.wat @@ -60,10 +60,10 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "cabi_realloc" (core func (;0;))) (type (;0;) (func)) - (alias core export 0 "a" (core func (;1;))) - (func (;0;) (type 0) (canon lift (core func 1))) + (alias core export 0 "a" (core func (;0;))) + (alias core export 0 "cabi_realloc" (core func (;1;))) + (func (;0;) (type 0) (canon lift (core func 0))) (export (;1;) "a" (func 0)) (type (;1;) (func (param "a" s8) (param "b" s16) (param "c" s32) (param "d" s64) (result string))) (alias core export 0 "b" (core func (;2;))) @@ -102,11 +102,11 @@ (type (;8;) (func (param "x" string) (result 7))) (alias core export 0 "foo#b" (core func (;7;))) (alias core export 0 "cabi_post_foo#b" (core func (;8;))) - (func (;8;) (type 8) (canon lift (core func 7) (memory 0) (realloc 0) string-encoding=utf8 (post-return 8))) + (func (;8;) (type 8) (canon lift (core func 7) (memory 0) (realloc 1) string-encoding=utf8 (post-return 8))) (type (;9;) (func (param "x" 7) (result string))) (alias core export 0 "foo#c" (core func (;9;))) (alias core export 0 "cabi_post_foo#c" (core func (;10;))) - (func (;9;) (type 9) (canon lift (core func 9) (memory 0) (realloc 0) string-encoding=utf8 (post-return 10))) + (func (;9;) (type 9) (canon lift (core func 9) (memory 0) (realloc 1) string-encoding=utf8 (post-return 10))) (component (;1;) (type (;0;) (func)) (import "import-func-a" (func (;0;) (type 0))) diff --git a/crates/wit-component/tests/components/import-and-export-resource/component.wat b/crates/wit-component/tests/components/import-and-export-resource/component.wat index a2bf92b192..836877ef30 100644 --- a/crates/wit-component/tests/components/import-and-export-resource/component.wat +++ b/crates/wit-component/tests/components/import-and-export-resource/component.wat @@ -19,15 +19,15 @@ (processed-by "my-fake-bindgen" "123.45") ) ) - (alias export 0 "a" (type (;3;))) - (core func (;0;) (canon resource.drop 3)) + (type (;3;) (resource (rep i32))) + (alias export 0 "a" (type (;4;))) + (core func (;0;) (canon resource.drop 4)) (core instance (;0;) (export "[resource-drop]a" (func 0)) ) - (type (;4;) (resource (rep i32))) - (core func (;1;) (canon resource.drop 4)) - (core func (;2;) (canon resource.rep 4)) - (core func (;3;) (canon resource.new 4)) + (core func (;1;) (canon resource.drop 3)) + (core func (;2;) (canon resource.rep 3)) + (core func (;3;) (canon resource.new 3)) (core instance (;1;) (export "[resource-drop]a" (func 1)) (export "[resource-rep]a" (func 2)) @@ -43,7 +43,7 @@ (export (;1;) "a" (type 0)) ) (instance (;1;) (instantiate 0 - (with "import-type-a" (type 4)) + (with "import-type-a" (type 3)) ) ) (export (;2;) "foo:bar/foo" (instance 1)) diff --git a/crates/wit-component/tests/components/import-conflict/component.wat b/crates/wit-component/tests/components/import-conflict/component.wat index 6bc1dc93d6..e5b1b0e629 100644 --- a/crates/wit-component/tests/components/import-conflict/component.wat +++ b/crates/wit-component/tests/components/import-conflict/component.wat @@ -97,9 +97,9 @@ ) ) (alias core export 4 "memory" (core memory (;0;))) - (alias core export 4 "cabi_realloc" (core func (;3;))) (alias core export 0 "$imports" (core table (;0;))) (alias export 0 "a" (func (;1;))) + (alias core export 4 "cabi_realloc" (core func (;3;))) (core func (;4;) (canon lower (func 1) (memory 0) string-encoding=utf8)) (alias export 1 "baz" (func (;2;))) (core func (;5;) (canon lower (func 2) (memory 0) (realloc 3))) diff --git a/crates/wit-component/tests/components/import-export/component.wat b/crates/wit-component/tests/components/import-export/component.wat index 5d6745a7c1..88311a53d4 100644 --- a/crates/wit-component/tests/components/import-export/component.wat +++ b/crates/wit-component/tests/components/import-export/component.wat @@ -77,9 +77,9 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) (alias core export 0 "$imports" (core table (;0;))) (alias export 0 "a" (func (;0;))) + (alias core export 2 "cabi_realloc" (core func (;1;))) (core func (;2;) (canon lower (func 0) (memory 0) (realloc 1) string-encoding=utf8)) (core instance (;3;) (export "$imports" (table 0)) diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat index 6adc2ff289..539b64713f 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat @@ -93,9 +93,9 @@ (table (;0;) 5 5 funcref) (export "0" (func $indirect-foo:shared-dependency/doc-g1)) (export "1" (func $indirect-foo:shared-dependency/doc-g2)) - (export "2" (func $"#func2 indirect-foo:shared-dependency/doc-g1")) - (export "3" (func $indirect-foo:shared-dependency/doc-g3)) - (export "4" (func $adapt-old-adapter-f1)) + (export "2" (func $adapt-old-adapter-f1)) + (export "3" (func $"#func3 indirect-foo:shared-dependency/doc-g1")) + (export "4" (func $indirect-foo:shared-dependency/doc-g3)) (export "$imports" (table 0)) (func $indirect-foo:shared-dependency/doc-g1 (;0;) (type 0) (param i32) local.get 0 @@ -107,19 +107,19 @@ i32.const 1 call_indirect (type 0) ) - (func $"#func2 indirect-foo:shared-dependency/doc-g1" (@name "indirect-foo:shared-dependency/doc-g1") (;2;) (type 0) (param i32) - local.get 0 + (func $adapt-old-adapter-f1 (;2;) (type 1) i32.const 2 - call_indirect (type 0) + call_indirect (type 1) ) - (func $indirect-foo:shared-dependency/doc-g3 (;3;) (type 0) (param i32) + (func $"#func3 indirect-foo:shared-dependency/doc-g1" (@name "indirect-foo:shared-dependency/doc-g1") (;3;) (type 0) (param i32) local.get 0 i32.const 3 call_indirect (type 0) ) - (func $adapt-old-adapter-f1 (;4;) (type 1) + (func $indirect-foo:shared-dependency/doc-g3 (;4;) (type 0) (param i32) + local.get 0 i32.const 4 - call_indirect (type 1) + call_indirect (type 0) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") @@ -130,9 +130,9 @@ (type (;1;) (func)) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 0))) - (import "" "2" (func (;2;) (type 0))) + (import "" "2" (func (;2;) (type 1))) (import "" "3" (func (;3;) (type 0))) - (import "" "4" (func (;4;) (type 1))) + (import "" "4" (func (;4;) (type 0))) (import "" "$imports" (table (;0;) 5 5 funcref)) (elem (;0;) (i32.const 0) func 0 1 2 3 4) (@producers @@ -152,61 +152,61 @@ (export "g1" (func 2)) (export "g2" (func 3)) ) - (alias export 2 "foo" (func (;2;))) - (core func (;4;) (canon lower (func 2))) + (alias core export 0 "2" (core func (;4;))) (core instance (;2;) - (export "foo" (func 4)) + (export "adapter-f1" (func 4)) ) - (alias core export 0 "4" (core func (;5;))) + (alias export 2 "foo" (func (;2;))) + (core func (;5;) (canon lower (func 2))) (core instance (;3;) - (export "adapter-f1" (func 5)) + (export "foo" (func 5)) ) (core instance (;4;) (instantiate 0 (with "foo:shared-dependency/doc" (instance 1)) - (with "main-dep" (instance 2)) - (with "old" (instance 3)) + (with "old" (instance 2)) + (with "main-dep" (instance 3)) ) ) (alias core export 4 "memory" (core memory (;0;))) - (alias core export 4 "cabi_realloc" (core func (;6;))) (alias export 0 "f1" (func (;3;))) - (core func (;7;) (canon lower (func 3))) + (core func (;6;) (canon lower (func 3))) (alias export 0 "f3" (func (;4;))) - (core func (;8;) (canon lower (func 4))) - (alias core export 0 "2" (core func (;9;))) - (alias core export 0 "3" (core func (;10;))) + (core func (;7;) (canon lower (func 4))) + (alias core export 0 "3" (core func (;8;))) + (alias core export 0 "4" (core func (;9;))) (core instance (;5;) - (export "f1" (func 7)) - (export "f3" (func 8)) - (export "g1" (func 9)) - (export "g3" (func 10)) + (export "f1" (func 6)) + (export "f3" (func 7)) + (export "g1" (func 8)) + (export "g3" (func 9)) ) (alias export 3 "foo" (func (;5;))) - (core func (;11;) (canon lower (func 5))) + (core func (;10;) (canon lower (func 5))) (core instance (;6;) - (export "foo" (func 11)) + (export "foo" (func 10)) ) (core instance (;7;) (instantiate 1 (with "foo:shared-dependency/doc" (instance 5)) (with "adapter-dep" (instance 6)) ) ) - (alias core export 7 "cabi_import_realloc" (core func (;12;))) (alias core export 0 "$imports" (core table (;0;))) (alias export 0 "g1" (func (;6;))) - (core func (;13;) (canon lower (func 6) (memory 0) (realloc 6) string-encoding=utf8)) + (alias core export 4 "cabi_realloc" (core func (;11;))) + (core func (;12;) (canon lower (func 6) (memory 0) (realloc 11) string-encoding=utf8)) (alias export 0 "g2" (func (;7;))) - (core func (;14;) (canon lower (func 7) (memory 0) (realloc 6) string-encoding=utf8)) + (core func (;13;) (canon lower (func 7) (memory 0) (realloc 11) string-encoding=utf8)) + (alias core export 7 "adapter-f1" (core func (;14;))) (alias export 0 "g1" (func (;8;))) - (core func (;15;) (canon lower (func 8) (memory 0) (realloc 12) string-encoding=utf8)) + (alias core export 7 "cabi_import_realloc" (core func (;15;))) + (core func (;16;) (canon lower (func 8) (memory 0) (realloc 15) string-encoding=utf8)) (alias export 0 "g3" (func (;9;))) - (core func (;16;) (canon lower (func 9) (memory 0) (realloc 12) string-encoding=utf8)) - (alias core export 7 "adapter-f1" (core func (;17;))) + (core func (;17;) (canon lower (func 9) (memory 0) (realloc 15) string-encoding=utf8)) (core instance (;8;) (export "$imports" (table 0)) - (export "0" (func 13)) - (export "1" (func 14)) - (export "2" (func 15)) + (export "0" (func 12)) + (export "1" (func 13)) + (export "2" (func 14)) (export "3" (func 16)) (export "4" (func 17)) ) diff --git a/crates/wit-component/tests/components/import-resource-in-interface/component.wat b/crates/wit-component/tests/components/import-resource-in-interface/component.wat index 87ad873da6..60e0cbb845 100644 --- a/crates/wit-component/tests/components/import-resource-in-interface/component.wat +++ b/crates/wit-component/tests/components/import-resource-in-interface/component.wat @@ -20,16 +20,16 @@ (processed-by "my-fake-bindgen" "123.45") ) ) - (alias export 0 "a" (type (;1;))) - (core func (;0;) (canon resource.drop 1)) (alias export 0 "[constructor]a" (func (;0;))) - (core func (;1;) (canon lower (func 0))) + (core func (;0;) (canon lower (func 0))) (alias export 0 "[static]a.other-new" (func (;1;))) - (core func (;2;) (canon lower (func 1))) + (core func (;1;) (canon lower (func 1))) + (alias export 0 "a" (type (;1;))) + (core func (;2;) (canon resource.drop 1)) (core instance (;0;) - (export "[resource-drop]a" (func 0)) - (export "[constructor]a" (func 1)) - (export "[static]a.other-new" (func 2)) + (export "[constructor]a" (func 0)) + (export "[static]a.other-new" (func 1)) + (export "[resource-drop]a" (func 2)) ) (core instance (;1;) (instantiate 0 (with "foo" (instance 0)) diff --git a/crates/wit-component/tests/components/import-resource-simple/component.wat b/crates/wit-component/tests/components/import-resource-simple/component.wat index 7fa9207f93..c05f9818da 100644 --- a/crates/wit-component/tests/components/import-resource-simple/component.wat +++ b/crates/wit-component/tests/components/import-resource-simple/component.wat @@ -15,13 +15,13 @@ (processed-by "my-fake-bindgen" "123.45") ) ) - (core func (;0;) (canon resource.drop 0)) - (core func (;1;) (canon lower (func 0))) - (core func (;2;) (canon lower (func 1))) + (core func (;0;) (canon lower (func 0))) + (core func (;1;) (canon lower (func 1))) + (core func (;2;) (canon resource.drop 0)) (core instance (;0;) - (export "[resource-drop]a" (func 0)) - (export "[constructor]a" (func 1)) - (export "[static]a.other-new" (func 2)) + (export "[constructor]a" (func 0)) + (export "[static]a.other-new" (func 1)) + (export "[resource-drop]a" (func 2)) ) (core instance (;1;) (instantiate 0 (with "$root" (instance 0)) diff --git a/crates/wit-component/tests/components/imports/component.wat b/crates/wit-component/tests/components/imports/component.wat index b9404b7ee6..b0e2feb9df 100644 --- a/crates/wit-component/tests/components/imports/component.wat +++ b/crates/wit-component/tests/components/imports/component.wat @@ -128,9 +128,9 @@ ) ) (alias core export 4 "memory" (core memory (;0;))) - (alias core export 4 "cabi_realloc" (core func (;8;))) (alias core export 0 "$imports" (core table (;0;))) (alias export 0 "bar1" (func (;6;))) + (alias core export 4 "cabi_realloc" (core func (;8;))) (core func (;9;) (canon lower (func 6) (memory 0) string-encoding=utf8)) (alias export 1 "baz1" (func (;7;))) (core func (;10;) (canon lower (func 7) (memory 0) string-encoding=utf8)) diff --git a/crates/wit-component/tests/components/lift-options/component.wat b/crates/wit-component/tests/components/lift-options/component.wat index 577d7e24f7..f56c0b8b38 100644 --- a/crates/wit-component/tests/components/lift-options/component.wat +++ b/crates/wit-component/tests/components/lift-options/component.wat @@ -99,22 +99,22 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "cabi_realloc" (core func (;0;))) (type (;0;) (func)) - (alias core export 0 "foo:foo/my-default#a" (core func (;1;))) - (func (;0;) (type 0) (canon lift (core func 1))) + (alias core export 0 "foo:foo/my-default#a" (core func (;0;))) + (alias core export 0 "cabi_realloc" (core func (;1;))) + (func (;0;) (type 0) (canon lift (core func 0))) (type (;1;) (list string)) (type (;2;) (func (param "x" 1))) (alias core export 0 "foo:foo/my-default#b" (core func (;2;))) - (func (;1;) (type 2) (canon lift (core func 2) (memory 0) (realloc 0) string-encoding=utf8)) + (func (;1;) (type 2) (canon lift (core func 2) (memory 0) (realloc 1) string-encoding=utf8)) (type (;3;) (record (field "s" string))) (type (;4;) (func (param "x" 3))) (alias core export 0 "foo:foo/my-default#c" (core func (;3;))) - (func (;2;) (type 4) (canon lift (core func 3) (memory 0) (realloc 0) string-encoding=utf8)) + (func (;2;) (type 4) (canon lift (core func 3) (memory 0) (realloc 1) string-encoding=utf8)) (type (;5;) (variant (case "s" string))) (type (;6;) (func (param "x" 5))) (alias core export 0 "foo:foo/my-default#d" (core func (;4;))) - (func (;3;) (type 6) (canon lift (core func 4) (memory 0) (realloc 0) string-encoding=utf8)) + (func (;3;) (type 6) (canon lift (core func 4) (memory 0) (realloc 1) string-encoding=utf8)) (type (;7;) (record (field "s" u32))) (type (;8;) (func (param "x" 7))) (alias core export 0 "foo:foo/my-default#e" (core func (;5;))) @@ -126,15 +126,15 @@ (type (;11;) (list 3)) (type (;12;) (func (param "x" 11))) (alias core export 0 "foo:foo/my-default#g" (core func (;7;))) - (func (;6;) (type 12) (canon lift (core func 7) (memory 0) (realloc 0) string-encoding=utf8)) + (func (;6;) (type 12) (canon lift (core func 7) (memory 0) (realloc 1) string-encoding=utf8)) (type (;13;) (list 5)) (type (;14;) (func (param "x" 13))) (alias core export 0 "foo:foo/my-default#h" (core func (;8;))) - (func (;7;) (type 14) (canon lift (core func 8) (memory 0) (realloc 0) string-encoding=utf8)) + (func (;7;) (type 14) (canon lift (core func 8) (memory 0) (realloc 1) string-encoding=utf8)) (type (;15;) (list u32)) (type (;16;) (func (param "x" 15))) (alias core export 0 "foo:foo/my-default#i" (core func (;9;))) - (func (;8;) (type 16) (canon lift (core func 9) (memory 0) (realloc 0))) + (func (;8;) (type 16) (canon lift (core func 9) (memory 0) (realloc 1))) (type (;17;) (func (param "x" u32))) (alias core export 0 "foo:foo/my-default#j" (core func (;10;))) (func (;9;) (type 17) (canon lift (core func 10))) diff --git a/crates/wit-component/tests/components/link-bare-funcs/component.wat b/crates/wit-component/tests/components/link-bare-funcs/component.wat index a0c6b7036c..97f0900574 100644 --- a/crates/wit-component/tests/components/link-bare-funcs/component.wat +++ b/crates/wit-component/tests/components/link-bare-funcs/component.wat @@ -106,22 +106,22 @@ ) ) (core module (;4;) - (type (;0;) (func (param i32))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) + (type (;0;) (func (param i32 i32 i32 i32) (result i32))) + (type (;1;) (func (param i32))) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-$root-bar)) - (export "1" (func $adapt-foo-cabi_realloc)) + (export "0" (func $adapt-foo-cabi_realloc)) + (export "1" (func $indirect-$root-bar)) (export "$imports" (table 0)) - (func $indirect-$root-bar (;0;) (type 0) (param i32) + (func $adapt-foo-cabi_realloc (;0;) (type 0) (param i32 i32 i32 i32) (result i32) local.get 0 + local.get 1 + local.get 2 + local.get 3 i32.const 0 call_indirect (type 0) ) - (func $adapt-foo-cabi_realloc (;1;) (type 1) (param i32 i32 i32 i32) (result i32) + (func $indirect-$root-bar (;1;) (type 1) (param i32) local.get 0 - local.get 1 - local.get 2 - local.get 3 i32.const 1 call_indirect (type 1) ) @@ -130,8 +130,8 @@ ) ) (core module (;5;) - (type (;0;) (func (param i32))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) + (type (;0;) (func (param i32 i32 i32 i32) (result i32))) + (type (;1;) (func (param i32))) (import "" "0" (func (;0;) (type 0))) (import "" "1" (func (;1;) (type 1))) (import "" "$imports" (table (;0;) 2 2 funcref)) @@ -141,7 +141,7 @@ ) ) (core instance (;0;) (instantiate 4)) - (alias core export 0 "1" (core func (;0;))) + (alias core export 0 "0" (core func (;0;))) (core instance (;1;) (export "cabi_realloc" (func 0)) ) diff --git a/crates/wit-component/tests/components/lower-options/component.wat b/crates/wit-component/tests/components/lower-options/component.wat index 9151756caf..fe5d16a7bf 100644 --- a/crates/wit-component/tests/components/lower-options/component.wat +++ b/crates/wit-component/tests/components/lower-options/component.wat @@ -233,9 +233,9 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;16;))) (alias core export 0 "$imports" (core table (;0;))) (alias export 0 "b" (func (;5;))) + (alias core export 2 "cabi_realloc" (core func (;16;))) (core func (;17;) (canon lower (func 5) (memory 0) string-encoding=utf8)) (alias export 0 "c" (func (;6;))) (core func (;18;) (canon lower (func 6) (memory 0) string-encoding=utf8)) diff --git a/crates/wit-component/tests/components/post-return/component.wat b/crates/wit-component/tests/components/post-return/component.wat index 3a800d0bb9..f4d8762a60 100644 --- a/crates/wit-component/tests/components/post-return/component.wat +++ b/crates/wit-component/tests/components/post-return/component.wat @@ -24,11 +24,11 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "cabi_realloc" (core func (;0;))) (type (;0;) (func (result string))) - (alias core export 0 "a" (core func (;1;))) + (alias core export 0 "a" (core func (;0;))) + (alias core export 0 "cabi_realloc" (core func (;1;))) (alias core export 0 "cabi_post_a" (core func (;2;))) - (func (;0;) (type 0) (canon lift (core func 1) (memory 0) string-encoding=utf8 (post-return 2))) + (func (;0;) (type 0) (canon lift (core func 0) (memory 0) string-encoding=utf8 (post-return 2))) (export (;1;) "a" (func 0)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/simple/component.wat b/crates/wit-component/tests/components/simple/component.wat index 5fc0e70565..480fb5f3aa 100644 --- a/crates/wit-component/tests/components/simple/component.wat +++ b/crates/wit-component/tests/components/simple/component.wat @@ -43,10 +43,10 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "cabi_realloc" (core func (;0;))) (type (;0;) (func)) - (alias core export 0 "a" (core func (;1;))) - (func (;0;) (type 0) (canon lift (core func 1))) + (alias core export 0 "a" (core func (;0;))) + (alias core export 0 "cabi_realloc" (core func (;1;))) + (func (;0;) (type 0) (canon lift (core func 0))) (export (;1;) "a" (func 0)) (type (;1;) (func (result string))) (alias core export 0 "b" (core func (;2;))) @@ -56,7 +56,7 @@ (type (;2;) (func (param "x" string) (result string))) (alias core export 0 "c" (core func (;4;))) (alias core export 0 "cabi_post_c" (core func (;5;))) - (func (;4;) (type 2) (canon lift (core func 4) (memory 0) (realloc 0) string-encoding=utf8 (post-return 5))) + (func (;4;) (type 2) (canon lift (core func 4) (memory 0) (realloc 1) string-encoding=utf8 (post-return 5))) (export (;5;) "c" (func 4)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat index 4d272ffb1c..5e72b52618 100644 --- a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat +++ b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat @@ -40,11 +40,11 @@ ) ) (alias core export 1 "memory" (core memory (;0;))) - (alias core export 1 "cabi_realloc" (core func (;1;))) (type (;3;) (record (field "f" u8))) (type (;4;) (func (result 3))) - (alias core export 1 "foo:foo/i#the-func" (core func (;2;))) - (func (;1;) (type 4) (canon lift (core func 2))) + (alias core export 1 "foo:foo/i#the-func" (core func (;1;))) + (alias core export 1 "cabi_realloc" (core func (;2;))) + (func (;1;) (type 4) (canon lift (core func 1))) (component (;0;) (type (;0;) (record (field "f" u8))) (import "import-type-some-type" (type (;1;) (eq 0))) From 41a0bd50e81a8b2a1347d8ec6e7823804351bebb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2024 17:22:04 -0700 Subject: [PATCH 2/3] Update link-related tests --- .../components/link-asyncify/component.wat | 81 ++++------- .../components/link-bare-funcs/component.wat | 100 +++++--------- .../components/link-circular/component.wat | 76 +++------- .../component.wat | 101 ++++---------- .../component.wat | 130 ++++-------------- .../components/link-dl-openable/component.wat | 34 +---- .../link-duplicate-symbols/component.wat | 73 +++------- .../components/link-got-func/component.wat | 76 +++------- .../components/link-initialize/component.wat | 105 +++++--------- .../components/link-resources/component.wat | 68 ++------- .../components/link-stub-wasip2/component.wat | 129 +++++++---------- .../tests/components/link-stubs/component.wat | 71 ++-------- .../link-weak-cabi-realloc/component.wat | 37 ++--- .../components/link-weak-import/component.wat | 71 ++-------- .../tests/components/link/component.wat | 105 +++++--------- 15 files changed, 336 insertions(+), 921 deletions(-) diff --git a/crates/wit-component/tests/components/link-asyncify/component.wat b/crates/wit-component/tests/components/link-asyncify/component.wat index bdf11c903f..957971ac67 100644 --- a/crates/wit-component/tests/components/link-asyncify/component.wat +++ b/crates/wit-component/tests/components/link-asyncify/component.wat @@ -206,72 +206,45 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) + (alias core export 0 "bar:memory_base" (core global (;0;))) + (alias core export 0 "bar:table_base" (core global (;1;))) + (alias core export 0 "__asyncify_state" (core global (;2;))) + (alias core export 0 "__asyncify_data" (core global (;3;))) (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "bar:memory_base" (core global (;3;))) - (alias core export 0 "bar:table_base" (core global (;4;))) - (alias core export 0 "__asyncify_state" (core global (;5;))) - (alias core export 0 "__asyncify_data" (core global (;6;))) - (core instance (;3;) - (export "memory" (memory 1)) + (core instance (;1;) + (export "__memory_base" (global 0)) + (export "__table_base" (global 1)) + (export "__asyncify_state" (global 2)) + (export "__asyncify_data" (global 3)) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - (export "__asyncify_state" (global 5)) - (export "__asyncify_data" (global 6)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) + (core instance (;2;) (instantiate 1 + (with "env" (instance 1)) ) ) - (alias core export 0 "__heap_base" (core global (;7;))) - (alias core export 0 "__heap_end" (core global (;8;))) - (core instance (;5;) - (export "__heap_base" (global 7)) - (export "__heap_end" (global 8)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;9;))) - (alias core export 0 "foo:memory_base" (core global (;10;))) - (alias core export 0 "foo:table_base" (core global (;11;))) - (alias core export 0 "__asyncify_state" (core global (;12;))) - (alias core export 0 "__asyncify_data" (core global (;13;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 9)) - (export "__memory_base" (global 10)) - (export "__table_base" (global 11)) - (export "__asyncify_state" (global 12)) - (export "__asyncify_data" (global 13)) + (alias core export 0 "foo:memory_base" (core global (;4;))) + (alias core export 0 "foo:table_base" (core global (;5;))) + (core instance (;3;) + (export "__memory_base" (global 4)) + (export "__table_base" (global 5)) + (export "__asyncify_state" (global 2)) + (export "__asyncify_data" (global 3)) + (export "memory" (memory 0)) + (export "__indirect_function_table" (table 0)) ) - (core instance (;8;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) + (core instance (;4;) (instantiate 2 + (with "env" (instance 3)) ) ) - (core instance (;9;) (instantiate 3 + (core instance (;5;) (instantiate 3 (with "env" (instance 0)) - (with "bar" (instance 4)) - (with "foo" (instance 8)) + (with "bar" (instance 2)) + (with "foo" (instance 4)) ) ) (type (;0;) (func)) - (alias core export 4 "test:test/test#bar" (core func (;0;))) + (alias core export 2 "test:test/test#bar" (core func (;0;))) (func (;0;) (type 0) (canon lift (core func 0))) (component (;0;) (type (;0;) (func)) diff --git a/crates/wit-component/tests/components/link-bare-funcs/component.wat b/crates/wit-component/tests/components/link-bare-funcs/component.wat index 97f0900574..c5260d0898 100644 --- a/crates/wit-component/tests/components/link-bare-funcs/component.wat +++ b/crates/wit-component/tests/components/link-bare-funcs/component.wat @@ -150,93 +150,57 @@ ) ) (alias core export 2 "memory" (core memory (;0;))) - (alias core export 2 "cabi_realloc" (core func (;1;))) (alias core export 2 "__heap_base" (core global (;0;))) (alias core export 2 "__heap_end" (core global (;1;))) (core instance (;3;) (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;4;)) - (alias core export 2 "memory" (core memory (;1;))) - (alias core export 2 "__indirect_function_table" (core table (;0;))) - (alias core export 2 "__stack_pointer" (core global (;2;))) - (alias core export 2 "c:memory_base" (core global (;3;))) - (alias core export 2 "c:table_base" (core global (;4;))) + (core instance (;4;) (instantiate 1 + (with "GOT.mem" (instance 3)) + ) + ) (core instance (;5;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) + (export "memory" (memory 0)) ) - (core instance (;6;) (instantiate 1 - (with "GOT.mem" (instance 3)) - (with "GOT.func" (instance 4)) + (core func (;1;) (canon lower (func 0))) + (alias core export 0 "1" (core func (;2;))) + (core instance (;6;) + (export "foo1" (func 1)) + (export "bar" (func 2)) + ) + (core instance (;7;) (instantiate 2 (with "env" (instance 5)) + (with "$root" (instance 6)) ) ) - (alias core export 2 "__heap_base" (core global (;5;))) - (alias core export 2 "__heap_end" (core global (;6;))) - (core instance (;7;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) + (alias core export 0 "$imports" (core table (;0;))) + (alias core export 7 "cabi_realloc" (core func (;3;))) + (alias core export 7 "cabi_import_realloc" (core func (;4;))) + (core func (;5;) (canon lower (func 1) (memory 0) (realloc 4) string-encoding=utf8)) + (core instance (;8;) + (export "$imports" (table 0)) + (export "0" (func 3)) + (export "1" (func 5)) + ) + (core instance (;9;) (instantiate 5 + (with "" (instance 8)) + ) ) - (core instance (;8;)) - (alias core export 2 "memory" (core memory (;2;))) - (alias core export 2 "__indirect_function_table" (core table (;1;))) - (alias core export 2 "__stack_pointer" (core global (;7;))) - (alias core export 2 "foo:memory_base" (core global (;8;))) - (alias core export 2 "foo:table_base" (core global (;9;))) - (core instance (;9;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - ) - (core func (;2;) (canon lower (func 0))) - (alias core export 0 "0" (core func (;3;))) - (core instance (;10;) - (export "foo1" (func 2)) - (export "bar" (func 3)) - ) - (core instance (;11;) (instantiate 2 - (with "GOT.mem" (instance 7)) - (with "GOT.func" (instance 8)) - (with "env" (instance 9)) - (with "$root" (instance 10)) - ) - ) - (alias core export 11 "cabi_export_realloc" (core func (;4;))) - (alias core export 11 "cabi_import_realloc" (core func (;5;))) - (alias core export 0 "$imports" (core table (;2;))) - (core func (;6;) (canon lower (func 1) (memory 0) (realloc 5) string-encoding=utf8)) - (alias core export 11 "cabi_realloc" (core func (;7;))) - (core instance (;12;) - (export "$imports" (table 2)) - (export "0" (func 6)) - (export "1" (func 7)) - ) - (core instance (;13;) (instantiate 5 - (with "" (instance 12)) - ) - ) - (core instance (;14;) (instantiate 3 + (core instance (;10;) (instantiate 3 (with "env" (instance 2)) - (with "c" (instance 6)) - (with "foo" (instance 11)) ) ) - (alias core export 11 "baz" (core func (;8;))) - (func (;2;) (type 0) (canon lift (core func 8))) + (alias core export 7 "baz" (core func (;6;))) + (alias core export 7 "cabi_export_realloc" (core func (;7;))) + (func (;2;) (type 0) (canon lift (core func 6))) (export (;3;) "baz" (func 2)) (type (;2;) (list u8)) (type (;3;) (option 2)) (type (;4;) (func (param "x" string) (result 3))) - (alias core export 11 "foo2" (core func (;9;))) - (alias core export 11 "cabi_post_foo2" (core func (;10;))) - (func (;4;) (type 4) (canon lift (core func 9) (memory 0) (realloc 4) string-encoding=utf8 (post-return 10))) + (alias core export 7 "foo2" (core func (;8;))) + (alias core export 7 "cabi_post_foo2" (core func (;9;))) + (func (;4;) (type 4) (canon lift (core func 8) (memory 0) (realloc 7) string-encoding=utf8 (post-return 9))) (export (;5;) "foo2" (func 4)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/link-circular/component.wat b/crates/wit-component/tests/components/link-circular/component.wat index 631007d141..f459b1ac4b 100644 --- a/crates/wit-component/tests/components/link-circular/component.wat +++ b/crates/wit-component/tests/components/link-circular/component.wat @@ -81,77 +81,37 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "bar:memory_base" (core global (;3;))) - (alias core export 0 "bar:table_base" (core global (;4;))) (alias core export 0 "foo" (core func (;0;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) + (core instance (;1;) (export "foo" (func 0)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) + (core instance (;2;) (instantiate 1 + (with "env" (instance 1)) ) ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "foo:memory_base" (core global (;8;))) - (alias core export 0 "foo:table_base" (core global (;9;))) - (alias core export 4 "bar" (core func (;1;))) - (alias core export 0 "foo" (core func (;2;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - (export "bar" (func 1)) - (export "foo" (func 2)) - ) (alias export 0 "foo" (func (;0;))) - (core func (;3;) (canon lower (func 0))) - (core instance (;8;) - (export "foo" (func 3)) + (core func (;1;) (canon lower (func 0))) + (core instance (;3;) + (export "foo" (func 1)) + ) + (alias core export 2 "bar" (core func (;2;))) + (core instance (;4;) + (export "foo" (func 0)) + (export "bar" (func 2)) ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;5;) (instantiate 2 + (with "test:test/test" (instance 3)) + (with "env" (instance 4)) ) ) - (core instance (;10;) (instantiate 3 + (core instance (;6;) (instantiate 3 (with "env" (instance 0)) - (with "bar" (instance 4)) - (with "foo" (instance 9)) + (with "foo" (instance 5)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 9 "test:test/test#foo" (core func (;4;))) - (func (;1;) (type 1) (canon lift (core func 4))) + (alias core export 5 "test:test/test#foo" (core func (;3;))) + (func (;1;) (type 1) (canon lift (core func 3))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) (import "import-func-foo" (func (;0;) (type 0))) diff --git a/crates/wit-component/tests/components/link-dl-openable-builtin-libdl-with-unused/component.wat b/crates/wit-component/tests/components/link-dl-openable-builtin-libdl-with-unused/component.wat index f3ac00af72..13303962b6 100644 --- a/crates/wit-component/tests/components/link-dl-openable-builtin-libdl-with-unused/component.wat +++ b/crates/wit-component/tests/components/link-dl-openable-builtin-libdl-with-unused/component.wat @@ -550,96 +550,49 @@ (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) + (core instance (;2;) (instantiate 1 + (with "GOT.mem" (instance 1)) + ) + ) (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "libc.so:memory_base" (core global (;3;))) - (alias core export 0 "libc.so:table_base" (core global (;4;))) + (alias core export 0 "libdl.so:memory_base" (core global (;2;))) + (alias core export 0 "libdl.so:table_base" (core global (;3;))) + (alias core export 2 "strlen" (core func (;0;))) + (alias core export 2 "memcmp" (core func (;1;))) (core instance (;3;) - (export "memory" (memory 1)) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) + (export "__memory_base" (global 2)) + (export "__table_base" (global 3)) + (export "strlen" (func 0)) + (export "memcmp" (func 1)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) + (core instance (;4;) (instantiate 2 (with "env" (instance 3)) ) ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) + (alias export 0 "foo" (func (;0;))) + (core func (;2;) (canon lower (func 0))) (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) + (export "foo" (func 2)) ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "libdl.so:memory_base" (core global (;8;))) - (alias core export 0 "libdl.so:table_base" (core global (;9;))) - (alias core export 4 "memcmp" (core func (;0;))) - (alias core export 4 "strlen" (core func (;1;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - (export "memcmp" (func 0)) - (export "strlen" (func 1)) - ) - (core instance (;8;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - ) - ) - (alias core export 0 "__heap_base" (core global (;10;))) - (alias core export 0 "__heap_end" (core global (;11;))) - (core instance (;9;) - (export "__heap_base" (global 10)) - (export "__heap_end" (global 11)) - ) - (core instance (;10;)) - (alias core export 0 "memory" (core memory (;3;))) - (alias core export 0 "__indirect_function_table" (core table (;2;))) - (alias core export 0 "__stack_pointer" (core global (;12;))) - (alias core export 0 "foo:memory_base" (core global (;13;))) - (alias core export 0 "foo:table_base" (core global (;14;))) - (alias core export 8 "dlopen" (core func (;2;))) - (core instance (;11;) - (export "memory" (memory 3)) - (export "__indirect_function_table" (table 2)) - (export "__stack_pointer" (global 12)) - (export "__memory_base" (global 13)) - (export "__table_base" (global 14)) - (export "dlopen" (func 2)) - ) - (alias export 0 "foo" (func (;0;))) - (core func (;3;) (canon lower (func 0))) - (core instance (;12;) - (export "foo" (func 3)) + (alias core export 4 "dlopen" (core func (;3;))) + (core instance (;6;) + (export "dlopen" (func 3)) ) - (core instance (;13;) (instantiate 3 - (with "GOT.mem" (instance 9)) - (with "GOT.func" (instance 10)) - (with "env" (instance 11)) - (with "test:test/test" (instance 12)) + (core instance (;7;) (instantiate 3 + (with "test:test/test" (instance 5)) + (with "env" (instance 6)) ) ) - (core instance (;14;) (instantiate 4 + (core instance (;8;) (instantiate 4 (with "env" (instance 0)) - (with "foo" (instance 13)) - (with "libc.so" (instance 4)) - (with "libdl.so" (instance 8)) + (with "foo" (instance 7)) + (with "libdl.so" (instance 4)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 13 "test:test/test#foo" (core func (;4;))) + (alias core export 7 "test:test/test#foo" (core func (;4;))) (func (;1;) (type 1) (canon lift (core func 4))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-dl-openable-builtin-libdl/component.wat b/crates/wit-component/tests/components/link-dl-openable-builtin-libdl/component.wat index 37da0d7801..e27ddbb886 100644 --- a/crates/wit-component/tests/components/link-dl-openable-builtin-libdl/component.wat +++ b/crates/wit-component/tests/components/link-dl-openable-builtin-libdl/component.wat @@ -552,122 +552,50 @@ (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) + (core instance (;2;) (instantiate 1 + (with "GOT.mem" (instance 1)) + ) + ) + (core instance (;3;) (instantiate 2)) (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "libc.so:memory_base" (core global (;3;))) - (alias core export 0 "libc.so:table_base" (core global (;4;))) - (core instance (;3;) - (export "memory" (memory 1)) + (alias core export 0 "libdl.so:memory_base" (core global (;2;))) + (alias core export 0 "libdl.so:table_base" (core global (;3;))) + (alias core export 3 "strlen" (core func (;0;))) + (alias core export 3 "memcmp" (core func (;1;))) + (core instance (;4;) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) + (export "__memory_base" (global 2)) + (export "__table_base" (global 3)) + (export "strlen" (func 0)) + (export "memcmp" (func 1)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) + (core instance (;5;) (instantiate 3 + (with "env" (instance 4)) ) ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) + (alias export 0 "foo" (func (;0;))) + (core func (;2;) (canon lower (func 0))) + (core instance (;6;) + (export "foo" (func 2)) ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "wit-component:stubs:memory_base" (core global (;8;))) - (alias core export 0 "wit-component:stubs:table_base" (core global (;9;))) + (alias core export 5 "dlopen" (core func (;3;))) (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) + (export "dlopen" (func 3)) ) - (core instance (;8;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) + (core instance (;8;) (instantiate 4 + (with "test:test/test" (instance 6)) (with "env" (instance 7)) ) ) - (alias core export 0 "__heap_base" (core global (;10;))) - (alias core export 0 "__heap_end" (core global (;11;))) - (core instance (;9;) - (export "__heap_base" (global 10)) - (export "__heap_end" (global 11)) - ) - (core instance (;10;)) - (alias core export 0 "memory" (core memory (;3;))) - (alias core export 0 "__indirect_function_table" (core table (;2;))) - (alias core export 0 "__stack_pointer" (core global (;12;))) - (alias core export 0 "libdl.so:memory_base" (core global (;13;))) - (alias core export 0 "libdl.so:table_base" (core global (;14;))) - (alias core export 8 "memcmp" (core func (;0;))) - (alias core export 8 "strlen" (core func (;1;))) - (core instance (;11;) - (export "memory" (memory 3)) - (export "__indirect_function_table" (table 2)) - (export "__stack_pointer" (global 12)) - (export "__memory_base" (global 13)) - (export "__table_base" (global 14)) - (export "memcmp" (func 0)) - (export "strlen" (func 1)) - ) - (core instance (;12;) (instantiate 3 - (with "GOT.mem" (instance 9)) - (with "GOT.func" (instance 10)) - (with "env" (instance 11)) - ) - ) - (alias core export 0 "__heap_base" (core global (;15;))) - (alias core export 0 "__heap_end" (core global (;16;))) - (core instance (;13;) - (export "__heap_base" (global 15)) - (export "__heap_end" (global 16)) - ) - (core instance (;14;)) - (alias core export 0 "memory" (core memory (;4;))) - (alias core export 0 "__indirect_function_table" (core table (;3;))) - (alias core export 0 "__stack_pointer" (core global (;17;))) - (alias core export 0 "foo:memory_base" (core global (;18;))) - (alias core export 0 "foo:table_base" (core global (;19;))) - (alias core export 12 "dlopen" (core func (;2;))) - (core instance (;15;) - (export "memory" (memory 4)) - (export "__indirect_function_table" (table 3)) - (export "__stack_pointer" (global 17)) - (export "__memory_base" (global 18)) - (export "__table_base" (global 19)) - (export "dlopen" (func 2)) - ) - (alias export 0 "foo" (func (;0;))) - (core func (;3;) (canon lower (func 0))) - (core instance (;16;) - (export "foo" (func 3)) - ) - (core instance (;17;) (instantiate 4 - (with "GOT.mem" (instance 13)) - (with "GOT.func" (instance 14)) - (with "env" (instance 15)) - (with "test:test/test" (instance 16)) - ) - ) - (core instance (;18;) (instantiate 5 + (core instance (;9;) (instantiate 5 (with "env" (instance 0)) - (with "foo" (instance 17)) - (with "libc.so" (instance 4)) - (with "libdl.so" (instance 12)) - (with "wit-component:stubs" (instance 8)) + (with "foo" (instance 8)) + (with "libdl.so" (instance 5)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 17 "test:test/test#foo" (core func (;4;))) + (alias core export 8 "test:test/test#foo" (core func (;4;))) (func (;1;) (type 1) (canon lift (core func 4))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-dl-openable/component.wat b/crates/wit-component/tests/components/link-dl-openable/component.wat index 82ae096da0..c4a968044a 100644 --- a/crates/wit-component/tests/components/link-dl-openable/component.wat +++ b/crates/wit-component/tests/components/link-dl-openable/component.wat @@ -70,44 +70,22 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "foo:memory_base" (core global (;3;))) - (alias core export 0 "foo:table_base" (core global (;4;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - ) (alias export 0 "foo" (func (;0;))) (core func (;0;) (canon lower (func 0))) - (core instance (;4;) + (core instance (;1;) (export "foo" (func 0)) ) - (core instance (;5;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - (with "test:test/test" (instance 4)) + (core instance (;2;) (instantiate 1 + (with "test:test/test" (instance 1)) ) ) - (core instance (;6;) (instantiate 2 + (core instance (;3;) (instantiate 2 (with "env" (instance 0)) - (with "foo" (instance 5)) + (with "foo" (instance 2)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 5 "test:test/test#foo" (core func (;1;))) + (alias core export 2 "test:test/test#foo" (core func (;1;))) (func (;1;) (type 1) (canon lift (core func 1))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-duplicate-symbols/component.wat b/crates/wit-component/tests/components/link-duplicate-symbols/component.wat index 280f3742ef..4707ebb747 100644 --- a/crates/wit-component/tests/components/link-duplicate-symbols/component.wat +++ b/crates/wit-component/tests/components/link-duplicate-symbols/component.wat @@ -82,76 +82,37 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "bar:memory_base" (core global (;3;))) - (alias core export 0 "bar:table_base" (core global (;4;))) (alias core export 0 "foo" (core func (;0;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) + (core instance (;1;) (export "foo" (func 0)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) + (core instance (;2;) (instantiate 1 + (with "env" (instance 1)) ) ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) + (alias export 0 "foo" (func (;0;))) + (core func (;1;) (canon lower (func 0))) + (core instance (;3;) + (export "foo" (func 1)) ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "foo:memory_base" (core global (;8;))) - (alias core export 0 "foo:table_base" (core global (;9;))) - (alias core export 4 "bar" (core func (;1;))) - (alias core export 4 "foo" (core func (;2;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - (export "bar" (func 1)) + (alias core export 2 "foo" (core func (;2;))) + (alias core export 2 "bar" (core func (;3;))) + (core instance (;4;) (export "foo" (func 2)) + (export "bar" (func 3)) ) - (alias export 0 "foo" (func (;0;))) - (core func (;3;) (canon lower (func 0))) - (core instance (;8;) - (export "foo" (func 3)) - ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;5;) (instantiate 2 + (with "test:test/test" (instance 3)) + (with "env" (instance 4)) ) ) - (core instance (;10;) (instantiate 3 + (core instance (;6;) (instantiate 3 (with "env" (instance 0)) - (with "bar" (instance 4)) - (with "foo" (instance 9)) + (with "bar" (instance 2)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 9 "test:test/test#foo" (core func (;4;))) + (alias core export 5 "test:test/test#foo" (core func (;4;))) (func (;1;) (type 1) (canon lift (core func 4))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-got-func/component.wat b/crates/wit-component/tests/components/link-got-func/component.wat index e866026874..ea1124fea6 100644 --- a/crates/wit-component/tests/components/link-got-func/component.wat +++ b/crates/wit-component/tests/components/link-got-func/component.wat @@ -76,75 +76,33 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "bar:memory_base" (core global (;3;))) - (alias core export 0 "bar:table_base" (core global (;4;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) - ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) - ) - (alias core export 0 "foo:foo" (core global (;7;))) - (core instance (;6;) - (export "foo" (global 7)) - ) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;8;))) - (alias core export 0 "foo:memory_base" (core global (;9;))) - (alias core export 0 "foo:table_base" (core global (;10;))) - (alias core export 4 "foo" (core func (;0;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 8)) - (export "__memory_base" (global 9)) - (export "__table_base" (global 10)) + (core instance (;1;) (instantiate 1)) + (alias export 0 "foo" (func (;0;))) + (core func (;0;) (canon lower (func 0))) + (core instance (;2;) (export "foo" (func 0)) ) - (alias export 0 "foo" (func (;0;))) - (core func (;1;) (canon lower (func 0))) - (core instance (;8;) + (alias core export 1 "foo" (core func (;1;))) + (core instance (;3;) (export "foo" (func 1)) ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (alias core export 0 "foo:foo" (core global (;0;))) + (core instance (;4;) + (export "foo" (global 0)) + ) + (core instance (;5;) (instantiate 2 + (with "test:test/test" (instance 2)) + (with "env" (instance 3)) + (with "GOT.func" (instance 4)) ) ) - (core instance (;10;) (instantiate 3 + (core instance (;6;) (instantiate 3 (with "env" (instance 0)) - (with "bar" (instance 4)) - (with "foo" (instance 9)) + (with "bar" (instance 1)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 9 "test:test/test#foo" (core func (;2;))) + (alias core export 5 "test:test/test#foo" (core func (;2;))) (func (;1;) (type 1) (canon lift (core func 2))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-initialize/component.wat b/crates/wit-component/tests/components/link-initialize/component.wat index c59812a539..d8b0e2ed38 100644 --- a/crates/wit-component/tests/components/link-initialize/component.wat +++ b/crates/wit-component/tests/components/link-initialize/component.wat @@ -188,100 +188,67 @@ (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) + (core instance (;2;) (instantiate 1 + (with "GOT.mem" (instance 1)) + ) + ) (alias core export 0 "__indirect_function_table" (core table (;0;))) (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "c:memory_base" (core global (;3;))) - (alias core export 0 "c:table_base" (core global (;4;))) + (alias core export 0 "foo:memory_base" (core global (;3;))) + (alias core export 0 "foo:table_base" (core global (;4;))) + (alias core export 2 "malloc" (core func (;0;))) + (alias core export 2 "abort" (core func (;1;))) (core instance (;3;) - (export "memory" (memory 1)) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) (export "__stack_pointer" (global 2)) (export "__memory_base" (global 3)) (export "__table_base" (global 4)) - ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) + (export "malloc" (func 0)) + (export "abort" (func 1)) ) (alias core export 0 "foo:um" (core global (;5;))) - (alias core export 0 "__heap_base" (core global (;6;))) - (alias core export 0 "__heap_end" (core global (;7;))) - (core instance (;5;) + (core instance (;4;) (export "um" (global 5)) - (export "__heap_base" (global 6)) - (export "__heap_end" (global 7)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;8;))) - (alias core export 0 "foo:memory_base" (core global (;9;))) - (alias core export 0 "foo:table_base" (core global (;10;))) - (alias core export 4 "abort" (core func (;0;))) - (alias core export 4 "malloc" (core func (;1;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 8)) - (export "__memory_base" (global 9)) - (export "__table_base" (global 10)) - (export "abort" (func 0)) - (export "malloc" (func 1)) ) (alias export 0 "bar" (func (;0;))) (core func (;2;) (canon lower (func 0))) - (core instance (;8;) + (core instance (;5;) (export "bar" (func 2)) ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;6;) (instantiate 2 + (with "env" (instance 3)) + (with "GOT.mem" (instance 4)) + (with "test:test/test" (instance 5)) ) ) - (alias core export 0 "bar:well" (core global (;11;))) - (alias core export 0 "__heap_base" (core global (;12;))) - (alias core export 0 "__heap_end" (core global (;13;))) - (core instance (;10;) - (export "well" (global 11)) - (export "__heap_base" (global 12)) - (export "__heap_end" (global 13)) - ) - (core instance (;11;)) - (alias core export 0 "memory" (core memory (;3;))) - (alias core export 0 "__indirect_function_table" (core table (;2;))) - (alias core export 0 "__stack_pointer" (core global (;14;))) - (alias core export 0 "bar:memory_base" (core global (;15;))) - (alias core export 0 "bar:table_base" (core global (;16;))) - (alias core export 9 "foo" (core func (;3;))) - (core instance (;12;) - (export "memory" (memory 3)) - (export "__indirect_function_table" (table 2)) - (export "__stack_pointer" (global 14)) - (export "__memory_base" (global 15)) - (export "__table_base" (global 16)) + (alias core export 0 "bar:memory_base" (core global (;6;))) + (alias core export 0 "bar:table_base" (core global (;7;))) + (alias core export 6 "foo" (core func (;3;))) + (core instance (;7;) + (export "memory" (memory 0)) + (export "__indirect_function_table" (table 0)) + (export "__memory_base" (global 6)) + (export "__table_base" (global 7)) (export "foo" (func 3)) ) - (core instance (;13;) (instantiate 3 - (with "GOT.mem" (instance 10)) - (with "GOT.func" (instance 11)) - (with "env" (instance 12)) + (alias core export 0 "bar:well" (core global (;8;))) + (core instance (;8;) + (export "well" (global 8)) + ) + (core instance (;9;) (instantiate 3 + (with "env" (instance 7)) + (with "GOT.mem" (instance 8)) ) ) - (core instance (;14;) (instantiate 4 + (core instance (;10;) (instantiate 4 (with "env" (instance 0)) - (with "bar" (instance 13)) - (with "c" (instance 4)) - (with "foo" (instance 9)) + (with "bar" (instance 9)) + (with "foo" (instance 6)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 13 "test:test/test#bar" (core func (;4;))) + (alias core export 9 "test:test/test#bar" (core func (;4;))) (func (;1;) (type 1) (canon lift (core func 4))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-resources/component.wat b/crates/wit-component/tests/components/link-resources/component.wat index 07988f9bf2..dd06d8ac0a 100644 --- a/crates/wit-component/tests/components/link-resources/component.wat +++ b/crates/wit-component/tests/components/link-resources/component.wat @@ -68,73 +68,23 @@ (processed-by "wit-component" "$CARGO_PKG_VERSION") ) ) - (core instance (;0;) (instantiate 0)) - (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "foo:memory_base" (core global (;3;))) - (alias core export 0 "foo:table_base" (core global (;4;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - ) (type (;0;) (resource (rep i32))) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) - ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "bar:memory_base" (core global (;8;))) - (alias core export 0 "bar:table_base" (core global (;9;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - ) (type (;1;) (resource (rep i32))) - (core instance (;8;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - ) - ) - (core instance (;9;) (instantiate 3 + (core instance (;0;) (instantiate 0)) + (alias core export 0 "memory" (core memory (;0;))) + (core instance (;1;) (instantiate 1)) + (core instance (;2;) (instantiate 2)) + (core instance (;3;) (instantiate 3 (with "env" (instance 0)) - (with "bar" (instance 8)) - (with "foo" (instance 4)) ) ) (type (;2;) (own 0)) (type (;3;) (func (param "v" u32) (result 2))) - (alias core export 4 "test:test/foo#[constructor]x" (core func (;0;))) + (alias core export 1 "test:test/foo#[constructor]x" (core func (;0;))) (func (;0;) (type 3) (canon lift (core func 0))) (type (;4;) (borrow 0)) (type (;5;) (func (param "self" 4) (result u32))) - (alias core export 4 "test:test/foo#[method]x.get" (core func (;1;))) + (alias core export 1 "test:test/foo#[method]x.get" (core func (;1;))) (func (;1;) (type 5) (canon lift (core func 1))) (component (;0;) (import "import-type-x" (type (;0;) (sub resource))) @@ -161,11 +111,11 @@ (export (;1;) "test:test/foo" (instance 0)) (type (;6;) (own 1)) (type (;7;) (func (param "v" u32) (result 6))) - (alias core export 8 "test:test/bar#[constructor]x" (core func (;2;))) + (alias core export 2 "test:test/bar#[constructor]x" (core func (;2;))) (func (;2;) (type 7) (canon lift (core func 2))) (type (;8;) (borrow 1)) (type (;9;) (func (param "self" 8) (result u32))) - (alias core export 8 "test:test/bar#[method]x.get" (core func (;3;))) + (alias core export 2 "test:test/bar#[method]x.get" (core func (;3;))) (func (;3;) (type 9) (canon lift (core func 3))) (component (;1;) (import "import-type-x" (type (;0;) (sub resource))) diff --git a/crates/wit-component/tests/components/link-stub-wasip2/component.wat b/crates/wit-component/tests/components/link-stub-wasip2/component.wat index f69da45d7b..71f83c3aff 100644 --- a/crates/wit-component/tests/components/link-stub-wasip2/component.wat +++ b/crates/wit-component/tests/components/link-stub-wasip2/component.wat @@ -226,121 +226,88 @@ ) (alias core export 2 "memory" (core memory (;0;))) (core instance (;3;) (instantiate 1)) + (alias core export 2 "wasi:cli/environment@0.2.0:get-environment" (core func (;1;))) + (core instance (;4;) + (export "get-environment" (func 1)) + ) (alias core export 2 "__heap_base" (core global (;0;))) (alias core export 2 "__heap_end" (core global (;1;))) - (core instance (;4;) + (core instance (;5;) (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;5;)) - (alias core export 2 "memory" (core memory (;1;))) + (core instance (;6;) (instantiate 2 + (with "wasi:cli/environment@0.2.0" (instance 4)) + (with "GOT.mem" (instance 5)) + ) + ) (alias core export 2 "__indirect_function_table" (core table (;0;))) (alias core export 2 "__stack_pointer" (core global (;2;))) - (alias core export 2 "c:memory_base" (core global (;3;))) - (alias core export 2 "c:table_base" (core global (;4;))) - (core instance (;6;) - (export "memory" (memory 1)) + (alias core export 2 "foo:memory_base" (core global (;3;))) + (alias core export 2 "foo:table_base" (core global (;4;))) + (alias core export 6 "malloc" (core func (;2;))) + (alias core export 6 "abort" (core func (;3;))) + (core instance (;7;) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) (export "__stack_pointer" (global 2)) (export "__memory_base" (global 3)) (export "__table_base" (global 4)) - ) - (alias core export 2 "wasi:cli/environment@0.2.0:get-environment" (core func (;1;))) - (core instance (;7;) - (export "get-environment" (func 1)) - ) - (core instance (;8;) (instantiate 2 - (with "GOT.mem" (instance 4)) - (with "GOT.func" (instance 5)) - (with "env" (instance 6)) - (with "wasi:cli/environment@0.2.0" (instance 7)) - ) + (export "malloc" (func 2)) + (export "abort" (func 3)) ) (alias core export 2 "foo:um" (core global (;5;))) - (alias core export 2 "__heap_base" (core global (;6;))) - (alias core export 2 "__heap_end" (core global (;7;))) - (core instance (;9;) + (core instance (;8;) (export "um" (global 5)) - (export "__heap_base" (global 6)) - (export "__heap_end" (global 7)) - ) - (core instance (;10;)) - (alias core export 2 "memory" (core memory (;2;))) - (alias core export 2 "__indirect_function_table" (core table (;1;))) - (alias core export 2 "__stack_pointer" (core global (;8;))) - (alias core export 2 "foo:memory_base" (core global (;9;))) - (alias core export 2 "foo:table_base" (core global (;10;))) - (alias core export 8 "abort" (core func (;2;))) - (alias core export 8 "malloc" (core func (;3;))) - (core instance (;11;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 8)) - (export "__memory_base" (global 9)) - (export "__table_base" (global 10)) - (export "abort" (func 2)) - (export "malloc" (func 3)) ) (alias export 0 "bar" (func (;0;))) (core func (;4;) (canon lower (func 0))) - (core instance (;12;) + (core instance (;9;) (export "bar" (func 4)) ) - (core instance (;13;) (instantiate 3 - (with "GOT.mem" (instance 9)) - (with "GOT.func" (instance 10)) - (with "env" (instance 11)) - (with "test:test/test" (instance 12)) + (core instance (;10;) (instantiate 3 + (with "env" (instance 7)) + (with "GOT.mem" (instance 8)) + (with "test:test/test" (instance 9)) ) ) - (alias core export 2 "bar:well" (core global (;11;))) - (alias core export 2 "__heap_base" (core global (;12;))) - (alias core export 2 "__heap_end" (core global (;13;))) - (core instance (;14;) - (export "well" (global 11)) - (export "__heap_base" (global 12)) - (export "__heap_end" (global 13)) - ) - (core instance (;15;)) - (alias core export 2 "memory" (core memory (;3;))) - (alias core export 2 "__indirect_function_table" (core table (;2;))) - (alias core export 2 "__stack_pointer" (core global (;14;))) - (alias core export 2 "bar:memory_base" (core global (;15;))) - (alias core export 2 "bar:table_base" (core global (;16;))) - (alias core export 13 "foo" (core func (;5;))) - (core instance (;16;) - (export "memory" (memory 3)) - (export "__indirect_function_table" (table 2)) - (export "__stack_pointer" (global 14)) - (export "__memory_base" (global 15)) - (export "__table_base" (global 16)) + (alias core export 2 "bar:memory_base" (core global (;6;))) + (alias core export 2 "bar:table_base" (core global (;7;))) + (alias core export 10 "foo" (core func (;5;))) + (core instance (;11;) + (export "memory" (memory 0)) + (export "__indirect_function_table" (table 0)) + (export "__memory_base" (global 6)) + (export "__table_base" (global 7)) (export "foo" (func 5)) ) - (core instance (;17;) (instantiate 4 - (with "GOT.mem" (instance 14)) - (with "GOT.func" (instance 15)) - (with "env" (instance 16)) + (alias core export 2 "bar:well" (core global (;8;))) + (core instance (;12;) + (export "well" (global 8)) + ) + (core instance (;13;) (instantiate 4 + (with "env" (instance 11)) + (with "GOT.mem" (instance 12)) ) ) - (alias core export 0 "$imports" (core table (;3;))) + (alias core export 0 "$imports" (core table (;1;))) (alias core export 3 "get-environment" (core func (;6;))) - (core instance (;18;) - (export "$imports" (table 3)) + (core instance (;14;) + (export "$imports" (table 1)) (export "0" (func 6)) ) - (core instance (;19;) (instantiate 7 - (with "" (instance 18)) + (core instance (;15;) (instantiate 7 + (with "" (instance 14)) ) ) - (core instance (;20;) (instantiate 5 + (core instance (;16;) (instantiate 5 (with "env" (instance 2)) - (with "bar" (instance 17)) - (with "c" (instance 8)) - (with "foo" (instance 13)) + (with "bar" (instance 13)) + (with "foo" (instance 10)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 17 "test:test/test#bar" (core func (;7;))) + (alias core export 13 "test:test/test#bar" (core func (;7;))) (func (;1;) (type 1) (canon lift (core func 7))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-stubs/component.wat b/crates/wit-component/tests/components/link-stubs/component.wat index c1b0b01a55..7fc5fef072 100644 --- a/crates/wit-component/tests/components/link-stubs/component.wat +++ b/crates/wit-component/tests/components/link-stubs/component.wat @@ -73,74 +73,29 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) + (core instance (;1;) (instantiate 1)) + (alias export 0 "foo" (func (;0;))) + (core func (;0;) (canon lower (func 0))) + (core instance (;2;) + (export "foo" (func 0)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "wit-component:stubs:memory_base" (core global (;3;))) - (alias core export 0 "wit-component:stubs:table_base" (core global (;4;))) + (alias core export 1 "foo" (core func (;1;))) + (alias core export 1 "bar" (core func (;2;))) (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) - ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "foo:memory_base" (core global (;8;))) - (alias core export 0 "foo:table_base" (core global (;9;))) - (alias core export 4 "bar" (core func (;0;))) - (alias core export 4 "foo" (core func (;1;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - (export "bar" (func 0)) (export "foo" (func 1)) + (export "bar" (func 2)) ) - (alias export 0 "foo" (func (;0;))) - (core func (;2;) (canon lower (func 0))) - (core instance (;8;) - (export "foo" (func 2)) - ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;4;) (instantiate 2 + (with "test:test/test" (instance 2)) + (with "env" (instance 3)) ) ) - (core instance (;10;) (instantiate 3 + (core instance (;5;) (instantiate 3 (with "env" (instance 0)) - (with "foo" (instance 9)) - (with "wit-component:stubs" (instance 4)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 9 "test:test/test#foo" (core func (;3;))) + (alias core export 4 "test:test/test#foo" (core func (;3;))) (func (;1;) (type 1) (canon lift (core func 3))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link-weak-cabi-realloc/component.wat b/crates/wit-component/tests/components/link-weak-cabi-realloc/component.wat index 885e515849..6b072e77fe 100644 --- a/crates/wit-component/tests/components/link-weak-cabi-realloc/component.wat +++ b/crates/wit-component/tests/components/link-weak-cabi-realloc/component.wat @@ -62,43 +62,22 @@ (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) (alias core export 0 "cabi_realloc" (core func (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) - ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "foo:memory_base" (core global (;3;))) - (alias core export 0 "foo:table_base" (core global (;4;))) - (alias core export 0 "cabi_realloc" (core func (;1;))) - (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - (export "cabi_realloc" (func 1)) + (export "cabi_realloc" (func 0)) ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) + (core instance (;2;) (instantiate 1 + (with "env" (instance 1)) ) ) - (alias core export 4 "cabi_realloc" (core func (;2;))) - (alias core export 4 "cabi_realloc" (core func (;3;))) - (core instance (;5;) (instantiate 2 + (core instance (;3;) (instantiate 2 (with "env" (instance 0)) - (with "foo" (instance 4)) + (with "foo" (instance 2)) ) ) (type (;0;) (func (param "x" string))) - (alias core export 4 "test:test/test#foo" (core func (;4;))) - (func (;0;) (type 0) (canon lift (core func 4) (memory 0) (realloc 2) string-encoding=utf8)) + (alias core export 2 "test:test/test#foo" (core func (;1;))) + (alias core export 2 "cabi_realloc" (core func (;2;))) + (func (;0;) (type 0) (canon lift (core func 1) (memory 0) (realloc 2) string-encoding=utf8)) (component (;0;) (type (;0;) (func (param "x" string))) (import "import-func-foo" (func (;0;) (type 0))) diff --git a/crates/wit-component/tests/components/link-weak-import/component.wat b/crates/wit-component/tests/components/link-weak-import/component.wat index ca5fef401f..bc5d3e977b 100644 --- a/crates/wit-component/tests/components/link-weak-import/component.wat +++ b/crates/wit-component/tests/components/link-weak-import/component.wat @@ -75,74 +75,29 @@ ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) - (alias core export 0 "__heap_base" (core global (;0;))) - (alias core export 0 "__heap_end" (core global (;1;))) - (core instance (;1;) - (export "__heap_base" (global 0)) - (export "__heap_end" (global 1)) + (core instance (;1;) (instantiate 1)) + (alias export 0 "foo" (func (;0;))) + (core func (;0;) (canon lower (func 0))) + (core instance (;2;) + (export "foo" (func 0)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) - (alias core export 0 "__indirect_function_table" (core table (;0;))) - (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "wit-component:stubs:memory_base" (core global (;3;))) - (alias core export 0 "wit-component:stubs:table_base" (core global (;4;))) + (alias core export 1 "foo" (core func (;1;))) + (alias core export 1 "bar" (core func (;2;))) (core instance (;3;) - (export "memory" (memory 1)) - (export "__indirect_function_table" (table 0)) - (export "__stack_pointer" (global 2)) - (export "__memory_base" (global 3)) - (export "__table_base" (global 4)) - ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) - ) - (alias core export 0 "__heap_base" (core global (;5;))) - (alias core export 0 "__heap_end" (core global (;6;))) - (core instance (;5;) - (export "__heap_base" (global 5)) - (export "__heap_end" (global 6)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;7;))) - (alias core export 0 "foo:memory_base" (core global (;8;))) - (alias core export 0 "foo:table_base" (core global (;9;))) - (alias core export 4 "bar" (core func (;0;))) - (alias core export 4 "foo" (core func (;1;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9)) - (export "bar" (func 0)) (export "foo" (func 1)) + (export "bar" (func 2)) ) - (alias export 0 "foo" (func (;0;))) - (core func (;2;) (canon lower (func 0))) - (core instance (;8;) - (export "foo" (func 2)) - ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;4;) (instantiate 2 + (with "test:test/test" (instance 2)) + (with "env" (instance 3)) ) ) - (core instance (;10;) (instantiate 3 + (core instance (;5;) (instantiate 3 (with "env" (instance 0)) - (with "foo" (instance 9)) - (with "wit-component:stubs" (instance 4)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 9 "test:test/test#foo" (core func (;3;))) + (alias core export 4 "test:test/test#foo" (core func (;3;))) (func (;1;) (type 1) (canon lift (core func 3))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) diff --git a/crates/wit-component/tests/components/link/component.wat b/crates/wit-component/tests/components/link/component.wat index c7ba5a3f77..a7374888d8 100644 --- a/crates/wit-component/tests/components/link/component.wat +++ b/crates/wit-component/tests/components/link/component.wat @@ -188,100 +188,67 @@ (export "__heap_base" (global 0)) (export "__heap_end" (global 1)) ) - (core instance (;2;)) - (alias core export 0 "memory" (core memory (;1;))) + (core instance (;2;) (instantiate 1 + (with "GOT.mem" (instance 1)) + ) + ) (alias core export 0 "__indirect_function_table" (core table (;0;))) (alias core export 0 "__stack_pointer" (core global (;2;))) - (alias core export 0 "c:memory_base" (core global (;3;))) - (alias core export 0 "c:table_base" (core global (;4;))) + (alias core export 0 "foo:memory_base" (core global (;3;))) + (alias core export 0 "foo:table_base" (core global (;4;))) + (alias core export 2 "malloc" (core func (;0;))) + (alias core export 2 "abort" (core func (;1;))) (core instance (;3;) - (export "memory" (memory 1)) + (export "memory" (memory 0)) (export "__indirect_function_table" (table 0)) (export "__stack_pointer" (global 2)) (export "__memory_base" (global 3)) (export "__table_base" (global 4)) - ) - (core instance (;4;) (instantiate 1 - (with "GOT.mem" (instance 1)) - (with "GOT.func" (instance 2)) - (with "env" (instance 3)) - ) + (export "malloc" (func 0)) + (export "abort" (func 1)) ) (alias core export 0 "foo:um" (core global (;5;))) - (alias core export 0 "__heap_base" (core global (;6;))) - (alias core export 0 "__heap_end" (core global (;7;))) - (core instance (;5;) + (core instance (;4;) (export "um" (global 5)) - (export "__heap_base" (global 6)) - (export "__heap_end" (global 7)) - ) - (core instance (;6;)) - (alias core export 0 "memory" (core memory (;2;))) - (alias core export 0 "__indirect_function_table" (core table (;1;))) - (alias core export 0 "__stack_pointer" (core global (;8;))) - (alias core export 0 "foo:memory_base" (core global (;9;))) - (alias core export 0 "foo:table_base" (core global (;10;))) - (alias core export 4 "abort" (core func (;0;))) - (alias core export 4 "malloc" (core func (;1;))) - (core instance (;7;) - (export "memory" (memory 2)) - (export "__indirect_function_table" (table 1)) - (export "__stack_pointer" (global 8)) - (export "__memory_base" (global 9)) - (export "__table_base" (global 10)) - (export "abort" (func 0)) - (export "malloc" (func 1)) ) (alias export 0 "bar" (func (;0;))) (core func (;2;) (canon lower (func 0))) - (core instance (;8;) + (core instance (;5;) (export "bar" (func 2)) ) - (core instance (;9;) (instantiate 2 - (with "GOT.mem" (instance 5)) - (with "GOT.func" (instance 6)) - (with "env" (instance 7)) - (with "test:test/test" (instance 8)) + (core instance (;6;) (instantiate 2 + (with "env" (instance 3)) + (with "GOT.mem" (instance 4)) + (with "test:test/test" (instance 5)) ) ) - (alias core export 0 "bar:well" (core global (;11;))) - (alias core export 0 "__heap_base" (core global (;12;))) - (alias core export 0 "__heap_end" (core global (;13;))) - (core instance (;10;) - (export "well" (global 11)) - (export "__heap_base" (global 12)) - (export "__heap_end" (global 13)) - ) - (core instance (;11;)) - (alias core export 0 "memory" (core memory (;3;))) - (alias core export 0 "__indirect_function_table" (core table (;2;))) - (alias core export 0 "__stack_pointer" (core global (;14;))) - (alias core export 0 "bar:memory_base" (core global (;15;))) - (alias core export 0 "bar:table_base" (core global (;16;))) - (alias core export 9 "foo" (core func (;3;))) - (core instance (;12;) - (export "memory" (memory 3)) - (export "__indirect_function_table" (table 2)) - (export "__stack_pointer" (global 14)) - (export "__memory_base" (global 15)) - (export "__table_base" (global 16)) + (alias core export 0 "bar:memory_base" (core global (;6;))) + (alias core export 0 "bar:table_base" (core global (;7;))) + (alias core export 6 "foo" (core func (;3;))) + (core instance (;7;) + (export "memory" (memory 0)) + (export "__indirect_function_table" (table 0)) + (export "__memory_base" (global 6)) + (export "__table_base" (global 7)) (export "foo" (func 3)) ) - (core instance (;13;) (instantiate 3 - (with "GOT.mem" (instance 10)) - (with "GOT.func" (instance 11)) - (with "env" (instance 12)) + (alias core export 0 "bar:well" (core global (;8;))) + (core instance (;8;) + (export "well" (global 8)) + ) + (core instance (;9;) (instantiate 3 + (with "env" (instance 7)) + (with "GOT.mem" (instance 8)) ) ) - (core instance (;14;) (instantiate 4 + (core instance (;10;) (instantiate 4 (with "env" (instance 0)) - (with "bar" (instance 13)) - (with "c" (instance 4)) - (with "foo" (instance 9)) + (with "bar" (instance 9)) + (with "foo" (instance 6)) ) ) (type (;1;) (func (param "v" s32) (result s32))) - (alias core export 13 "test:test/test#bar" (core func (;4;))) + (alias core export 9 "test:test/test#bar" (core func (;4;))) (func (;1;) (type 1) (canon lift (core func 4))) (component (;0;) (type (;0;) (func (param "v" s32) (result s32))) From 0aacde287a459c9df43ee57659d9eb243e7d750f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2024 17:30:06 -0700 Subject: [PATCH 3/3] Bless some more tests --- tests/cli/bad-component-new.wat.stderr | 3 ++- tests/cli/semver-check-add-export.wit.stderr | 2 +- tests/cli/semver-check-remove-import.wit.stderr | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/cli/bad-component-new.wat.stderr b/tests/cli/bad-component-new.wat.stderr index 0bcb399ba0..dabbb42957 100644 --- a/tests/cli/bad-component-new.wat.stderr +++ b/tests/cli/bad-component-new.wat.stderr @@ -3,4 +3,5 @@ error: failed to encode a component from module Caused by: 0: failed to decode world from module 1: module was not valid - 2: module has duplicate import for `a::a` + 2: failed to resolve import `a::a` + 3: module requires an import interface named `a` diff --git a/tests/cli/semver-check-add-export.wit.stderr b/tests/cli/semver-check-add-export.wit.stderr index 22b80f144a..e7391d9617 100644 --- a/tests/cli/semver-check-add-export.wit.stderr +++ b/tests/cli/semver-check-add-export.wit.stderr @@ -2,4 +2,4 @@ error: new world is not semver-compatible with the previous world Caused by: 0: type mismatch for import `new` - missing export named `a` (at offset 0x101) + missing export named `a` (at offset 0xf0) diff --git a/tests/cli/semver-check-remove-import.wit.stderr b/tests/cli/semver-check-remove-import.wit.stderr index 9dd23d83fd..339e755284 100644 --- a/tests/cli/semver-check-remove-import.wit.stderr +++ b/tests/cli/semver-check-remove-import.wit.stderr @@ -2,4 +2,4 @@ error: new world is not semver-compatible with the previous world Caused by: 0: type mismatch for import `new` - missing import named `a` (at offset 0x12a) + missing import named `a` (at offset 0x119)