Skip to main content

wasmtime_environ/component/
translate.rs

1use crate::Abi;
2use crate::component::dfg::AbstractInstantiations;
3use crate::component::*;
4use crate::prelude::*;
5use crate::{
6    DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, EngineOrModuleTypeIndex,
7    EntityIndex, FactInlineIntrinsic, FuncKey, ImportPositions, KnownEntity, KnownGlobal,
8    ModuleEnvironment, ModuleInternedTypeIndex, ModuleTranslation, ModuleTypesBuilder, PrimaryMap,
9    ScopeVec, TagIndex, Tunables, TypeConvert, WasmHeapType, WasmResult, WasmValType,
10};
11use core::str::FromStr;
12use cranelift_entity::{EntityRef, SecondaryMap};
13use indexmap::IndexMap;
14use std::collections::{HashMap, HashSet};
15use std::mem;
16use wasmparser::component_types::{
17    AliasableResourceId, ComponentCoreModuleTypeId, ComponentCoreTypeId, ComponentDefinedTypeId,
18    ComponentEntityType, ComponentFuncTypeId, ComponentInstanceTypeId, ComponentValType,
19};
20use wasmparser::types::Types;
21use wasmparser::{Chunk, ComponentExternName, Encoding, Parser, Payload, Validator};
22
23mod adapt;
24pub use self::adapt::*;
25mod inline;
26
27/// Structure used to translate a component and parse it.
28pub struct Translator<'a, 'data> {
29    /// The current component being translated.
30    ///
31    /// This will get swapped out as translation traverses the body of a
32    /// component and a sub-component is entered or left.
33    result: Translation<'data>,
34
35    /// Current state of parsing a binary component. Note that like `result`
36    /// this will change as the component is traversed.
37    parser: Parser,
38
39    /// Stack of lexical scopes that are in-progress but not finished yet.
40    ///
41    /// This is pushed to whenever a component is entered and popped from
42    /// whenever a component is left. Each lexical scope also contains
43    /// information about the variables that it is currently required to close
44    /// over which is threaded into the current in-progress translation of
45    /// the sub-component which pushed a scope here.
46    lexical_scopes: Vec<LexicalScope<'data>>,
47
48    /// The validator in use to verify that the raw input binary is a valid
49    /// component.
50    validator: &'a mut Validator,
51
52    /// Type information shared for the entire component.
53    ///
54    /// This builder is also used for all core wasm modules found to intern
55    /// signatures across all modules.
56    types: PreInliningComponentTypes<'a>,
57
58    /// The compiler configuration provided by the embedder.
59    tunables: &'a Tunables,
60
61    /// Auxiliary location to push generated adapter modules onto.
62    scope_vec: &'data ScopeVec<u8>,
63
64    /// Completely translated core wasm modules that have been found so far.
65    ///
66    /// Note that this translation only involves learning about type
67    /// information and functions are not actually compiled here.
68    static_modules: PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
69
70    /// Completely translated components that have been found so far.
71    ///
72    /// As frames are popped from `lexical_scopes` their completed component
73    /// will be pushed onto this list.
74    static_components: PrimaryMap<StaticComponentIndex, Translation<'data>>,
75
76    /// The top-level import name for Wasmtime's unsafe intrinsics, if any.
77    unsafe_intrinsics_import: Option<&'a str>,
78}
79
80/// Representation of the syntactic scope of a component meaning where it is
81/// and what its state is at in the binary format.
82///
83/// These scopes are pushed and popped when a sub-component starts being
84/// parsed and finishes being parsed. The main purpose of this frame is to
85/// have a `ClosedOverVars` field which encapsulates data that is inherited
86/// from the scope specified into the component being translated just beneath
87/// it.
88///
89/// This structure exists to implement outer aliases to components and modules.
90/// When a component or module is closed over then that means it needs to be
91/// inherited in a sense to the component which actually had the alias. This is
92/// achieved with a deceptively simple scheme where each parent of the
93/// component with the alias will inherit the component from the desired
94/// location.
95///
96/// For example with a component structure that looks like:
97///
98/// ```wasm
99/// (component $A
100///     (core module $M)
101///     (component $B
102///         (component $C
103///             (alias outer $A $M (core module))
104///         )
105///     )
106/// )
107/// ```
108///
109/// here the `C` component is closing over `M` located in the root component
110/// `A`. When `C` is being translated the `lexical_scopes` field will look like
111/// `[A, B]`. When the alias is encountered (for module index 0) this will
112/// place a `ClosedOverModule::Local(0)` entry into the `closure_args` field of
113/// `A`'s frame. This will in turn give a `ModuleUpvarIndex` which is then
114/// inserted into `closure_args` in `B`'s frame. This produces yet another
115/// `ModuleUpvarIndex` which is finally inserted into `C`'s module index space
116/// via `LocalInitializer::AliasModuleUpvar` with the last index.
117///
118/// All of these upvar indices and such are interpreted in the "inline" phase
119/// of compilation and not at runtime. This means that when `A` is being
120/// instantiated one of its initializers will be
121/// `LocalInitializer::ComponentStatic`. This starts to create `B` and the
122/// variables captured for `B` are listed as local module 0, or `M`. This list
123/// is then preserved in the definition of the component `B` and later reused
124/// by `C` again to finally get access to the closed over component.
125///
126/// Effectively the scopes are managed hierarchically where a reference to an
127/// outer variable automatically injects references into all parents up to
128/// where the reference is. This variable scopes are the processed during
129/// inlining where a component definition is a reference to the static
130/// component information (`Translation`) plus closed over variables
131/// (`ComponentClosure` during inlining).
132struct LexicalScope<'data> {
133    /// Current state of translating the `translation` below.
134    parser: Parser,
135    /// Current state of the component's translation as found so far.
136    translation: Translation<'data>,
137    /// List of captures that `translation` will need to process to create the
138    /// sub-component which is directly beneath this lexical scope.
139    closure_args: ClosedOverVars,
140}
141
142/// A "local" translation of a component.
143///
144/// This structure is used as a sort of in-progress translation of a component.
145/// This is not `Component` which is the final form as consumed by Wasmtime
146/// at runtime. Instead this is a fairly simple representation of a component
147/// where almost everything is ordered as a list of initializers. The binary
148/// format is translated to a list of initializers here which is later processed
149/// during "inlining" to produce a final component with the final set of
150/// initializers.
151#[derive(Default)]
152struct Translation<'data> {
153    /// Instructions which form this component.
154    ///
155    /// There is one initializer for all members of each index space, and all
156    /// index spaces are incrementally built here as the initializer list is
157    /// processed.
158    initializers: Vec<LocalInitializer<'data>>,
159
160    /// The list of exports from this component, as pairs of names and an
161    /// index into an index space of what's being exported.
162    exports: IndexMap<&'data str, (ComponentItem, wasmparser::ComponentExternName<'data>)>,
163
164    /// Type information produced by `wasmparser` for this component.
165    ///
166    /// This type information is available after the translation of the entire
167    /// component has finished, e.g. for the `inline` pass, but beforehand this
168    /// is set to `None`.
169    types: Option<Types>,
170}
171
172// NB: the type information contained in `LocalInitializer` should always point
173// to `wasmparser`'s type information, not Wasmtime's. Component types cannot be
174// fully determined due to resources until instantiations are known which is
175// tracked during the inlining phase. This means that all type information below
176// is straight from `wasmparser`'s passes.
177enum LocalInitializer<'data> {
178    // imports
179    Import(ComponentExternName<'data>, ComponentEntityType),
180
181    // An import of an intrinsic for compile-time builtins.
182    IntrinsicsImport,
183
184    // canonical function sections
185    Lower {
186        func: ComponentFuncIndex,
187        lower_ty: ComponentFuncTypeId,
188        options: LocalCanonicalOptions,
189    },
190    Lift(ComponentFuncTypeId, FuncIndex, LocalCanonicalOptions),
191
192    // resources
193    Resource(AliasableResourceId, WasmValType, Option<FuncIndex>),
194    ResourceNew(AliasableResourceId, ModuleInternedTypeIndex),
195    ResourceRep(AliasableResourceId, ModuleInternedTypeIndex),
196    ResourceDrop(AliasableResourceId, ModuleInternedTypeIndex),
197
198    BackpressureInc {
199        func: ModuleInternedTypeIndex,
200    },
201    BackpressureDec {
202        func: ModuleInternedTypeIndex,
203    },
204    TaskReturn {
205        result: Option<ComponentValType>,
206        options: LocalCanonicalOptions,
207    },
208    TaskCancel {
209        func: ModuleInternedTypeIndex,
210    },
211    WaitableSetNew {
212        func: ModuleInternedTypeIndex,
213    },
214    WaitableSetWait {
215        options: LocalCanonicalOptions,
216    },
217    WaitableSetPoll {
218        options: LocalCanonicalOptions,
219    },
220    WaitableSetDrop {
221        func: ModuleInternedTypeIndex,
222    },
223    WaitableJoin {
224        func: ModuleInternedTypeIndex,
225    },
226    SubtaskDrop {
227        func: ModuleInternedTypeIndex,
228    },
229    SubtaskCancel {
230        func: ModuleInternedTypeIndex,
231        async_: bool,
232    },
233    StreamNew {
234        ty: ComponentDefinedTypeId,
235        func: ModuleInternedTypeIndex,
236    },
237    StreamRead {
238        ty: ComponentDefinedTypeId,
239        options: LocalCanonicalOptions,
240    },
241    StreamWrite {
242        ty: ComponentDefinedTypeId,
243        options: LocalCanonicalOptions,
244    },
245    StreamCancelRead {
246        ty: ComponentDefinedTypeId,
247        func: ModuleInternedTypeIndex,
248        async_: bool,
249    },
250    StreamCancelWrite {
251        ty: ComponentDefinedTypeId,
252        func: ModuleInternedTypeIndex,
253        async_: bool,
254    },
255    StreamDropReadable {
256        ty: ComponentDefinedTypeId,
257        func: ModuleInternedTypeIndex,
258    },
259    StreamDropWritable {
260        ty: ComponentDefinedTypeId,
261        func: ModuleInternedTypeIndex,
262    },
263    FutureNew {
264        ty: ComponentDefinedTypeId,
265        func: ModuleInternedTypeIndex,
266    },
267    FutureRead {
268        ty: ComponentDefinedTypeId,
269        options: LocalCanonicalOptions,
270    },
271    FutureWrite {
272        ty: ComponentDefinedTypeId,
273        options: LocalCanonicalOptions,
274    },
275    FutureCancelRead {
276        ty: ComponentDefinedTypeId,
277        func: ModuleInternedTypeIndex,
278        async_: bool,
279    },
280    FutureCancelWrite {
281        ty: ComponentDefinedTypeId,
282        func: ModuleInternedTypeIndex,
283        async_: bool,
284    },
285    FutureDropReadable {
286        ty: ComponentDefinedTypeId,
287        func: ModuleInternedTypeIndex,
288    },
289    FutureDropWritable {
290        ty: ComponentDefinedTypeId,
291        func: ModuleInternedTypeIndex,
292    },
293    ErrorContextNew {
294        options: LocalCanonicalOptions,
295    },
296    ErrorContextDebugMessage {
297        options: LocalCanonicalOptions,
298    },
299    ErrorContextDrop {
300        func: ModuleInternedTypeIndex,
301    },
302    ContextGet {
303        func: ModuleInternedTypeIndex,
304        i: u32,
305    },
306    ContextSet {
307        func: ModuleInternedTypeIndex,
308        i: u32,
309    },
310    ThreadIndex {
311        func: ModuleInternedTypeIndex,
312    },
313    ThreadNewIndirect {
314        func: ModuleInternedTypeIndex,
315        start_func_ty: ModuleInternedTypeIndex,
316        start_func_table_index: TableIndex,
317    },
318    ThreadResumeLater {
319        func: ModuleInternedTypeIndex,
320    },
321    ThreadSuspend {
322        func: ModuleInternedTypeIndex,
323    },
324    ThreadYield {
325        func: ModuleInternedTypeIndex,
326    },
327    ThreadSuspendThenResume {
328        func: ModuleInternedTypeIndex,
329    },
330    ThreadYieldThenResume {
331        func: ModuleInternedTypeIndex,
332    },
333    ThreadSuspendThenPromote {
334        func: ModuleInternedTypeIndex,
335    },
336    ThreadYieldThenPromote {
337        func: ModuleInternedTypeIndex,
338    },
339
340    // core wasm modules
341    ModuleStatic(StaticModuleIndex, ComponentCoreModuleTypeId),
342
343    // core wasm module instances
344    ModuleInstantiate(ModuleIndex, HashMap<&'data str, ModuleInstanceIndex>),
345    ModuleSynthetic(HashMap<&'data str, EntityIndex>),
346
347    // components
348    ComponentStatic(StaticComponentIndex, ClosedOverVars),
349
350    // component instances
351    ComponentInstantiate(
352        ComponentIndex,
353        HashMap<&'data str, ComponentItem>,
354        ComponentInstanceTypeId,
355    ),
356    ComponentSynthetic(HashMap<&'data str, ComponentItem>, ComponentInstanceTypeId),
357
358    // alias section
359    AliasExportFunc(ModuleInstanceIndex, &'data str),
360    AliasExportTable(ModuleInstanceIndex, &'data str),
361    AliasExportGlobal(ModuleInstanceIndex, &'data str),
362    AliasExportMemory(ModuleInstanceIndex, &'data str),
363    AliasExportTag(ModuleInstanceIndex, &'data str),
364    AliasComponentExport(ComponentInstanceIndex, &'data str),
365    AliasModule(ClosedOverModule),
366    AliasComponent(ClosedOverComponent),
367
368    // export section
369    Export(ComponentItem),
370}
371
372/// The "closure environment" of components themselves.
373///
374/// For more information see `LexicalScope`.
375#[derive(Default)]
376struct ClosedOverVars {
377    components: PrimaryMap<ComponentUpvarIndex, ClosedOverComponent>,
378    modules: PrimaryMap<ModuleUpvarIndex, ClosedOverModule>,
379}
380
381/// Description how a component is closed over when the closure variables for
382/// a component are being created.
383///
384/// For more information see `LexicalScope`.
385enum ClosedOverComponent {
386    /// A closed over component is coming from the local component's index
387    /// space, meaning a previously defined component is being captured.
388    Local(ComponentIndex),
389    /// A closed over component is coming from our own component's list of
390    /// upvars. This list was passed to us by our enclosing component, which
391    /// will eventually have bottomed out in closing over a `Local` component
392    /// index for some parent component.
393    Upvar(ComponentUpvarIndex),
394}
395
396/// Same as `ClosedOverComponent`, but for modules.
397enum ClosedOverModule {
398    Local(ModuleIndex),
399    Upvar(ModuleUpvarIndex),
400}
401
402/// The data model for objects that are not unboxed in locals.
403#[derive(Debug, Clone, Hash, Eq, PartialEq)]
404pub enum LocalDataModel {
405    /// Data is stored in GC objects.
406    Gc {},
407
408    /// Data is stored in a linear memory.
409    LinearMemory {
410        /// An optional memory definition supplied.
411        memory: Option<MemoryIndex>,
412        /// An optional definition of `realloc` to used.
413        realloc: Option<FuncIndex>,
414    },
415}
416
417/// Representation of canonical ABI options.
418struct LocalCanonicalOptions {
419    string_encoding: StringEncoding,
420    post_return: Option<FuncIndex>,
421    async_: bool,
422    callback: Option<FuncIndex>,
423    /// The type index of the core GC types signature.
424    core_type: ModuleInternedTypeIndex,
425    data_model: LocalDataModel,
426}
427
428enum Action {
429    KeepGoing,
430    Skip(usize),
431    Done,
432}
433
434impl<'a, 'data> Translator<'a, 'data> {
435    /// Creates a new translation state ready to translate a component.
436    pub fn new(
437        tunables: &'a Tunables,
438        validator: &'a mut Validator,
439        types: &'a mut ComponentTypesBuilder,
440        scope_vec: &'data ScopeVec<u8>,
441    ) -> Self {
442        let mut parser = Parser::new(0);
443        parser.set_features(*validator.features());
444        Self {
445            result: Translation::default(),
446            tunables,
447            validator,
448            types: PreInliningComponentTypes::new(types),
449            parser,
450            lexical_scopes: Vec::new(),
451            static_components: Default::default(),
452            static_modules: Default::default(),
453            scope_vec,
454            unsafe_intrinsics_import: None,
455        }
456    }
457
458    /// Expose Wasmtime's unsafe intrinsics under the given top-level import
459    /// name.
460    pub fn expose_unsafe_intrinsics(&mut self, name: &'a str) -> &mut Self {
461        assert!(self.unsafe_intrinsics_import.is_none());
462        self.unsafe_intrinsics_import = Some(name);
463        self
464    }
465
466    /// Translates the binary `component`.
467    ///
468    /// This is the workhorse of compilation which will parse all of
469    /// `component` and create type information for Wasmtime and such. The
470    /// `component` does not have to be valid and it will be validated during
471    /// compilation.
472    ///
473    /// The result of this function is a tuple of the final component's
474    /// description plus a list of core wasm modules found within the
475    /// component. The component's description actually erases internal
476    /// components, instances, etc, as much as it can. Instead `Component`
477    /// retains a flat list of initializers (no nesting) which was created
478    /// as part of compilation from the nested structure of the original
479    /// component.
480    ///
481    /// The list of core wasm modules found is provided to allow compiling
482    /// modules externally in parallel. Additionally initializers in
483    /// `Component` may refer to the modules in the map returned by index.
484    ///
485    /// # Errors
486    ///
487    /// This function will return an error if the `component` provided is
488    /// invalid.
489    pub fn translate(
490        mut self,
491        component: &'data [u8],
492    ) -> Result<(
493        ComponentTranslation,
494        PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
495    )> {
496        // First up wasmparser is used to actually perform the translation and
497        // validation of this component. This will produce a list of core wasm
498        // modules in addition to components which are found during the
499        // translation process. When doing this only a `Translation` is created
500        // which is a simple representation of a component.
501        let mut remaining = component;
502        loop {
503            let payload = match self.parser.parse(remaining, true)? {
504                Chunk::Parsed { payload, consumed } => {
505                    remaining = &remaining[consumed..];
506                    payload
507                }
508                Chunk::NeedMoreData(_) => unreachable!(),
509            };
510
511            match self.translate_payload(payload, component)? {
512                Action::KeepGoing => {}
513                Action::Skip(n) => remaining = &remaining[n..],
514                Action::Done => break,
515            }
516        }
517        assert!(remaining.is_empty());
518        assert!(self.lexical_scopes.is_empty());
519
520        // ... after translation initially finishes the next pass is performed
521        // which we're calling "inlining". This will "instantiate" the root
522        // component, following nested component instantiations, creating a
523        // global list of initializers along the way. This phase uses the simple
524        // initializers in each component to track dataflow of host imports and
525        // internal references to items throughout a component at compile-time.
526        // The produce initializers in the final `Component` are intended to be
527        // much simpler than the original component and more efficient for
528        // Wasmtime to process at runtime as well (e.g. no string lookups as
529        // most everything is done through indices instead).
530        let mut component = inline::run(
531            self.types.types_mut_for_inlining(),
532            &self.result,
533            &self.static_modules,
534            &self.static_components,
535        )?;
536
537        // Now that inlining has finished and the dataflow graph is complete,
538        // determine which fused adapters can skip their
539        // `{enter,exit}-sync-call` calls.
540        component.transparent_adapters = transparent_adapters(&component, self.types.types());
541
542        self.partition_adapter_modules(&mut component)?;
543
544        analyze_same_vmctx_imports(&component, &mut self.static_modules);
545
546        let translation =
547            component.finish(self.types.types_mut_for_inlining(), self.result.types_ref())?;
548
549        self.analyze_imports(&translation);
550
551        Ok((translation, self.static_modules))
552    }
553
554    /// Record everything we statically know about each module's imports.
555    ///
556    /// See `ModuleTranslation::known_imported_functions` and
557    /// `ModuleTranslation::known_imported_globals` for how we can optimize
558    /// lowering based on this information.
559    fn analyze_imports(&mut self, translation: &ComponentTranslation) {
560        // First, abstract interpret the initializers to create a map from each
561        // static module to its abstract set of instantiations.
562        let mut instantiations = SecondaryMap::<StaticModuleIndex, AbstractInstantiations>::new();
563        let mut instances = StaticInstances::new(&self.static_modules);
564        for init in &translation.component.initializers {
565            match init {
566                GlobalInitializer::InstantiateModule(instantiation, _) => match instantiation {
567                    InstantiateModule::Static(module, args) => {
568                        instantiations[*module].join(AbstractInstantiations::One(&*args));
569                        instances.push(Some((*module, &args[..])));
570                    }
571                    _ => {
572                        instances.push(None);
573                    }
574                },
575                _ => continue,
576            }
577        }
578
579        // Second, make sure to mark exported modules as instantiated many
580        // times, since they could be linked with who-knows-what at runtime.
581        for item in translation.component.export_items.values() {
582            if let Export::ModuleStatic { index, .. } = item {
583                instantiations[*index].join(AbstractInstantiations::Many)
584            }
585        }
586
587        // Third, find the globals, memories, and tables whose identity is not
588        // statically known to everything that can access them. Note that this
589        // is a property of the whole component and not of a single module's
590        // instantiations; see `ModuleTranslation::known_imported_globals` for
591        // details.
592        let ambiguous = ambiguous_entities(translation, &instantiations, &instances);
593
594        // Fourth, record which of each module's own defined entities all of
595        // their importers agree on, which lets those modules use a precise alias
596        // region for them even when they are exported.
597        for (module, translation) in self.static_modules.iter_mut() {
598            for i in 0..translation.module.num_defined_globals() {
599                let index = DefinedGlobalIndex::new(i);
600                let global = translation.module.global_index(index);
601                if !ambiguous
602                    .entities
603                    .contains(&(module, EntityIndex::Global(global)))
604                {
605                    translation.globals_known_to_importers.insert(index);
606                }
607            }
608            for i in 0..translation.module.num_defined_memories() {
609                let index = DefinedMemoryIndex::new(i);
610                let memory = translation.module.memory_index(index);
611                if !ambiguous
612                    .entities
613                    .contains(&(module, EntityIndex::Memory(memory)))
614                {
615                    translation.memories_known_to_importers.insert(index);
616                }
617            }
618            for i in 0..translation.module.num_defined_tables() {
619                let index = DefinedTableIndex::new(i);
620                let table = translation.module.table_index(index);
621                if !ambiguous
622                    .entities
623                    .contains(&(module, EntityIndex::Table(table)))
624                {
625                    translation.tables_known_to_importers.insert(index);
626                }
627            }
628        }
629
630        // Finally, iterate over our instantiations and record statically-known
631        // imports: function imports so that they can get translated into direct
632        // calls (and eventually get inlined) rather than indirect calls through
633        // the imports table; and global, memory, and table imports so that they
634        // can get precise alias regions instead of the conservative regions
635        // shared by everything that crosses a module boundary.
636        for (module, instantiations) in instantiations.iter() {
637            let args = match instantiations {
638                dfg::AbstractInstantiations::Many | dfg::AbstractInstantiations::None => continue,
639                dfg::AbstractInstantiations::One(args) => args,
640            };
641
642            for (i, arg) in args.iter().enumerate() {
643                // Record that this global, memory, or table import is always the
644                // same defined entity, when we know that and when everything
645                // else that imports that entity knows it too.
646                macro_rules! record_known_entity {
647                    ($variant:ident, $imported:expr, $defined_index:ident, $known:ident, $wrap:expr) => {{
648                        let Some((arg_module, EntityIndex::$variant(arg_entity))) =
649                            unambiguous_entity(&instances, &ambiguous.entities, arg)
650                        else {
651                            continue;
652                        };
653                        let index = self.static_modules[arg_module]
654                            .module
655                            .$defined_index(arg_entity)
656                            .expect(
657                                "`resolve_core_export` only returns entities that their module \
658                                 defines",
659                            );
660                        assert!(self.static_modules[module].$known[$imported].is_none());
661                        self.static_modules[module].$known[$imported] = Some($wrap(KnownEntity {
662                            module: arg_module,
663                            index,
664                        }));
665                    }};
666                }
667
668                match self.static_modules[module].module.import_index(i).unwrap() {
669                    EntityIndex::Function(imported_func) => {
670                        debug_assert!(
671                            self.static_modules[module]
672                                .module
673                                .defined_func_index(imported_func)
674                                .is_none()
675                        );
676
677                        let known_func = match arg {
678                            CoreDef::InstanceFlags(_) => {
679                                unreachable!("instance flags are not a function")
680                            }
681
682                            // We could in theory inline these trampolines, so it
683                            // could potentially make sense to record that we
684                            // know this imported function is this particular
685                            // trampoline. However, everything else is based
686                            // around (module, defined-function) pairs and these
687                            // trampolines don't fit that paradigm. Also,
688                            // inlining trampolines gets really tricky when we
689                            // consider the stack pointer, frame pointer, and
690                            // return address note-taking that they do for the
691                            // purposes of stack walking. We could, with enough
692                            // effort, turn them into direct calls even though we
693                            // probably wouldn't ever inline them, but it just
694                            // doesn't seem worth the effort.
695                            //
696                            // That said, a couple of adapter trampolines are
697                            // lowered inline during translation. We record these
698                            // here so `FuncEnvironment` recognizes them. All
699                            // other trampolines remain indirect calls.
700                            CoreDef::Trampoline(index) => match translation.trampolines[*index] {
701                                Trampoline::EnterSyncCall => {
702                                    FactInlineIntrinsic::EnterSyncCall.into()
703                                }
704                                Trampoline::ExitSyncCall => {
705                                    FactInlineIntrinsic::ExitSyncCall.into()
706                                }
707                                Trampoline::Trap(trap) => FactInlineIntrinsic::Trap(trap).into(),
708                                _ => continue,
709                            },
710
711                            // This import is a compile-time builtin intrinsic,
712                            // we should inline its implementation during
713                            // function translation.
714                            CoreDef::UnsafeIntrinsic(i) => {
715                                FuncKey::UnsafeIntrinsic(Abi::Wasm, *i).into()
716                            }
717
718                            // This imported function is an export from another
719                            // instance, a perfect candidate for becoming an
720                            // inlinable direct call!
721                            CoreDef::Export(export) => {
722                                let Some((arg_module, arg_entity)) =
723                                    resolve_core_export(&instances, export)
724                                else {
725                                    // Either an instance of a dynamic module that
726                                    // is not part of this component, or a
727                                    // re-export chain that bottoms out in
728                                    // something that isn't a defined function
729                                    // (for example a re-export of a trampoline;
730                                    // note that we only match trampolines and
731                                    // intrinsics as *direct* arguments above).
732                                    // Either way we have to do an indirect call.
733                                    continue;
734                                };
735
736                                let EntityIndex::Function(arg_func) = arg_entity else {
737                                    unreachable!("function imports must be functions")
738                                };
739
740                                let arg_module_def_func = self.static_modules[arg_module]
741                                    .module
742                                    .defined_func_index(arg_func)
743                                    .expect(
744                                        "`resolve_core_export` only returns entities that their \
745                                         module defines",
746                                    );
747
748                                FuncKey::DefinedWasmFunction(arg_module, arg_module_def_func).into()
749                            }
750                        };
751
752                        assert!(
753                            self.static_modules[module].known_imported_functions[imported_func]
754                                .is_none()
755                        );
756                        self.static_modules[module].known_imported_functions[imported_func] =
757                            Some(known_func);
758                    }
759
760                    // Note that a global import is not necessarily satisfied by a
761                    // wasm global: it can also be one of the component-model
762                    // flags that live in the `VMComponentContext`, and those get
763                    // their own alias regions rather than a defined-global one.
764                    EntityIndex::Global(imported_global) => match component_flags(arg) {
765                        Some(flags) => {
766                            if ambiguous.flags.contains(&flags) {
767                                continue;
768                            }
769                            assert!(
770                                self.static_modules[module].known_imported_globals[imported_global]
771                                    .is_none()
772                            );
773                            self.static_modules[module].known_imported_globals[imported_global] =
774                                Some(flags);
775                        }
776                        None => record_known_entity!(
777                            Global,
778                            imported_global,
779                            defined_global_index,
780                            known_imported_globals,
781                            KnownGlobal::Defined
782                        ),
783                    },
784
785                    EntityIndex::Memory(imported_memory) => record_known_entity!(
786                        Memory,
787                        imported_memory,
788                        defined_memory_index,
789                        known_imported_memories,
790                        core::convert::identity
791                    ),
792
793                    EntityIndex::Table(imported_table) => record_known_entity!(
794                        Table,
795                        imported_table,
796                        defined_table_index,
797                        known_imported_tables,
798                        core::convert::identity
799                    ),
800
801                    // Tags don't have alias regions of their own.
802                    EntityIndex::Tag(_) => {}
803                }
804            }
805        }
806    }
807
808    fn translate_payload(
809        &mut self,
810        payload: Payload<'data>,
811        component: &'data [u8],
812    ) -> Result<Action> {
813        match payload {
814            Payload::Version {
815                num,
816                encoding,
817                range,
818            } => {
819                self.validator.version(num, encoding, &range)?;
820
821                match encoding {
822                    Encoding::Component => {}
823                    Encoding::Module => {
824                        bail!("attempted to parse a wasm module with a component parser");
825                    }
826                }
827            }
828
829            Payload::End(offset) => {
830                assert!(self.result.types.is_none());
831                self.result.types = Some(self.validator.end(offset)?);
832
833                // Exit the current lexical scope. If there is no parent (no
834                // frame currently on the stack) then translation is finished.
835                // Otherwise that means that a nested component has been
836                // completed and is recorded as such.
837                let LexicalScope {
838                    parser,
839                    translation,
840                    closure_args,
841                } = match self.lexical_scopes.pop() {
842                    Some(frame) => frame,
843                    None => return Ok(Action::Done),
844                };
845                self.parser = parser;
846                let component = mem::replace(&mut self.result, translation);
847                let static_idx = self.static_components.push(component);
848                self.result
849                    .initializers
850                    .push(LocalInitializer::ComponentStatic(static_idx, closure_args));
851            }
852
853            // When we see a type section the types are validated and then
854            // translated into Wasmtime's representation. Each active type
855            // definition is recorded in the `ComponentTypesBuilder` tables, or
856            // this component's active scope.
857            //
858            // Note that the push/pop of the component types scope happens above
859            // in `Version` and `End` since multiple type sections can appear
860            // within a component.
861            Payload::ComponentTypeSection(s) => {
862                let mut component_type_index =
863                    self.validator.types(0).unwrap().component_type_count();
864                self.validator.component_type_section(&s)?;
865
866                // Look for resource types and if a local resource is defined
867                // then an initializer is added to define that resource type and
868                // reference its destructor.
869                let types = self.validator.types(0).unwrap();
870                for ty in s {
871                    match ty? {
872                        wasmparser::ComponentType::Resource { rep, dtor } => {
873                            let rep = self.types.convert_valtype(rep)?;
874                            let id = types
875                                .component_any_type_at(component_type_index)
876                                .unwrap_resource();
877                            let dtor = dtor.map(FuncIndex::from_u32);
878                            self.result
879                                .initializers
880                                .push(LocalInitializer::Resource(id, rep, dtor));
881                        }
882
883                        // no extra processing needed
884                        wasmparser::ComponentType::Defined(_)
885                        | wasmparser::ComponentType::Func(_)
886                        | wasmparser::ComponentType::Instance(_)
887                        | wasmparser::ComponentType::Component(_) => {}
888                    }
889
890                    component_type_index += 1;
891                }
892            }
893
894            // Core types defined at the component level, such as the type of a
895            // `thread.new-indirect` start function, are interned as they're
896            // defined, just like in a core module. This ensures that all rec
897            // groups that a rec group refers to are interned before it is.
898            Payload::CoreTypeSection(s) => {
899                let mut index = self
900                    .validator
901                    .types(0)
902                    .unwrap()
903                    .core_type_count_in_component();
904                self.validator.core_type_section(&s)?;
905                let types = self.validator.types(0).unwrap();
906                let count = types.core_type_count_in_component();
907                while index < count {
908                    match types.core_type_at_in_component(index) {
909                        // The current type index is always the first type of
910                        // its rec group, so intern the group and then skip
911                        // past the rest of its types.
912                        ComponentCoreTypeId::Sub(id) => {
913                            let group_id = types.rec_group_id_of(id);
914                            self.types
915                                .module_types_builder()
916                                .intern_rec_group(types, group_id)?;
917                            index +=
918                                u32::try_from(types.rec_group_elements(group_id).len()).unwrap();
919                        }
920                        ComponentCoreTypeId::Module(_) => index += 1,
921                    }
922                }
923            }
924
925            // Processing the import section at this point is relatively simple
926            // which is to simply record the name of the import and the type
927            // information associated with it.
928            Payload::ComponentImportSection(s) => {
929                self.validator.component_import_section(&s)?;
930                for import in s {
931                    let import = import?;
932                    let types = self.validator.types(0).unwrap();
933                    let ty = types
934                        .component_item_for_import(import.name.name)
935                        .unwrap()
936                        .ty;
937
938                    if self.is_unsafe_intrinsics_import(import.name.name) {
939                        self.check_unsafe_intrinsics_import(import.name.name, ty)?;
940                        self.result
941                            .initializers
942                            .push(LocalInitializer::IntrinsicsImport);
943                    } else {
944                        self.result
945                            .initializers
946                            .push(LocalInitializer::Import(import.name, ty));
947                    }
948                }
949            }
950
951            // Entries in the canonical section will get initializers recorded
952            // with the listed options for lifting/lowering.
953            Payload::ComponentCanonicalSection(s) => {
954                let types = self.validator.types(0).unwrap();
955                let mut core_func_index = types.function_count();
956                self.validator.component_canonical_section(&s)?;
957                for func in s {
958                    let init = match func? {
959                        wasmparser::CanonicalFunction::Lift {
960                            type_index,
961                            core_func_index,
962                            options,
963                        } => {
964                            let ty = self
965                                .validator
966                                .types(0)
967                                .unwrap()
968                                .component_any_type_at(type_index)
969                                .unwrap_func();
970
971                            let func = FuncIndex::from_u32(core_func_index);
972                            let options = self.canonical_options(&options, core_func_index)?;
973                            LocalInitializer::Lift(ty, func, options)
974                        }
975                        wasmparser::CanonicalFunction::Lower {
976                            func_index,
977                            options,
978                        } => {
979                            let lower_ty = self
980                                .validator
981                                .types(0)
982                                .unwrap()
983                                .component_function_at(func_index);
984                            let func = ComponentFuncIndex::from_u32(func_index);
985                            let options = self.canonical_options(&options, core_func_index)?;
986                            core_func_index += 1;
987                            LocalInitializer::Lower {
988                                func,
989                                options,
990                                lower_ty,
991                            }
992                        }
993                        wasmparser::CanonicalFunction::ResourceNew { resource } => {
994                            let resource = self
995                                .validator
996                                .types(0)
997                                .unwrap()
998                                .component_any_type_at(resource)
999                                .unwrap_resource();
1000                            let ty = self.core_func_signature(core_func_index)?;
1001                            core_func_index += 1;
1002                            LocalInitializer::ResourceNew(resource, ty)
1003                        }
1004                        wasmparser::CanonicalFunction::ResourceDrop { resource } => {
1005                            let resource = self
1006                                .validator
1007                                .types(0)
1008                                .unwrap()
1009                                .component_any_type_at(resource)
1010                                .unwrap_resource();
1011                            let ty = self.core_func_signature(core_func_index)?;
1012                            core_func_index += 1;
1013                            LocalInitializer::ResourceDrop(resource, ty)
1014                        }
1015                        wasmparser::CanonicalFunction::ResourceRep { resource } => {
1016                            let resource = self
1017                                .validator
1018                                .types(0)
1019                                .unwrap()
1020                                .component_any_type_at(resource)
1021                                .unwrap_resource();
1022                            let ty = self.core_func_signature(core_func_index)?;
1023                            core_func_index += 1;
1024                            LocalInitializer::ResourceRep(resource, ty)
1025                        }
1026                        wasmparser::CanonicalFunction::ThreadSpawnRef { .. }
1027                        | wasmparser::CanonicalFunction::ThreadSpawnIndirect { .. }
1028                        | wasmparser::CanonicalFunction::ThreadAvailableParallelism => {
1029                            bail!("unsupported intrinsic")
1030                        }
1031                        wasmparser::CanonicalFunction::BackpressureInc => {
1032                            let core_type = self.core_func_signature(core_func_index)?;
1033                            core_func_index += 1;
1034                            LocalInitializer::BackpressureInc { func: core_type }
1035                        }
1036                        wasmparser::CanonicalFunction::BackpressureDec => {
1037                            let core_type = self.core_func_signature(core_func_index)?;
1038                            core_func_index += 1;
1039                            LocalInitializer::BackpressureDec { func: core_type }
1040                        }
1041
1042                        wasmparser::CanonicalFunction::TaskReturn { result, options } => {
1043                            let result = result.map(|ty| match ty {
1044                                wasmparser::ComponentValType::Primitive(ty) => {
1045                                    ComponentValType::Primitive(ty)
1046                                }
1047                                wasmparser::ComponentValType::Type(ty) => ComponentValType::Type(
1048                                    self.validator
1049                                        .types(0)
1050                                        .unwrap()
1051                                        .component_defined_type_at(ty),
1052                                ),
1053                            });
1054                            let options = self.canonical_options(&options, core_func_index)?;
1055                            core_func_index += 1;
1056                            LocalInitializer::TaskReturn { result, options }
1057                        }
1058                        wasmparser::CanonicalFunction::TaskCancel => {
1059                            let func = self.core_func_signature(core_func_index)?;
1060                            core_func_index += 1;
1061                            LocalInitializer::TaskCancel { func }
1062                        }
1063                        wasmparser::CanonicalFunction::WaitableSetNew => {
1064                            let func = self.core_func_signature(core_func_index)?;
1065                            core_func_index += 1;
1066                            LocalInitializer::WaitableSetNew { func }
1067                        }
1068                        wasmparser::CanonicalFunction::WaitableSetWait { memory } => {
1069                            let core_type = self.core_func_signature(core_func_index)?;
1070                            core_func_index += 1;
1071                            LocalInitializer::WaitableSetWait {
1072                                options: LocalCanonicalOptions {
1073                                    core_type,
1074                                    async_: false,
1075                                    data_model: LocalDataModel::LinearMemory {
1076                                        memory: Some(MemoryIndex::from_u32(memory)),
1077                                        realloc: None,
1078                                    },
1079                                    post_return: None,
1080                                    callback: None,
1081                                    string_encoding: StringEncoding::Utf8,
1082                                },
1083                            }
1084                        }
1085                        wasmparser::CanonicalFunction::WaitableSetPoll { memory } => {
1086                            let core_type = self.core_func_signature(core_func_index)?;
1087                            core_func_index += 1;
1088                            LocalInitializer::WaitableSetPoll {
1089                                options: LocalCanonicalOptions {
1090                                    core_type,
1091                                    async_: false,
1092                                    data_model: LocalDataModel::LinearMemory {
1093                                        memory: Some(MemoryIndex::from_u32(memory)),
1094                                        realloc: None,
1095                                    },
1096                                    post_return: None,
1097                                    callback: None,
1098                                    string_encoding: StringEncoding::Utf8,
1099                                },
1100                            }
1101                        }
1102                        wasmparser::CanonicalFunction::WaitableSetDrop => {
1103                            let func = self.core_func_signature(core_func_index)?;
1104                            core_func_index += 1;
1105                            LocalInitializer::WaitableSetDrop { func }
1106                        }
1107                        wasmparser::CanonicalFunction::WaitableJoin => {
1108                            let func = self.core_func_signature(core_func_index)?;
1109                            core_func_index += 1;
1110                            LocalInitializer::WaitableJoin { func }
1111                        }
1112                        wasmparser::CanonicalFunction::SubtaskDrop => {
1113                            let func = self.core_func_signature(core_func_index)?;
1114                            core_func_index += 1;
1115                            LocalInitializer::SubtaskDrop { func }
1116                        }
1117                        wasmparser::CanonicalFunction::SubtaskCancel { async_ } => {
1118                            let func = self.core_func_signature(core_func_index)?;
1119                            core_func_index += 1;
1120                            LocalInitializer::SubtaskCancel { func, async_ }
1121                        }
1122                        wasmparser::CanonicalFunction::StreamNew { ty } => {
1123                            let ty = self
1124                                .validator
1125                                .types(0)
1126                                .unwrap()
1127                                .component_defined_type_at(ty);
1128                            let func = self.core_func_signature(core_func_index)?;
1129                            core_func_index += 1;
1130                            LocalInitializer::StreamNew { ty, func }
1131                        }
1132                        wasmparser::CanonicalFunction::StreamRead { ty, options } => {
1133                            let ty = self
1134                                .validator
1135                                .types(0)
1136                                .unwrap()
1137                                .component_defined_type_at(ty);
1138                            let options = self.canonical_options(&options, core_func_index)?;
1139                            core_func_index += 1;
1140                            LocalInitializer::StreamRead { ty, options }
1141                        }
1142                        wasmparser::CanonicalFunction::StreamWrite { ty, options } => {
1143                            let ty = self
1144                                .validator
1145                                .types(0)
1146                                .unwrap()
1147                                .component_defined_type_at(ty);
1148                            let options = self.canonical_options(&options, core_func_index)?;
1149                            core_func_index += 1;
1150                            LocalInitializer::StreamWrite { ty, options }
1151                        }
1152                        wasmparser::CanonicalFunction::StreamCancelRead { ty, async_ } => {
1153                            let ty = self
1154                                .validator
1155                                .types(0)
1156                                .unwrap()
1157                                .component_defined_type_at(ty);
1158                            let func = self.core_func_signature(core_func_index)?;
1159                            core_func_index += 1;
1160                            LocalInitializer::StreamCancelRead { ty, func, async_ }
1161                        }
1162                        wasmparser::CanonicalFunction::StreamCancelWrite { ty, async_ } => {
1163                            let ty = self
1164                                .validator
1165                                .types(0)
1166                                .unwrap()
1167                                .component_defined_type_at(ty);
1168                            let func = self.core_func_signature(core_func_index)?;
1169                            core_func_index += 1;
1170                            LocalInitializer::StreamCancelWrite { ty, func, async_ }
1171                        }
1172                        wasmparser::CanonicalFunction::StreamDropReadable { ty } => {
1173                            let ty = self
1174                                .validator
1175                                .types(0)
1176                                .unwrap()
1177                                .component_defined_type_at(ty);
1178                            let func = self.core_func_signature(core_func_index)?;
1179                            core_func_index += 1;
1180                            LocalInitializer::StreamDropReadable { ty, func }
1181                        }
1182                        wasmparser::CanonicalFunction::StreamDropWritable { ty } => {
1183                            let ty = self
1184                                .validator
1185                                .types(0)
1186                                .unwrap()
1187                                .component_defined_type_at(ty);
1188                            let func = self.core_func_signature(core_func_index)?;
1189                            core_func_index += 1;
1190                            LocalInitializer::StreamDropWritable { ty, func }
1191                        }
1192                        wasmparser::CanonicalFunction::FutureNew { ty } => {
1193                            let ty = self
1194                                .validator
1195                                .types(0)
1196                                .unwrap()
1197                                .component_defined_type_at(ty);
1198                            let func = self.core_func_signature(core_func_index)?;
1199                            core_func_index += 1;
1200                            LocalInitializer::FutureNew { ty, func }
1201                        }
1202                        wasmparser::CanonicalFunction::FutureRead { ty, options } => {
1203                            let ty = self
1204                                .validator
1205                                .types(0)
1206                                .unwrap()
1207                                .component_defined_type_at(ty);
1208                            let options = self.canonical_options(&options, core_func_index)?;
1209                            core_func_index += 1;
1210                            LocalInitializer::FutureRead { ty, options }
1211                        }
1212                        wasmparser::CanonicalFunction::FutureWrite { ty, options } => {
1213                            let ty = self
1214                                .validator
1215                                .types(0)
1216                                .unwrap()
1217                                .component_defined_type_at(ty);
1218                            let options = self.canonical_options(&options, core_func_index)?;
1219                            core_func_index += 1;
1220                            LocalInitializer::FutureWrite { ty, options }
1221                        }
1222                        wasmparser::CanonicalFunction::FutureCancelRead { ty, async_ } => {
1223                            let ty = self
1224                                .validator
1225                                .types(0)
1226                                .unwrap()
1227                                .component_defined_type_at(ty);
1228                            let func = self.core_func_signature(core_func_index)?;
1229                            core_func_index += 1;
1230                            LocalInitializer::FutureCancelRead { ty, func, async_ }
1231                        }
1232                        wasmparser::CanonicalFunction::FutureCancelWrite { ty, async_ } => {
1233                            let ty = self
1234                                .validator
1235                                .types(0)
1236                                .unwrap()
1237                                .component_defined_type_at(ty);
1238                            let func = self.core_func_signature(core_func_index)?;
1239                            core_func_index += 1;
1240                            LocalInitializer::FutureCancelWrite { ty, func, async_ }
1241                        }
1242                        wasmparser::CanonicalFunction::FutureDropReadable { ty } => {
1243                            let ty = self
1244                                .validator
1245                                .types(0)
1246                                .unwrap()
1247                                .component_defined_type_at(ty);
1248                            let func = self.core_func_signature(core_func_index)?;
1249                            core_func_index += 1;
1250                            LocalInitializer::FutureDropReadable { ty, func }
1251                        }
1252                        wasmparser::CanonicalFunction::FutureDropWritable { ty } => {
1253                            let ty = self
1254                                .validator
1255                                .types(0)
1256                                .unwrap()
1257                                .component_defined_type_at(ty);
1258                            let func = self.core_func_signature(core_func_index)?;
1259                            core_func_index += 1;
1260                            LocalInitializer::FutureDropWritable { ty, func }
1261                        }
1262                        wasmparser::CanonicalFunction::ErrorContextNew { options } => {
1263                            let options = self.canonical_options(&options, core_func_index)?;
1264                            core_func_index += 1;
1265                            LocalInitializer::ErrorContextNew { options }
1266                        }
1267                        wasmparser::CanonicalFunction::ErrorContextDebugMessage { options } => {
1268                            let options = self.canonical_options(&options, core_func_index)?;
1269                            core_func_index += 1;
1270                            LocalInitializer::ErrorContextDebugMessage { options }
1271                        }
1272                        wasmparser::CanonicalFunction::ErrorContextDrop => {
1273                            let func = self.core_func_signature(core_func_index)?;
1274                            core_func_index += 1;
1275                            LocalInitializer::ErrorContextDrop { func }
1276                        }
1277                        wasmparser::CanonicalFunction::ContextGet { slot, ty } => {
1278                            if ty != wasmparser::ValType::I32 {
1279                                bail!("unsupported context.get type: {ty:?}");
1280                            }
1281                            let func = self.core_func_signature(core_func_index)?;
1282                            core_func_index += 1;
1283                            LocalInitializer::ContextGet { i: slot, func }
1284                        }
1285                        wasmparser::CanonicalFunction::ContextSet { slot, ty } => {
1286                            if ty != wasmparser::ValType::I32 {
1287                                bail!("unsupported context.set type: {ty:?}");
1288                            }
1289                            let func = self.core_func_signature(core_func_index)?;
1290                            core_func_index += 1;
1291                            LocalInitializer::ContextSet { i: slot, func }
1292                        }
1293                        wasmparser::CanonicalFunction::ThreadIndex => {
1294                            let func = self.core_func_signature(core_func_index)?;
1295                            core_func_index += 1;
1296                            LocalInitializer::ThreadIndex { func }
1297                        }
1298                        wasmparser::CanonicalFunction::ThreadNewIndirect {
1299                            func_ty_index,
1300                            table_index,
1301                        } => {
1302                            let func = self.core_func_signature(core_func_index)?;
1303                            core_func_index += 1;
1304                            let types = self.validator.types(0).unwrap();
1305                            let start_func_ty =
1306                                types.core_type_at_in_component(func_ty_index).unwrap_sub();
1307                            let start_func_ty = self
1308                                .types
1309                                .module_types_builder()
1310                                .intern_type(types, start_func_ty)?;
1311                            LocalInitializer::ThreadNewIndirect {
1312                                func,
1313                                start_func_ty,
1314                                start_func_table_index: TableIndex::from_u32(table_index),
1315                            }
1316                        }
1317                        wasmparser::CanonicalFunction::ThreadResumeLater => {
1318                            let func = self.core_func_signature(core_func_index)?;
1319                            core_func_index += 1;
1320                            LocalInitializer::ThreadResumeLater { func }
1321                        }
1322                        wasmparser::CanonicalFunction::ThreadSuspend => {
1323                            let func = self.core_func_signature(core_func_index)?;
1324                            core_func_index += 1;
1325                            LocalInitializer::ThreadSuspend { func }
1326                        }
1327                        wasmparser::CanonicalFunction::ThreadYield => {
1328                            let func = self.core_func_signature(core_func_index)?;
1329                            core_func_index += 1;
1330                            LocalInitializer::ThreadYield { func }
1331                        }
1332                        wasmparser::CanonicalFunction::ThreadSuspendThenResume => {
1333                            let func = self.core_func_signature(core_func_index)?;
1334                            core_func_index += 1;
1335                            LocalInitializer::ThreadSuspendThenResume { func }
1336                        }
1337                        wasmparser::CanonicalFunction::ThreadYieldThenResume => {
1338                            let func = self.core_func_signature(core_func_index)?;
1339                            core_func_index += 1;
1340                            LocalInitializer::ThreadYieldThenResume { func }
1341                        }
1342                        wasmparser::CanonicalFunction::ThreadSuspendThenPromote => {
1343                            let func = self.core_func_signature(core_func_index)?;
1344                            core_func_index += 1;
1345                            LocalInitializer::ThreadSuspendThenPromote { func }
1346                        }
1347                        wasmparser::CanonicalFunction::ThreadYieldThenPromote => {
1348                            let func = self.core_func_signature(core_func_index)?;
1349                            core_func_index += 1;
1350                            LocalInitializer::ThreadYieldThenPromote { func }
1351                        }
1352                        wasmparser::CanonicalFunction::StreamForward { .. } => {
1353                            bail!("unimplemented stream.forward")
1354                        }
1355                        wasmparser::CanonicalFunction::FutureForward { .. } => {
1356                            bail!("unimplemented stream.forward")
1357                        }
1358                    };
1359                    self.result.initializers.push(init);
1360                }
1361            }
1362
1363            // Core wasm modules are translated inline directly here with the
1364            // `ModuleEnvironment` from core wasm compilation. This will return
1365            // to the caller the size of the module so it knows how many bytes
1366            // of the input are skipped.
1367            //
1368            // Note that this is just initial type translation of the core wasm
1369            // module and actual function compilation is deferred until this
1370            // entire process has completed.
1371            Payload::ModuleSection {
1372                parser,
1373                unchecked_range,
1374            } => {
1375                let index = self.validator.types(0).unwrap().module_count();
1376                self.validator.module_section(&unchecked_range)?;
1377                let static_module_index = self.static_modules.next_key();
1378                let mut translation = ModuleEnvironment::new(
1379                    self.tunables,
1380                    self.validator,
1381                    self.types.module_types_builder(),
1382                    static_module_index,
1383                )
1384                .translate(
1385                    parser,
1386                    component
1387                        .get(unchecked_range.start as usize..unchecked_range.end as usize)
1388                        .ok_or_else(|| {
1389                            format_err!(
1390                                "section range {}..{} is out of bounds (bound = {})",
1391                                unchecked_range.start,
1392                                unchecked_range.end,
1393                                component.len()
1394                            )
1395                            .context("wasm component contains an invalid module section")
1396                        })?,
1397                )?;
1398
1399                translation.wasm_module_offset = unchecked_range.start;
1400                let static_module_index2 = self.static_modules.push(translation);
1401                assert_eq!(static_module_index, static_module_index2);
1402                let types = self.validator.types(0).unwrap();
1403                let ty = types.module_at(index);
1404                self.result
1405                    .initializers
1406                    .push(LocalInitializer::ModuleStatic(static_module_index, ty));
1407                return Ok(Action::Skip(
1408                    (unchecked_range.end - unchecked_range.start) as usize,
1409                ));
1410            }
1411
1412            // When a sub-component is found then the current translation state
1413            // is pushed onto the `lexical_scopes` stack. This will subsequently
1414            // get popped as part of `Payload::End` processing above.
1415            //
1416            // Note that the set of closure args for this new lexical scope
1417            // starts empty since it will only get populated if translation of
1418            // the nested component ends up aliasing some outer module or
1419            // component.
1420            Payload::ComponentSection {
1421                parser,
1422                unchecked_range,
1423            } => {
1424                self.validator.component_section(&unchecked_range)?;
1425                self.lexical_scopes.push(LexicalScope {
1426                    parser: mem::replace(&mut self.parser, parser),
1427                    translation: mem::take(&mut self.result),
1428                    closure_args: ClosedOverVars::default(),
1429                });
1430            }
1431
1432            // Both core wasm instances and component instances record
1433            // initializers of what form of instantiation is performed which
1434            // largely just records the arguments given from wasmparser into a
1435            // `HashMap` for processing later during inlining.
1436            Payload::InstanceSection(s) => {
1437                self.validator.instance_section(&s)?;
1438                for instance in s {
1439                    let init = match instance? {
1440                        wasmparser::Instance::Instantiate { module_index, args } => {
1441                            let index = ModuleIndex::from_u32(module_index);
1442                            self.instantiate_module(index, &args)
1443                        }
1444                        wasmparser::Instance::FromExports(exports) => {
1445                            self.instantiate_module_from_exports(&exports)
1446                        }
1447                    };
1448                    self.result.initializers.push(init);
1449                }
1450            }
1451            Payload::ComponentInstanceSection(s) => {
1452                let mut index = self.validator.types(0).unwrap().component_instance_count();
1453                self.validator.component_instance_section(&s)?;
1454                for instance in s {
1455                    let types = self.validator.types(0).unwrap();
1456                    let ty = types.component_instance_at(index);
1457                    let init = match instance? {
1458                        wasmparser::ComponentInstance::Instantiate {
1459                            component_index,
1460                            args,
1461                        } => {
1462                            let index = ComponentIndex::from_u32(component_index);
1463                            self.instantiate_component(index, &args, ty)?
1464                        }
1465                        wasmparser::ComponentInstance::FromExports(exports) => {
1466                            self.instantiate_component_from_exports(&exports, ty)?
1467                        }
1468                    };
1469                    self.result.initializers.push(init);
1470                    index += 1;
1471                }
1472            }
1473
1474            // Exports don't actually fill out the `initializers` array but
1475            // instead fill out the one other field in a `Translation`, the
1476            // `exports` field (as one might imagine). This for now simply
1477            // records the index of what's exported and that's tracked further
1478            // later during inlining.
1479            Payload::ComponentExportSection(s) => {
1480                self.validator.component_export_section(&s)?;
1481                for export in s {
1482                    let export = export?;
1483                    let item = self.kind_to_item(export.kind, export.index)?;
1484                    let prev = self
1485                        .result
1486                        .exports
1487                        .insert(export.name.name, (item, export.name));
1488                    assert!(prev.is_none());
1489                    self.result
1490                        .initializers
1491                        .push(LocalInitializer::Export(item));
1492                }
1493            }
1494
1495            Payload::ComponentStartSection { start, range } => {
1496                self.validator.component_start_section(&start, &range)?;
1497                unimplemented!("component start section");
1498            }
1499
1500            // Aliases of instance exports (either core or component) will be
1501            // recorded as an initializer of the appropriate type with outer
1502            // aliases handled specially via upvars and type processing.
1503            Payload::ComponentAliasSection(s) => {
1504                self.validator.component_alias_section(&s)?;
1505                for alias in s {
1506                    let init = match alias? {
1507                        wasmparser::ComponentAlias::InstanceExport {
1508                            kind: _,
1509                            instance_index,
1510                            name,
1511                        } => {
1512                            let instance = ComponentInstanceIndex::from_u32(instance_index);
1513                            LocalInitializer::AliasComponentExport(instance, name)
1514                        }
1515                        wasmparser::ComponentAlias::Outer { kind, count, index } => {
1516                            self.alias_component_outer(kind, count, index);
1517                            continue;
1518                        }
1519                        wasmparser::ComponentAlias::CoreInstanceExport {
1520                            kind,
1521                            instance_index,
1522                            name,
1523                        } => {
1524                            let instance = ModuleInstanceIndex::from_u32(instance_index);
1525                            self.alias_module_instance_export(kind, instance, name)
1526                        }
1527                    };
1528                    self.result.initializers.push(init);
1529                }
1530            }
1531
1532            // All custom sections are ignored by Wasmtime at this time.
1533            //
1534            // FIXME(WebAssembly/component-model#14): probably want to specify
1535            // and parse a `name` section here.
1536            Payload::CustomSection { .. } => {}
1537
1538            // Anything else is either not reachable since we never enable the
1539            // feature in Wasmtime or we do enable it and it's a bug we don't
1540            // implement it, so let validation take care of most errors here and
1541            // if it gets past validation provide a helpful error message to
1542            // debug.
1543            other => {
1544                self.validator.payload(&other)?;
1545                panic!("unimplemented section {other:?}");
1546            }
1547        }
1548
1549        Ok(Action::KeepGoing)
1550    }
1551
1552    fn instantiate_module(
1553        &mut self,
1554        module: ModuleIndex,
1555        raw_args: &[wasmparser::InstantiationArg<'data>],
1556    ) -> LocalInitializer<'data> {
1557        let mut args = HashMap::with_capacity(raw_args.len());
1558        for arg in raw_args {
1559            match arg.kind {
1560                wasmparser::InstantiationArgKind::Instance => {
1561                    let idx = ModuleInstanceIndex::from_u32(arg.index);
1562                    args.insert(arg.name, idx);
1563                }
1564            }
1565        }
1566        LocalInitializer::ModuleInstantiate(module, args)
1567    }
1568
1569    /// Creates a synthetic module from the list of items currently in the
1570    /// module and their given names.
1571    fn instantiate_module_from_exports(
1572        &mut self,
1573        exports: &[wasmparser::Export<'data>],
1574    ) -> LocalInitializer<'data> {
1575        let mut map = HashMap::with_capacity(exports.len());
1576        for export in exports {
1577            let idx = match export.kind {
1578                wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
1579                    let index = FuncIndex::from_u32(export.index);
1580                    EntityIndex::Function(index)
1581                }
1582                wasmparser::ExternalKind::Table => {
1583                    let index = TableIndex::from_u32(export.index);
1584                    EntityIndex::Table(index)
1585                }
1586                wasmparser::ExternalKind::Memory => {
1587                    let index = MemoryIndex::from_u32(export.index);
1588                    EntityIndex::Memory(index)
1589                }
1590                wasmparser::ExternalKind::Global => {
1591                    let index = GlobalIndex::from_u32(export.index);
1592                    EntityIndex::Global(index)
1593                }
1594                wasmparser::ExternalKind::Tag => {
1595                    let index = TagIndex::from_u32(export.index);
1596                    EntityIndex::Tag(index)
1597                }
1598            };
1599            map.insert(export.name, idx);
1600        }
1601        LocalInitializer::ModuleSynthetic(map)
1602    }
1603
1604    fn instantiate_component(
1605        &mut self,
1606        component: ComponentIndex,
1607        raw_args: &[wasmparser::ComponentInstantiationArg<'data>],
1608        ty: ComponentInstanceTypeId,
1609    ) -> Result<LocalInitializer<'data>> {
1610        let mut args = HashMap::with_capacity(raw_args.len());
1611        for arg in raw_args {
1612            let idx = self.kind_to_item(arg.kind, arg.index)?;
1613            args.insert(arg.name, idx);
1614        }
1615
1616        Ok(LocalInitializer::ComponentInstantiate(component, args, ty))
1617    }
1618
1619    /// Creates a synthetic module from the list of items currently in the
1620    /// module and their given names.
1621    fn instantiate_component_from_exports(
1622        &mut self,
1623        exports: &[wasmparser::ComponentExport<'data>],
1624        ty: ComponentInstanceTypeId,
1625    ) -> Result<LocalInitializer<'data>> {
1626        let mut map = HashMap::with_capacity(exports.len());
1627        for export in exports {
1628            let idx = self.kind_to_item(export.kind, export.index)?;
1629            map.insert(export.name.name, idx);
1630        }
1631
1632        Ok(LocalInitializer::ComponentSynthetic(map, ty))
1633    }
1634
1635    fn kind_to_item(
1636        &mut self,
1637        kind: wasmparser::ComponentExternalKind,
1638        index: u32,
1639    ) -> Result<ComponentItem> {
1640        Ok(match kind {
1641            wasmparser::ComponentExternalKind::Func => {
1642                let index = ComponentFuncIndex::from_u32(index);
1643                ComponentItem::Func(index)
1644            }
1645            wasmparser::ComponentExternalKind::Module => {
1646                let index = ModuleIndex::from_u32(index);
1647                ComponentItem::Module(index)
1648            }
1649            wasmparser::ComponentExternalKind::Instance => {
1650                let index = ComponentInstanceIndex::from_u32(index);
1651                ComponentItem::ComponentInstance(index)
1652            }
1653            wasmparser::ComponentExternalKind::Component => {
1654                let index = ComponentIndex::from_u32(index);
1655                ComponentItem::Component(index)
1656            }
1657            wasmparser::ComponentExternalKind::Value => {
1658                unimplemented!("component values");
1659            }
1660            wasmparser::ComponentExternalKind::Type => {
1661                let types = self.validator.types(0).unwrap();
1662                let ty = types.component_any_type_at(index);
1663                ComponentItem::Type(ty)
1664            }
1665        })
1666    }
1667
1668    fn alias_module_instance_export(
1669        &mut self,
1670        kind: wasmparser::ExternalKind,
1671        instance: ModuleInstanceIndex,
1672        name: &'data str,
1673    ) -> LocalInitializer<'data> {
1674        match kind {
1675            wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
1676                LocalInitializer::AliasExportFunc(instance, name)
1677            }
1678            wasmparser::ExternalKind::Memory => LocalInitializer::AliasExportMemory(instance, name),
1679            wasmparser::ExternalKind::Table => LocalInitializer::AliasExportTable(instance, name),
1680            wasmparser::ExternalKind::Global => LocalInitializer::AliasExportGlobal(instance, name),
1681            wasmparser::ExternalKind::Tag => LocalInitializer::AliasExportTag(instance, name),
1682        }
1683    }
1684
1685    fn alias_component_outer(
1686        &mut self,
1687        kind: wasmparser::ComponentOuterAliasKind,
1688        count: u32,
1689        index: u32,
1690    ) {
1691        match kind {
1692            wasmparser::ComponentOuterAliasKind::CoreType
1693            | wasmparser::ComponentOuterAliasKind::Type => {}
1694
1695            // For more information about the implementation of outer aliases
1696            // see the documentation of `LexicalScope`. Otherwise though the
1697            // main idea here is that the data to close over starts as `Local`
1698            // and then transitions to `Upvar` as its inserted into the parents
1699            // in order from target we're aliasing back to the current
1700            // component.
1701            wasmparser::ComponentOuterAliasKind::CoreModule => {
1702                let index = ModuleIndex::from_u32(index);
1703                let mut module = ClosedOverModule::Local(index);
1704                let depth = self.lexical_scopes.len() - (count as usize);
1705                for frame in self.lexical_scopes[depth..].iter_mut() {
1706                    module = ClosedOverModule::Upvar(frame.closure_args.modules.push(module));
1707                }
1708
1709                // If the `module` is still `Local` then the `depth` was 0 and
1710                // it's an alias into our own space. Otherwise it's switched to
1711                // an upvar and will index into the upvar space. Either way
1712                // it's just plumbed directly into the initializer.
1713                self.result
1714                    .initializers
1715                    .push(LocalInitializer::AliasModule(module));
1716            }
1717            wasmparser::ComponentOuterAliasKind::Component => {
1718                let index = ComponentIndex::from_u32(index);
1719                let mut component = ClosedOverComponent::Local(index);
1720                let depth = self.lexical_scopes.len() - (count as usize);
1721                for frame in self.lexical_scopes[depth..].iter_mut() {
1722                    component =
1723                        ClosedOverComponent::Upvar(frame.closure_args.components.push(component));
1724                }
1725
1726                self.result
1727                    .initializers
1728                    .push(LocalInitializer::AliasComponent(component));
1729            }
1730        }
1731    }
1732
1733    fn canonical_options(
1734        &mut self,
1735        opts: &[wasmparser::CanonicalOption],
1736        core_func_index: u32,
1737    ) -> WasmResult<LocalCanonicalOptions> {
1738        let core_type = self.core_func_signature(core_func_index)?;
1739
1740        let mut string_encoding = StringEncoding::Utf8;
1741        let mut post_return = None;
1742        let mut async_ = false;
1743        let mut callback = None;
1744        let mut memory = None;
1745        let mut realloc = None;
1746        let mut gc = false;
1747
1748        for opt in opts {
1749            match opt {
1750                wasmparser::CanonicalOption::UTF8 => {
1751                    string_encoding = StringEncoding::Utf8;
1752                }
1753                wasmparser::CanonicalOption::UTF16 => {
1754                    string_encoding = StringEncoding::Utf16;
1755                }
1756                wasmparser::CanonicalOption::CompactUTF16 => {
1757                    string_encoding = StringEncoding::CompactUtf16;
1758                }
1759                wasmparser::CanonicalOption::Memory(idx) => {
1760                    let idx = MemoryIndex::from_u32(*idx);
1761                    memory = Some(idx);
1762                }
1763                wasmparser::CanonicalOption::Realloc(idx) => {
1764                    let idx = FuncIndex::from_u32(*idx);
1765                    realloc = Some(idx);
1766                }
1767                wasmparser::CanonicalOption::PostReturn(idx) => {
1768                    let idx = FuncIndex::from_u32(*idx);
1769                    post_return = Some(idx);
1770                }
1771                wasmparser::CanonicalOption::Async => async_ = true,
1772                wasmparser::CanonicalOption::Callback(idx) => {
1773                    let idx = FuncIndex::from_u32(*idx);
1774                    callback = Some(idx);
1775                }
1776                wasmparser::CanonicalOption::CoreType(idx) => {
1777                    if cfg!(debug_assertions) {
1778                        let types = self.validator.types(0).unwrap();
1779                        let core_ty_id = types.core_type_at_in_component(*idx).unwrap_sub();
1780                        let interned = self
1781                            .types
1782                            .module_types_builder()
1783                            .intern_type(types, core_ty_id)?;
1784                        debug_assert_eq!(interned, core_type);
1785                    }
1786                }
1787                wasmparser::CanonicalOption::Gc => {
1788                    gc = true;
1789                }
1790            }
1791        }
1792
1793        Ok(LocalCanonicalOptions {
1794            string_encoding,
1795            post_return,
1796            async_,
1797            callback,
1798            core_type,
1799            data_model: if gc {
1800                LocalDataModel::Gc {}
1801            } else {
1802                LocalDataModel::LinearMemory { memory, realloc }
1803            },
1804        })
1805    }
1806
1807    /// Get the interned type index for the `index`th core function.
1808    fn core_func_signature(&mut self, index: u32) -> WasmResult<ModuleInternedTypeIndex> {
1809        let types = self.validator.types(0).unwrap();
1810        let id = types.core_function_at(index);
1811        self.types.module_types_builder().intern_type(types, id)
1812    }
1813
1814    fn is_unsafe_intrinsics_import(&self, import: &str) -> bool {
1815        self.lexical_scopes.is_empty()
1816            && self
1817                .unsafe_intrinsics_import
1818                .is_some_and(|name| import == name)
1819    }
1820
1821    fn check_unsafe_intrinsics_import(&self, import: &str, ty: ComponentEntityType) -> Result<()> {
1822        let types = &self.validator.types(0).unwrap();
1823
1824        let ComponentEntityType::Instance(instance_ty) = ty else {
1825            bail!("bad unsafe intrinsics import: import `{import}` must be an instance import")
1826        };
1827        let instance_ty = &types[instance_ty];
1828
1829        ensure!(
1830            instance_ty.defined_resources.is_empty(),
1831            "bad unsafe intrinsics import: import `{import}` cannot define any resources"
1832        );
1833
1834        for (name, ty) in &instance_ty.exports {
1835            let ComponentEntityType::Func(func_ty) = ty.ty else {
1836                bail!(
1837                    "bad unsafe intrinsics import: imported instance `{import}` must \
1838                     only export functions"
1839                )
1840            };
1841            let func_ty = &types[func_ty];
1842
1843            fn ty_eq(a: &InterfaceType, b: &wasmparser::component_types::ComponentValType) -> bool {
1844                use wasmparser::{PrimitiveValType as P, component_types::ComponentValType as C};
1845                match (a, b) {
1846                    (InterfaceType::U8, C::Primitive(P::U8)) => true,
1847                    (InterfaceType::U8, _) => false,
1848
1849                    (InterfaceType::U16, C::Primitive(P::U16)) => true,
1850                    (InterfaceType::U16, _) => false,
1851
1852                    (InterfaceType::U32, C::Primitive(P::U32)) => true,
1853                    (InterfaceType::U32, _) => false,
1854
1855                    (InterfaceType::U64, C::Primitive(P::U64)) => true,
1856                    (InterfaceType::U64, _) => false,
1857
1858                    (ty, _) => unreachable!("no unsafe intrinsics use {ty:?}"),
1859                }
1860            }
1861
1862            fn check_types<'a>(
1863                expected: impl ExactSizeIterator<Item = &'a InterfaceType>,
1864                actual: impl ExactSizeIterator<Item = &'a wasmparser::component_types::ComponentValType>,
1865                kind: &str,
1866                import: &str,
1867                name: &str,
1868            ) -> Result<()> {
1869                let expected_len = expected.len();
1870                let actual_len = actual.len();
1871                ensure!(
1872                    expected_len == actual_len,
1873                    "bad unsafe intrinsics import at `{import}`: function `{name}` must have \
1874                     {expected_len} {kind}, found {actual_len}"
1875                );
1876
1877                for (i, (actual_ty, expected_ty)) in actual.zip(expected).enumerate() {
1878                    ensure!(
1879                        ty_eq(expected_ty, actual_ty),
1880                        "bad unsafe intrinsics import at `{import}`: {kind}[{i}] for function \
1881                         `{name}` must be `{expected_ty:?}`, found `{actual_ty:?}`"
1882                    );
1883                }
1884                Ok(())
1885            }
1886
1887            let intrinsic = UnsafeIntrinsic::from_str(name)
1888                .with_context(|| format!("bad unsafe intrinsics import at `{import}`"))?;
1889
1890            check_types(
1891                intrinsic.component_params().iter(),
1892                func_ty.params.iter().map(|(_name, ty)| ty),
1893                "parameters",
1894                &import,
1895                &name,
1896            )?;
1897            check_types(
1898                intrinsic.component_results().iter(),
1899                func_ty.result.iter(),
1900                "results",
1901                &import,
1902                &name,
1903            )?;
1904        }
1905
1906        Ok(())
1907    }
1908}
1909
1910impl Translation<'_> {
1911    fn types_ref(&self) -> wasmparser::types::TypesRef<'_> {
1912        self.types.as_ref().unwrap().as_ref()
1913    }
1914}
1915
1916/// A small helper module which wraps a `ComponentTypesBuilder` and attempts
1917/// to disallow access to mutable access to the builder before the inlining
1918/// pass.
1919///
1920/// Type information in this translation pass must be preserved at the
1921/// wasmparser layer of abstraction rather than being lowered into Wasmtime's
1922/// own type system. Only during inlining are types fully assigned because
1923/// that's when resource types become available as it's known which instance
1924/// defines which resource, or more concretely the same component instantiated
1925/// twice will produce two unique resource types unlike one as seen by
1926/// wasmparser within the component.
1927mod pre_inlining {
1928    use super::*;
1929
1930    pub struct PreInliningComponentTypes<'a> {
1931        types: &'a mut ComponentTypesBuilder,
1932    }
1933
1934    impl<'a> PreInliningComponentTypes<'a> {
1935        pub fn new(types: &'a mut ComponentTypesBuilder) -> Self {
1936            Self { types }
1937        }
1938
1939        pub fn module_types_builder(&mut self) -> &mut ModuleTypesBuilder {
1940            self.types.module_types_builder_mut()
1941        }
1942
1943        pub fn types(&self) -> &ComponentTypesBuilder {
1944            self.types
1945        }
1946
1947        // NB: this should in theory only be used for the `inline` phase of
1948        // translation.
1949        pub fn types_mut_for_inlining(&mut self) -> &mut ComponentTypesBuilder {
1950            self.types
1951        }
1952    }
1953
1954    impl TypeConvert for PreInliningComponentTypes<'_> {
1955        fn lookup_heap_type(&self, index: wasmparser::UnpackedIndex) -> WasmHeapType {
1956            self.types.lookup_heap_type(index)
1957        }
1958
1959        fn lookup_type_index(&self, index: wasmparser::UnpackedIndex) -> EngineOrModuleTypeIndex {
1960            self.types.lookup_type_index(index)
1961        }
1962    }
1963}
1964use pre_inlining::PreInliningComponentTypes;
1965
1966/// A map from each runtime instance to the static module it is an instance of,
1967/// along with the definition that each of its arguments resolves to, when we
1968/// statically know them.
1969struct StaticInstances {
1970    /// The position of each import of each static module.
1971    import_positions: PrimaryMap<StaticModuleIndex, ImportPositions>,
1972
1973    /// Each instance's module and what each of its arguments resolves to, by
1974    /// import position, as computed by `resolve_core_export`.
1975    ///
1976    /// `None` for instances of modules that are not part of this component,
1977    /// and whose shape we therefore cannot see into.
1978    instances: PrimaryMap<
1979        RuntimeInstanceIndex,
1980        Option<(
1981            StaticModuleIndex,
1982            Vec<Option<(StaticModuleIndex, EntityIndex)>>,
1983        )>,
1984    >,
1985}
1986
1987impl StaticInstances {
1988    fn new(static_modules: &PrimaryMap<StaticModuleIndex, ModuleTranslation<'_>>) -> Self {
1989        StaticInstances {
1990            import_positions: static_modules
1991                .values()
1992                .map(|translation| translation.module.import_positions())
1993                .collect(),
1994            instances: PrimaryMap::new(),
1995        }
1996    }
1997
1998    /// Push the next runtime instance.
1999    ///
2000    /// It must be an instance of the given static module with the given
2001    /// arguments, or `None` for an instance of a module that is not part of
2002    /// this component.
2003    fn push(&mut self, instance: Option<(StaticModuleIndex, &[CoreDef])>) {
2004        let instance = instance.map(|(module, args)| {
2005            let next = self.instances.next_key();
2006            let args = args
2007                .iter()
2008                .map(|arg| match arg {
2009                    CoreDef::Export(export) => {
2010                        // An instantiation's arguments are always exports of
2011                        // instances created before the instance being
2012                        // instantiated.
2013                        assert!(export.instance < next);
2014                        resolve_core_export(self, export)
2015                    }
2016
2017                    CoreDef::InstanceFlags(_)
2018                    | CoreDef::Trampoline(_)
2019                    | CoreDef::UnsafeIntrinsic(_) => None,
2020                })
2021                .collect();
2022            (module, args)
2023        });
2024        self.instances.push(instance);
2025    }
2026}
2027
2028/// Every entity whose identity is not statically known to everything that can
2029/// access it.
2030#[derive(Default)]
2031struct Ambiguous {
2032    /// Globals, memories, and tables defined by a static module in this
2033    /// component.
2034    entities: HashSet<(StaticModuleIndex, EntityIndex)>,
2035
2036    /// Component-model flags living in the `VMComponentContext`. Only ever
2037    /// contains the non-`KnownGlobal::Defined` variants.
2038    flags: HashSet<KnownGlobal>,
2039}
2040
2041/// Get the component-model flag that a `CoreDef` names, if it names one.
2042fn component_flags(def: &CoreDef) -> Option<KnownGlobal> {
2043    match def {
2044        CoreDef::InstanceFlags(instance) => Some(KnownGlobal::ComponentInstanceFlags(*instance)),
2045        CoreDef::Export(_) | CoreDef::Trampoline(_) | CoreDef::UnsafeIntrinsic(_) => None,
2046    }
2047}
2048
2049/// Resolve a `CoreExport` to the static module that *defines* it and the entity
2050/// index it refers to within that module, when we can see through it statically.
2051///
2052/// A module may import an entity and then re-export it, in which case the
2053/// export names an index in the re-exporting module's *imported* index space.
2054/// We follow those chains all the way back to the module that actually defines
2055/// the entity, so that the returned pair is a canonical identity for it: every
2056/// reference to the same entity resolves to the same `(module, entity)` pair, no
2057/// matter how many modules it was laundered through along the way. That is
2058/// load-bearing for alias regions, where naming the same bytes with two
2059/// different keys is a miscompile.
2060///
2061/// Therefore a returned `Some((module, entity))` always satisfies
2062/// `!static_modules[module].module.is_imported(entity)`.
2063fn resolve_core_export(
2064    instances: &StaticInstances,
2065    export: &CoreExport<EntityIndex>,
2066) -> Option<(StaticModuleIndex, EntityIndex)> {
2067    let (module, args) = instances.instances[export.instance].as_ref()?;
2068
2069    let ExportItem::Index(index) = export.item else {
2070        // Names are only used for instances of modules whose shape we don't
2071        // statically know, which we already filtered out.
2072        unreachable!()
2073    };
2074
2075    match instances.import_positions[*module].get(index) {
2076        // The common case: this instance's module defines the entity itself,
2077        // so we've bottomed out at its canonical identity.
2078        None => Some((*module, index)),
2079
2080        // Otherwise this is a re-export of one of the module's imports, which
2081        // resolves to the same thing as whichever argument satisfied that
2082        // import. `StaticInstances::push` already resolved that argument all
2083        // the way back to its definition.
2084        Some(position) => args[position],
2085    }
2086}
2087
2088/// Same as `resolve_core_export`, but for a `CoreDef` that must additionally be
2089/// unambiguous.
2090fn unambiguous_entity(
2091    instances: &StaticInstances,
2092    ambiguous: &HashSet<(StaticModuleIndex, EntityIndex)>,
2093    def: &CoreDef,
2094) -> Option<(StaticModuleIndex, EntityIndex)> {
2095    let CoreDef::Export(export) = def else {
2096        return None;
2097    };
2098    let entity = resolve_core_export(instances, export)?;
2099    if ambiguous.contains(&entity) {
2100        return None;
2101    }
2102    Some(entity)
2103}
2104
2105/// Find every core wasm entity in this component whose identity is *not*
2106/// statically known to every module that may import it.
2107///
2108/// An entity is unambiguous when every argument it flows into belongs to a
2109/// module that we only ever instantiate with that same entity:
2110///
2111/// * An argument to a module that we may instantiate differently elsewhere is
2112///   ambiguous because that module cannot statically know which one of these
2113///   entities it was given at runtime.
2114///
2115/// * An argument to an imported module is ambiguous because that module is
2116///   compiled separately from this component, and it may re-export the entity
2117///   back to us under a name we cannot see through, which we may then hand to a
2118///   module whose imports we do otherwise know.
2119///
2120/// Note that ambiguity is never partial: if a module importing an entity has to
2121/// conservatively tag its accesses with that entity's public alias region, then
2122/// the module defining the entity must do the same, or else inlining one of
2123/// them into the other would access the same bytes through two different alias
2124/// regions, which is invalid.
2125///
2126/// Entities in the returned set are identified by the module that *defines*
2127/// them, as resolved by `resolve_core_export`. That is what makes the previous
2128/// paragraph work through re-exports: marking a module's re-export of an import
2129/// as ambiguous poisons the definition it ultimately refers to, and therefore
2130/// every other module that can reach that definition, and not just the
2131/// re-exporter.
2132fn ambiguous_entities(
2133    translation: &ComponentTranslation,
2134    instantiations: &SecondaryMap<StaticModuleIndex, dfg::AbstractInstantiations<'_>>,
2135    instances: &StaticInstances,
2136) -> Ambiguous {
2137    let mut ambiguous = Ambiguous::default();
2138
2139    let mut mark = |def: &CoreDef| match def {
2140        CoreDef::Export(export) => {
2141            if let Some(entity) = resolve_core_export(instances, export) {
2142                ambiguous.entities.insert(entity);
2143            }
2144        }
2145
2146        CoreDef::InstanceFlags(_) => {
2147            ambiguous.flags.insert(component_flags(def).unwrap());
2148        }
2149
2150        // Neither of these is an entity that gets an alias region keyed by a
2151        // defining module and index.
2152        CoreDef::Trampoline(_) | CoreDef::UnsafeIntrinsic(_) => {}
2153    };
2154
2155    for init in &translation.component.initializers {
2156        match init {
2157            GlobalInitializer::InstantiateModule(instantiation, _) => match instantiation {
2158                InstantiateModule::Static(module, args) => {
2159                    // Arguments to modules that we only instantiate one way are
2160                    // exactly the references that keep an entity unambiguous, so
2161                    // they are the one case we do not mark here. Everything else
2162                    // gets whichever of a number of different entities it was
2163                    // handed at runtime, and so has to be conservative.
2164                    if !matches!(instantiations[*module], dfg::AbstractInstantiations::One(_)) {
2165                        for arg in args.iter() {
2166                            mark(arg);
2167                        }
2168                    }
2169                }
2170
2171                // We cannot see through an imported module's exports, so an
2172                // entity we pass into one and that comes back out to a module
2173                // whose imports we do know would be accessed via two different
2174                // alias regions.
2175                InstantiateModule::Import(_, args) => {
2176                    for arg in args.values().flat_map(|args| args.values()) {
2177                        mark(arg);
2178                    }
2179                }
2180            },
2181
2182            // The remaining initializers do not involve the global/table/memory
2183            // alias regions.
2184            GlobalInitializer::ExtractMemory(_)
2185            | GlobalInitializer::ExtractTable(_)
2186            | GlobalInitializer::ExtractRealloc(_)
2187            | GlobalInitializer::ExtractCallback(_)
2188            | GlobalInitializer::ExtractPostReturn(_)
2189            | GlobalInitializer::Resource(_)
2190            | GlobalInitializer::LowerImport { .. } => {}
2191        }
2192    }
2193
2194    ambiguous
2195}