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-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 a0c6b7036c..c5260d0898 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)) ) @@ -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))) 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))) 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)