1use crate::component::*;
2use crate::prelude::*;
3use crate::ScopeVec;
4use crate::{
5 EngineOrModuleTypeIndex, EntityIndex, ModuleEnvironment, ModuleInternedTypeIndex,
6 ModuleTranslation, ModuleTypesBuilder, PrimaryMap, Tunables, TypeConvert, WasmHeapType,
7 WasmResult, WasmValType,
8};
9use anyhow::anyhow;
10use anyhow::{bail, Result};
11use indexmap::IndexMap;
12use std::collections::HashMap;
13use std::mem;
14use wasmparser::component_types::{
15 AliasableResourceId, ComponentCoreModuleTypeId, ComponentDefinedTypeId, ComponentEntityType,
16 ComponentFuncTypeId, ComponentInstanceTypeId,
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 TaskBackpressure {
192 func: ModuleInternedTypeIndex,
193 },
194 TaskReturn {
195 func: ModuleInternedTypeIndex,
196 },
197 TaskWait {
198 func: ModuleInternedTypeIndex,
199 async_: bool,
200 memory: MemoryIndex,
201 },
202 TaskPoll {
203 func: ModuleInternedTypeIndex,
204 async_: bool,
205 memory: MemoryIndex,
206 },
207 TaskYield {
208 func: ModuleInternedTypeIndex,
209 async_: bool,
210 },
211 SubtaskDrop {
212 func: ModuleInternedTypeIndex,
213 },
214 StreamNew {
215 ty: ComponentDefinedTypeId,
216 func: ModuleInternedTypeIndex,
217 },
218 StreamRead {
219 ty: ComponentDefinedTypeId,
220 func: ModuleInternedTypeIndex,
221 options: LocalCanonicalOptions,
222 },
223 StreamWrite {
224 ty: ComponentDefinedTypeId,
225 func: ModuleInternedTypeIndex,
226 options: LocalCanonicalOptions,
227 },
228 StreamCancelRead {
229 ty: ComponentDefinedTypeId,
230 func: ModuleInternedTypeIndex,
231 async_: bool,
232 },
233 StreamCancelWrite {
234 ty: ComponentDefinedTypeId,
235 func: ModuleInternedTypeIndex,
236 async_: bool,
237 },
238 StreamCloseReadable {
239 ty: ComponentDefinedTypeId,
240 func: ModuleInternedTypeIndex,
241 },
242 StreamCloseWritable {
243 ty: ComponentDefinedTypeId,
244 func: ModuleInternedTypeIndex,
245 },
246 FutureNew {
247 ty: ComponentDefinedTypeId,
248 func: ModuleInternedTypeIndex,
249 },
250 FutureRead {
251 ty: ComponentDefinedTypeId,
252 func: ModuleInternedTypeIndex,
253 options: LocalCanonicalOptions,
254 },
255 FutureWrite {
256 ty: ComponentDefinedTypeId,
257 func: ModuleInternedTypeIndex,
258 options: LocalCanonicalOptions,
259 },
260 FutureCancelRead {
261 ty: ComponentDefinedTypeId,
262 func: ModuleInternedTypeIndex,
263 async_: bool,
264 },
265 FutureCancelWrite {
266 ty: ComponentDefinedTypeId,
267 func: ModuleInternedTypeIndex,
268 async_: bool,
269 },
270 FutureCloseReadable {
271 ty: ComponentDefinedTypeId,
272 func: ModuleInternedTypeIndex,
273 },
274 FutureCloseWritable {
275 ty: ComponentDefinedTypeId,
276 func: ModuleInternedTypeIndex,
277 },
278 ErrorContextNew {
279 func: ModuleInternedTypeIndex,
280 options: LocalCanonicalOptions,
281 },
282 ErrorContextDebugMessage {
283 func: ModuleInternedTypeIndex,
284 options: LocalCanonicalOptions,
285 },
286 ErrorContextDrop {
287 func: ModuleInternedTypeIndex,
288 },
289
290 ModuleStatic(StaticModuleIndex, ComponentCoreModuleTypeId),
292
293 ModuleInstantiate(ModuleIndex, HashMap<&'data str, ModuleInstanceIndex>),
295 ModuleSynthetic(HashMap<&'data str, EntityIndex>),
296
297 ComponentStatic(StaticComponentIndex, ClosedOverVars),
299
300 ComponentInstantiate(
302 ComponentIndex,
303 HashMap<&'data str, ComponentItem>,
304 ComponentInstanceTypeId,
305 ),
306 ComponentSynthetic(HashMap<&'data str, ComponentItem>, ComponentInstanceTypeId),
307
308 AliasExportFunc(ModuleInstanceIndex, &'data str),
310 AliasExportTable(ModuleInstanceIndex, &'data str),
311 AliasExportGlobal(ModuleInstanceIndex, &'data str),
312 AliasExportMemory(ModuleInstanceIndex, &'data str),
313 AliasComponentExport(ComponentInstanceIndex, &'data str),
314 AliasModule(ClosedOverModule),
315 AliasComponent(ClosedOverComponent),
316
317 Export(ComponentItem),
319}
320
321#[derive(Default)]
325struct ClosedOverVars {
326 components: PrimaryMap<ComponentUpvarIndex, ClosedOverComponent>,
327 modules: PrimaryMap<ModuleUpvarIndex, ClosedOverModule>,
328}
329
330enum ClosedOverComponent {
335 Local(ComponentIndex),
338 Upvar(ComponentUpvarIndex),
343}
344
345enum ClosedOverModule {
347 Local(ModuleIndex),
348 Upvar(ModuleUpvarIndex),
349}
350
351struct LocalCanonicalOptions {
353 string_encoding: StringEncoding,
354 memory: Option<MemoryIndex>,
355 realloc: Option<FuncIndex>,
356 post_return: Option<FuncIndex>,
357 async_: bool,
358 callback: Option<FuncIndex>,
359}
360
361enum Action {
362 KeepGoing,
363 Skip(usize),
364 Done,
365}
366
367impl<'a, 'data> Translator<'a, 'data> {
368 pub fn new(
370 tunables: &'a Tunables,
371 validator: &'a mut Validator,
372 types: &'a mut ComponentTypesBuilder,
373 scope_vec: &'data ScopeVec<u8>,
374 ) -> Self {
375 let mut parser = Parser::new(0);
376 parser.set_features(*validator.features());
377 Self {
378 result: Translation::default(),
379 tunables,
380 validator,
381 types: PreInliningComponentTypes::new(types),
382 parser,
383 lexical_scopes: Vec::new(),
384 static_components: Default::default(),
385 static_modules: Default::default(),
386 scope_vec,
387 }
388 }
389
390 pub fn translate(
414 mut self,
415 component: &'data [u8],
416 ) -> Result<(
417 ComponentTranslation,
418 PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
419 )> {
420 let mut remaining = component;
426 loop {
427 let payload = match self.parser.parse(remaining, true)? {
428 Chunk::Parsed { payload, consumed } => {
429 remaining = &remaining[consumed..];
430 payload
431 }
432 Chunk::NeedMoreData(_) => unreachable!(),
433 };
434
435 match self.translate_payload(payload, component)? {
436 Action::KeepGoing => {}
437 Action::Skip(n) => remaining = &remaining[n..],
438 Action::Done => break,
439 }
440 }
441 assert!(remaining.is_empty());
442 assert!(self.lexical_scopes.is_empty());
443
444 let mut component = inline::run(
455 self.types.types_mut_for_inlining(),
456 &self.result,
457 &self.static_modules,
458 &self.static_components,
459 )?;
460 self.partition_adapter_modules(&mut component);
461 let translation =
462 component.finish(self.types.types_mut_for_inlining(), self.result.types_ref())?;
463 Ok((translation, self.static_modules))
464 }
465
466 fn translate_payload(
467 &mut self,
468 payload: Payload<'data>,
469 component: &'data [u8],
470 ) -> Result<Action> {
471 match payload {
472 Payload::Version {
473 num,
474 encoding,
475 range,
476 } => {
477 self.validator.version(num, encoding, &range)?;
478
479 match encoding {
480 Encoding::Component => {}
481 Encoding::Module => {
482 bail!("attempted to parse a wasm module with a component parser");
483 }
484 }
485 }
486
487 Payload::End(offset) => {
488 assert!(self.result.types.is_none());
489 self.result.types = Some(self.validator.end(offset)?);
490
491 let LexicalScope {
496 parser,
497 translation,
498 closure_args,
499 } = match self.lexical_scopes.pop() {
500 Some(frame) => frame,
501 None => return Ok(Action::Done),
502 };
503 self.parser = parser;
504 let component = mem::replace(&mut self.result, translation);
505 let static_idx = self.static_components.push(component);
506 self.result
507 .initializers
508 .push(LocalInitializer::ComponentStatic(static_idx, closure_args));
509 }
510
511 Payload::ComponentTypeSection(s) => {
520 let mut component_type_index =
521 self.validator.types(0).unwrap().component_type_count();
522 self.validator.component_type_section(&s)?;
523
524 let types = self.validator.types(0).unwrap();
528 for ty in s {
529 match ty? {
530 wasmparser::ComponentType::Resource { rep, dtor } => {
531 let rep = self.types.convert_valtype(rep);
532 let id = types
533 .component_any_type_at(component_type_index)
534 .unwrap_resource();
535 let dtor = dtor.map(FuncIndex::from_u32);
536 self.result
537 .initializers
538 .push(LocalInitializer::Resource(id, rep, dtor));
539 }
540
541 wasmparser::ComponentType::Defined(_)
543 | wasmparser::ComponentType::Func(_)
544 | wasmparser::ComponentType::Instance(_)
545 | wasmparser::ComponentType::Component(_) => {}
546 }
547
548 component_type_index += 1;
549 }
550 }
551 Payload::CoreTypeSection(s) => {
552 self.validator.core_type_section(&s)?;
553 }
554
555 Payload::ComponentImportSection(s) => {
559 self.validator.component_import_section(&s)?;
560 for import in s {
561 let import = import?;
562 let types = self.validator.types(0).unwrap();
563 let ty = types
564 .component_entity_type_of_import(import.name.0)
565 .unwrap();
566 self.result
567 .initializers
568 .push(LocalInitializer::Import(import.name, ty));
569 }
570 }
571
572 Payload::ComponentCanonicalSection(s) => {
575 let types = self.validator.types(0).unwrap();
576 let mut core_func_index = types.function_count();
577 self.validator.component_canonical_section(&s)?;
578 for func in s {
579 let types = self.validator.types(0).unwrap();
580 let init = match func? {
581 wasmparser::CanonicalFunction::Lift {
582 type_index,
583 core_func_index,
584 options,
585 } => {
586 let ty = types.component_any_type_at(type_index).unwrap_func();
587 let func = FuncIndex::from_u32(core_func_index);
588 let options = self.canonical_options(&options);
589 LocalInitializer::Lift(ty, func, options)
590 }
591 wasmparser::CanonicalFunction::Lower {
592 func_index,
593 options,
594 } => {
595 let lower_ty = types.component_function_at(func_index);
596 let func = ComponentFuncIndex::from_u32(func_index);
597 let options = self.canonical_options(&options);
598 let canonical_abi = self.core_func_signature(core_func_index)?;
599
600 core_func_index += 1;
601 LocalInitializer::Lower {
602 func,
603 options,
604 canonical_abi,
605 lower_ty,
606 }
607 }
608 wasmparser::CanonicalFunction::ResourceNew { resource } => {
609 let resource = types.component_any_type_at(resource).unwrap_resource();
610 let ty = self.core_func_signature(core_func_index)?;
611 core_func_index += 1;
612 LocalInitializer::ResourceNew(resource, ty)
613 }
614 wasmparser::CanonicalFunction::ResourceDrop { resource } => {
615 let resource = types.component_any_type_at(resource).unwrap_resource();
616 let ty = self.core_func_signature(core_func_index)?;
617 core_func_index += 1;
618 LocalInitializer::ResourceDrop(resource, ty)
619 }
620 wasmparser::CanonicalFunction::ResourceRep { 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::ResourceRep(resource, ty)
625 }
626 wasmparser::CanonicalFunction::ThreadSpawn { .. }
627 | wasmparser::CanonicalFunction::ThreadHwConcurrency => {
628 bail!("unsupported intrinsic")
629 }
630 wasmparser::CanonicalFunction::TaskBackpressure => {
631 let core_type = self.core_func_signature(core_func_index)?;
632 core_func_index += 1;
633 LocalInitializer::TaskBackpressure { func: core_type }
634 }
635 wasmparser::CanonicalFunction::TaskReturn { .. } => {
636 let core_type = self.core_func_signature(core_func_index)?;
637 core_func_index += 1;
638 LocalInitializer::TaskReturn { func: core_type }
639 }
640 wasmparser::CanonicalFunction::TaskWait { async_, memory } => {
641 let func = self.core_func_signature(core_func_index)?;
642 core_func_index += 1;
643 LocalInitializer::TaskWait {
644 func,
645 async_,
646 memory: MemoryIndex::from_u32(memory),
647 }
648 }
649 wasmparser::CanonicalFunction::TaskPoll { async_, memory } => {
650 let func = self.core_func_signature(core_func_index)?;
651 core_func_index += 1;
652 LocalInitializer::TaskPoll {
653 func,
654 async_,
655 memory: MemoryIndex::from_u32(memory),
656 }
657 }
658 wasmparser::CanonicalFunction::TaskYield { async_ } => {
659 let func = self.core_func_signature(core_func_index)?;
660 core_func_index += 1;
661 LocalInitializer::TaskYield { func, async_ }
662 }
663 wasmparser::CanonicalFunction::SubtaskDrop => {
664 let func = self.core_func_signature(core_func_index)?;
665 core_func_index += 1;
666 LocalInitializer::SubtaskDrop { func }
667 }
668 wasmparser::CanonicalFunction::StreamNew { ty } => {
669 let ty = types.component_defined_type_at(ty);
670 let func = self.core_func_signature(core_func_index)?;
671 core_func_index += 1;
672 LocalInitializer::StreamNew { ty, func }
673 }
674 wasmparser::CanonicalFunction::StreamRead { ty, options } => {
675 let ty = types.component_defined_type_at(ty);
676 let options = self.canonical_options(&options);
677 let func = self.core_func_signature(core_func_index)?;
678 core_func_index += 1;
679 LocalInitializer::StreamRead { ty, func, options }
680 }
681 wasmparser::CanonicalFunction::StreamWrite { ty, options } => {
682 let ty = types.component_defined_type_at(ty);
683 let options = self.canonical_options(&options);
684 let func = self.core_func_signature(core_func_index)?;
685 core_func_index += 1;
686 LocalInitializer::StreamWrite { ty, func, options }
687 }
688 wasmparser::CanonicalFunction::StreamCancelRead { ty, async_ } => {
689 let ty = types.component_defined_type_at(ty);
690 let func = self.core_func_signature(core_func_index)?;
691 core_func_index += 1;
692 LocalInitializer::StreamCancelRead { ty, func, async_ }
693 }
694 wasmparser::CanonicalFunction::StreamCancelWrite { ty, async_ } => {
695 let ty = types.component_defined_type_at(ty);
696 let func = self.core_func_signature(core_func_index)?;
697 core_func_index += 1;
698 LocalInitializer::StreamCancelWrite { ty, func, async_ }
699 }
700 wasmparser::CanonicalFunction::StreamCloseReadable { ty } => {
701 let ty = types.component_defined_type_at(ty);
702 let func = self.core_func_signature(core_func_index)?;
703 core_func_index += 1;
704 LocalInitializer::StreamCloseReadable { ty, func }
705 }
706 wasmparser::CanonicalFunction::StreamCloseWritable { ty } => {
707 let ty = types.component_defined_type_at(ty);
708 let func = self.core_func_signature(core_func_index)?;
709 core_func_index += 1;
710 LocalInitializer::StreamCloseWritable { ty, func }
711 }
712 wasmparser::CanonicalFunction::FutureNew { ty } => {
713 let ty = types.component_defined_type_at(ty);
714 let func = self.core_func_signature(core_func_index)?;
715 core_func_index += 1;
716 LocalInitializer::FutureNew { ty, func }
717 }
718 wasmparser::CanonicalFunction::FutureRead { ty, options } => {
719 let ty = types.component_defined_type_at(ty);
720 let options = self.canonical_options(&options);
721 let func = self.core_func_signature(core_func_index)?;
722 core_func_index += 1;
723 LocalInitializer::FutureRead { ty, func, options }
724 }
725 wasmparser::CanonicalFunction::FutureWrite { ty, options } => {
726 let ty = types.component_defined_type_at(ty);
727 let options = self.canonical_options(&options);
728 let func = self.core_func_signature(core_func_index)?;
729 core_func_index += 1;
730 LocalInitializer::FutureWrite { ty, func, options }
731 }
732 wasmparser::CanonicalFunction::FutureCancelRead { ty, async_ } => {
733 let ty = types.component_defined_type_at(ty);
734 let func = self.core_func_signature(core_func_index)?;
735 core_func_index += 1;
736 LocalInitializer::FutureCancelRead { ty, func, async_ }
737 }
738 wasmparser::CanonicalFunction::FutureCancelWrite { ty, async_ } => {
739 let ty = types.component_defined_type_at(ty);
740 let func = self.core_func_signature(core_func_index)?;
741 core_func_index += 1;
742 LocalInitializer::FutureCancelWrite { ty, func, async_ }
743 }
744 wasmparser::CanonicalFunction::FutureCloseReadable { ty } => {
745 let ty = types.component_defined_type_at(ty);
746 let func = self.core_func_signature(core_func_index)?;
747 core_func_index += 1;
748 LocalInitializer::FutureCloseReadable { ty, func }
749 }
750 wasmparser::CanonicalFunction::FutureCloseWritable { ty } => {
751 let ty = types.component_defined_type_at(ty);
752 let func = self.core_func_signature(core_func_index)?;
753 core_func_index += 1;
754 LocalInitializer::FutureCloseWritable { ty, func }
755 }
756 wasmparser::CanonicalFunction::ErrorContextNew { options } => {
757 let options = self.canonical_options(&options);
758 let func = self.core_func_signature(core_func_index)?;
759 core_func_index += 1;
760 LocalInitializer::ErrorContextNew { func, options }
761 }
762 wasmparser::CanonicalFunction::ErrorContextDebugMessage { options } => {
763 let options = self.canonical_options(&options);
764 let func = self.core_func_signature(core_func_index)?;
765 core_func_index += 1;
766 LocalInitializer::ErrorContextDebugMessage { func, options }
767 }
768 wasmparser::CanonicalFunction::ErrorContextDrop => {
769 let func = self.core_func_signature(core_func_index)?;
770 core_func_index += 1;
771 LocalInitializer::ErrorContextDrop { func }
772 }
773 };
774 self.result.initializers.push(init);
775 }
776 }
777
778 Payload::ModuleSection {
787 parser,
788 unchecked_range,
789 } => {
790 let index = self.validator.types(0).unwrap().module_count();
791 self.validator.module_section(&unchecked_range)?;
792 let translation = ModuleEnvironment::new(
793 self.tunables,
794 self.validator,
795 self.types.module_types_builder(),
796 )
797 .translate(
798 parser,
799 component
800 .get(unchecked_range.start..unchecked_range.end)
801 .ok_or_else(|| {
802 anyhow!(
803 "section range {}..{} is out of bounds (bound = {})",
804 unchecked_range.start,
805 unchecked_range.end,
806 component.len()
807 )
808 .context("wasm component contains an invalid module section")
809 })?,
810 )?;
811 let static_idx = self.static_modules.push(translation);
812 let types = self.validator.types(0).unwrap();
813 let ty = types.module_at(index);
814 self.result
815 .initializers
816 .push(LocalInitializer::ModuleStatic(static_idx, ty));
817 return Ok(Action::Skip(unchecked_range.end - unchecked_range.start));
818 }
819
820 Payload::ComponentSection {
829 parser,
830 unchecked_range,
831 } => {
832 self.validator.component_section(&unchecked_range)?;
833 self.lexical_scopes.push(LexicalScope {
834 parser: mem::replace(&mut self.parser, parser),
835 translation: mem::take(&mut self.result),
836 closure_args: ClosedOverVars::default(),
837 });
838 }
839
840 Payload::InstanceSection(s) => {
845 self.validator.instance_section(&s)?;
846 for instance in s {
847 let init = match instance? {
848 wasmparser::Instance::Instantiate { module_index, args } => {
849 let index = ModuleIndex::from_u32(module_index);
850 self.instantiate_module(index, &args)
851 }
852 wasmparser::Instance::FromExports(exports) => {
853 self.instantiate_module_from_exports(&exports)
854 }
855 };
856 self.result.initializers.push(init);
857 }
858 }
859 Payload::ComponentInstanceSection(s) => {
860 let mut index = self.validator.types(0).unwrap().component_instance_count();
861 self.validator.component_instance_section(&s)?;
862 for instance in s {
863 let types = self.validator.types(0).unwrap();
864 let ty = types.component_instance_at(index);
865 let init = match instance? {
866 wasmparser::ComponentInstance::Instantiate {
867 component_index,
868 args,
869 } => {
870 let index = ComponentIndex::from_u32(component_index);
871 self.instantiate_component(index, &args, ty)?
872 }
873 wasmparser::ComponentInstance::FromExports(exports) => {
874 self.instantiate_component_from_exports(&exports, ty)?
875 }
876 };
877 self.result.initializers.push(init);
878 index += 1;
879 }
880 }
881
882 Payload::ComponentExportSection(s) => {
888 self.validator.component_export_section(&s)?;
889 for export in s {
890 let export = export?;
891 let item = self.kind_to_item(export.kind, export.index)?;
892 let prev = self.result.exports.insert(export.name.0, item);
893 assert!(prev.is_none());
894 self.result
895 .initializers
896 .push(LocalInitializer::Export(item));
897 }
898 }
899
900 Payload::ComponentStartSection { start, range } => {
901 self.validator.component_start_section(&start, &range)?;
902 unimplemented!("component start section");
903 }
904
905 Payload::ComponentAliasSection(s) => {
909 self.validator.component_alias_section(&s)?;
910 for alias in s {
911 let init = match alias? {
912 wasmparser::ComponentAlias::InstanceExport {
913 kind: _,
914 instance_index,
915 name,
916 } => {
917 let instance = ComponentInstanceIndex::from_u32(instance_index);
918 LocalInitializer::AliasComponentExport(instance, name)
919 }
920 wasmparser::ComponentAlias::Outer { kind, count, index } => {
921 self.alias_component_outer(kind, count, index);
922 continue;
923 }
924 wasmparser::ComponentAlias::CoreInstanceExport {
925 kind,
926 instance_index,
927 name,
928 } => {
929 let instance = ModuleInstanceIndex::from_u32(instance_index);
930 self.alias_module_instance_export(kind, instance, name)
931 }
932 };
933 self.result.initializers.push(init);
934 }
935 }
936
937 Payload::CustomSection { .. } => {}
942
943 other => {
949 self.validator.payload(&other)?;
950 panic!("unimplemented section {other:?}");
951 }
952 }
953
954 Ok(Action::KeepGoing)
955 }
956
957 fn instantiate_module(
958 &mut self,
959 module: ModuleIndex,
960 raw_args: &[wasmparser::InstantiationArg<'data>],
961 ) -> LocalInitializer<'data> {
962 let mut args = HashMap::with_capacity(raw_args.len());
963 for arg in raw_args {
964 match arg.kind {
965 wasmparser::InstantiationArgKind::Instance => {
966 let idx = ModuleInstanceIndex::from_u32(arg.index);
967 args.insert(arg.name, idx);
968 }
969 }
970 }
971 LocalInitializer::ModuleInstantiate(module, args)
972 }
973
974 fn instantiate_module_from_exports(
977 &mut self,
978 exports: &[wasmparser::Export<'data>],
979 ) -> LocalInitializer<'data> {
980 let mut map = HashMap::with_capacity(exports.len());
981 for export in exports {
982 let idx = match export.kind {
983 wasmparser::ExternalKind::Func => {
984 let index = FuncIndex::from_u32(export.index);
985 EntityIndex::Function(index)
986 }
987 wasmparser::ExternalKind::Table => {
988 let index = TableIndex::from_u32(export.index);
989 EntityIndex::Table(index)
990 }
991 wasmparser::ExternalKind::Memory => {
992 let index = MemoryIndex::from_u32(export.index);
993 EntityIndex::Memory(index)
994 }
995 wasmparser::ExternalKind::Global => {
996 let index = GlobalIndex::from_u32(export.index);
997 EntityIndex::Global(index)
998 }
999
1000 wasmparser::ExternalKind::Tag => unimplemented!("wasm exceptions"),
1002 };
1003 map.insert(export.name, idx);
1004 }
1005 LocalInitializer::ModuleSynthetic(map)
1006 }
1007
1008 fn instantiate_component(
1009 &mut self,
1010 component: ComponentIndex,
1011 raw_args: &[wasmparser::ComponentInstantiationArg<'data>],
1012 ty: ComponentInstanceTypeId,
1013 ) -> Result<LocalInitializer<'data>> {
1014 let mut args = HashMap::with_capacity(raw_args.len());
1015 for arg in raw_args {
1016 let idx = self.kind_to_item(arg.kind, arg.index)?;
1017 args.insert(arg.name, idx);
1018 }
1019
1020 Ok(LocalInitializer::ComponentInstantiate(component, args, ty))
1021 }
1022
1023 fn instantiate_component_from_exports(
1026 &mut self,
1027 exports: &[wasmparser::ComponentExport<'data>],
1028 ty: ComponentInstanceTypeId,
1029 ) -> Result<LocalInitializer<'data>> {
1030 let mut map = HashMap::with_capacity(exports.len());
1031 for export in exports {
1032 let idx = self.kind_to_item(export.kind, export.index)?;
1033 map.insert(export.name.0, idx);
1034 }
1035
1036 Ok(LocalInitializer::ComponentSynthetic(map, ty))
1037 }
1038
1039 fn kind_to_item(
1040 &mut self,
1041 kind: wasmparser::ComponentExternalKind,
1042 index: u32,
1043 ) -> Result<ComponentItem> {
1044 Ok(match kind {
1045 wasmparser::ComponentExternalKind::Func => {
1046 let index = ComponentFuncIndex::from_u32(index);
1047 ComponentItem::Func(index)
1048 }
1049 wasmparser::ComponentExternalKind::Module => {
1050 let index = ModuleIndex::from_u32(index);
1051 ComponentItem::Module(index)
1052 }
1053 wasmparser::ComponentExternalKind::Instance => {
1054 let index = ComponentInstanceIndex::from_u32(index);
1055 ComponentItem::ComponentInstance(index)
1056 }
1057 wasmparser::ComponentExternalKind::Component => {
1058 let index = ComponentIndex::from_u32(index);
1059 ComponentItem::Component(index)
1060 }
1061 wasmparser::ComponentExternalKind::Value => {
1062 unimplemented!("component values");
1063 }
1064 wasmparser::ComponentExternalKind::Type => {
1065 let types = self.validator.types(0).unwrap();
1066 let ty = types.component_any_type_at(index);
1067 ComponentItem::Type(ty)
1068 }
1069 })
1070 }
1071
1072 fn alias_module_instance_export(
1073 &mut self,
1074 kind: wasmparser::ExternalKind,
1075 instance: ModuleInstanceIndex,
1076 name: &'data str,
1077 ) -> LocalInitializer<'data> {
1078 match kind {
1079 wasmparser::ExternalKind::Func => LocalInitializer::AliasExportFunc(instance, name),
1080 wasmparser::ExternalKind::Memory => LocalInitializer::AliasExportMemory(instance, name),
1081 wasmparser::ExternalKind::Table => LocalInitializer::AliasExportTable(instance, name),
1082 wasmparser::ExternalKind::Global => LocalInitializer::AliasExportGlobal(instance, name),
1083 wasmparser::ExternalKind::Tag => {
1084 unimplemented!("wasm exceptions");
1085 }
1086 }
1087 }
1088
1089 fn alias_component_outer(
1090 &mut self,
1091 kind: wasmparser::ComponentOuterAliasKind,
1092 count: u32,
1093 index: u32,
1094 ) {
1095 match kind {
1096 wasmparser::ComponentOuterAliasKind::CoreType
1097 | wasmparser::ComponentOuterAliasKind::Type => {}
1098
1099 wasmparser::ComponentOuterAliasKind::CoreModule => {
1106 let index = ModuleIndex::from_u32(index);
1107 let mut module = ClosedOverModule::Local(index);
1108 let depth = self.lexical_scopes.len() - (count as usize);
1109 for frame in self.lexical_scopes[depth..].iter_mut() {
1110 module = ClosedOverModule::Upvar(frame.closure_args.modules.push(module));
1111 }
1112
1113 self.result
1118 .initializers
1119 .push(LocalInitializer::AliasModule(module));
1120 }
1121 wasmparser::ComponentOuterAliasKind::Component => {
1122 let index = ComponentIndex::from_u32(index);
1123 let mut component = ClosedOverComponent::Local(index);
1124 let depth = self.lexical_scopes.len() - (count as usize);
1125 for frame in self.lexical_scopes[depth..].iter_mut() {
1126 component =
1127 ClosedOverComponent::Upvar(frame.closure_args.components.push(component));
1128 }
1129
1130 self.result
1131 .initializers
1132 .push(LocalInitializer::AliasComponent(component));
1133 }
1134 }
1135 }
1136
1137 fn canonical_options(&self, opts: &[wasmparser::CanonicalOption]) -> LocalCanonicalOptions {
1138 let mut ret = LocalCanonicalOptions {
1139 string_encoding: StringEncoding::Utf8,
1140 memory: None,
1141 realloc: None,
1142 post_return: None,
1143 async_: false,
1144 callback: None,
1145 };
1146 for opt in opts {
1147 match opt {
1148 wasmparser::CanonicalOption::UTF8 => {
1149 ret.string_encoding = StringEncoding::Utf8;
1150 }
1151 wasmparser::CanonicalOption::UTF16 => {
1152 ret.string_encoding = StringEncoding::Utf16;
1153 }
1154 wasmparser::CanonicalOption::CompactUTF16 => {
1155 ret.string_encoding = StringEncoding::CompactUtf16;
1156 }
1157 wasmparser::CanonicalOption::Memory(idx) => {
1158 let idx = MemoryIndex::from_u32(*idx);
1159 ret.memory = Some(idx);
1160 }
1161 wasmparser::CanonicalOption::Realloc(idx) => {
1162 let idx = FuncIndex::from_u32(*idx);
1163 ret.realloc = Some(idx);
1164 }
1165 wasmparser::CanonicalOption::PostReturn(idx) => {
1166 let idx = FuncIndex::from_u32(*idx);
1167 ret.post_return = Some(idx);
1168 }
1169 wasmparser::CanonicalOption::Async => ret.async_ = true,
1170 wasmparser::CanonicalOption::Callback(idx) => {
1171 let idx = FuncIndex::from_u32(*idx);
1172 ret.callback = Some(idx);
1173 }
1174 }
1175 }
1176 return ret;
1177 }
1178
1179 fn core_func_signature(&mut self, index: u32) -> WasmResult<ModuleInternedTypeIndex> {
1181 let types = self.validator.types(0).unwrap();
1182 let id = types.core_function_at(index);
1183 self.types.module_types_builder().intern_type(types, id)
1184 }
1185}
1186
1187impl Translation<'_> {
1188 fn types_ref(&self) -> wasmparser::types::TypesRef<'_> {
1189 self.types.as_ref().unwrap().as_ref()
1190 }
1191}
1192
1193mod pre_inlining {
1205 use super::*;
1206
1207 pub struct PreInliningComponentTypes<'a> {
1208 types: &'a mut ComponentTypesBuilder,
1209 }
1210
1211 impl<'a> PreInliningComponentTypes<'a> {
1212 pub fn new(types: &'a mut ComponentTypesBuilder) -> Self {
1213 Self { types }
1214 }
1215
1216 pub fn module_types_builder(&mut self) -> &mut ModuleTypesBuilder {
1217 self.types.module_types_builder_mut()
1218 }
1219
1220 pub fn types(&self) -> &ComponentTypesBuilder {
1221 self.types
1222 }
1223
1224 pub fn types_mut_for_inlining(&mut self) -> &mut ComponentTypesBuilder {
1227 self.types
1228 }
1229 }
1230
1231 impl TypeConvert for PreInliningComponentTypes<'_> {
1232 fn lookup_heap_type(&self, index: wasmparser::UnpackedIndex) -> WasmHeapType {
1233 self.types.lookup_heap_type(index)
1234 }
1235
1236 fn lookup_type_index(&self, index: wasmparser::UnpackedIndex) -> EngineOrModuleTypeIndex {
1237 self.types.lookup_type_index(index)
1238 }
1239 }
1240}
1241use pre_inlining::PreInliningComponentTypes;