1use crate::ScopeVec;
2use crate::component::*;
3use crate::prelude::*;
4use crate::{
5 EngineOrModuleTypeIndex, EntityIndex, ModuleEnvironment, ModuleInternedTypeIndex,
6 ModuleTranslation, ModuleTypesBuilder, PrimaryMap, TagIndex, Tunables, TypeConvert,
7 WasmHeapType, WasmResult, WasmValType,
8};
9use anyhow::anyhow;
10use anyhow::{Result, bail};
11use indexmap::IndexMap;
12use std::collections::HashMap;
13use std::mem;
14use wasmparser::component_types::{
15 AliasableResourceId, ComponentCoreModuleTypeId, ComponentDefinedTypeId, ComponentEntityType,
16 ComponentFuncTypeId, ComponentInstanceTypeId, ComponentValType,
17};
18use wasmparser::types::Types;
19use wasmparser::{Chunk, ComponentImportName, Encoding, Parser, Payload, Validator};
20
21mod adapt;
22pub use self::adapt::*;
23mod inline;
24
25pub struct Translator<'a, 'data> {
27 result: Translation<'data>,
32
33 parser: Parser,
36
37 lexical_scopes: Vec<LexicalScope<'data>>,
45
46 validator: &'a mut Validator,
49
50 types: PreInliningComponentTypes<'a>,
55
56 tunables: &'a Tunables,
58
59 scope_vec: &'data ScopeVec<u8>,
61
62 static_modules: PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
67
68 static_components: PrimaryMap<StaticComponentIndex, Translation<'data>>,
73}
74
75struct LexicalScope<'data> {
128 parser: Parser,
130 translation: Translation<'data>,
132 closure_args: ClosedOverVars,
135}
136
137#[derive(Default)]
147struct Translation<'data> {
148 initializers: Vec<LocalInitializer<'data>>,
154
155 exports: IndexMap<&'data str, ComponentItem>,
158
159 types: Option<Types>,
165}
166
167enum LocalInitializer<'data> {
173 Import(ComponentImportName<'data>, ComponentEntityType),
175
176 Lower {
178 func: ComponentFuncIndex,
179 lower_ty: ComponentFuncTypeId,
180 canonical_abi: ModuleInternedTypeIndex,
181 options: LocalCanonicalOptions,
182 },
183 Lift(ComponentFuncTypeId, FuncIndex, LocalCanonicalOptions),
184
185 Resource(AliasableResourceId, WasmValType, Option<FuncIndex>),
187 ResourceNew(AliasableResourceId, ModuleInternedTypeIndex),
188 ResourceRep(AliasableResourceId, ModuleInternedTypeIndex),
189 ResourceDrop(AliasableResourceId, ModuleInternedTypeIndex),
190
191 BackpressureSet {
192 func: ModuleInternedTypeIndex,
193 },
194 TaskReturn {
195 func: ModuleInternedTypeIndex,
196 result: Option<ComponentValType>,
197 options: LocalCanonicalOptions,
198 },
199 WaitableSetNew {
200 func: ModuleInternedTypeIndex,
201 },
202 WaitableSetWait {
203 func: ModuleInternedTypeIndex,
204 async_: bool,
205 memory: MemoryIndex,
206 },
207 WaitableSetPoll {
208 func: ModuleInternedTypeIndex,
209 async_: bool,
210 memory: MemoryIndex,
211 },
212 WaitableSetDrop {
213 func: ModuleInternedTypeIndex,
214 },
215 WaitableJoin {
216 func: ModuleInternedTypeIndex,
217 },
218 Yield {
219 func: ModuleInternedTypeIndex,
220 async_: bool,
221 },
222 SubtaskDrop {
223 func: ModuleInternedTypeIndex,
224 },
225 StreamNew {
226 ty: ComponentDefinedTypeId,
227 func: ModuleInternedTypeIndex,
228 },
229 StreamRead {
230 ty: ComponentDefinedTypeId,
231 func: ModuleInternedTypeIndex,
232 options: LocalCanonicalOptions,
233 },
234 StreamWrite {
235 ty: ComponentDefinedTypeId,
236 func: ModuleInternedTypeIndex,
237 options: LocalCanonicalOptions,
238 },
239 StreamCancelRead {
240 ty: ComponentDefinedTypeId,
241 func: ModuleInternedTypeIndex,
242 async_: bool,
243 },
244 StreamCancelWrite {
245 ty: ComponentDefinedTypeId,
246 func: ModuleInternedTypeIndex,
247 async_: bool,
248 },
249 StreamCloseReadable {
250 ty: ComponentDefinedTypeId,
251 func: ModuleInternedTypeIndex,
252 },
253 StreamCloseWritable {
254 ty: ComponentDefinedTypeId,
255 func: ModuleInternedTypeIndex,
256 },
257 FutureNew {
258 ty: ComponentDefinedTypeId,
259 func: ModuleInternedTypeIndex,
260 },
261 FutureRead {
262 ty: ComponentDefinedTypeId,
263 func: ModuleInternedTypeIndex,
264 options: LocalCanonicalOptions,
265 },
266 FutureWrite {
267 ty: ComponentDefinedTypeId,
268 func: ModuleInternedTypeIndex,
269 options: LocalCanonicalOptions,
270 },
271 FutureCancelRead {
272 ty: ComponentDefinedTypeId,
273 func: ModuleInternedTypeIndex,
274 async_: bool,
275 },
276 FutureCancelWrite {
277 ty: ComponentDefinedTypeId,
278 func: ModuleInternedTypeIndex,
279 async_: bool,
280 },
281 FutureCloseReadable {
282 ty: ComponentDefinedTypeId,
283 func: ModuleInternedTypeIndex,
284 },
285 FutureCloseWritable {
286 ty: ComponentDefinedTypeId,
287 func: ModuleInternedTypeIndex,
288 },
289 ErrorContextNew {
290 func: ModuleInternedTypeIndex,
291 options: LocalCanonicalOptions,
292 },
293 ErrorContextDebugMessage {
294 func: ModuleInternedTypeIndex,
295 options: LocalCanonicalOptions,
296 },
297 ErrorContextDrop {
298 func: ModuleInternedTypeIndex,
299 },
300
301 ModuleStatic(StaticModuleIndex, ComponentCoreModuleTypeId),
303
304 ModuleInstantiate(ModuleIndex, HashMap<&'data str, ModuleInstanceIndex>),
306 ModuleSynthetic(HashMap<&'data str, EntityIndex>),
307
308 ComponentStatic(StaticComponentIndex, ClosedOverVars),
310
311 ComponentInstantiate(
313 ComponentIndex,
314 HashMap<&'data str, ComponentItem>,
315 ComponentInstanceTypeId,
316 ),
317 ComponentSynthetic(HashMap<&'data str, ComponentItem>, ComponentInstanceTypeId),
318
319 AliasExportFunc(ModuleInstanceIndex, &'data str),
321 AliasExportTable(ModuleInstanceIndex, &'data str),
322 AliasExportGlobal(ModuleInstanceIndex, &'data str),
323 AliasExportMemory(ModuleInstanceIndex, &'data str),
324 AliasExportTag(ModuleInstanceIndex, &'data str),
325 AliasComponentExport(ComponentInstanceIndex, &'data str),
326 AliasModule(ClosedOverModule),
327 AliasComponent(ClosedOverComponent),
328
329 Export(ComponentItem),
331}
332
333#[derive(Default)]
337struct ClosedOverVars {
338 components: PrimaryMap<ComponentUpvarIndex, ClosedOverComponent>,
339 modules: PrimaryMap<ModuleUpvarIndex, ClosedOverModule>,
340}
341
342enum ClosedOverComponent {
347 Local(ComponentIndex),
350 Upvar(ComponentUpvarIndex),
355}
356
357enum ClosedOverModule {
359 Local(ModuleIndex),
360 Upvar(ModuleUpvarIndex),
361}
362
363struct LocalCanonicalOptions {
365 string_encoding: StringEncoding,
366 memory: Option<MemoryIndex>,
367 realloc: Option<FuncIndex>,
368 post_return: Option<FuncIndex>,
369 async_: bool,
370 callback: Option<FuncIndex>,
371}
372
373enum Action {
374 KeepGoing,
375 Skip(usize),
376 Done,
377}
378
379impl<'a, 'data> Translator<'a, 'data> {
380 pub fn new(
382 tunables: &'a Tunables,
383 validator: &'a mut Validator,
384 types: &'a mut ComponentTypesBuilder,
385 scope_vec: &'data ScopeVec<u8>,
386 ) -> Self {
387 let mut parser = Parser::new(0);
388 parser.set_features(*validator.features());
389 Self {
390 result: Translation::default(),
391 tunables,
392 validator,
393 types: PreInliningComponentTypes::new(types),
394 parser,
395 lexical_scopes: Vec::new(),
396 static_components: Default::default(),
397 static_modules: Default::default(),
398 scope_vec,
399 }
400 }
401
402 pub fn translate(
426 mut self,
427 component: &'data [u8],
428 ) -> Result<(
429 ComponentTranslation,
430 PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
431 )> {
432 let mut remaining = component;
438 loop {
439 let payload = match self.parser.parse(remaining, true)? {
440 Chunk::Parsed { payload, consumed } => {
441 remaining = &remaining[consumed..];
442 payload
443 }
444 Chunk::NeedMoreData(_) => unreachable!(),
445 };
446
447 match self.translate_payload(payload, component)? {
448 Action::KeepGoing => {}
449 Action::Skip(n) => remaining = &remaining[n..],
450 Action::Done => break,
451 }
452 }
453 assert!(remaining.is_empty());
454 assert!(self.lexical_scopes.is_empty());
455
456 let mut component = inline::run(
467 self.types.types_mut_for_inlining(),
468 &self.result,
469 &self.static_modules,
470 &self.static_components,
471 )?;
472 self.partition_adapter_modules(&mut component);
473 let translation =
474 component.finish(self.types.types_mut_for_inlining(), self.result.types_ref())?;
475 Ok((translation, self.static_modules))
476 }
477
478 fn translate_payload(
479 &mut self,
480 payload: Payload<'data>,
481 component: &'data [u8],
482 ) -> Result<Action> {
483 match payload {
484 Payload::Version {
485 num,
486 encoding,
487 range,
488 } => {
489 self.validator.version(num, encoding, &range)?;
490
491 match encoding {
492 Encoding::Component => {}
493 Encoding::Module => {
494 bail!("attempted to parse a wasm module with a component parser");
495 }
496 }
497 }
498
499 Payload::End(offset) => {
500 assert!(self.result.types.is_none());
501 self.result.types = Some(self.validator.end(offset)?);
502
503 let LexicalScope {
508 parser,
509 translation,
510 closure_args,
511 } = match self.lexical_scopes.pop() {
512 Some(frame) => frame,
513 None => return Ok(Action::Done),
514 };
515 self.parser = parser;
516 let component = mem::replace(&mut self.result, translation);
517 let static_idx = self.static_components.push(component);
518 self.result
519 .initializers
520 .push(LocalInitializer::ComponentStatic(static_idx, closure_args));
521 }
522
523 Payload::ComponentTypeSection(s) => {
532 let mut component_type_index =
533 self.validator.types(0).unwrap().component_type_count();
534 self.validator.component_type_section(&s)?;
535
536 let types = self.validator.types(0).unwrap();
540 for ty in s {
541 match ty? {
542 wasmparser::ComponentType::Resource { rep, dtor } => {
543 let rep = self.types.convert_valtype(rep)?;
544 let id = types
545 .component_any_type_at(component_type_index)
546 .unwrap_resource();
547 let dtor = dtor.map(FuncIndex::from_u32);
548 self.result
549 .initializers
550 .push(LocalInitializer::Resource(id, rep, dtor));
551 }
552
553 wasmparser::ComponentType::Defined(_)
555 | wasmparser::ComponentType::Func(_)
556 | wasmparser::ComponentType::Instance(_)
557 | wasmparser::ComponentType::Component(_) => {}
558 }
559
560 component_type_index += 1;
561 }
562 }
563 Payload::CoreTypeSection(s) => {
564 self.validator.core_type_section(&s)?;
565 }
566
567 Payload::ComponentImportSection(s) => {
571 self.validator.component_import_section(&s)?;
572 for import in s {
573 let import = import?;
574 let types = self.validator.types(0).unwrap();
575 let ty = types
576 .component_entity_type_of_import(import.name.0)
577 .unwrap();
578 self.result
579 .initializers
580 .push(LocalInitializer::Import(import.name, ty));
581 }
582 }
583
584 Payload::ComponentCanonicalSection(s) => {
587 let types = self.validator.types(0).unwrap();
588 let mut core_func_index = types.function_count();
589 self.validator.component_canonical_section(&s)?;
590 for func in s {
591 let types = self.validator.types(0).unwrap();
592 let init = match func? {
593 wasmparser::CanonicalFunction::Lift {
594 type_index,
595 core_func_index,
596 options,
597 } => {
598 let ty = types.component_any_type_at(type_index).unwrap_func();
599 let func = FuncIndex::from_u32(core_func_index);
600 let options = self.canonical_options(&options);
601 LocalInitializer::Lift(ty, func, options)
602 }
603 wasmparser::CanonicalFunction::Lower {
604 func_index,
605 options,
606 } => {
607 let lower_ty = types.component_function_at(func_index);
608 let func = ComponentFuncIndex::from_u32(func_index);
609 let options = self.canonical_options(&options);
610 let canonical_abi = self.core_func_signature(core_func_index)?;
611
612 core_func_index += 1;
613 LocalInitializer::Lower {
614 func,
615 options,
616 canonical_abi,
617 lower_ty,
618 }
619 }
620 wasmparser::CanonicalFunction::ResourceNew { resource } => {
621 let resource = types.component_any_type_at(resource).unwrap_resource();
622 let ty = self.core_func_signature(core_func_index)?;
623 core_func_index += 1;
624 LocalInitializer::ResourceNew(resource, ty)
625 }
626 wasmparser::CanonicalFunction::ResourceDrop { resource } => {
627 let resource = types.component_any_type_at(resource).unwrap_resource();
628 let ty = self.core_func_signature(core_func_index)?;
629 core_func_index += 1;
630 LocalInitializer::ResourceDrop(resource, ty)
631 }
632 wasmparser::CanonicalFunction::ResourceDropAsync { resource } => {
633 let _ = resource;
634 bail!("support for `resource.drop async` not implemented yet")
635 }
636 wasmparser::CanonicalFunction::ResourceRep { resource } => {
637 let resource = types.component_any_type_at(resource).unwrap_resource();
638 let ty = self.core_func_signature(core_func_index)?;
639 core_func_index += 1;
640 LocalInitializer::ResourceRep(resource, ty)
641 }
642 wasmparser::CanonicalFunction::BackpressureSet => {
643 let core_type = self.core_func_signature(core_func_index)?;
644 core_func_index += 1;
645 LocalInitializer::BackpressureSet { func: core_type }
646 }
647 wasmparser::CanonicalFunction::TaskReturn { result, options } => {
648 let result = result.map(|ty| match ty {
649 wasmparser::ComponentValType::Primitive(ty) => {
650 ComponentValType::Primitive(ty)
651 }
652 wasmparser::ComponentValType::Type(ty) => {
653 ComponentValType::Type(types.component_defined_type_at(ty))
654 }
655 });
656 let options = self.canonical_options(&options);
657 let func = self.core_func_signature(core_func_index)?;
658 core_func_index += 1;
659 LocalInitializer::TaskReturn {
660 func,
661 result,
662 options,
663 }
664 }
665 wasmparser::CanonicalFunction::WaitableSetNew => {
666 let func = self.core_func_signature(core_func_index)?;
667 core_func_index += 1;
668 LocalInitializer::WaitableSetNew { func }
669 }
670 wasmparser::CanonicalFunction::WaitableSetWait { async_, memory } => {
671 let func = self.core_func_signature(core_func_index)?;
672 core_func_index += 1;
673 LocalInitializer::WaitableSetWait {
674 func,
675 async_,
676 memory: MemoryIndex::from_u32(memory),
677 }
678 }
679 wasmparser::CanonicalFunction::WaitableSetPoll { async_, memory } => {
680 let func = self.core_func_signature(core_func_index)?;
681 core_func_index += 1;
682 LocalInitializer::WaitableSetPoll {
683 func,
684 async_,
685 memory: MemoryIndex::from_u32(memory),
686 }
687 }
688 wasmparser::CanonicalFunction::WaitableSetDrop => {
689 let func = self.core_func_signature(core_func_index)?;
690 core_func_index += 1;
691 LocalInitializer::WaitableSetDrop { func }
692 }
693 wasmparser::CanonicalFunction::WaitableJoin => {
694 let func = self.core_func_signature(core_func_index)?;
695 core_func_index += 1;
696 LocalInitializer::WaitableJoin { func }
697 }
698 wasmparser::CanonicalFunction::Yield { async_ } => {
699 let func = self.core_func_signature(core_func_index)?;
700 core_func_index += 1;
701 LocalInitializer::Yield { func, async_ }
702 }
703 wasmparser::CanonicalFunction::SubtaskDrop => {
704 let func = self.core_func_signature(core_func_index)?;
705 core_func_index += 1;
706 LocalInitializer::SubtaskDrop { func }
707 }
708 wasmparser::CanonicalFunction::StreamNew { ty } => {
709 let ty = types.component_defined_type_at(ty);
710 let func = self.core_func_signature(core_func_index)?;
711 core_func_index += 1;
712 LocalInitializer::StreamNew { ty, func }
713 }
714 wasmparser::CanonicalFunction::StreamRead { ty, options } => {
715 let ty = types.component_defined_type_at(ty);
716 let options = self.canonical_options(&options);
717 let func = self.core_func_signature(core_func_index)?;
718 core_func_index += 1;
719 LocalInitializer::StreamRead { ty, func, options }
720 }
721 wasmparser::CanonicalFunction::StreamWrite { ty, options } => {
722 let ty = types.component_defined_type_at(ty);
723 let options = self.canonical_options(&options);
724 let func = self.core_func_signature(core_func_index)?;
725 core_func_index += 1;
726 LocalInitializer::StreamWrite { ty, func, options }
727 }
728 wasmparser::CanonicalFunction::StreamCancelRead { ty, async_ } => {
729 let ty = types.component_defined_type_at(ty);
730 let func = self.core_func_signature(core_func_index)?;
731 core_func_index += 1;
732 LocalInitializer::StreamCancelRead { ty, func, async_ }
733 }
734 wasmparser::CanonicalFunction::StreamCancelWrite { ty, async_ } => {
735 let ty = types.component_defined_type_at(ty);
736 let func = self.core_func_signature(core_func_index)?;
737 core_func_index += 1;
738 LocalInitializer::StreamCancelWrite { ty, func, async_ }
739 }
740 wasmparser::CanonicalFunction::StreamCloseReadable { ty } => {
741 let ty = types.component_defined_type_at(ty);
742 let func = self.core_func_signature(core_func_index)?;
743 core_func_index += 1;
744 LocalInitializer::StreamCloseReadable { ty, func }
745 }
746 wasmparser::CanonicalFunction::StreamCloseWritable { ty } => {
747 let ty = types.component_defined_type_at(ty);
748 let func = self.core_func_signature(core_func_index)?;
749 core_func_index += 1;
750 LocalInitializer::StreamCloseWritable { ty, func }
751 }
752 wasmparser::CanonicalFunction::FutureNew { ty } => {
753 let ty = types.component_defined_type_at(ty);
754 let func = self.core_func_signature(core_func_index)?;
755 core_func_index += 1;
756 LocalInitializer::FutureNew { ty, func }
757 }
758 wasmparser::CanonicalFunction::FutureRead { ty, options } => {
759 let ty = types.component_defined_type_at(ty);
760 let options = self.canonical_options(&options);
761 let func = self.core_func_signature(core_func_index)?;
762 core_func_index += 1;
763 LocalInitializer::FutureRead { ty, func, options }
764 }
765 wasmparser::CanonicalFunction::FutureWrite { ty, options } => {
766 let ty = types.component_defined_type_at(ty);
767 let options = self.canonical_options(&options);
768 let func = self.core_func_signature(core_func_index)?;
769 core_func_index += 1;
770 LocalInitializer::FutureWrite { ty, func, options }
771 }
772 wasmparser::CanonicalFunction::FutureCancelRead { ty, async_ } => {
773 let ty = types.component_defined_type_at(ty);
774 let func = self.core_func_signature(core_func_index)?;
775 core_func_index += 1;
776 LocalInitializer::FutureCancelRead { ty, func, async_ }
777 }
778 wasmparser::CanonicalFunction::FutureCancelWrite { ty, async_ } => {
779 let ty = types.component_defined_type_at(ty);
780 let func = self.core_func_signature(core_func_index)?;
781 core_func_index += 1;
782 LocalInitializer::FutureCancelWrite { ty, func, async_ }
783 }
784 wasmparser::CanonicalFunction::FutureCloseReadable { ty } => {
785 let ty = types.component_defined_type_at(ty);
786 let func = self.core_func_signature(core_func_index)?;
787 core_func_index += 1;
788 LocalInitializer::FutureCloseReadable { ty, func }
789 }
790 wasmparser::CanonicalFunction::FutureCloseWritable { ty } => {
791 let ty = types.component_defined_type_at(ty);
792 let func = self.core_func_signature(core_func_index)?;
793 core_func_index += 1;
794 LocalInitializer::FutureCloseWritable { ty, func }
795 }
796 wasmparser::CanonicalFunction::ErrorContextNew { options } => {
797 let options = self.canonical_options(&options);
798 let func = self.core_func_signature(core_func_index)?;
799 core_func_index += 1;
800 LocalInitializer::ErrorContextNew { func, options }
801 }
802 wasmparser::CanonicalFunction::ErrorContextDebugMessage { options } => {
803 let options = self.canonical_options(&options);
804 let func = self.core_func_signature(core_func_index)?;
805 core_func_index += 1;
806 LocalInitializer::ErrorContextDebugMessage { func, options }
807 }
808 wasmparser::CanonicalFunction::ErrorContextDrop => {
809 let func = self.core_func_signature(core_func_index)?;
810 core_func_index += 1;
811 LocalInitializer::ErrorContextDrop { func }
812 }
813 wasmparser::CanonicalFunction::ContextGet(..)
814 | wasmparser::CanonicalFunction::ContextSet(..)
815 | wasmparser::CanonicalFunction::TaskCancel
816 | wasmparser::CanonicalFunction::SubtaskCancel { .. }
817 | wasmparser::CanonicalFunction::ThreadSpawnRef { .. }
818 | wasmparser::CanonicalFunction::ThreadSpawnIndirect { .. }
819 | wasmparser::CanonicalFunction::ThreadAvailableParallelism => {
820 bail!("unsupported intrinsic")
821 }
822 };
823 self.result.initializers.push(init);
824 }
825 }
826
827 Payload::ModuleSection {
836 parser,
837 unchecked_range,
838 } => {
839 let index = self.validator.types(0).unwrap().module_count();
840 self.validator.module_section(&unchecked_range)?;
841 let translation = ModuleEnvironment::new(
842 self.tunables,
843 self.validator,
844 self.types.module_types_builder(),
845 )
846 .translate(
847 parser,
848 component
849 .get(unchecked_range.start..unchecked_range.end)
850 .ok_or_else(|| {
851 anyhow!(
852 "section range {}..{} is out of bounds (bound = {})",
853 unchecked_range.start,
854 unchecked_range.end,
855 component.len()
856 )
857 .context("wasm component contains an invalid module section")
858 })?,
859 )?;
860 let static_idx = self.static_modules.push(translation);
861 let types = self.validator.types(0).unwrap();
862 let ty = types.module_at(index);
863 self.result
864 .initializers
865 .push(LocalInitializer::ModuleStatic(static_idx, ty));
866 return Ok(Action::Skip(unchecked_range.end - unchecked_range.start));
867 }
868
869 Payload::ComponentSection {
878 parser,
879 unchecked_range,
880 } => {
881 self.validator.component_section(&unchecked_range)?;
882 self.lexical_scopes.push(LexicalScope {
883 parser: mem::replace(&mut self.parser, parser),
884 translation: mem::take(&mut self.result),
885 closure_args: ClosedOverVars::default(),
886 });
887 }
888
889 Payload::InstanceSection(s) => {
894 self.validator.instance_section(&s)?;
895 for instance in s {
896 let init = match instance? {
897 wasmparser::Instance::Instantiate { module_index, args } => {
898 let index = ModuleIndex::from_u32(module_index);
899 self.instantiate_module(index, &args)
900 }
901 wasmparser::Instance::FromExports(exports) => {
902 self.instantiate_module_from_exports(&exports)
903 }
904 };
905 self.result.initializers.push(init);
906 }
907 }
908 Payload::ComponentInstanceSection(s) => {
909 let mut index = self.validator.types(0).unwrap().component_instance_count();
910 self.validator.component_instance_section(&s)?;
911 for instance in s {
912 let types = self.validator.types(0).unwrap();
913 let ty = types.component_instance_at(index);
914 let init = match instance? {
915 wasmparser::ComponentInstance::Instantiate {
916 component_index,
917 args,
918 } => {
919 let index = ComponentIndex::from_u32(component_index);
920 self.instantiate_component(index, &args, ty)?
921 }
922 wasmparser::ComponentInstance::FromExports(exports) => {
923 self.instantiate_component_from_exports(&exports, ty)?
924 }
925 };
926 self.result.initializers.push(init);
927 index += 1;
928 }
929 }
930
931 Payload::ComponentExportSection(s) => {
937 self.validator.component_export_section(&s)?;
938 for export in s {
939 let export = export?;
940 let item = self.kind_to_item(export.kind, export.index)?;
941 let prev = self.result.exports.insert(export.name.0, item);
942 assert!(prev.is_none());
943 self.result
944 .initializers
945 .push(LocalInitializer::Export(item));
946 }
947 }
948
949 Payload::ComponentStartSection { start, range } => {
950 self.validator.component_start_section(&start, &range)?;
951 unimplemented!("component start section");
952 }
953
954 Payload::ComponentAliasSection(s) => {
958 self.validator.component_alias_section(&s)?;
959 for alias in s {
960 let init = match alias? {
961 wasmparser::ComponentAlias::InstanceExport {
962 kind: _,
963 instance_index,
964 name,
965 } => {
966 let instance = ComponentInstanceIndex::from_u32(instance_index);
967 LocalInitializer::AliasComponentExport(instance, name)
968 }
969 wasmparser::ComponentAlias::Outer { kind, count, index } => {
970 self.alias_component_outer(kind, count, index);
971 continue;
972 }
973 wasmparser::ComponentAlias::CoreInstanceExport {
974 kind,
975 instance_index,
976 name,
977 } => {
978 let instance = ModuleInstanceIndex::from_u32(instance_index);
979 self.alias_module_instance_export(kind, instance, name)
980 }
981 };
982 self.result.initializers.push(init);
983 }
984 }
985
986 Payload::CustomSection { .. } => {}
991
992 other => {
998 self.validator.payload(&other)?;
999 panic!("unimplemented section {other:?}");
1000 }
1001 }
1002
1003 Ok(Action::KeepGoing)
1004 }
1005
1006 fn instantiate_module(
1007 &mut self,
1008 module: ModuleIndex,
1009 raw_args: &[wasmparser::InstantiationArg<'data>],
1010 ) -> LocalInitializer<'data> {
1011 let mut args = HashMap::with_capacity(raw_args.len());
1012 for arg in raw_args {
1013 match arg.kind {
1014 wasmparser::InstantiationArgKind::Instance => {
1015 let idx = ModuleInstanceIndex::from_u32(arg.index);
1016 args.insert(arg.name, idx);
1017 }
1018 }
1019 }
1020 LocalInitializer::ModuleInstantiate(module, args)
1021 }
1022
1023 fn instantiate_module_from_exports(
1026 &mut self,
1027 exports: &[wasmparser::Export<'data>],
1028 ) -> LocalInitializer<'data> {
1029 let mut map = HashMap::with_capacity(exports.len());
1030 for export in exports {
1031 let idx = match export.kind {
1032 wasmparser::ExternalKind::Func => {
1033 let index = FuncIndex::from_u32(export.index);
1034 EntityIndex::Function(index)
1035 }
1036 wasmparser::ExternalKind::Table => {
1037 let index = TableIndex::from_u32(export.index);
1038 EntityIndex::Table(index)
1039 }
1040 wasmparser::ExternalKind::Memory => {
1041 let index = MemoryIndex::from_u32(export.index);
1042 EntityIndex::Memory(index)
1043 }
1044 wasmparser::ExternalKind::Global => {
1045 let index = GlobalIndex::from_u32(export.index);
1046 EntityIndex::Global(index)
1047 }
1048 wasmparser::ExternalKind::Tag => {
1049 let index = TagIndex::from_u32(export.index);
1050 EntityIndex::Tag(index)
1051 }
1052 };
1053 map.insert(export.name, idx);
1054 }
1055 LocalInitializer::ModuleSynthetic(map)
1056 }
1057
1058 fn instantiate_component(
1059 &mut self,
1060 component: ComponentIndex,
1061 raw_args: &[wasmparser::ComponentInstantiationArg<'data>],
1062 ty: ComponentInstanceTypeId,
1063 ) -> Result<LocalInitializer<'data>> {
1064 let mut args = HashMap::with_capacity(raw_args.len());
1065 for arg in raw_args {
1066 let idx = self.kind_to_item(arg.kind, arg.index)?;
1067 args.insert(arg.name, idx);
1068 }
1069
1070 Ok(LocalInitializer::ComponentInstantiate(component, args, ty))
1071 }
1072
1073 fn instantiate_component_from_exports(
1076 &mut self,
1077 exports: &[wasmparser::ComponentExport<'data>],
1078 ty: ComponentInstanceTypeId,
1079 ) -> Result<LocalInitializer<'data>> {
1080 let mut map = HashMap::with_capacity(exports.len());
1081 for export in exports {
1082 let idx = self.kind_to_item(export.kind, export.index)?;
1083 map.insert(export.name.0, idx);
1084 }
1085
1086 Ok(LocalInitializer::ComponentSynthetic(map, ty))
1087 }
1088
1089 fn kind_to_item(
1090 &mut self,
1091 kind: wasmparser::ComponentExternalKind,
1092 index: u32,
1093 ) -> Result<ComponentItem> {
1094 Ok(match kind {
1095 wasmparser::ComponentExternalKind::Func => {
1096 let index = ComponentFuncIndex::from_u32(index);
1097 ComponentItem::Func(index)
1098 }
1099 wasmparser::ComponentExternalKind::Module => {
1100 let index = ModuleIndex::from_u32(index);
1101 ComponentItem::Module(index)
1102 }
1103 wasmparser::ComponentExternalKind::Instance => {
1104 let index = ComponentInstanceIndex::from_u32(index);
1105 ComponentItem::ComponentInstance(index)
1106 }
1107 wasmparser::ComponentExternalKind::Component => {
1108 let index = ComponentIndex::from_u32(index);
1109 ComponentItem::Component(index)
1110 }
1111 wasmparser::ComponentExternalKind::Value => {
1112 unimplemented!("component values");
1113 }
1114 wasmparser::ComponentExternalKind::Type => {
1115 let types = self.validator.types(0).unwrap();
1116 let ty = types.component_any_type_at(index);
1117 ComponentItem::Type(ty)
1118 }
1119 })
1120 }
1121
1122 fn alias_module_instance_export(
1123 &mut self,
1124 kind: wasmparser::ExternalKind,
1125 instance: ModuleInstanceIndex,
1126 name: &'data str,
1127 ) -> LocalInitializer<'data> {
1128 match kind {
1129 wasmparser::ExternalKind::Func => LocalInitializer::AliasExportFunc(instance, name),
1130 wasmparser::ExternalKind::Memory => LocalInitializer::AliasExportMemory(instance, name),
1131 wasmparser::ExternalKind::Table => LocalInitializer::AliasExportTable(instance, name),
1132 wasmparser::ExternalKind::Global => LocalInitializer::AliasExportGlobal(instance, name),
1133 wasmparser::ExternalKind::Tag => LocalInitializer::AliasExportTag(instance, name),
1134 }
1135 }
1136
1137 fn alias_component_outer(
1138 &mut self,
1139 kind: wasmparser::ComponentOuterAliasKind,
1140 count: u32,
1141 index: u32,
1142 ) {
1143 match kind {
1144 wasmparser::ComponentOuterAliasKind::CoreType
1145 | wasmparser::ComponentOuterAliasKind::Type => {}
1146
1147 wasmparser::ComponentOuterAliasKind::CoreModule => {
1154 let index = ModuleIndex::from_u32(index);
1155 let mut module = ClosedOverModule::Local(index);
1156 let depth = self.lexical_scopes.len() - (count as usize);
1157 for frame in self.lexical_scopes[depth..].iter_mut() {
1158 module = ClosedOverModule::Upvar(frame.closure_args.modules.push(module));
1159 }
1160
1161 self.result
1166 .initializers
1167 .push(LocalInitializer::AliasModule(module));
1168 }
1169 wasmparser::ComponentOuterAliasKind::Component => {
1170 let index = ComponentIndex::from_u32(index);
1171 let mut component = ClosedOverComponent::Local(index);
1172 let depth = self.lexical_scopes.len() - (count as usize);
1173 for frame in self.lexical_scopes[depth..].iter_mut() {
1174 component =
1175 ClosedOverComponent::Upvar(frame.closure_args.components.push(component));
1176 }
1177
1178 self.result
1179 .initializers
1180 .push(LocalInitializer::AliasComponent(component));
1181 }
1182 }
1183 }
1184
1185 fn canonical_options(&self, opts: &[wasmparser::CanonicalOption]) -> LocalCanonicalOptions {
1186 let mut ret = LocalCanonicalOptions {
1187 string_encoding: StringEncoding::Utf8,
1188 memory: None,
1189 realloc: None,
1190 post_return: None,
1191 async_: false,
1192 callback: None,
1193 };
1194 for opt in opts {
1195 match opt {
1196 wasmparser::CanonicalOption::UTF8 => {
1197 ret.string_encoding = StringEncoding::Utf8;
1198 }
1199 wasmparser::CanonicalOption::UTF16 => {
1200 ret.string_encoding = StringEncoding::Utf16;
1201 }
1202 wasmparser::CanonicalOption::CompactUTF16 => {
1203 ret.string_encoding = StringEncoding::CompactUtf16;
1204 }
1205 wasmparser::CanonicalOption::Memory(idx) => {
1206 let idx = MemoryIndex::from_u32(*idx);
1207 ret.memory = Some(idx);
1208 }
1209 wasmparser::CanonicalOption::Realloc(idx) => {
1210 let idx = FuncIndex::from_u32(*idx);
1211 ret.realloc = Some(idx);
1212 }
1213 wasmparser::CanonicalOption::PostReturn(idx) => {
1214 let idx = FuncIndex::from_u32(*idx);
1215 ret.post_return = Some(idx);
1216 }
1217 wasmparser::CanonicalOption::Async => ret.async_ = true,
1218 wasmparser::CanonicalOption::Callback(idx) => {
1219 let idx = FuncIndex::from_u32(*idx);
1220 ret.callback = Some(idx);
1221 }
1222 wasmparser::CanonicalOption::CoreType(_) => todo!(),
1223 }
1224 }
1225 return ret;
1226 }
1227
1228 fn core_func_signature(&mut self, index: u32) -> WasmResult<ModuleInternedTypeIndex> {
1230 let types = self.validator.types(0).unwrap();
1231 let id = types.core_function_at(index);
1232 self.types.module_types_builder().intern_type(types, id)
1233 }
1234}
1235
1236impl Translation<'_> {
1237 fn types_ref(&self) -> wasmparser::types::TypesRef<'_> {
1238 self.types.as_ref().unwrap().as_ref()
1239 }
1240}
1241
1242mod pre_inlining {
1254 use super::*;
1255
1256 pub struct PreInliningComponentTypes<'a> {
1257 types: &'a mut ComponentTypesBuilder,
1258 }
1259
1260 impl<'a> PreInliningComponentTypes<'a> {
1261 pub fn new(types: &'a mut ComponentTypesBuilder) -> Self {
1262 Self { types }
1263 }
1264
1265 pub fn module_types_builder(&mut self) -> &mut ModuleTypesBuilder {
1266 self.types.module_types_builder_mut()
1267 }
1268
1269 pub fn types(&self) -> &ComponentTypesBuilder {
1270 self.types
1271 }
1272
1273 pub fn types_mut_for_inlining(&mut self) -> &mut ComponentTypesBuilder {
1276 self.types
1277 }
1278 }
1279
1280 impl TypeConvert for PreInliningComponentTypes<'_> {
1281 fn lookup_heap_type(&self, index: wasmparser::UnpackedIndex) -> WasmHeapType {
1282 self.types.lookup_heap_type(index)
1283 }
1284
1285 fn lookup_type_index(&self, index: wasmparser::UnpackedIndex) -> EngineOrModuleTypeIndex {
1286 self.types.lookup_type_index(index)
1287 }
1288 }
1289}
1290use pre_inlining::PreInliningComponentTypes;