1use crate::core::resolve::Ns;
2use crate::core::*;
3use crate::names::{resolve_error, Namespace};
4use crate::token::{Id, Index};
5use crate::Error;
6use std::collections::HashMap;
7
8pub fn resolve<'a>(fields: &mut Vec<ModuleField<'a>>) -> Result<Resolver<'a>, Error> {
9 let mut resolver: Resolver<'_> = Resolver::default();
10 resolver.process(fields)?;
11 Ok(resolver)
12}
13
14/// Context structure used to perform name resolution.
15#[derive(Default)]
16pub struct Resolver<'a> {
17 // Namespaces within each module. Note that each namespace carries with it
18 // information about the signature of the item in that namespace. The
19 // signature is later used to synthesize the type of a module and inject
20 // type annotations if necessary.
21 funcs: Namespace<'a>,
22 globals: Namespace<'a>,
23 tables: Namespace<'a>,
24 memories: Namespace<'a>,
25 types: Namespace<'a>,
26 tags: Namespace<'a>,
27 datas: Namespace<'a>,
28 elems: Namespace<'a>,
29 fields: HashMap<u32, Namespace<'a>>,
30 type_info: Vec<TypeInfo<'a>>,
31}
32
33impl<'a> Resolver<'a> {
34 fn process(&mut self, fields: &mut Vec<ModuleField<'a>>) -> Result<(), Error> {
35 // Number everything in the module, recording what names correspond to
36 // what indices.
37 for field in fields.iter_mut() {
38 self.register(field)?;
39 }
40
41 // Then we can replace all our `Index::Id` instances with `Index::Num`
42 // in the AST. Note that this also recurses into nested modules.
43 for field in fields.iter_mut() {
44 self.resolve_field(field)?;
45 }
46 Ok(())
47 }
48
49 fn register_type(&mut self, ty: &Type<'a>) -> Result<(), Error> {
50 let type_index = self.types.register(ty.id, "type")?;
51
52 match &ty.def.kind {
53 // For GC structure types we need to be sure to populate the
54 // field namespace here as well.
55 //
56 // The field namespace is relative to the struct fields are defined in
57 InnerTypeKind::Struct(r#struct) => {
58 for (i, field) in r#struct.fields.iter().enumerate() {
59 if let Some(id) = field.id {
60 self.fields
61 .entry(type_index)
62 .or_insert(Namespace::default())
63 .register_specific(id, i as u32, "field")?;
64 }
65 }
66 }
67
68 InnerTypeKind::Array(_) | InnerTypeKind::Func(_) | InnerTypeKind::Cont(_) => {}
69 }
70
71 // Record function signatures as we see them to so we can
72 // generate errors for mismatches in references such as
73 // `call_indirect`.
74 match &ty.def.kind {
75 InnerTypeKind::Func(f) => {
76 let params = f.params.iter().map(|p| p.2).collect();
77 let results = f.results.clone();
78 self.type_info.push(TypeInfo::Func { params, results });
79 }
80 _ => self.type_info.push(TypeInfo::Other),
81 }
82
83 Ok(())
84 }
85
86 fn register(&mut self, item: &ModuleField<'a>) -> Result<(), Error> {
87 match item {
88 ModuleField::Import(i) => match &i.item.kind {
89 ItemKind::Func(_) => self.funcs.register(i.item.id, "func")?,
90 ItemKind::Memory(_) => self.memories.register(i.item.id, "memory")?,
91 ItemKind::Table(_) => self.tables.register(i.item.id, "table")?,
92 ItemKind::Global(_) => self.globals.register(i.item.id, "global")?,
93 ItemKind::Tag(_) => self.tags.register(i.item.id, "tag")?,
94 },
95 ModuleField::Global(i) => self.globals.register(i.id, "global")?,
96 ModuleField::Memory(i) => self.memories.register(i.id, "memory")?,
97 ModuleField::Func(i) => self.funcs.register(i.id, "func")?,
98 ModuleField::Table(i) => self.tables.register(i.id, "table")?,
99
100 ModuleField::Type(i) => {
101 return self.register_type(i);
102 }
103 ModuleField::Rec(i) => {
104 for ty in &i.types {
105 self.register_type(ty)?;
106 }
107 return Ok(());
108 }
109 ModuleField::Elem(e) => self.elems.register(e.id, "elem")?,
110 ModuleField::Data(d) => self.datas.register(d.id, "data")?,
111 ModuleField::Tag(t) => self.tags.register(t.id, "tag")?,
112
113 // These fields don't define any items in any index space.
114 ModuleField::Export(_) | ModuleField::Start(_) | ModuleField::Custom(_) => {
115 return Ok(())
116 }
117 };
118
119 Ok(())
120 }
121
122 fn resolve_field(&self, field: &mut ModuleField<'a>) -> Result<(), Error> {
123 match field {
124 ModuleField::Import(i) => {
125 self.resolve_item_sig(&mut i.item)?;
126 Ok(())
127 }
128
129 ModuleField::Type(ty) => self.resolve_type(ty),
130 ModuleField::Rec(rec) => {
131 for ty in &mut rec.types {
132 self.resolve_type(ty)?;
133 }
134 Ok(())
135 }
136
137 ModuleField::Func(f) => {
138 let (idx, inline) = self.resolve_type_use(&mut f.ty)?;
139 let n = match idx {
140 Index::Num(n, _) => *n,
141 Index::Id(_) => panic!("expected `Num`"),
142 };
143 if let FuncKind::Inline { locals, expression } = &mut f.kind {
144 // Resolve (ref T) in locals
145 for local in locals.iter_mut() {
146 self.resolve_valtype(&mut local.ty)?;
147 }
148
149 // Build a scope with a local namespace for the function
150 // body
151 let mut scope = Namespace::default();
152
153 // Parameters come first in the scope...
154 if let Some(inline) = &inline {
155 for (id, _, _) in inline.params.iter() {
156 scope.register(*id, "local")?;
157 }
158 } else if let Some(TypeInfo::Func { params, .. }) =
159 self.type_info.get(n as usize)
160 {
161 for _ in 0..params.len() {
162 scope.register(None, "local")?;
163 }
164 }
165
166 // .. followed by locals themselves
167 for local in locals.iter() {
168 scope.register(local.id, "local")?;
169 }
170
171 // Initialize the expression resolver with this scope
172 let mut resolver = ExprResolver::new(self, scope);
173
174 // and then we can resolve the expression!
175 resolver.resolve(expression)?;
176
177 // specifically save the original `sig`, if it was present,
178 // because that's what we're using for local names.
179 f.ty.inline = inline;
180 }
181 Ok(())
182 }
183
184 ModuleField::Elem(e) => {
185 match &mut e.kind {
186 ElemKind::Active { table, offset } => {
187 if let Some(table) = table {
188 self.resolve(table, Ns::Table)?;
189 }
190 self.resolve_expr(offset)?;
191 }
192 ElemKind::Passive { .. } | ElemKind::Declared { .. } => {}
193 }
194 match &mut e.payload {
195 ElemPayload::Indices(elems) => {
196 for idx in elems {
197 self.resolve(idx, Ns::Func)?;
198 }
199 }
200 ElemPayload::Exprs { exprs, ty } => {
201 for expr in exprs {
202 self.resolve_expr(expr)?;
203 }
204 self.resolve_heaptype(&mut ty.heap)?;
205 }
206 }
207 Ok(())
208 }
209
210 ModuleField::Data(d) => {
211 if let DataKind::Active { memory, offset } = &mut d.kind {
212 self.resolve(memory, Ns::Memory)?;
213 self.resolve_expr(offset)?;
214 }
215 Ok(())
216 }
217
218 ModuleField::Start(i) => {
219 self.resolve(i, Ns::Func)?;
220 Ok(())
221 }
222
223 ModuleField::Export(e) => {
224 self.resolve(
225 &mut e.item,
226 match e.kind {
227 ExportKind::Func => Ns::Func,
228 ExportKind::Table => Ns::Table,
229 ExportKind::Memory => Ns::Memory,
230 ExportKind::Global => Ns::Global,
231 ExportKind::Tag => Ns::Tag,
232 },
233 )?;
234 Ok(())
235 }
236
237 ModuleField::Global(g) => {
238 self.resolve_valtype(&mut g.ty.ty)?;
239 if let GlobalKind::Inline(expr) = &mut g.kind {
240 self.resolve_expr(expr)?;
241 }
242 Ok(())
243 }
244
245 ModuleField::Tag(t) => {
246 match &mut t.ty {
247 TagType::Exception(ty) => {
248 self.resolve_type_use(ty)?;
249 }
250 }
251 Ok(())
252 }
253
254 ModuleField::Table(t) => {
255 if let TableKind::Normal { ty, init_expr } = &mut t.kind {
256 self.resolve_heaptype(&mut ty.elem.heap)?;
257 if let Some(init_expr) = init_expr {
258 self.resolve_expr(init_expr)?;
259 }
260 }
261 Ok(())
262 }
263
264 ModuleField::Memory(_) | ModuleField::Custom(_) => Ok(()),
265 }
266 }
267
268 fn resolve_item_sig(&self, item: &mut ItemSig<'a>) -> Result<(), Error> {
269 match &mut item.kind {
270 ItemKind::Func(t) | ItemKind::Tag(TagType::Exception(t)) => {
271 self.resolve_type_use(t)?;
272 }
273 ItemKind::Global(t) => self.resolve_valtype(&mut t.ty)?,
274 ItemKind::Table(t) => {
275 self.resolve_heaptype(&mut t.elem.heap)?;
276 }
277 ItemKind::Memory(_) => {}
278 }
279 Ok(())
280 }
281
282 fn resolve_type_use<'b, T>(
283 &self,
284 ty: &'b mut TypeUse<'a, T>,
285 ) -> Result<(&'b Index<'a>, Option<T>), Error>
286 where
287 T: TypeReference<'a>,
288 {
289 let idx = ty.index.as_mut().unwrap();
290 self.resolve(idx, Ns::Type)?;
291
292 // If the type was listed inline *and* it was specified via a type index
293 // we need to assert they're the same.
294 //
295 // Note that we resolve the type first to transform all names to
296 // indices to ensure that all the indices line up.
297 if let Some(inline) = &mut ty.inline {
298 inline.resolve(self)?;
299 inline.check_matches(idx, self)?;
300 }
301
302 Ok((idx, ty.inline.take()))
303 }
304
305 fn resolve_expr(&self, expr: &mut Expression<'a>) -> Result<(), Error> {
306 ExprResolver::new(self, Namespace::default()).resolve(expr)
307 }
308
309 pub fn resolve(&self, idx: &mut Index<'a>, ns: Ns) -> Result<u32, Error> {
310 match ns {
311 Ns::Func => self.funcs.resolve(idx, "func"),
312 Ns::Table => self.tables.resolve(idx, "table"),
313 Ns::Global => self.globals.resolve(idx, "global"),
314 Ns::Memory => self.memories.resolve(idx, "memory"),
315 Ns::Tag => self.tags.resolve(idx, "tag"),
316 Ns::Type => self.types.resolve(idx, "type"),
317 }
318 }
319
320 fn resolve_type(&self, ty: &mut Type<'a>) -> Result<(), Error> {
321 ResolveCoreType::resolve_type(&mut &*self, ty)
322 }
323
324 fn resolve_valtype(&self, ty: &mut ValType<'a>) -> Result<(), Error> {
325 ResolveCoreType::resolve_valtype(&mut &*self, ty)
326 }
327
328 fn resolve_heaptype(&self, ty: &mut HeapType<'a>) -> Result<(), Error> {
329 ResolveCoreType::resolve_heaptype(&mut &*self, ty)
330 }
331}
332
333#[derive(Debug, Clone)]
334struct ExprBlock<'a> {
335 // The label of the block
336 label: Option<Id<'a>>,
337 // Whether this block pushed a new scope for resolving locals
338 pushed_scope: bool,
339}
340
341struct ExprResolver<'a, 'b> {
342 resolver: &'b Resolver<'a>,
343 // Scopes tracks the local namespace and dynamically grows as we enter/exit
344 // `let` blocks
345 scopes: Vec<Namespace<'a>>,
346 blocks: Vec<ExprBlock<'a>>,
347}
348
349impl<'a, 'b> ExprResolver<'a, 'b> {
350 fn new(resolver: &'b Resolver<'a>, initial_scope: Namespace<'a>) -> ExprResolver<'a, 'b> {
351 ExprResolver {
352 resolver,
353 scopes: vec![initial_scope],
354 blocks: Vec::new(),
355 }
356 }
357
358 fn resolve(&mut self, expr: &mut Expression<'a>) -> Result<(), Error> {
359 for instr in expr.instrs.iter_mut() {
360 self.resolve_instr(instr)?;
361 }
362 Ok(())
363 }
364
365 fn resolve_block_type(&mut self, bt: &mut BlockType<'a>) -> Result<(), Error> {
366 // If the index is specified on this block type then that's the source
367 // of resolution and the resolver step here will verify the inline type
368 // matches. Note that indexes may come from the source text itself but
369 // may also come from being injected as part of the type expansion phase
370 // of resolution.
371 //
372 // If no type is present then that means that the inline type is not
373 // present or has 0-1 results. In that case the nested value types are
374 // resolved, if they're there, to get encoded later on.
375 if bt.ty.index.is_some() {
376 self.resolver.resolve_type_use(&mut bt.ty)?;
377 } else if let Some(inline) = &mut bt.ty.inline {
378 inline.resolve(self.resolver)?;
379 }
380
381 Ok(())
382 }
383
384 fn resolve_instr(&mut self, instr: &mut Instruction<'a>) -> Result<(), Error> {
385 use Instruction::*;
386
387 if let Some(m) = instr.memarg_mut() {
388 self.resolver.resolve(&mut m.memory, Ns::Memory)?;
389 }
390
391 match instr {
392 MemorySize(i) | MemoryGrow(i) | MemoryFill(i) | MemoryDiscard(i) => {
393 self.resolver.resolve(&mut i.mem, Ns::Memory)?;
394 }
395 MemoryInit(i) => {
396 self.resolver.datas.resolve(&mut i.data, "data")?;
397 self.resolver.resolve(&mut i.mem, Ns::Memory)?;
398 }
399 MemoryCopy(i) => {
400 self.resolver.resolve(&mut i.src, Ns::Memory)?;
401 self.resolver.resolve(&mut i.dst, Ns::Memory)?;
402 }
403 DataDrop(i) => {
404 self.resolver.datas.resolve(i, "data")?;
405 }
406
407 TableInit(i) => {
408 self.resolver.elems.resolve(&mut i.elem, "elem")?;
409 self.resolver.resolve(&mut i.table, Ns::Table)?;
410 }
411 ElemDrop(i) => {
412 self.resolver.elems.resolve(i, "elem")?;
413 }
414
415 TableCopy(i) => {
416 self.resolver.resolve(&mut i.dst, Ns::Table)?;
417 self.resolver.resolve(&mut i.src, Ns::Table)?;
418 }
419
420 TableFill(i) | TableSet(i) | TableGet(i) | TableSize(i) | TableGrow(i) => {
421 self.resolver.resolve(&mut i.dst, Ns::Table)?;
422 }
423
424 TableAtomicGet(i)
425 | TableAtomicSet(i)
426 | TableAtomicRmwXchg(i)
427 | TableAtomicRmwCmpxchg(i) => {
428 self.resolver.resolve(&mut i.inner.dst, Ns::Table)?;
429 }
430
431 GlobalSet(i) | GlobalGet(i) => {
432 self.resolver.resolve(i, Ns::Global)?;
433 }
434
435 GlobalAtomicSet(i)
436 | GlobalAtomicGet(i)
437 | GlobalAtomicRmwAdd(i)
438 | GlobalAtomicRmwSub(i)
439 | GlobalAtomicRmwAnd(i)
440 | GlobalAtomicRmwOr(i)
441 | GlobalAtomicRmwXor(i)
442 | GlobalAtomicRmwXchg(i)
443 | GlobalAtomicRmwCmpxchg(i) => {
444 self.resolver.resolve(&mut i.inner, Ns::Global)?;
445 }
446
447 LocalSet(i) | LocalGet(i) | LocalTee(i) => {
448 assert!(self.scopes.len() > 0);
449 // Resolve a local by iterating over scopes from most recent
450 // to less recent. This allows locals added by `let` blocks to
451 // shadow less recent locals.
452 for (depth, scope) in self.scopes.iter().enumerate().rev() {
453 if let Err(e) = scope.resolve(i, "local") {
454 if depth == 0 {
455 // There are no more scopes left, report this as
456 // the result
457 return Err(e);
458 }
459 } else {
460 break;
461 }
462 }
463 // We must have taken the `break` and resolved the local
464 assert!(i.is_resolved());
465 }
466
467 Call(i) | RefFunc(i) | ReturnCall(i) => {
468 self.resolver.resolve(i, Ns::Func)?;
469 }
470
471 CallIndirect(c) | ReturnCallIndirect(c) => {
472 self.resolver.resolve(&mut c.table, Ns::Table)?;
473 self.resolver.resolve_type_use(&mut c.ty)?;
474 }
475
476 CallRef(i) | ReturnCallRef(i) => {
477 self.resolver.resolve(i, Ns::Type)?;
478 }
479
480 Block(bt) | If(bt) | Loop(bt) | Try(bt) => {
481 self.blocks.push(ExprBlock {
482 label: bt.label,
483 pushed_scope: false,
484 });
485 self.resolve_block_type(bt)?;
486 }
487 TryTable(try_table) => {
488 self.resolve_block_type(&mut try_table.block)?;
489 for catch in &mut try_table.catches {
490 if let Some(tag) = catch.kind.tag_index_mut() {
491 self.resolver.resolve(tag, Ns::Tag)?;
492 }
493 self.resolve_label(&mut catch.label)?;
494 }
495 self.blocks.push(ExprBlock {
496 label: try_table.block.label,
497 pushed_scope: false,
498 });
499 }
500
501 // On `End` instructions we pop a label from the stack, and for both
502 // `End` and `Else` instructions if they have labels listed we
503 // verify that they match the label at the beginning of the block.
504 Else(_) | End(_) => {
505 let (matching_block, label) = match &instr {
506 Else(label) => (self.blocks.last().cloned(), label),
507 End(label) => (self.blocks.pop(), label),
508 _ => unreachable!(),
509 };
510 let matching_block = match matching_block {
511 Some(l) => l,
512 None => return Ok(()),
513 };
514
515 // Reset the local scopes to before this block was entered
516 if matching_block.pushed_scope {
517 if let End(_) = instr {
518 self.scopes.pop();
519 }
520 }
521
522 let label = match label {
523 Some(l) => l,
524 None => return Ok(()),
525 };
526 if Some(*label) == matching_block.label {
527 return Ok(());
528 }
529 return Err(Error::new(
530 label.span(),
531 "mismatching labels between end and block".to_string(),
532 ));
533 }
534
535 Br(i) | BrIf(i) | BrOnNull(i) | BrOnNonNull(i) => {
536 self.resolve_label(i)?;
537 }
538
539 BrTable(i) => {
540 for label in i.labels.iter_mut() {
541 self.resolve_label(label)?;
542 }
543 self.resolve_label(&mut i.default)?;
544 }
545
546 Throw(i) | Catch(i) => {
547 self.resolver.resolve(i, Ns::Tag)?;
548 }
549
550 Rethrow(i) => {
551 self.resolve_label(i)?;
552 }
553
554 Delegate(i) => {
555 // Since a delegate starts counting one layer out from the
556 // current try-delegate block, we pop before we resolve labels.
557 self.blocks.pop();
558 self.resolve_label(i)?;
559 }
560
561 Select(s) => {
562 if let Some(list) = &mut s.tys {
563 for ty in list {
564 self.resolver.resolve_valtype(ty)?;
565 }
566 }
567 }
568
569 RefTest(i) => {
570 self.resolver.resolve_reftype(&mut i.r#type)?;
571 }
572 RefCast(i) => {
573 self.resolver.resolve_reftype(&mut i.r#type)?;
574 }
575 BrOnCast(i) => {
576 self.resolve_label(&mut i.label)?;
577 self.resolver.resolve_reftype(&mut i.to_type)?;
578 self.resolver.resolve_reftype(&mut i.from_type)?;
579 }
580 BrOnCastFail(i) => {
581 self.resolve_label(&mut i.label)?;
582 self.resolver.resolve_reftype(&mut i.to_type)?;
583 self.resolver.resolve_reftype(&mut i.from_type)?;
584 }
585
586 StructNew(i) | StructNewDefault(i) | ArrayNew(i) | ArrayNewDefault(i) | ArrayGet(i)
587 | ArrayGetS(i) | ArrayGetU(i) | ArraySet(i) => {
588 self.resolver.resolve(i, Ns::Type)?;
589 }
590
591 StructSet(s) | StructGet(s) | StructGetS(s) | StructGetU(s) => {
592 self.resolve_field(s)?;
593 }
594
595 StructAtomicGet(s)
596 | StructAtomicGetS(s)
597 | StructAtomicGetU(s)
598 | StructAtomicSet(s)
599 | StructAtomicRmwAdd(s)
600 | StructAtomicRmwSub(s)
601 | StructAtomicRmwAnd(s)
602 | StructAtomicRmwOr(s)
603 | StructAtomicRmwXor(s)
604 | StructAtomicRmwXchg(s)
605 | StructAtomicRmwCmpxchg(s) => {
606 self.resolve_field(&mut s.inner)?;
607 }
608
609 ArrayNewFixed(a) => {
610 self.resolver.resolve(&mut a.array, Ns::Type)?;
611 }
612 ArrayNewData(a) => {
613 self.resolver.resolve(&mut a.array, Ns::Type)?;
614 self.resolver.datas.resolve(&mut a.data_idx, "data")?;
615 }
616 ArrayNewElem(a) => {
617 self.resolver.resolve(&mut a.array, Ns::Type)?;
618 self.resolver.elems.resolve(&mut a.elem_idx, "elem")?;
619 }
620 ArrayFill(a) => {
621 self.resolver.resolve(&mut a.array, Ns::Type)?;
622 }
623 ArrayCopy(a) => {
624 self.resolver.resolve(&mut a.dest_array, Ns::Type)?;
625 self.resolver.resolve(&mut a.src_array, Ns::Type)?;
626 }
627 ArrayInitData(a) => {
628 self.resolver.resolve(&mut a.array, Ns::Type)?;
629 self.resolver.datas.resolve(&mut a.segment, "data")?;
630 }
631 ArrayInitElem(a) => {
632 self.resolver.resolve(&mut a.array, Ns::Type)?;
633 self.resolver.elems.resolve(&mut a.segment, "elem")?;
634 }
635
636 ArrayAtomicGet(i)
637 | ArrayAtomicGetS(i)
638 | ArrayAtomicGetU(i)
639 | ArrayAtomicSet(i)
640 | ArrayAtomicRmwAdd(i)
641 | ArrayAtomicRmwSub(i)
642 | ArrayAtomicRmwAnd(i)
643 | ArrayAtomicRmwOr(i)
644 | ArrayAtomicRmwXor(i)
645 | ArrayAtomicRmwXchg(i)
646 | ArrayAtomicRmwCmpxchg(i) => {
647 self.resolver.resolve(&mut i.inner, Ns::Type)?;
648 }
649
650 RefNull(ty) => self.resolver.resolve_heaptype(ty)?,
651
652 ContNew(ty) => {
653 self.resolver.resolve(ty, Ns::Type)?;
654 }
655 ContBind(cb) => {
656 self.resolver.resolve(&mut cb.argument_index, Ns::Type)?;
657 self.resolver.resolve(&mut cb.result_index, Ns::Type)?;
658 }
659 Suspend(ty) => {
660 self.resolver.resolve(ty, Ns::Tag)?;
661 }
662 Resume(r) => {
663 self.resolver.resolve(&mut r.type_index, Ns::Type)?;
664 self.resolve_resume_table(&mut r.table)?;
665 }
666 ResumeThrow(rt) => {
667 self.resolver.resolve(&mut rt.type_index, Ns::Type)?;
668 self.resolver.resolve(&mut rt.tag_index, Ns::Tag)?;
669 self.resolve_resume_table(&mut rt.table)?;
670 }
671 Switch(s) => {
672 self.resolver.resolve(&mut s.type_index, Ns::Type)?;
673 self.resolver.resolve(&mut s.tag_index, Ns::Tag)?;
674 }
675
676 _ => {}
677 }
678 Ok(())
679 }
680
681 fn resolve_resume_table(&self, table: &mut ResumeTable<'a>) -> Result<(), Error> {
682 for handle in &mut table.handlers {
683 match handle {
684 Handle::OnLabel { tag, label } => {
685 self.resolver.resolve(tag, Ns::Tag)?;
686 self.resolve_label(label)?;
687 }
688 Handle::OnSwitch { tag } => {
689 self.resolver.resolve(tag, Ns::Tag)?;
690 }
691 }
692 }
693 Ok(())
694 }
695
696 fn resolve_label(&self, label: &mut Index<'a>) -> Result<(), Error> {
697 let id = match label {
698 Index::Num(..) => return Ok(()),
699 Index::Id(id) => *id,
700 };
701 let idx = self
702 .blocks
703 .iter()
704 .rev()
705 .enumerate()
706 .filter_map(|(i, b)| b.label.map(|l| (i, l)))
707 .find(|(_, l)| *l == id);
708 match idx {
709 Some((idx, _)) => {
710 *label = Index::Num(idx as u32, id.span());
711 Ok(())
712 }
713 None => Err(resolve_error(id, "label")),
714 }
715 }
716
717 fn resolve_field(&self, s: &mut StructAccess<'a>) -> Result<(), Error> {
718 let type_index = self.resolver.resolve(&mut s.r#struct, Ns::Type)?;
719 if let Index::Id(field_id) = s.field {
720 self.resolver
721 .fields
722 .get(&type_index)
723 .ok_or(Error::new(field_id.span(), format!("accessing a named field `{}` in a struct without named fields, type index {}", field_id.name(), type_index)))?
724 .resolve(&mut s.field, "field")?;
725 }
726 Ok(())
727 }
728}
729
730enum TypeInfo<'a> {
731 Func {
732 params: Box<[ValType<'a>]>,
733 results: Box<[ValType<'a>]>,
734 },
735 Other,
736}
737
738trait TypeReference<'a> {
739 fn check_matches(&mut self, idx: &Index<'a>, cx: &Resolver<'a>) -> Result<(), Error>;
740 fn resolve(&mut self, cx: &Resolver<'a>) -> Result<(), Error>;
741}
742
743impl<'a> TypeReference<'a> for FunctionType<'a> {
744 fn check_matches(&mut self, idx: &Index<'a>, cx: &Resolver<'a>) -> Result<(), Error> {
745 let n = match idx {
746 Index::Num(n, _) => *n,
747 Index::Id(_) => panic!("expected `Num`"),
748 };
749 let (params, results) = match cx.type_info.get(n as usize) {
750 Some(TypeInfo::Func { params, results }) => (params, results),
751 _ => return Ok(()),
752 };
753
754 // Here we need to check that the inline type listed (ourselves) matches
755 // what was listed in the module itself (the `params` and `results`
756 // above). The listed values in `types` are not resolved yet, although
757 // we should be resolved. In any case we do name resolution
758 // opportunistically here to see if the values are equal.
759
760 let types_not_equal = |a: &ValType, b: &ValType| {
761 let mut a = *a;
762 let mut b = *b;
763 drop((&cx).resolve_valtype(&mut a));
764 drop((&cx).resolve_valtype(&mut b));
765 a != b
766 };
767
768 let not_equal = params.len() != self.params.len()
769 || results.len() != self.results.len()
770 || params
771 .iter()
772 .zip(self.params.iter())
773 .any(|(a, (_, _, b))| types_not_equal(a, b))
774 || results
775 .iter()
776 .zip(self.results.iter())
777 .any(|(a, b)| types_not_equal(a, b));
778 if not_equal {
779 return Err(Error::new(
780 idx.span(),
781 format!("inline function type doesn't match type reference"),
782 ));
783 }
784
785 Ok(())
786 }
787
788 fn resolve(&mut self, cx: &Resolver<'a>) -> Result<(), Error> {
789 (&mut &*cx).resolve_type_func(self)
790 }
791}
792
793pub(crate) trait ResolveCoreType<'a> {
794 fn resolve_type_name(&mut self, name: &mut Index<'a>) -> Result<u32, Error>;
795
796 fn resolve_type(&mut self, ty: &mut Type<'a>) -> Result<(), Error> {
797 self.resolve_type_def(&mut ty.def)?;
798 Ok(())
799 }
800
801 fn resolve_type_def(&mut self, ty: &mut TypeDef<'a>) -> Result<(), Error> {
802 if let Some(parent) = &mut ty.parent {
803 self.resolve_type_name(parent)?;
804 }
805 match &mut ty.kind {
806 InnerTypeKind::Func(func) => self.resolve_type_func(func),
807 InnerTypeKind::Struct(struct_) => {
808 for field in &mut struct_.fields {
809 self.resolve_storagetype(&mut field.ty)?;
810 }
811 Ok(())
812 }
813 InnerTypeKind::Array(array) => self.resolve_storagetype(&mut array.ty),
814 InnerTypeKind::Cont(cont) => {
815 self.resolve_type_name(&mut cont.0)?;
816 Ok(())
817 }
818 }
819 }
820
821 fn resolve_type_func(&mut self, ty: &mut FunctionType<'a>) -> Result<(), Error> {
822 // Resolve the (ref T) value types in the final function type
823 for param in ty.params.iter_mut() {
824 self.resolve_valtype(&mut param.2)?;
825 }
826 for result in ty.results.iter_mut() {
827 self.resolve_valtype(result)?;
828 }
829 Ok(())
830 }
831
832 fn resolve_valtype(&mut self, ty: &mut ValType<'a>) -> Result<(), Error> {
833 match ty {
834 ValType::Ref(ty) => self.resolve_reftype(ty),
835 ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()),
836 }
837 }
838
839 fn resolve_reftype(&mut self, ty: &mut RefType<'a>) -> Result<(), Error> {
840 self.resolve_heaptype(&mut ty.heap)
841 }
842
843 fn resolve_heaptype(&mut self, ty: &mut HeapType<'a>) -> Result<(), Error> {
844 match ty {
845 HeapType::Concrete(i) => {
846 self.resolve_type_name(i)?;
847 }
848 HeapType::Abstract { .. } => {}
849 }
850 Ok(())
851 }
852
853 fn resolve_storagetype(&mut self, ty: &mut StorageType<'a>) -> Result<(), Error> {
854 match ty {
855 StorageType::Val(ty) => self.resolve_valtype(ty),
856 StorageType::I8 | StorageType::I16 => Ok(()),
857 }
858 }
859}
860
861impl<'a> ResolveCoreType<'a> for &Resolver<'a> {
862 fn resolve_type_name(&mut self, name: &mut Index<'a>) -> Result<u32, Error> {
863 self.resolve(idx:name, Ns::Type)
864 }
865}
866