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: &mut Vec> = match &mut component.kind {
13 ComponentKind::Text(fields: &mut Vec>) => fields,
14 ComponentKind::Binary(_) => return Ok(()),
15 };
16 let mut resolver: 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(name:sig.id, desc:"core module"),
90 ItemSigKind::Func(_) => self.funcs.register(name:sig.id, desc:"func"),
91 ItemSigKind::Component(_) => self.components.register(name:sig.id, desc:"component"),
92 ItemSigKind::Instance(_) => self.instances.register(name:sig.id, desc:"instance"),
93 ItemSigKind::Value(_) => self.values.register(name:sig.id, desc:"value"),
94 ItemSigKind::Type(_) => self.types.register(name:sig.id, desc:"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::Lower(info) => {
374 self.component_item_ref(&mut info.func)?;
375 self.canon_opts(&mut info.opts)?;
376 }
377 CanonicalFuncKind::ResourceNew(info) => {
378 self.resolve_ns(&mut info.ty, Ns::Type)?;
379 }
380 CanonicalFuncKind::ResourceRep(info) => {
381 self.resolve_ns(&mut info.ty, Ns::Type)?;
382 }
383 CanonicalFuncKind::ResourceDrop(info) => {
384 self.resolve_ns(&mut info.ty, Ns::Type)?;
385 }
386 CanonicalFuncKind::ThreadSpawn(info) => {
387 self.resolve_ns(&mut info.ty, Ns::CoreType)?;
388 }
389 CanonicalFuncKind::ThreadHwConcurrency(_)
390 | CanonicalFuncKind::TaskBackpressure
391 | CanonicalFuncKind::TaskYield(_)
392 | CanonicalFuncKind::SubtaskDrop
393 | CanonicalFuncKind::ErrorContextDrop => {}
394 CanonicalFuncKind::TaskReturn(info) => {
395 self.resolve_ns(&mut info.ty, Ns::CoreType)?;
396 }
397 CanonicalFuncKind::TaskWait(info) => {
398 self.core_item_ref(&mut info.memory)?;
399 }
400 CanonicalFuncKind::TaskPoll(info) => {
401 self.core_item_ref(&mut info.memory)?;
402 }
403 CanonicalFuncKind::StreamNew(info) => {
404 self.resolve_ns(&mut info.ty, Ns::Type)?;
405 }
406 CanonicalFuncKind::StreamRead(info) => {
407 self.resolve_ns(&mut info.ty, Ns::Type)?;
408 self.canon_opts(&mut info.opts)?;
409 }
410 CanonicalFuncKind::StreamWrite(info) => {
411 self.resolve_ns(&mut info.ty, Ns::Type)?;
412 self.canon_opts(&mut info.opts)?;
413 }
414 CanonicalFuncKind::StreamCancelRead(info) => {
415 self.resolve_ns(&mut info.ty, Ns::Type)?;
416 }
417 CanonicalFuncKind::StreamCancelWrite(info) => {
418 self.resolve_ns(&mut info.ty, Ns::Type)?;
419 }
420 CanonicalFuncKind::StreamCloseReadable(info) => {
421 self.resolve_ns(&mut info.ty, Ns::Type)?;
422 }
423 CanonicalFuncKind::StreamCloseWritable(info) => {
424 self.resolve_ns(&mut info.ty, Ns::Type)?;
425 }
426 CanonicalFuncKind::FutureNew(info) => {
427 self.resolve_ns(&mut info.ty, Ns::Type)?;
428 }
429 CanonicalFuncKind::FutureRead(info) => {
430 self.resolve_ns(&mut info.ty, Ns::Type)?;
431 self.canon_opts(&mut info.opts)?;
432 }
433 CanonicalFuncKind::FutureWrite(info) => {
434 self.resolve_ns(&mut info.ty, Ns::Type)?;
435 self.canon_opts(&mut info.opts)?;
436 }
437 CanonicalFuncKind::FutureCancelRead(info) => {
438 self.resolve_ns(&mut info.ty, Ns::Type)?;
439 }
440 CanonicalFuncKind::FutureCancelWrite(info) => {
441 self.resolve_ns(&mut info.ty, Ns::Type)?;
442 }
443 CanonicalFuncKind::FutureCloseReadable(info) => {
444 self.resolve_ns(&mut info.ty, Ns::Type)?;
445 }
446 CanonicalFuncKind::FutureCloseWritable(info) => {
447 self.resolve_ns(&mut info.ty, Ns::Type)?;
448 }
449 CanonicalFuncKind::ErrorContextNew(info) => {
450 self.canon_opts(&mut info.opts)?;
451 }
452 CanonicalFuncKind::ErrorContextDebugMessage(info) => {
453 self.canon_opts(&mut info.opts)?;
454 }
455 }
456
457 Ok(())
458 }
459
460 fn canon_opts(&mut self, opts: &mut [CanonOpt<'a>]) -> Result<(), Error> {
461 for opt in opts {
462 match opt {
463 CanonOpt::StringUtf8
464 | CanonOpt::StringUtf16
465 | CanonOpt::StringLatin1Utf16
466 | CanonOpt::Async => {}
467 CanonOpt::Memory(r) => self.core_item_ref(r)?,
468 CanonOpt::Realloc(r) | CanonOpt::PostReturn(r) | CanonOpt::Callback(r) => {
469 self.core_item_ref(r)?
470 }
471 }
472 }
473
474 Ok(())
475 }
476
477 fn core_type_use<T>(&mut self, ty: &mut CoreTypeUse<'a, T>) -> Result<(), Error> {
478 let item = match ty {
479 CoreTypeUse::Ref(r) => r,
480 CoreTypeUse::Inline(_) => {
481 unreachable!("inline type-use should be expanded by now")
482 }
483 };
484 self.core_item_ref(item)
485 }
486
487 fn component_type_use<T>(&mut self, ty: &mut ComponentTypeUse<'a, T>) -> Result<(), Error> {
488 let item = match ty {
489 ComponentTypeUse::Ref(r) => r,
490 ComponentTypeUse::Inline(_) => {
491 unreachable!("inline type-use should be expanded by now")
492 }
493 };
494 self.component_item_ref(item)
495 }
496
497 fn defined_type(&mut self, ty: &mut ComponentDefinedType<'a>) -> Result<(), Error> {
498 match ty {
499 ComponentDefinedType::Primitive(_) => {}
500 ComponentDefinedType::Flags(_) => {}
501 ComponentDefinedType::Enum(_) => {}
502 ComponentDefinedType::Record(r) => {
503 for field in r.fields.iter_mut() {
504 self.component_val_type(&mut field.ty)?;
505 }
506 }
507 ComponentDefinedType::Variant(v) => {
508 // Namespace for case identifier resolution
509 let mut ns = Namespace::default();
510 for case in v.cases.iter_mut() {
511 let index = ns.register(case.id, "variant case")?;
512
513 if let Some(ty) = &mut case.ty {
514 self.component_val_type(ty)?;
515 }
516
517 if let Some(refines) = &mut case.refines {
518 if let Refinement::Index(span, idx) = refines {
519 let resolved = ns.resolve(idx, "variant case")?;
520 if resolved == index {
521 return Err(Error::new(
522 *span,
523 "variant case cannot refine itself".to_string(),
524 ));
525 }
526
527 *refines = Refinement::Resolved(resolved);
528 }
529 }
530 }
531 }
532 ComponentDefinedType::List(l) => {
533 self.component_val_type(&mut l.element)?;
534 }
535 ComponentDefinedType::Tuple(t) => {
536 for field in t.fields.iter_mut() {
537 self.component_val_type(field)?;
538 }
539 }
540 ComponentDefinedType::Option(o) => {
541 self.component_val_type(&mut o.element)?;
542 }
543 ComponentDefinedType::Result(r) => {
544 if let Some(ty) = &mut r.ok {
545 self.component_val_type(ty)?;
546 }
547
548 if let Some(ty) = &mut r.err {
549 self.component_val_type(ty)?;
550 }
551 }
552 ComponentDefinedType::Own(t) | ComponentDefinedType::Borrow(t) => {
553 self.resolve_ns(t, Ns::Type)?;
554 }
555 ComponentDefinedType::Stream(s) => {
556 self.component_val_type(&mut s.element)?;
557 }
558 ComponentDefinedType::Future(f) => {
559 if let Some(ty) = &mut f.element {
560 self.component_val_type(ty)?;
561 }
562 }
563 }
564 Ok(())
565 }
566
567 fn component_val_type(&mut self, ty: &mut ComponentValType<'a>) -> Result<(), Error> {
568 match ty {
569 ComponentValType::Ref(idx) => {
570 self.resolve_ns(idx, Ns::Type)?;
571 Ok(())
572 }
573 ComponentValType::Inline(ComponentDefinedType::Primitive(_)) => Ok(()),
574 ComponentValType::Inline(_) => unreachable!("should be expanded by now"),
575 }
576 }
577
578 fn core_ty(&mut self, field: &mut CoreType<'a>) -> Result<(), Error> {
579 match &mut field.def {
580 CoreTypeDef::Def(ty) => {
581 // See comments in `module_type` for why registration of ids happens
582 // here for core types early.
583 self.current().core_types.register(field.id, "core type")?;
584 self.current().resolve_type_def(ty)?;
585 assert!(self.aliases_to_insert.is_empty());
586 }
587 CoreTypeDef::Module(t) => {
588 self.stack.push(ComponentState::new(field.id));
589 self.module_type(t)?;
590 self.stack.pop();
591 }
592 }
593 Ok(())
594 }
595
596 fn core_rec(&mut self, rec: &mut core::Rec<'a>) -> Result<(), Error> {
597 // See comments in `module_type` for why registration of ids happens
598 // here for core types early.
599 for ty in rec.types.iter() {
600 self.current().core_types.register(ty.id, "core type")?;
601 }
602 for ty in rec.types.iter_mut() {
603 self.current().resolve_type(ty)?;
604 }
605 assert!(self.aliases_to_insert.is_empty());
606 Ok(())
607 }
608
609 fn ty(&mut self, field: &mut Type<'a>) -> Result<(), Error> {
610 match &mut field.def {
611 TypeDef::Defined(t) => {
612 self.defined_type(t)?;
613 }
614 TypeDef::Func(f) => {
615 for param in f.params.iter_mut() {
616 self.component_val_type(&mut param.ty)?;
617 }
618
619 for result in f.results.iter_mut() {
620 self.component_val_type(&mut result.ty)?;
621 }
622 }
623 TypeDef::Component(c) => {
624 self.stack.push(ComponentState::new(field.id));
625 self.component_type(c)?;
626 self.stack.pop();
627 }
628 TypeDef::Instance(i) => {
629 self.stack.push(ComponentState::new(field.id));
630 self.instance_type(i)?;
631 self.stack.pop();
632 }
633 TypeDef::Resource(r) => {
634 match &mut r.rep {
635 ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => {}
636 ValType::Ref(r) => match &mut r.heap {
637 core::HeapType::Abstract { .. } => {}
638 core::HeapType::Concrete(id) => {
639 self.resolve_ns(id, Ns::Type)?;
640 }
641 },
642 }
643 if let Some(dtor) = &mut r.dtor {
644 self.core_item_ref(dtor)?;
645 }
646 }
647 }
648 Ok(())
649 }
650
651 fn component_type(&mut self, c: &mut ComponentType<'a>) -> Result<(), Error> {
652 self.resolve_prepending_aliases(
653 &mut c.decls,
654 |resolver, decl| match decl {
655 ComponentTypeDecl::Alias(alias) => resolver.alias(alias),
656 ComponentTypeDecl::CoreType(ty) => resolver.core_ty(ty),
657 ComponentTypeDecl::Type(ty) => resolver.ty(ty),
658 ComponentTypeDecl::Import(import) => resolver.item_sig(&mut import.item),
659 ComponentTypeDecl::Export(export) => resolver.item_sig(&mut export.item),
660 },
661 |state, decl| {
662 match decl {
663 ComponentTypeDecl::Alias(alias) => {
664 state.register_alias(alias)?;
665 }
666 ComponentTypeDecl::CoreType(ty) => {
667 state.core_types.register(ty.id, "core type")?;
668 }
669 ComponentTypeDecl::Type(ty) => {
670 state.types.register(ty.id, "type")?;
671 }
672 ComponentTypeDecl::Export(e) => {
673 state.register_item_sig(&e.item)?;
674 }
675 ComponentTypeDecl::Import(i) => {
676 state.register_item_sig(&i.item)?;
677 }
678 }
679 Ok(())
680 },
681 )
682 }
683
684 fn instance_type(&mut self, c: &mut InstanceType<'a>) -> Result<(), Error> {
685 self.resolve_prepending_aliases(
686 &mut c.decls,
687 |resolver, decl| match decl {
688 InstanceTypeDecl::Alias(alias) => resolver.alias(alias),
689 InstanceTypeDecl::CoreType(ty) => resolver.core_ty(ty),
690 InstanceTypeDecl::Type(ty) => resolver.ty(ty),
691 InstanceTypeDecl::Export(export) => resolver.item_sig(&mut export.item),
692 },
693 |state, decl| {
694 match decl {
695 InstanceTypeDecl::Alias(alias) => {
696 state.register_alias(alias)?;
697 }
698 InstanceTypeDecl::CoreType(ty) => {
699 state.core_types.register(ty.id, "core type")?;
700 }
701 InstanceTypeDecl::Type(ty) => {
702 state.types.register(ty.id, "type")?;
703 }
704 InstanceTypeDecl::Export(export) => {
705 state.register_item_sig(&export.item)?;
706 }
707 }
708 Ok(())
709 },
710 )
711 }
712
713 fn core_item_ref<K>(&mut self, item: &mut CoreItemRef<'a, K>) -> Result<(), Error>
714 where
715 K: CoreItem + Copy,
716 {
717 // Check for not being an instance export reference
718 if item.export_name.is_none() {
719 self.resolve_ns(&mut item.idx, item.kind.ns())?;
720 return Ok(());
721 }
722
723 // This is a reference to a core instance export
724 let mut index = item.idx;
725 self.resolve_ns(&mut index, Ns::CoreInstance)?;
726
727 // Record an alias to reference the export
728 let span = item.idx.span();
729 let alias = Alias {
730 span,
731 id: None,
732 name: None,
733 target: AliasTarget::CoreExport {
734 instance: index,
735 name: item.export_name.unwrap(),
736 kind: item.kind.ns().into(),
737 },
738 };
739
740 index = Index::Num(self.current().register_alias(&alias)?, span);
741 self.aliases_to_insert.push(alias);
742
743 item.idx = index;
744 item.export_name = None;
745
746 Ok(())
747 }
748
749 fn component_item_ref<K>(&mut self, item: &mut ItemRef<'a, K>) -> Result<(), Error>
750 where
751 K: ComponentItem + Copy,
752 {
753 // Check for not being an instance export reference
754 if item.export_names.is_empty() {
755 self.resolve_ns(&mut item.idx, item.kind.ns())?;
756 return Ok(());
757 }
758
759 // This is a reference to an instance export
760 let mut index = item.idx;
761 self.resolve_ns(&mut index, Ns::Instance)?;
762
763 let span = item.idx.span();
764 for (pos, export_name) in item.export_names.iter().enumerate() {
765 // Record an alias to reference the export
766 let alias = Alias {
767 span,
768 id: None,
769 name: None,
770 target: AliasTarget::Export {
771 instance: index,
772 name: export_name,
773 kind: if pos == item.export_names.len() - 1 {
774 item.kind.ns().into()
775 } else {
776 ComponentExportAliasKind::Instance
777 },
778 },
779 };
780
781 index = Index::Num(self.current().register_alias(&alias)?, span);
782 self.aliases_to_insert.push(alias);
783 }
784
785 item.idx = index;
786 item.export_names = Vec::new();
787
788 Ok(())
789 }
790
791 fn resolve_ns(&mut self, idx: &mut Index<'a>, ns: Ns) -> Result<u32, Error> {
792 // Perform resolution on a local clone walking up the stack of components
793 // that we have. Note that a local clone is used since we don't want to use
794 // the parent's resolved index if a parent matches, instead we want to use
795 // the index of the alias that we will automatically insert.
796 let mut idx_clone = *idx;
797 for (depth, resolver) in self.stack.iter_mut().rev().enumerate() {
798 let depth = depth as u32;
799 let found = match resolver.resolve(ns, &mut idx_clone) {
800 Ok(idx) => idx,
801 // Try the next parent
802 Err(_) => continue,
803 };
804
805 // If this is the current component then no extra alias is necessary, so
806 // return success.
807 if depth == 0 {
808 *idx = idx_clone;
809 return Ok(found);
810 }
811 let id = match idx {
812 Index::Id(id) => *id,
813 Index::Num(..) => unreachable!(),
814 };
815
816 // When resolution succeeds in a parent then an outer alias is
817 // automatically inserted here in this component.
818 let span = idx.span();
819 let alias = Alias {
820 span,
821 id: Some(id),
822 name: None,
823 target: AliasTarget::Outer {
824 outer: Index::Num(depth, span),
825 index: Index::Num(found, span),
826 kind: ns.into(),
827 },
828 };
829 let local_index = self.current().register_alias(&alias)?;
830 self.aliases_to_insert.push(alias);
831 *idx = Index::Num(local_index, span);
832 return Ok(local_index);
833 }
834
835 // If resolution in any parent failed then simply return the error from our
836 // local namespace
837 self.current().resolve(ns, idx)?;
838 unreachable!()
839 }
840
841 fn module_type(&mut self, ty: &mut ModuleType<'a>) -> Result<(), Error> {
842 return self.resolve_prepending_aliases(
843 &mut ty.decls,
844 |resolver, decl| match decl {
845 ModuleTypeDecl::Alias(alias) => resolver.alias(alias),
846
847 // For types since the GC proposal to core wasm they're allowed
848 // to both refer to themselves and additionally a recursion
849 // group can define a set of types that all refer to one
850 // another. That means that the type names must be registered
851 // first before the type is resolved so the type's own name is
852 // in scope for itself.
853 //
854 // Note though that this means that aliases cannot be injected
855 // automatically for references to outer types. We don't know
856 // how many aliases are going to be created so we otherwise
857 // don't know the type index to register.
858 //
859 // As a compromise for now core types don't support
860 // auto-injection of aliases from outer scopes. They must be
861 // explicitly aliased in. Also note that the error message isn't
862 // great either. This may be something we want to improve in the
863 // future with a better error message or a pass that goes over
864 // everything first to inject aliases and then afterwards all
865 // other names are registered.
866 ModuleTypeDecl::Type(t) => {
867 resolver.current().core_types.register(t.id, "type")?;
868 resolver.current().resolve_type(t)
869 }
870 ModuleTypeDecl::Rec(t) => {
871 for t in t.types.iter_mut() {
872 resolver.current().core_types.register(t.id, "type")?;
873 }
874 for t in t.types.iter_mut() {
875 resolver.current().resolve_type(t)?;
876 }
877 Ok(())
878 }
879
880 ModuleTypeDecl::Import(import) => resolve_item_sig(resolver, &mut import.item),
881 ModuleTypeDecl::Export(_, item) => resolve_item_sig(resolver, item),
882 },
883 |state, decl| {
884 match decl {
885 ModuleTypeDecl::Alias(alias) => {
886 state.register_alias(alias)?;
887 }
888 // These were registered above already
889 ModuleTypeDecl::Type(_) | ModuleTypeDecl::Rec(_) => {}
890 // Only the type namespace is populated within the module type
891 // namespace so these are ignored here.
892 ModuleTypeDecl::Import(_) | ModuleTypeDecl::Export(..) => {}
893 }
894 Ok(())
895 },
896 );
897
898 fn resolve_item_sig<'a>(
899 resolver: &Resolver<'a>,
900 sig: &mut core::ItemSig<'a>,
901 ) -> Result<(), Error> {
902 match &mut sig.kind {
903 core::ItemKind::Func(ty) | core::ItemKind::Tag(core::TagType::Exception(ty)) => {
904 let idx = ty.index.as_mut().expect("index should be filled in");
905 resolver
906 .stack
907 .last()
908 .unwrap()
909 .core_types
910 .resolve(idx, "type")?;
911 }
912 core::ItemKind::Memory(_)
913 | core::ItemKind::Global(_)
914 | core::ItemKind::Table(_) => {}
915 }
916 Ok(())
917 }
918 }
919}
920
921impl<'a> ComponentState<'a> {
922 fn resolve(&self, ns: Ns, idx: &mut Index<'a>) -> Result<u32, Error> {
923 match ns {
924 Ns::CoreFunc => self.core_funcs.resolve(idx, "core func"),
925 Ns::CoreGlobal => self.core_globals.resolve(idx, "core global"),
926 Ns::CoreTable => self.core_tables.resolve(idx, "core table"),
927 Ns::CoreMemory => self.core_memories.resolve(idx, "core memory"),
928 Ns::CoreType => self.core_types.resolve(idx, "core type"),
929 Ns::CoreTag => self.core_tags.resolve(idx, "core tag"),
930 Ns::CoreInstance => self.core_instances.resolve(idx, "core instance"),
931 Ns::CoreModule => self.core_modules.resolve(idx, "core module"),
932 Ns::Func => self.funcs.resolve(idx, "func"),
933 Ns::Type => self.types.resolve(idx, "type"),
934 Ns::Instance => self.instances.resolve(idx, "instance"),
935 Ns::Component => self.components.resolve(idx, "component"),
936 Ns::Value => self.values.resolve(idx, "value"),
937 }
938 }
939
940 /// Assign an index to the given field.
941 fn register(&mut self, item: &ComponentField<'a>) -> Result<(), Error> {
942 match item {
943 ComponentField::CoreModule(m) => self.core_modules.register(m.id, "core module")?,
944 ComponentField::CoreInstance(i) => {
945 self.core_instances.register(i.id, "core instance")?
946 }
947 ComponentField::CoreType(ty) => match &ty.def {
948 CoreTypeDef::Def(_) => 0, // done above in `core_rec`
949 CoreTypeDef::Module(_) => self.core_types.register(ty.id, "core type")?,
950 },
951 ComponentField::CoreRec(_) => 0, // done above in `core_rec`
952 ComponentField::Component(c) => self.components.register(c.id, "component")?,
953 ComponentField::Instance(i) => self.instances.register(i.id, "instance")?,
954 ComponentField::Alias(a) => self.register_alias(a)?,
955 ComponentField::Type(t) => self.types.register(t.id, "type")?,
956 ComponentField::CanonicalFunc(f) => match &f.kind {
957 CanonicalFuncKind::Lift { .. } => self.funcs.register(f.id, "func")?,
958 CanonicalFuncKind::Lower(_)
959 | CanonicalFuncKind::ResourceNew(_)
960 | CanonicalFuncKind::ResourceRep(_)
961 | CanonicalFuncKind::ResourceDrop(_)
962 | CanonicalFuncKind::ThreadSpawn(_)
963 | CanonicalFuncKind::ThreadHwConcurrency(_)
964 | CanonicalFuncKind::TaskBackpressure
965 | CanonicalFuncKind::TaskReturn(_)
966 | CanonicalFuncKind::TaskWait(_)
967 | CanonicalFuncKind::TaskPoll(_)
968 | CanonicalFuncKind::TaskYield(_)
969 | CanonicalFuncKind::SubtaskDrop
970 | CanonicalFuncKind::StreamNew(_)
971 | CanonicalFuncKind::StreamRead(_)
972 | CanonicalFuncKind::StreamWrite(_)
973 | CanonicalFuncKind::StreamCancelRead(_)
974 | CanonicalFuncKind::StreamCancelWrite(_)
975 | CanonicalFuncKind::StreamCloseReadable(_)
976 | CanonicalFuncKind::StreamCloseWritable(_)
977 | CanonicalFuncKind::FutureNew(_)
978 | CanonicalFuncKind::FutureRead(_)
979 | CanonicalFuncKind::FutureWrite(_)
980 | CanonicalFuncKind::FutureCancelRead(_)
981 | CanonicalFuncKind::FutureCancelWrite(_)
982 | CanonicalFuncKind::FutureCloseReadable(_)
983 | CanonicalFuncKind::FutureCloseWritable(_)
984 | CanonicalFuncKind::ErrorContextNew(_)
985 | CanonicalFuncKind::ErrorContextDebugMessage(_)
986 | CanonicalFuncKind::ErrorContextDrop => {
987 self.core_funcs.register(f.id, "core func")?
988 }
989 },
990 ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
991 unreachable!("should be expanded already")
992 }
993 ComponentField::Start(s) => {
994 for r in &s.results {
995 self.values.register(*r, "value")?;
996 }
997 return Ok(());
998 }
999 ComponentField::Import(i) => self.register_item_sig(&i.item)?,
1000 ComponentField::Export(e) => match &e.kind {
1001 ComponentExportKind::CoreModule(_) => {
1002 self.core_modules.register(e.id, "core module")?
1003 }
1004 ComponentExportKind::Func(_) => self.funcs.register(e.id, "func")?,
1005 ComponentExportKind::Instance(_) => self.instances.register(e.id, "instance")?,
1006 ComponentExportKind::Value(_) => self.values.register(e.id, "value")?,
1007 ComponentExportKind::Component(_) => self.components.register(e.id, "component")?,
1008 ComponentExportKind::Type(_) => self.types.register(e.id, "type")?,
1009 },
1010 ComponentField::Custom(_) | ComponentField::Producers(_) => return Ok(()),
1011 };
1012
1013 Ok(())
1014 }
1015
1016 fn register_alias(&mut self, alias: &Alias<'a>) -> Result<u32, Error> {
1017 match alias.target {
1018 AliasTarget::Export { kind, .. } => match kind {
1019 ComponentExportAliasKind::CoreModule => {
1020 self.core_modules.register(alias.id, "core module")
1021 }
1022 ComponentExportAliasKind::Func => self.funcs.register(alias.id, "func"),
1023 ComponentExportAliasKind::Value => self.values.register(alias.id, "value"),
1024 ComponentExportAliasKind::Type => self.types.register(alias.id, "type"),
1025 ComponentExportAliasKind::Component => {
1026 self.components.register(alias.id, "component")
1027 }
1028 ComponentExportAliasKind::Instance => self.instances.register(alias.id, "instance"),
1029 },
1030 AliasTarget::CoreExport { kind, .. } => match kind {
1031 core::ExportKind::Func => self.core_funcs.register(alias.id, "core func"),
1032 core::ExportKind::Table => self.core_tables.register(alias.id, "core table"),
1033 core::ExportKind::Memory => self.core_memories.register(alias.id, "core memory"),
1034 core::ExportKind::Global => self.core_globals.register(alias.id, "core global"),
1035 core::ExportKind::Tag => self.core_tags.register(alias.id, "core tag"),
1036 },
1037 AliasTarget::Outer { kind, .. } => match kind {
1038 ComponentOuterAliasKind::CoreModule => {
1039 self.core_modules.register(alias.id, "core module")
1040 }
1041 ComponentOuterAliasKind::CoreType => {
1042 self.core_types.register(alias.id, "core type")
1043 }
1044 ComponentOuterAliasKind::Type => self.types.register(alias.id, "type"),
1045 ComponentOuterAliasKind::Component => {
1046 self.components.register(alias.id, "component")
1047 }
1048 },
1049 }
1050 }
1051}
1052
1053impl<'a> ResolveCoreType<'a> for ComponentState<'a> {
1054 fn resolve_type_name(&mut self, name: &mut Index<'a>) -> Result<u32, Error> {
1055 self.resolve(Ns::CoreType, idx:name)
1056 }
1057}
1058
1059#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
1060enum Ns {
1061 CoreFunc,
1062 CoreGlobal,
1063 CoreTable,
1064 CoreMemory,
1065 CoreType,
1066 CoreTag,
1067 CoreInstance,
1068 CoreModule,
1069 Func,
1070 Type,
1071 Instance,
1072 Component,
1073 Value,
1074}
1075
1076trait ComponentItem {
1077 fn ns(&self) -> Ns;
1078}
1079
1080trait CoreItem {
1081 fn ns(&self) -> Ns;
1082}
1083
1084macro_rules! component_item {
1085 ($kw:path, $kind:ident) => {
1086 impl ComponentItem for $kw {
1087 fn ns(&self) -> Ns {
1088 Ns::$kind
1089 }
1090 }
1091 };
1092}
1093
1094macro_rules! core_item {
1095 ($kw:path, $kind:ident) => {
1096 impl CoreItem for $kw {
1097 fn ns(&self) -> Ns {
1098 Ns::$kind
1099 }
1100 }
1101 };
1102}
1103
1104component_item!(kw::func, Func);
1105component_item!(kw::r#type, Type);
1106component_item!(kw::r#instance, Instance);
1107component_item!(kw::component, Component);
1108component_item!(kw::value, Value);
1109component_item!(kw::module, CoreModule);
1110
1111core_item!(kw::func, CoreFunc);
1112core_item!(kw::memory, CoreMemory);
1113core_item!(kw::r#type, CoreType);
1114core_item!(kw::r#instance, CoreInstance);
1115
1116impl From<Ns> for ComponentExportAliasKind {
1117 fn from(ns: Ns) -> Self {
1118 match ns {
1119 Ns::CoreModule => Self::CoreModule,
1120 Ns::Func => Self::Func,
1121 Ns::Type => Self::Type,
1122 Ns::Instance => Self::Instance,
1123 Ns::Component => Self::Component,
1124 Ns::Value => Self::Value,
1125 _ => unreachable!("not a component exportable namespace"),
1126 }
1127 }
1128}
1129
1130impl From<Ns> for ComponentOuterAliasKind {
1131 fn from(ns: Ns) -> Self {
1132 match ns {
1133 Ns::CoreModule => Self::CoreModule,
1134 Ns::CoreType => Self::CoreType,
1135 Ns::Type => Self::Type,
1136 Ns::Component => Self::Component,
1137 _ => unreachable!("not an outer alias namespace"),
1138 }
1139 }
1140}
1141
1142impl From<Ns> for core::ExportKind {
1143 fn from(ns: Ns) -> Self {
1144 match ns {
1145 Ns::CoreFunc => Self::Func,
1146 Ns::CoreTable => Self::Table,
1147 Ns::CoreGlobal => Self::Global,
1148 Ns::CoreMemory => Self::Memory,
1149 Ns::CoreTag => Self::Tag,
1150 _ => unreachable!("not a core exportable namespace"),
1151 }
1152 }
1153}
1154
1155impl From<ComponentOuterAliasKind> for Ns {
1156 fn from(kind: ComponentOuterAliasKind) -> Self {
1157 match kind {
1158 ComponentOuterAliasKind::CoreModule => Self::CoreModule,
1159 ComponentOuterAliasKind::CoreType => Self::CoreType,
1160 ComponentOuterAliasKind::Type => Self::Type,
1161 ComponentOuterAliasKind::Component => Self::Component,
1162 }
1163 }
1164}
1165
1166impl CoreItem for core::ExportKind {
1167 fn ns(&self) -> Ns {
1168 match self {
1169 Self::Func => Ns::CoreFunc,
1170 Self::Table => Ns::CoreTable,
1171 Self::Global => Ns::CoreGlobal,
1172 Self::Memory => Ns::CoreMemory,
1173 Self::Tag => Ns::CoreTag,
1174 }
1175 }
1176}
1177