inf_wast/component/
resolve.rs

1use crate::component::*;
2use crate::core::{self, resolve::ResolveCoreType, ValType};
3use crate::kw;
4use crate::names::Namespace;
5use crate::token::Span;
6use crate::token::{Id, Index};
7use crate::Error;
8
9/// Resolve the fields of a component and everything nested within it, changing
10/// `Index::Id` to `Index::Num` and expanding alias syntax sugar.
11pub fn resolve(component: &mut Component<'_>) -> Result<(), Error> {
12    let fields = match &mut component.kind {
13        ComponentKind::Text(fields) => fields,
14        ComponentKind::Binary(_) => return Ok(()),
15    };
16    let mut resolver = Resolver::default();
17    resolver.fields(component.id, fields)
18}
19
20impl<'a> From<Alias<'a>> for ComponentField<'a> {
21    fn from(a: Alias<'a>) -> Self {
22        Self::Alias(a)
23    }
24}
25
26impl<'a> From<Alias<'a>> for ModuleTypeDecl<'a> {
27    fn from(a: Alias<'a>) -> Self {
28        Self::Alias(a)
29    }
30}
31
32impl<'a> From<Alias<'a>> for ComponentTypeDecl<'a> {
33    fn from(a: Alias<'a>) -> Self {
34        Self::Alias(a)
35    }
36}
37
38impl<'a> From<Alias<'a>> for InstanceTypeDecl<'a> {
39    fn from(a: Alias<'a>) -> Self {
40        Self::Alias(a)
41    }
42}
43
44#[derive(Default)]
45struct Resolver<'a> {
46    stack: Vec<ComponentState<'a>>,
47
48    // When a name refers to a definition in an outer scope, we'll need to
49    // insert an outer alias before it. This collects the aliases to be
50    // inserted during resolution.
51    aliases_to_insert: Vec<Alias<'a>>,
52}
53
54/// Context structure used to perform name resolution.
55#[derive(Default)]
56struct ComponentState<'a> {
57    id: Option<Id<'a>>,
58
59    // Namespaces within each component. Note that each namespace carries
60    // with it information about the signature of the item in that namespace.
61    // The signature is later used to synthesize the type of a component and
62    // inject type annotations if necessary.
63    core_funcs: Namespace<'a>,
64    core_globals: Namespace<'a>,
65    core_tables: Namespace<'a>,
66    core_memories: Namespace<'a>,
67    core_types: Namespace<'a>,
68    core_tags: Namespace<'a>,
69    core_instances: Namespace<'a>,
70    core_modules: Namespace<'a>,
71
72    funcs: Namespace<'a>,
73    types: Namespace<'a>,
74    instances: Namespace<'a>,
75    components: Namespace<'a>,
76    values: Namespace<'a>,
77}
78
79impl<'a> ComponentState<'a> {
80    fn new(id: Option<Id<'a>>) -> ComponentState<'a> {
81        ComponentState {
82            id,
83            ..ComponentState::default()
84        }
85    }
86
87    fn register_item_sig(&mut self, sig: &ItemSig<'a>) -> Result<u32, Error> {
88        match &sig.kind {
89            ItemSigKind::CoreModule(_) => self.core_modules.register(sig.id, "core module"),
90            ItemSigKind::Func(_) => self.funcs.register(sig.id, "func"),
91            ItemSigKind::Component(_) => self.components.register(sig.id, "component"),
92            ItemSigKind::Instance(_) => self.instances.register(sig.id, "instance"),
93            ItemSigKind::Value(_) => self.values.register(sig.id, "value"),
94            ItemSigKind::Type(_) => self.types.register(sig.id, "type"),
95        }
96    }
97}
98
99impl<'a> Resolver<'a> {
100    fn current(&mut self) -> &mut ComponentState<'a> {
101        self.stack
102            .last_mut()
103            .expect("should have at least one component state")
104    }
105
106    fn fields(
107        &mut self,
108        id: Option<Id<'a>>,
109        fields: &mut Vec<ComponentField<'a>>,
110    ) -> Result<(), Error> {
111        self.stack.push(ComponentState::new(id));
112        self.resolve_prepending_aliases(fields, Resolver::field, ComponentState::register)?;
113        self.stack.pop();
114        Ok(())
115    }
116
117    fn resolve_prepending_aliases<T>(
118        &mut self,
119        fields: &mut Vec<T>,
120        resolve: fn(&mut Self, &mut T) -> Result<(), Error>,
121        register: fn(&mut ComponentState<'a>, &T) -> Result<(), Error>,
122    ) -> Result<(), Error>
123    where
124        T: From<Alias<'a>>,
125    {
126        assert!(self.aliases_to_insert.is_empty());
127
128        // Iterate through the fields of the component. We use an index
129        // instead of an iterator because we'll be inserting aliases
130        // as we go.
131        let mut i = 0;
132        while i < fields.len() {
133            // Resolve names within the field.
134            resolve(self, &mut fields[i])?;
135
136            // Name resolution may have emitted some aliases. Insert them before
137            // the current definition.
138            let amt = self.aliases_to_insert.len();
139            fields.splice(i..i, self.aliases_to_insert.drain(..).map(T::from));
140            i += amt;
141
142            // Definitions can't refer to themselves or to definitions that appear
143            // later in the format. Now that we're done resolving this field,
144            // assign it an index for later definitions to refer to.
145            register(self.current(), &fields[i])?;
146
147            i += 1;
148        }
149
150        Ok(())
151    }
152
153    fn field(&mut self, field: &mut ComponentField<'a>) -> Result<(), Error> {
154        match field {
155            ComponentField::CoreModule(m) => self.core_module(m),
156            ComponentField::CoreInstance(i) => self.core_instance(i),
157            ComponentField::CoreType(t) => self.core_ty(t),
158            ComponentField::CoreRec(t) => self.core_rec(t),
159            ComponentField::Component(c) => self.component(c),
160            ComponentField::Instance(i) => self.instance(i),
161            ComponentField::Alias(a) => self.alias(a),
162            ComponentField::Type(t) => self.ty(t),
163            ComponentField::CanonicalFunc(f) => self.canonical_func(f),
164            ComponentField::CoreFunc(_) => unreachable!("should be expanded already"),
165            ComponentField::Func(_) => unreachable!("should be expanded already"),
166            ComponentField::Start(s) => self.start(s),
167            ComponentField::Import(i) => self.item_sig(&mut i.item),
168            ComponentField::Export(e) => {
169                if let Some(ty) = &mut e.ty {
170                    self.item_sig(&mut ty.0)?;
171                }
172                self.export(&mut e.kind)
173            }
174            ComponentField::Custom(_) | ComponentField::Producers(_) => Ok(()),
175        }
176    }
177
178    fn core_module(&mut self, module: &mut CoreModule) -> Result<(), Error> {
179        match &mut module.kind {
180            CoreModuleKind::Inline { fields } => {
181                crate::core::resolve::resolve(fields)?;
182            }
183
184            CoreModuleKind::Import { .. } => {
185                unreachable!("should be expanded already")
186            }
187        }
188
189        Ok(())
190    }
191
192    fn component(&mut self, component: &mut NestedComponent<'a>) -> Result<(), Error> {
193        match &mut component.kind {
194            NestedComponentKind::Import { .. } => unreachable!("should be expanded already"),
195            NestedComponentKind::Inline(fields) => self.fields(component.id, fields),
196        }
197    }
198
199    fn core_instance(&mut self, instance: &mut CoreInstance<'a>) -> Result<(), Error> {
200        match &mut instance.kind {
201            CoreInstanceKind::Instantiate { module, args } => {
202                self.component_item_ref(module)?;
203                for arg in args {
204                    match &mut arg.kind {
205                        CoreInstantiationArgKind::Instance(i) => {
206                            self.core_item_ref(i)?;
207                        }
208                        CoreInstantiationArgKind::BundleOfExports(..) => {
209                            unreachable!("should be expanded already");
210                        }
211                    }
212                }
213            }
214            CoreInstanceKind::BundleOfExports(exports) => {
215                for export in exports {
216                    self.core_item_ref(&mut export.item)?;
217                }
218            }
219        }
220        Ok(())
221    }
222
223    fn instance(&mut self, instance: &mut Instance<'a>) -> Result<(), Error> {
224        match &mut instance.kind {
225            InstanceKind::Instantiate { component, args } => {
226                self.component_item_ref(component)?;
227                for arg in args {
228                    match &mut arg.kind {
229                        InstantiationArgKind::Item(e) => {
230                            self.export(e)?;
231                        }
232                        InstantiationArgKind::BundleOfExports(..) => {
233                            unreachable!("should be expanded already")
234                        }
235                    }
236                }
237            }
238            InstanceKind::BundleOfExports(exports) => {
239                for export in exports {
240                    self.export(&mut export.kind)?;
241                }
242            }
243            InstanceKind::Import { .. } => {
244                unreachable!("should be expanded already")
245            }
246        }
247        Ok(())
248    }
249
250    fn item_sig(&mut self, item: &mut ItemSig<'a>) -> Result<(), Error> {
251        match &mut item.kind {
252            // Here we must be explicit otherwise the module type reference will
253            // be assumed to be in the component type namespace
254            ItemSigKind::CoreModule(t) => self.core_type_use(t),
255            ItemSigKind::Func(t) => self.component_type_use(t),
256            ItemSigKind::Component(t) => self.component_type_use(t),
257            ItemSigKind::Instance(t) => self.component_type_use(t),
258            ItemSigKind::Value(t) => self.component_val_type(&mut t.0),
259            ItemSigKind::Type(b) => match b {
260                TypeBounds::Eq(i) => {
261                    self.resolve_ns(i, Ns::Type)?;
262                    Ok(())
263                }
264                TypeBounds::SubResource => Ok(()),
265            },
266        }
267    }
268
269    fn export(&mut self, kind: &mut ComponentExportKind<'a>) -> Result<(), Error> {
270        match kind {
271            // Here we do *not* have to be explicit as the item ref is to a core module
272            ComponentExportKind::CoreModule(r) => self.component_item_ref(r),
273            ComponentExportKind::Func(r) => self.component_item_ref(r),
274            ComponentExportKind::Value(r) => self.component_item_ref(r),
275            ComponentExportKind::Type(r) => self.component_item_ref(r),
276            ComponentExportKind::Component(r) => self.component_item_ref(r),
277            ComponentExportKind::Instance(r) => self.component_item_ref(r),
278        }
279    }
280
281    fn start(&mut self, start: &mut Start<'a>) -> Result<(), Error> {
282        self.resolve_ns(&mut start.func, Ns::Func)?;
283        for arg in start.args.iter_mut() {
284            self.component_item_ref(arg)?;
285        }
286        Ok(())
287    }
288
289    fn outer_alias<T: Into<Ns>>(
290        &mut self,
291        outer: &mut Index<'a>,
292        index: &mut Index<'a>,
293        kind: T,
294        span: Span,
295    ) -> Result<(), Error> {
296        // Short-circuit when both indices are already resolved as this
297        // helps to write tests for invalid modules where wasmparser should
298        // be the one returning the error.
299        if let Index::Num(..) = outer {
300            if let Index::Num(..) = index {
301                return Ok(());
302            }
303        }
304
305        // Resolve `outer`, and compute the depth at which to look up
306        // `index`.
307        let depth = match outer {
308            Index::Id(id) => {
309                let mut depth = 0;
310                for resolver in self.stack.iter().rev() {
311                    if resolver.id == Some(*id) {
312                        break;
313                    }
314                    depth += 1;
315                }
316                if depth as usize == self.stack.len() {
317                    return Err(Error::new(
318                        span,
319                        format!("outer component `{}` not found", id.name()),
320                    ));
321                }
322                depth
323            }
324            Index::Num(n, _span) => *n,
325        };
326
327        if depth as usize >= self.stack.len() {
328            return Err(Error::new(
329                span,
330                format!("outer count of `{}` is too large", depth),
331            ));
332        }
333
334        *outer = Index::Num(depth, span);
335
336        // Resolve `index` within the computed scope depth.
337        let computed = self.stack.len() - 1 - depth as usize;
338        self.stack[computed].resolve(kind.into(), index)?;
339
340        Ok(())
341    }
342
343    fn alias(&mut self, alias: &mut Alias<'a>) -> Result<(), Error> {
344        match &mut alias.target {
345            AliasTarget::Export {
346                instance,
347                name: _,
348                kind: _,
349            } => {
350                self.resolve_ns(instance, Ns::Instance)?;
351            }
352            AliasTarget::CoreExport {
353                instance,
354                name: _,
355                kind: _,
356            } => {
357                self.resolve_ns(instance, Ns::CoreInstance)?;
358            }
359            AliasTarget::Outer { outer, index, kind } => {
360                self.outer_alias(outer, index, *kind, alias.span)?;
361            }
362        }
363        Ok(())
364    }
365
366    fn canonical_func(&mut self, func: &mut CanonicalFunc<'a>) -> Result<(), Error> {
367        match &mut func.kind {
368            CanonicalFuncKind::Lift { ty, info } => {
369                self.component_type_use(ty)?;
370                self.core_item_ref(&mut info.func)?;
371                self.canon_opts(&mut info.opts)?;
372            }
373            CanonicalFuncKind::Core(core) => match core {
374                CoreFuncKind::Alias(_) => {
375                    panic!("should have been removed during expansion")
376                }
377                CoreFuncKind::Lower(info) => {
378                    self.component_item_ref(&mut info.func)?;
379                    self.canon_opts(&mut info.opts)?;
380                }
381                CoreFuncKind::ResourceNew(info) => {
382                    self.resolve_ns(&mut info.ty, Ns::Type)?;
383                }
384                CoreFuncKind::ResourceRep(info) => {
385                    self.resolve_ns(&mut info.ty, Ns::Type)?;
386                }
387                CoreFuncKind::ResourceDrop(info) => {
388                    self.resolve_ns(&mut info.ty, Ns::Type)?;
389                }
390                CoreFuncKind::ThreadSpawnRef(info) => {
391                    self.resolve_ns(&mut info.ty, Ns::CoreType)?;
392                }
393                CoreFuncKind::ThreadSpawnIndirect(info) => {
394                    self.resolve_ns(&mut info.ty, Ns::CoreType)?;
395                    self.core_item_ref(&mut info.table)?;
396                }
397                CoreFuncKind::ThreadAvailableParallelism(_)
398                | CoreFuncKind::BackpressureSet
399                | CoreFuncKind::Yield(_)
400                | CoreFuncKind::SubtaskDrop
401                | CoreFuncKind::ErrorContextDrop => {}
402                CoreFuncKind::TaskReturn(info) => {
403                    if let Some(ty) = &mut info.result {
404                        self.component_val_type(ty)?;
405                    }
406                    self.canon_opts(&mut info.opts)?;
407                }
408                CoreFuncKind::ContextGet(_) | CoreFuncKind::ContextSet(_) => {}
409                CoreFuncKind::StreamNew(info) => {
410                    self.resolve_ns(&mut info.ty, Ns::Type)?;
411                }
412                CoreFuncKind::StreamRead(info) => {
413                    self.resolve_ns(&mut info.ty, Ns::Type)?;
414                    self.canon_opts(&mut info.opts)?;
415                }
416                CoreFuncKind::StreamWrite(info) => {
417                    self.resolve_ns(&mut info.ty, Ns::Type)?;
418                    self.canon_opts(&mut info.opts)?;
419                }
420                CoreFuncKind::StreamCancelRead(info) => {
421                    self.resolve_ns(&mut info.ty, Ns::Type)?;
422                }
423                CoreFuncKind::StreamCancelWrite(info) => {
424                    self.resolve_ns(&mut info.ty, Ns::Type)?;
425                }
426                CoreFuncKind::StreamCloseReadable(info) => {
427                    self.resolve_ns(&mut info.ty, Ns::Type)?;
428                }
429                CoreFuncKind::StreamCloseWritable(info) => {
430                    self.resolve_ns(&mut info.ty, Ns::Type)?;
431                }
432                CoreFuncKind::FutureNew(info) => {
433                    self.resolve_ns(&mut info.ty, Ns::Type)?;
434                }
435                CoreFuncKind::FutureRead(info) => {
436                    self.resolve_ns(&mut info.ty, Ns::Type)?;
437                    self.canon_opts(&mut info.opts)?;
438                }
439                CoreFuncKind::FutureWrite(info) => {
440                    self.resolve_ns(&mut info.ty, Ns::Type)?;
441                    self.canon_opts(&mut info.opts)?;
442                }
443                CoreFuncKind::FutureCancelRead(info) => {
444                    self.resolve_ns(&mut info.ty, Ns::Type)?;
445                }
446                CoreFuncKind::FutureCancelWrite(info) => {
447                    self.resolve_ns(&mut info.ty, Ns::Type)?;
448                }
449                CoreFuncKind::FutureCloseReadable(info) => {
450                    self.resolve_ns(&mut info.ty, Ns::Type)?;
451                }
452                CoreFuncKind::FutureCloseWritable(info) => {
453                    self.resolve_ns(&mut info.ty, Ns::Type)?;
454                }
455                CoreFuncKind::ErrorContextNew(info) => {
456                    self.canon_opts(&mut info.opts)?;
457                }
458                CoreFuncKind::ErrorContextDebugMessage(info) => {
459                    self.canon_opts(&mut info.opts)?;
460                }
461                CoreFuncKind::WaitableSetNew => {}
462                CoreFuncKind::WaitableSetWait(info) => {
463                    self.core_item_ref(&mut info.memory)?;
464                }
465                CoreFuncKind::WaitableSetPoll(info) => {
466                    self.core_item_ref(&mut info.memory)?;
467                }
468                CoreFuncKind::WaitableSetDrop => {}
469                CoreFuncKind::WaitableJoin => {}
470            },
471        }
472
473        Ok(())
474    }
475
476    fn canon_opts(&mut self, opts: &mut [CanonOpt<'a>]) -> Result<(), Error> {
477        for opt in opts {
478            match opt {
479                CanonOpt::StringUtf8
480                | CanonOpt::StringUtf16
481                | CanonOpt::StringLatin1Utf16
482                | CanonOpt::Async => {}
483                CanonOpt::Memory(r) => self.core_item_ref(r)?,
484                CanonOpt::Realloc(r) | CanonOpt::PostReturn(r) | CanonOpt::Callback(r) => {
485                    self.core_item_ref(r)?
486                }
487            }
488        }
489
490        Ok(())
491    }
492
493    fn core_type_use<T>(&mut self, ty: &mut CoreTypeUse<'a, T>) -> Result<(), Error> {
494        let item = match ty {
495            CoreTypeUse::Ref(r) => r,
496            CoreTypeUse::Inline(_) => {
497                unreachable!("inline type-use should be expanded by now")
498            }
499        };
500        self.core_item_ref(item)
501    }
502
503    fn component_type_use<T>(&mut self, ty: &mut ComponentTypeUse<'a, T>) -> Result<(), Error> {
504        let item = match ty {
505            ComponentTypeUse::Ref(r) => r,
506            ComponentTypeUse::Inline(_) => {
507                unreachable!("inline type-use should be expanded by now")
508            }
509        };
510        self.component_item_ref(item)
511    }
512
513    fn defined_type(&mut self, ty: &mut ComponentDefinedType<'a>) -> Result<(), Error> {
514        match ty {
515            ComponentDefinedType::Primitive(_) => {}
516            ComponentDefinedType::Flags(_) => {}
517            ComponentDefinedType::Enum(_) => {}
518            ComponentDefinedType::Record(r) => {
519                for field in r.fields.iter_mut() {
520                    self.component_val_type(&mut field.ty)?;
521                }
522            }
523            ComponentDefinedType::Variant(v) => {
524                // Namespace for case identifier resolution
525                let mut ns = Namespace::default();
526                for case in v.cases.iter_mut() {
527                    let index = ns.register(case.id, "variant case")?;
528
529                    if let Some(ty) = &mut case.ty {
530                        self.component_val_type(ty)?;
531                    }
532
533                    if let Some(refines) = &mut case.refines {
534                        if let Refinement::Index(span, idx) = refines {
535                            let resolved = ns.resolve(idx, "variant case")?;
536                            if resolved == index {
537                                return Err(Error::new(
538                                    *span,
539                                    "variant case cannot refine itself".to_string(),
540                                ));
541                            }
542
543                            *refines = Refinement::Resolved(resolved);
544                        }
545                    }
546                }
547            }
548            ComponentDefinedType::List(l) => {
549                self.component_val_type(&mut l.element)?;
550            }
551            ComponentDefinedType::Tuple(t) => {
552                for field in t.fields.iter_mut() {
553                    self.component_val_type(field)?;
554                }
555            }
556            ComponentDefinedType::Option(o) => {
557                self.component_val_type(&mut o.element)?;
558            }
559            ComponentDefinedType::Result(r) => {
560                if let Some(ty) = &mut r.ok {
561                    self.component_val_type(ty)?;
562                }
563
564                if let Some(ty) = &mut r.err {
565                    self.component_val_type(ty)?;
566                }
567            }
568            ComponentDefinedType::Own(t) | ComponentDefinedType::Borrow(t) => {
569                self.resolve_ns(t, Ns::Type)?;
570            }
571            ComponentDefinedType::Stream(s) => {
572                if let Some(ty) = &mut s.element {
573                    self.component_val_type(ty)?;
574                }
575            }
576            ComponentDefinedType::Future(f) => {
577                if let Some(ty) = &mut f.element {
578                    self.component_val_type(ty)?;
579                }
580            }
581        }
582        Ok(())
583    }
584
585    fn component_val_type(&mut self, ty: &mut ComponentValType<'a>) -> Result<(), Error> {
586        match ty {
587            ComponentValType::Ref(idx) => {
588                self.resolve_ns(idx, Ns::Type)?;
589                Ok(())
590            }
591            ComponentValType::Inline(ComponentDefinedType::Primitive(_)) => Ok(()),
592            ComponentValType::Inline(_) => unreachable!("should be expanded by now"),
593        }
594    }
595
596    fn core_ty(&mut self, field: &mut CoreType<'a>) -> Result<(), Error> {
597        match &mut field.def {
598            CoreTypeDef::Def(ty) => {
599                // See comments in `module_type` for why registration of ids happens
600                // here for core types early.
601                self.current().core_types.register(field.id, "core type")?;
602                self.current().resolve_type_def(ty)?;
603                assert!(self.aliases_to_insert.is_empty());
604            }
605            CoreTypeDef::Module(t) => {
606                self.stack.push(ComponentState::new(field.id));
607                self.module_type(t)?;
608                self.stack.pop();
609            }
610        }
611        Ok(())
612    }
613
614    fn core_rec(&mut self, rec: &mut core::Rec<'a>) -> Result<(), Error> {
615        // See comments in `module_type` for why registration of ids happens
616        // here for core types early.
617        for ty in rec.types.iter() {
618            self.current().core_types.register(ty.id, "core type")?;
619        }
620        for ty in rec.types.iter_mut() {
621            self.current().resolve_type(ty)?;
622        }
623        assert!(self.aliases_to_insert.is_empty());
624        Ok(())
625    }
626
627    fn ty(&mut self, field: &mut Type<'a>) -> Result<(), Error> {
628        match &mut field.def {
629            TypeDef::Defined(t) => {
630                self.defined_type(t)?;
631            }
632            TypeDef::Func(f) => {
633                for param in f.params.iter_mut() {
634                    self.component_val_type(&mut param.ty)?;
635                }
636
637                if let Some(result) = &mut f.result {
638                    self.component_val_type(result)?;
639                }
640            }
641            TypeDef::Component(c) => {
642                self.stack.push(ComponentState::new(field.id));
643                self.component_type(c)?;
644                self.stack.pop();
645            }
646            TypeDef::Instance(i) => {
647                self.stack.push(ComponentState::new(field.id));
648                self.instance_type(i)?;
649                self.stack.pop();
650            }
651            TypeDef::Resource(r) => {
652                match &mut r.rep {
653                    ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => {}
654                    ValType::Ref(r) => match &mut r.heap {
655                        core::HeapType::Abstract { .. } => {}
656                        core::HeapType::Concrete(id) => {
657                            self.resolve_ns(id, Ns::Type)?;
658                        }
659                    },
660                }
661                if let Some(dtor) = &mut r.dtor {
662                    self.core_item_ref(dtor)?;
663                }
664            }
665        }
666        Ok(())
667    }
668
669    fn component_type(&mut self, c: &mut ComponentType<'a>) -> Result<(), Error> {
670        self.resolve_prepending_aliases(
671            &mut c.decls,
672            |resolver, decl| match decl {
673                ComponentTypeDecl::Alias(alias) => resolver.alias(alias),
674                ComponentTypeDecl::CoreType(ty) => resolver.core_ty(ty),
675                ComponentTypeDecl::Type(ty) => resolver.ty(ty),
676                ComponentTypeDecl::Import(import) => resolver.item_sig(&mut import.item),
677                ComponentTypeDecl::Export(export) => resolver.item_sig(&mut export.item),
678            },
679            |state, decl| {
680                match decl {
681                    ComponentTypeDecl::Alias(alias) => {
682                        state.register_alias(alias)?;
683                    }
684                    ComponentTypeDecl::CoreType(ty) => {
685                        state.core_types.register(ty.id, "core type")?;
686                    }
687                    ComponentTypeDecl::Type(ty) => {
688                        state.types.register(ty.id, "type")?;
689                    }
690                    ComponentTypeDecl::Export(e) => {
691                        state.register_item_sig(&e.item)?;
692                    }
693                    ComponentTypeDecl::Import(i) => {
694                        state.register_item_sig(&i.item)?;
695                    }
696                }
697                Ok(())
698            },
699        )
700    }
701
702    fn instance_type(&mut self, c: &mut InstanceType<'a>) -> Result<(), Error> {
703        self.resolve_prepending_aliases(
704            &mut c.decls,
705            |resolver, decl| match decl {
706                InstanceTypeDecl::Alias(alias) => resolver.alias(alias),
707                InstanceTypeDecl::CoreType(ty) => resolver.core_ty(ty),
708                InstanceTypeDecl::Type(ty) => resolver.ty(ty),
709                InstanceTypeDecl::Export(export) => resolver.item_sig(&mut export.item),
710            },
711            |state, decl| {
712                match decl {
713                    InstanceTypeDecl::Alias(alias) => {
714                        state.register_alias(alias)?;
715                    }
716                    InstanceTypeDecl::CoreType(ty) => {
717                        state.core_types.register(ty.id, "core type")?;
718                    }
719                    InstanceTypeDecl::Type(ty) => {
720                        state.types.register(ty.id, "type")?;
721                    }
722                    InstanceTypeDecl::Export(export) => {
723                        state.register_item_sig(&export.item)?;
724                    }
725                }
726                Ok(())
727            },
728        )
729    }
730
731    fn core_item_ref<K>(&mut self, item: &mut CoreItemRef<'a, K>) -> Result<(), Error>
732    where
733        K: CoreItem + Copy,
734    {
735        // Check for not being an instance export reference
736        if item.export_name.is_none() {
737            self.resolve_ns(&mut item.idx, item.kind.ns())?;
738            return Ok(());
739        }
740
741        // This is a reference to a core instance export
742        let mut index = item.idx;
743        self.resolve_ns(&mut index, Ns::CoreInstance)?;
744
745        // Record an alias to reference the export
746        let span = item.idx.span();
747        let alias = Alias {
748            span,
749            id: None,
750            name: None,
751            target: AliasTarget::CoreExport {
752                instance: index,
753                name: item.export_name.unwrap(),
754                kind: item.kind.ns().into(),
755            },
756        };
757
758        index = Index::Num(self.current().register_alias(&alias)?, span);
759        self.aliases_to_insert.push(alias);
760
761        item.idx = index;
762        item.export_name = None;
763
764        Ok(())
765    }
766
767    fn component_item_ref<K>(&mut self, item: &mut ItemRef<'a, K>) -> Result<(), Error>
768    where
769        K: ComponentItem + Copy,
770    {
771        // Check for not being an instance export reference
772        if item.export_names.is_empty() {
773            self.resolve_ns(&mut item.idx, item.kind.ns())?;
774            return Ok(());
775        }
776
777        // This is a reference to an instance export
778        let mut index = item.idx;
779        self.resolve_ns(&mut index, Ns::Instance)?;
780
781        let span = item.idx.span();
782        for (pos, export_name) in item.export_names.iter().enumerate() {
783            // Record an alias to reference the export
784            let alias = Alias {
785                span,
786                id: None,
787                name: None,
788                target: AliasTarget::Export {
789                    instance: index,
790                    name: export_name,
791                    kind: if pos == item.export_names.len() - 1 {
792                        item.kind.ns().into()
793                    } else {
794                        ComponentExportAliasKind::Instance
795                    },
796                },
797            };
798
799            index = Index::Num(self.current().register_alias(&alias)?, span);
800            self.aliases_to_insert.push(alias);
801        }
802
803        item.idx = index;
804        item.export_names = Vec::new();
805
806        Ok(())
807    }
808
809    fn resolve_ns(&mut self, idx: &mut Index<'a>, ns: Ns) -> Result<u32, Error> {
810        // Perform resolution on a local clone walking up the stack of components
811        // that we have. Note that a local clone is used since we don't want to use
812        // the parent's resolved index if a parent matches, instead we want to use
813        // the index of the alias that we will automatically insert.
814        let mut idx_clone = *idx;
815        for (depth, resolver) in self.stack.iter_mut().rev().enumerate() {
816            let depth = depth as u32;
817            let found = match resolver.resolve(ns, &mut idx_clone) {
818                Ok(idx) => idx,
819                // Try the next parent
820                Err(_) => continue,
821            };
822
823            // If this is the current component then no extra alias is necessary, so
824            // return success.
825            if depth == 0 {
826                *idx = idx_clone;
827                return Ok(found);
828            }
829            let id = match idx {
830                Index::Id(id) => *id,
831                Index::Num(..) => unreachable!(),
832            };
833
834            // When resolution succeeds in a parent then an outer alias is
835            // automatically inserted here in this component.
836            let span = idx.span();
837            let alias = Alias {
838                span,
839                id: Some(id),
840                name: None,
841                target: AliasTarget::Outer {
842                    outer: Index::Num(depth, span),
843                    index: Index::Num(found, span),
844                    kind: match ns {
845                        Ns::CoreModule => ComponentOuterAliasKind::CoreModule,
846                        Ns::CoreType => ComponentOuterAliasKind::CoreType,
847                        Ns::Type => ComponentOuterAliasKind::Type,
848                        Ns::Component => ComponentOuterAliasKind::Component,
849                        _ => {
850                            return Err(Error::new(
851                                span,
852                                format!(
853                                    "outer item `{}` is not a module, type, or component",
854                                    id.name(),
855                                ),
856                            ))
857                        }
858                    },
859                },
860            };
861            let local_index = self.current().register_alias(&alias)?;
862            self.aliases_to_insert.push(alias);
863            *idx = Index::Num(local_index, span);
864            return Ok(local_index);
865        }
866
867        // If resolution in any parent failed then simply return the error from our
868        // local namespace
869        self.current().resolve(ns, idx)?;
870        unreachable!()
871    }
872
873    fn module_type(&mut self, ty: &mut ModuleType<'a>) -> Result<(), Error> {
874        return self.resolve_prepending_aliases(
875            &mut ty.decls,
876            |resolver, decl| match decl {
877                ModuleTypeDecl::Alias(alias) => resolver.alias(alias),
878
879                // For types since the GC proposal to core wasm they're allowed
880                // to both refer to themselves and additionally a recursion
881                // group can define a set of types that all refer to one
882                // another. That means that the type names must be registered
883                // first before the type is resolved so the type's own name is
884                // in scope for itself.
885                //
886                // Note though that this means that aliases cannot be injected
887                // automatically for references to outer types. We don't know
888                // how many aliases are going to be created so we otherwise
889                // don't know the type index to register.
890                //
891                // As a compromise for now core types don't support
892                // auto-injection of aliases from outer scopes. They must be
893                // explicitly aliased in. Also note that the error message isn't
894                // great either. This may be something we want to improve in the
895                // future with a better error message or a pass that goes over
896                // everything first to inject aliases and then afterwards all
897                // other names are registered.
898                ModuleTypeDecl::Type(t) => {
899                    resolver.current().core_types.register(t.id, "type")?;
900                    resolver.current().resolve_type(t)
901                }
902                ModuleTypeDecl::Rec(t) => {
903                    for t in t.types.iter_mut() {
904                        resolver.current().core_types.register(t.id, "type")?;
905                    }
906                    for t in t.types.iter_mut() {
907                        resolver.current().resolve_type(t)?;
908                    }
909                    Ok(())
910                }
911
912                ModuleTypeDecl::Import(import) => resolve_item_sig(resolver, &mut import.item),
913                ModuleTypeDecl::Export(_, item) => resolve_item_sig(resolver, item),
914            },
915            |state, decl| {
916                match decl {
917                    ModuleTypeDecl::Alias(alias) => {
918                        state.register_alias(alias)?;
919                    }
920                    // These were registered above already
921                    ModuleTypeDecl::Type(_) | ModuleTypeDecl::Rec(_) => {}
922                    // Only the type namespace is populated within the module type
923                    // namespace so these are ignored here.
924                    ModuleTypeDecl::Import(_) | ModuleTypeDecl::Export(..) => {}
925                }
926                Ok(())
927            },
928        );
929
930        fn resolve_item_sig<'a>(
931            resolver: &Resolver<'a>,
932            sig: &mut core::ItemSig<'a>,
933        ) -> Result<(), Error> {
934            match &mut sig.kind {
935                core::ItemKind::Func(ty) | core::ItemKind::Tag(core::TagType::Exception(ty)) => {
936                    let idx = ty.index.as_mut().expect("index should be filled in");
937                    resolver
938                        .stack
939                        .last()
940                        .unwrap()
941                        .core_types
942                        .resolve(idx, "type")?;
943                }
944                core::ItemKind::Memory(_)
945                | core::ItemKind::Global(_)
946                | core::ItemKind::Table(_) => {}
947            }
948            Ok(())
949        }
950    }
951}
952
953impl<'a> ComponentState<'a> {
954    fn resolve(&self, ns: Ns, idx: &mut Index<'a>) -> Result<u32, Error> {
955        match ns {
956            Ns::CoreFunc => self.core_funcs.resolve(idx, "core func"),
957            Ns::CoreGlobal => self.core_globals.resolve(idx, "core global"),
958            Ns::CoreTable => self.core_tables.resolve(idx, "core table"),
959            Ns::CoreMemory => self.core_memories.resolve(idx, "core memory"),
960            Ns::CoreType => self.core_types.resolve(idx, "core type"),
961            Ns::CoreTag => self.core_tags.resolve(idx, "core tag"),
962            Ns::CoreInstance => self.core_instances.resolve(idx, "core instance"),
963            Ns::CoreModule => self.core_modules.resolve(idx, "core module"),
964            Ns::Func => self.funcs.resolve(idx, "func"),
965            Ns::Type => self.types.resolve(idx, "type"),
966            Ns::Instance => self.instances.resolve(idx, "instance"),
967            Ns::Component => self.components.resolve(idx, "component"),
968            Ns::Value => self.values.resolve(idx, "value"),
969        }
970    }
971
972    /// Assign an index to the given field.
973    fn register(&mut self, item: &ComponentField<'a>) -> Result<(), Error> {
974        match item {
975            ComponentField::CoreModule(m) => self.core_modules.register(m.id, "core module")?,
976            ComponentField::CoreInstance(i) => {
977                self.core_instances.register(i.id, "core instance")?
978            }
979            ComponentField::CoreType(ty) => match &ty.def {
980                CoreTypeDef::Def(_) => 0, // done above in `core_rec`
981                CoreTypeDef::Module(_) => self.core_types.register(ty.id, "core type")?,
982            },
983            ComponentField::CoreRec(_) => 0, // done above in `core_rec`
984            ComponentField::Component(c) => self.components.register(c.id, "component")?,
985            ComponentField::Instance(i) => self.instances.register(i.id, "instance")?,
986            ComponentField::Alias(a) => self.register_alias(a)?,
987            ComponentField::Type(t) => self.types.register(t.id, "type")?,
988            ComponentField::CanonicalFunc(f) => match &f.kind {
989                CanonicalFuncKind::Lift { .. } => self.funcs.register(f.id, "func")?,
990                CanonicalFuncKind::Core(_) => self.core_funcs.register(f.id, "core func")?,
991            },
992            ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
993                unreachable!("should be expanded already")
994            }
995            ComponentField::Start(s) => {
996                for r in &s.results {
997                    self.values.register(*r, "value")?;
998                }
999                return Ok(());
1000            }
1001            ComponentField::Import(i) => self.register_item_sig(&i.item)?,
1002            ComponentField::Export(e) => match &e.kind {
1003                ComponentExportKind::CoreModule(_) => {
1004                    self.core_modules.register(e.id, "core module")?
1005                }
1006                ComponentExportKind::Func(_) => self.funcs.register(e.id, "func")?,
1007                ComponentExportKind::Instance(_) => self.instances.register(e.id, "instance")?,
1008                ComponentExportKind::Value(_) => self.values.register(e.id, "value")?,
1009                ComponentExportKind::Component(_) => self.components.register(e.id, "component")?,
1010                ComponentExportKind::Type(_) => self.types.register(e.id, "type")?,
1011            },
1012            ComponentField::Custom(_) | ComponentField::Producers(_) => return Ok(()),
1013        };
1014
1015        Ok(())
1016    }
1017
1018    fn register_alias(&mut self, alias: &Alias<'a>) -> Result<u32, Error> {
1019        match alias.target {
1020            AliasTarget::Export { kind, .. } => match kind {
1021                ComponentExportAliasKind::CoreModule => {
1022                    self.core_modules.register(alias.id, "core module")
1023                }
1024                ComponentExportAliasKind::Func => self.funcs.register(alias.id, "func"),
1025                ComponentExportAliasKind::Value => self.values.register(alias.id, "value"),
1026                ComponentExportAliasKind::Type => self.types.register(alias.id, "type"),
1027                ComponentExportAliasKind::Component => {
1028                    self.components.register(alias.id, "component")
1029                }
1030                ComponentExportAliasKind::Instance => self.instances.register(alias.id, "instance"),
1031            },
1032            AliasTarget::CoreExport { kind, .. } => match kind {
1033                core::ExportKind::Func => self.core_funcs.register(alias.id, "core func"),
1034                core::ExportKind::Table => self.core_tables.register(alias.id, "core table"),
1035                core::ExportKind::Memory => self.core_memories.register(alias.id, "core memory"),
1036                core::ExportKind::Global => self.core_globals.register(alias.id, "core global"),
1037                core::ExportKind::Tag => self.core_tags.register(alias.id, "core tag"),
1038            },
1039            AliasTarget::Outer { kind, .. } => match kind {
1040                ComponentOuterAliasKind::CoreModule => {
1041                    self.core_modules.register(alias.id, "core module")
1042                }
1043                ComponentOuterAliasKind::CoreType => {
1044                    self.core_types.register(alias.id, "core type")
1045                }
1046                ComponentOuterAliasKind::Type => self.types.register(alias.id, "type"),
1047                ComponentOuterAliasKind::Component => {
1048                    self.components.register(alias.id, "component")
1049                }
1050            },
1051        }
1052    }
1053}
1054
1055impl<'a> ResolveCoreType<'a> for ComponentState<'a> {
1056    fn resolve_type_name(&mut self, name: &mut Index<'a>) -> Result<u32, Error> {
1057        self.resolve(Ns::CoreType, name)
1058    }
1059}
1060
1061#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
1062enum Ns {
1063    CoreFunc,
1064    CoreGlobal,
1065    CoreTable,
1066    CoreMemory,
1067    CoreType,
1068    CoreTag,
1069    CoreInstance,
1070    CoreModule,
1071    Func,
1072    Type,
1073    Instance,
1074    Component,
1075    Value,
1076}
1077
1078trait ComponentItem {
1079    fn ns(&self) -> Ns;
1080}
1081
1082trait CoreItem {
1083    fn ns(&self) -> Ns;
1084}
1085
1086macro_rules! component_item {
1087    ($kw:path, $kind:ident) => {
1088        impl ComponentItem for $kw {
1089            fn ns(&self) -> Ns {
1090                Ns::$kind
1091            }
1092        }
1093    };
1094}
1095
1096macro_rules! core_item {
1097    ($kw:path, $kind:ident) => {
1098        impl CoreItem for $kw {
1099            fn ns(&self) -> Ns {
1100                Ns::$kind
1101            }
1102        }
1103    };
1104}
1105
1106component_item!(kw::func, Func);
1107component_item!(kw::r#type, Type);
1108component_item!(kw::r#instance, Instance);
1109component_item!(kw::component, Component);
1110component_item!(kw::value, Value);
1111component_item!(kw::module, CoreModule);
1112
1113core_item!(kw::func, CoreFunc);
1114core_item!(kw::memory, CoreMemory);
1115core_item!(kw::table, CoreTable);
1116core_item!(kw::r#type, CoreType);
1117core_item!(kw::r#instance, CoreInstance);
1118
1119impl From<Ns> for ComponentExportAliasKind {
1120    fn from(ns: Ns) -> Self {
1121        match ns {
1122            Ns::CoreModule => Self::CoreModule,
1123            Ns::Func => Self::Func,
1124            Ns::Type => Self::Type,
1125            Ns::Instance => Self::Instance,
1126            Ns::Component => Self::Component,
1127            Ns::Value => Self::Value,
1128            _ => unreachable!("not a component exportable namespace"),
1129        }
1130    }
1131}
1132
1133impl From<Ns> for core::ExportKind {
1134    fn from(ns: Ns) -> Self {
1135        match ns {
1136            Ns::CoreFunc => Self::Func,
1137            Ns::CoreTable => Self::Table,
1138            Ns::CoreGlobal => Self::Global,
1139            Ns::CoreMemory => Self::Memory,
1140            Ns::CoreTag => Self::Tag,
1141            _ => unreachable!("not a core exportable namespace"),
1142        }
1143    }
1144}
1145
1146impl From<ComponentOuterAliasKind> for Ns {
1147    fn from(kind: ComponentOuterAliasKind) -> Self {
1148        match kind {
1149            ComponentOuterAliasKind::CoreModule => Self::CoreModule,
1150            ComponentOuterAliasKind::CoreType => Self::CoreType,
1151            ComponentOuterAliasKind::Type => Self::Type,
1152            ComponentOuterAliasKind::Component => Self::Component,
1153        }
1154    }
1155}
1156
1157impl CoreItem for core::ExportKind {
1158    fn ns(&self) -> Ns {
1159        match self {
1160            Self::Func => Ns::CoreFunc,
1161            Self::Table => Ns::CoreTable,
1162            Self::Global => Ns::CoreGlobal,
1163            Self::Memory => Ns::CoreMemory,
1164            Self::Tag => Ns::CoreTag,
1165        }
1166    }
1167}