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