1use crate::Abi;
2use crate::component::dfg::AbstractInstantiations;
3use crate::component::*;
4use crate::prelude::*;
5use crate::{
6 EngineOrModuleTypeIndex, EntityIndex, FuncKey, ModuleEnvironment, ModuleInternedTypeIndex,
7 ModuleTranslation, ModuleTypesBuilder, PrimaryMap, ScopeVec, TagIndex, Tunables, TypeConvert,
8 WasmHeapType, WasmResult, WasmValType,
9};
10use anyhow::Context;
11use anyhow::anyhow;
12use anyhow::ensure;
13use anyhow::{Result, bail};
14use core::str::FromStr;
15use cranelift_entity::SecondaryMap;
16use cranelift_entity::packed_option::PackedOption;
17use indexmap::IndexMap;
18use std::collections::HashMap;
19use std::mem;
20use wasmparser::component_types::{
21 AliasableResourceId, ComponentCoreModuleTypeId, ComponentDefinedTypeId, ComponentEntityType,
22 ComponentFuncTypeId, ComponentInstanceTypeId, ComponentValType,
23};
24use wasmparser::types::Types;
25use wasmparser::{Chunk, ComponentImportName, Encoding, Parser, Payload, Validator};
26
27mod adapt;
28pub use self::adapt::*;
29mod inline;
30
31pub struct Translator<'a, 'data> {
33 result: Translation<'data>,
38
39 parser: Parser,
42
43 lexical_scopes: Vec<LexicalScope<'data>>,
51
52 validator: &'a mut Validator,
55
56 types: PreInliningComponentTypes<'a>,
61
62 tunables: &'a Tunables,
64
65 scope_vec: &'data ScopeVec<u8>,
67
68 static_modules: PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
73
74 static_components: PrimaryMap<StaticComponentIndex, Translation<'data>>,
79
80 unsafe_intrinsics_import: Option<&'a str>,
82}
83
84struct LexicalScope<'data> {
137 parser: Parser,
139 translation: Translation<'data>,
141 closure_args: ClosedOverVars,
144}
145
146#[derive(Default)]
156struct Translation<'data> {
157 initializers: Vec<LocalInitializer<'data>>,
163
164 exports: IndexMap<&'data str, ComponentItem>,
167
168 types: Option<Types>,
174}
175
176enum LocalInitializer<'data> {
182 Import(ComponentImportName<'data>, ComponentEntityType),
184
185 IntrinsicsImport,
187
188 Lower {
190 func: ComponentFuncIndex,
191 lower_ty: ComponentFuncTypeId,
192 options: LocalCanonicalOptions,
193 },
194 Lift(ComponentFuncTypeId, FuncIndex, LocalCanonicalOptions),
195
196 Resource(AliasableResourceId, WasmValType, Option<FuncIndex>),
198 ResourceNew(AliasableResourceId, ModuleInternedTypeIndex),
199 ResourceRep(AliasableResourceId, ModuleInternedTypeIndex),
200 ResourceDrop(AliasableResourceId, ModuleInternedTypeIndex),
201
202 BackpressureInc {
203 func: ModuleInternedTypeIndex,
204 },
205 BackpressureDec {
206 func: ModuleInternedTypeIndex,
207 },
208 TaskReturn {
209 result: Option<ComponentValType>,
210 options: LocalCanonicalOptions,
211 },
212 TaskCancel {
213 func: ModuleInternedTypeIndex,
214 },
215 WaitableSetNew {
216 func: ModuleInternedTypeIndex,
217 },
218 WaitableSetWait {
219 options: LocalCanonicalOptions,
220 },
221 WaitableSetPoll {
222 options: LocalCanonicalOptions,
223 },
224 WaitableSetDrop {
225 func: ModuleInternedTypeIndex,
226 },
227 WaitableJoin {
228 func: ModuleInternedTypeIndex,
229 },
230 ThreadYield {
231 func: ModuleInternedTypeIndex,
232 cancellable: bool,
233 },
234 SubtaskDrop {
235 func: ModuleInternedTypeIndex,
236 },
237 SubtaskCancel {
238 func: ModuleInternedTypeIndex,
239 async_: bool,
240 },
241 StreamNew {
242 ty: ComponentDefinedTypeId,
243 func: ModuleInternedTypeIndex,
244 },
245 StreamRead {
246 ty: ComponentDefinedTypeId,
247 options: LocalCanonicalOptions,
248 },
249 StreamWrite {
250 ty: ComponentDefinedTypeId,
251 options: LocalCanonicalOptions,
252 },
253 StreamCancelRead {
254 ty: ComponentDefinedTypeId,
255 func: ModuleInternedTypeIndex,
256 async_: bool,
257 },
258 StreamCancelWrite {
259 ty: ComponentDefinedTypeId,
260 func: ModuleInternedTypeIndex,
261 async_: bool,
262 },
263 StreamDropReadable {
264 ty: ComponentDefinedTypeId,
265 func: ModuleInternedTypeIndex,
266 },
267 StreamDropWritable {
268 ty: ComponentDefinedTypeId,
269 func: ModuleInternedTypeIndex,
270 },
271 FutureNew {
272 ty: ComponentDefinedTypeId,
273 func: ModuleInternedTypeIndex,
274 },
275 FutureRead {
276 ty: ComponentDefinedTypeId,
277 options: LocalCanonicalOptions,
278 },
279 FutureWrite {
280 ty: ComponentDefinedTypeId,
281 options: LocalCanonicalOptions,
282 },
283 FutureCancelRead {
284 ty: ComponentDefinedTypeId,
285 func: ModuleInternedTypeIndex,
286 async_: bool,
287 },
288 FutureCancelWrite {
289 ty: ComponentDefinedTypeId,
290 func: ModuleInternedTypeIndex,
291 async_: bool,
292 },
293 FutureDropReadable {
294 ty: ComponentDefinedTypeId,
295 func: ModuleInternedTypeIndex,
296 },
297 FutureDropWritable {
298 ty: ComponentDefinedTypeId,
299 func: ModuleInternedTypeIndex,
300 },
301 ErrorContextNew {
302 options: LocalCanonicalOptions,
303 },
304 ErrorContextDebugMessage {
305 options: LocalCanonicalOptions,
306 },
307 ErrorContextDrop {
308 func: ModuleInternedTypeIndex,
309 },
310 ContextGet {
311 func: ModuleInternedTypeIndex,
312 i: u32,
313 },
314 ContextSet {
315 func: ModuleInternedTypeIndex,
316 i: u32,
317 },
318 ThreadIndex {
319 func: ModuleInternedTypeIndex,
320 },
321 ThreadNewIndirect {
322 func: ModuleInternedTypeIndex,
323 start_func_ty: ComponentTypeIndex,
324 start_func_table_index: TableIndex,
325 },
326 ThreadSwitchTo {
327 func: ModuleInternedTypeIndex,
328 cancellable: bool,
329 },
330 ThreadSuspend {
331 func: ModuleInternedTypeIndex,
332 cancellable: bool,
333 },
334 ThreadResumeLater {
335 func: ModuleInternedTypeIndex,
336 },
337 ThreadYieldTo {
338 func: ModuleInternedTypeIndex,
339 cancellable: bool,
340 },
341
342 ModuleStatic(StaticModuleIndex, ComponentCoreModuleTypeId),
344
345 ModuleInstantiate(ModuleIndex, HashMap<&'data str, ModuleInstanceIndex>),
347 ModuleSynthetic(HashMap<&'data str, EntityIndex>),
348
349 ComponentStatic(StaticComponentIndex, ClosedOverVars),
351
352 ComponentInstantiate(
354 ComponentIndex,
355 HashMap<&'data str, ComponentItem>,
356 ComponentInstanceTypeId,
357 ),
358 ComponentSynthetic(HashMap<&'data str, ComponentItem>, ComponentInstanceTypeId),
359
360 AliasExportFunc(ModuleInstanceIndex, &'data str),
362 AliasExportTable(ModuleInstanceIndex, &'data str),
363 AliasExportGlobal(ModuleInstanceIndex, &'data str),
364 AliasExportMemory(ModuleInstanceIndex, &'data str),
365 AliasExportTag(ModuleInstanceIndex, &'data str),
366 AliasComponentExport(ComponentInstanceIndex, &'data str),
367 AliasModule(ClosedOverModule),
368 AliasComponent(ClosedOverComponent),
369
370 Export(ComponentItem),
372}
373
374#[derive(Default)]
378struct ClosedOverVars {
379 components: PrimaryMap<ComponentUpvarIndex, ClosedOverComponent>,
380 modules: PrimaryMap<ModuleUpvarIndex, ClosedOverModule>,
381}
382
383enum ClosedOverComponent {
388 Local(ComponentIndex),
391 Upvar(ComponentUpvarIndex),
396}
397
398enum ClosedOverModule {
400 Local(ModuleIndex),
401 Upvar(ModuleUpvarIndex),
402}
403
404#[derive(Debug, Clone, Hash, Eq, PartialEq)]
406pub enum LocalDataModel {
407 Gc {},
409
410 LinearMemory {
412 memory: Option<MemoryIndex>,
414 realloc: Option<FuncIndex>,
416 },
417}
418
419struct LocalCanonicalOptions {
421 string_encoding: StringEncoding,
422 post_return: Option<FuncIndex>,
423 async_: bool,
424 cancellable: bool,
425 callback: Option<FuncIndex>,
426 core_type: ModuleInternedTypeIndex,
428 data_model: LocalDataModel,
429}
430
431enum Action {
432 KeepGoing,
433 Skip(usize),
434 Done,
435}
436
437impl<'a, 'data> Translator<'a, 'data> {
438 pub fn new(
440 tunables: &'a Tunables,
441 validator: &'a mut Validator,
442 types: &'a mut ComponentTypesBuilder,
443 scope_vec: &'data ScopeVec<u8>,
444 ) -> Self {
445 let mut parser = Parser::new(0);
446 parser.set_features(*validator.features());
447 Self {
448 result: Translation::default(),
449 tunables,
450 validator,
451 types: PreInliningComponentTypes::new(types),
452 parser,
453 lexical_scopes: Vec::new(),
454 static_components: Default::default(),
455 static_modules: Default::default(),
456 scope_vec,
457 unsafe_intrinsics_import: None,
458 }
459 }
460
461 pub fn expose_unsafe_intrinsics(&mut self, name: &'a str) -> &mut Self {
464 assert!(self.unsafe_intrinsics_import.is_none());
465 self.unsafe_intrinsics_import = Some(name);
466 self
467 }
468
469 pub fn translate(
493 mut self,
494 component: &'data [u8],
495 ) -> Result<(
496 ComponentTranslation,
497 PrimaryMap<StaticModuleIndex, ModuleTranslation<'data>>,
498 )> {
499 let mut remaining = component;
505 loop {
506 let payload = match self.parser.parse(remaining, true)? {
507 Chunk::Parsed { payload, consumed } => {
508 remaining = &remaining[consumed..];
509 payload
510 }
511 Chunk::NeedMoreData(_) => unreachable!(),
512 };
513
514 match self.translate_payload(payload, component)? {
515 Action::KeepGoing => {}
516 Action::Skip(n) => remaining = &remaining[n..],
517 Action::Done => break,
518 }
519 }
520 assert!(remaining.is_empty());
521 assert!(self.lexical_scopes.is_empty());
522
523 let mut component = inline::run(
534 self.types.types_mut_for_inlining(),
535 &self.result,
536 &self.static_modules,
537 &self.static_components,
538 )?;
539
540 self.partition_adapter_modules(&mut component);
541
542 let translation =
543 component.finish(self.types.types_mut_for_inlining(), self.result.types_ref())?;
544
545 self.analyze_function_imports(&translation);
546
547 Ok((translation, self.static_modules))
548 }
549
550 fn analyze_function_imports(&mut self, translation: &ComponentTranslation) {
551 let mut instantiations = SecondaryMap::<StaticModuleIndex, AbstractInstantiations>::new();
554 let mut instance_to_module =
555 PrimaryMap::<RuntimeInstanceIndex, PackedOption<StaticModuleIndex>>::new();
556 for init in &translation.component.initializers {
557 match init {
558 GlobalInitializer::InstantiateModule(instantiation) => match instantiation {
559 InstantiateModule::Static(module, args) => {
560 instantiations[*module].join(AbstractInstantiations::One(&*args));
561 instance_to_module.push(Some(*module).into());
562 }
563 _ => {
564 instance_to_module.push(None.into());
565 }
566 },
567 _ => continue,
568 }
569 }
570
571 for item in translation.component.export_items.values() {
574 if let Export::ModuleStatic { index, .. } = item {
575 instantiations[*index].join(AbstractInstantiations::Many)
576 }
577 }
578
579 for (module, instantiations) in instantiations.iter() {
584 let args = match instantiations {
585 dfg::AbstractInstantiations::Many | dfg::AbstractInstantiations::None => continue,
586 dfg::AbstractInstantiations::One(args) => args,
587 };
588
589 let mut imported_func_counter = 0_u32;
590 for (i, arg) in args.iter().enumerate() {
591 let (_, _, crate::types::EntityType::Function(_)) =
593 self.static_modules[module].module.import(i).unwrap()
594 else {
595 continue;
596 };
597
598 let imported_func = FuncIndex::from_u32(imported_func_counter);
599 imported_func_counter += 1;
600 debug_assert!(
601 self.static_modules[module]
602 .module
603 .defined_func_index(imported_func)
604 .is_none()
605 );
606
607 let known_func = match arg {
608 CoreDef::InstanceFlags(_) => unreachable!("instance flags are not a function"),
609
610 CoreDef::Trampoline(_) => continue,
623
624 CoreDef::UnsafeIntrinsic(i) => FuncKey::UnsafeIntrinsic(Abi::Wasm, *i),
628
629 CoreDef::Export(export) => {
633 let Some(arg_module) = &instance_to_module[export.instance].expand() else {
634 continue;
639 };
640
641 let ExportItem::Index(EntityIndex::Function(arg_func)) = &export.item
642 else {
643 unreachable!("function imports must be functions")
644 };
645
646 let Some(arg_module_def_func) = self.static_modules[*arg_module]
647 .module
648 .defined_func_index(*arg_func)
649 else {
650 continue;
657 };
658
659 FuncKey::DefinedWasmFunction(*arg_module, arg_module_def_func)
660 }
661 };
662
663 assert!(
664 self.static_modules[module].known_imported_functions[imported_func].is_none()
665 );
666 self.static_modules[module].known_imported_functions[imported_func] =
667 Some(known_func);
668 }
669 }
670 }
671
672 fn translate_payload(
673 &mut self,
674 payload: Payload<'data>,
675 component: &'data [u8],
676 ) -> Result<Action> {
677 match payload {
678 Payload::Version {
679 num,
680 encoding,
681 range,
682 } => {
683 self.validator.version(num, encoding, &range)?;
684
685 match encoding {
686 Encoding::Component => {}
687 Encoding::Module => {
688 bail!("attempted to parse a wasm module with a component parser");
689 }
690 }
691 }
692
693 Payload::End(offset) => {
694 assert!(self.result.types.is_none());
695 self.result.types = Some(self.validator.end(offset)?);
696
697 let LexicalScope {
702 parser,
703 translation,
704 closure_args,
705 } = match self.lexical_scopes.pop() {
706 Some(frame) => frame,
707 None => return Ok(Action::Done),
708 };
709 self.parser = parser;
710 let component = mem::replace(&mut self.result, translation);
711 let static_idx = self.static_components.push(component);
712 self.result
713 .initializers
714 .push(LocalInitializer::ComponentStatic(static_idx, closure_args));
715 }
716
717 Payload::ComponentTypeSection(s) => {
726 let mut component_type_index =
727 self.validator.types(0).unwrap().component_type_count();
728 self.validator.component_type_section(&s)?;
729
730 let types = self.validator.types(0).unwrap();
734 for ty in s {
735 match ty? {
736 wasmparser::ComponentType::Resource { rep, dtor } => {
737 let rep = self.types.convert_valtype(rep)?;
738 let id = types
739 .component_any_type_at(component_type_index)
740 .unwrap_resource();
741 let dtor = dtor.map(FuncIndex::from_u32);
742 self.result
743 .initializers
744 .push(LocalInitializer::Resource(id, rep, dtor));
745 }
746
747 wasmparser::ComponentType::Defined(_)
749 | wasmparser::ComponentType::Func(_)
750 | wasmparser::ComponentType::Instance(_)
751 | wasmparser::ComponentType::Component(_) => {}
752 }
753
754 component_type_index += 1;
755 }
756 }
757 Payload::CoreTypeSection(s) => {
758 self.validator.core_type_section(&s)?;
759 }
760
761 Payload::ComponentImportSection(s) => {
765 self.validator.component_import_section(&s)?;
766 for import in s {
767 let import = import?;
768 let types = self.validator.types(0).unwrap();
769 let ty = types
770 .component_entity_type_of_import(import.name.0)
771 .unwrap();
772
773 if self.is_unsafe_intrinsics_import(import.name.0) {
774 self.check_unsafe_intrinsics_import(import.name.0, ty)?;
775 self.result
776 .initializers
777 .push(LocalInitializer::IntrinsicsImport);
778 } else {
779 self.result
780 .initializers
781 .push(LocalInitializer::Import(import.name, ty));
782 }
783 }
784 }
785
786 Payload::ComponentCanonicalSection(s) => {
789 let types = self.validator.types(0).unwrap();
790 let mut core_func_index = types.function_count();
791 self.validator.component_canonical_section(&s)?;
792 for func in s {
793 let init = match func? {
794 wasmparser::CanonicalFunction::Lift {
795 type_index,
796 core_func_index,
797 options,
798 } => {
799 let ty = self
800 .validator
801 .types(0)
802 .unwrap()
803 .component_any_type_at(type_index)
804 .unwrap_func();
805
806 let func = FuncIndex::from_u32(core_func_index);
807 let options = self.canonical_options(&options, core_func_index)?;
808 LocalInitializer::Lift(ty, func, options)
809 }
810 wasmparser::CanonicalFunction::Lower {
811 func_index,
812 options,
813 } => {
814 let lower_ty = self
815 .validator
816 .types(0)
817 .unwrap()
818 .component_function_at(func_index);
819 let func = ComponentFuncIndex::from_u32(func_index);
820 let options = self.canonical_options(&options, core_func_index)?;
821 core_func_index += 1;
822 LocalInitializer::Lower {
823 func,
824 options,
825 lower_ty,
826 }
827 }
828 wasmparser::CanonicalFunction::ResourceNew { resource } => {
829 let resource = self
830 .validator
831 .types(0)
832 .unwrap()
833 .component_any_type_at(resource)
834 .unwrap_resource();
835 let ty = self.core_func_signature(core_func_index)?;
836 core_func_index += 1;
837 LocalInitializer::ResourceNew(resource, ty)
838 }
839 wasmparser::CanonicalFunction::ResourceDrop { resource } => {
840 let resource = self
841 .validator
842 .types(0)
843 .unwrap()
844 .component_any_type_at(resource)
845 .unwrap_resource();
846 let ty = self.core_func_signature(core_func_index)?;
847 core_func_index += 1;
848 LocalInitializer::ResourceDrop(resource, ty)
849 }
850 wasmparser::CanonicalFunction::ResourceDropAsync { resource } => {
851 let _ = resource;
852 bail!("support for `resource.drop async` not implemented yet")
853 }
854 wasmparser::CanonicalFunction::ResourceRep { resource } => {
855 let resource = self
856 .validator
857 .types(0)
858 .unwrap()
859 .component_any_type_at(resource)
860 .unwrap_resource();
861 let ty = self.core_func_signature(core_func_index)?;
862 core_func_index += 1;
863 LocalInitializer::ResourceRep(resource, ty)
864 }
865 wasmparser::CanonicalFunction::ThreadSpawnRef { .. }
866 | wasmparser::CanonicalFunction::ThreadSpawnIndirect { .. }
867 | wasmparser::CanonicalFunction::ThreadAvailableParallelism => {
868 bail!("unsupported intrinsic")
869 }
870 wasmparser::CanonicalFunction::BackpressureSet => {
871 bail!("unsupported intrinsic")
872 }
873 wasmparser::CanonicalFunction::BackpressureInc => {
874 let core_type = self.core_func_signature(core_func_index)?;
875 core_func_index += 1;
876 LocalInitializer::BackpressureInc { func: core_type }
877 }
878 wasmparser::CanonicalFunction::BackpressureDec => {
879 let core_type = self.core_func_signature(core_func_index)?;
880 core_func_index += 1;
881 LocalInitializer::BackpressureDec { func: core_type }
882 }
883
884 wasmparser::CanonicalFunction::TaskReturn { result, options } => {
885 let result = result.map(|ty| match ty {
886 wasmparser::ComponentValType::Primitive(ty) => {
887 ComponentValType::Primitive(ty)
888 }
889 wasmparser::ComponentValType::Type(ty) => ComponentValType::Type(
890 self.validator
891 .types(0)
892 .unwrap()
893 .component_defined_type_at(ty),
894 ),
895 });
896 let options = self.canonical_options(&options, core_func_index)?;
897 core_func_index += 1;
898 LocalInitializer::TaskReturn { result, options }
899 }
900 wasmparser::CanonicalFunction::TaskCancel => {
901 let func = self.core_func_signature(core_func_index)?;
902 core_func_index += 1;
903 LocalInitializer::TaskCancel { func }
904 }
905 wasmparser::CanonicalFunction::WaitableSetNew => {
906 let func = self.core_func_signature(core_func_index)?;
907 core_func_index += 1;
908 LocalInitializer::WaitableSetNew { func }
909 }
910 wasmparser::CanonicalFunction::WaitableSetWait {
911 cancellable,
912 memory,
913 } => {
914 let core_type = self.core_func_signature(core_func_index)?;
915 core_func_index += 1;
916 LocalInitializer::WaitableSetWait {
917 options: LocalCanonicalOptions {
918 core_type,
919 cancellable,
920 async_: false,
921 data_model: LocalDataModel::LinearMemory {
922 memory: Some(MemoryIndex::from_u32(memory)),
923 realloc: None,
924 },
925 post_return: None,
926 callback: None,
927 string_encoding: StringEncoding::Utf8,
928 },
929 }
930 }
931 wasmparser::CanonicalFunction::WaitableSetPoll {
932 cancellable,
933 memory,
934 } => {
935 let core_type = self.core_func_signature(core_func_index)?;
936 core_func_index += 1;
937 LocalInitializer::WaitableSetPoll {
938 options: LocalCanonicalOptions {
939 core_type,
940 async_: false,
941 cancellable,
942 data_model: LocalDataModel::LinearMemory {
943 memory: Some(MemoryIndex::from_u32(memory)),
944 realloc: None,
945 },
946 post_return: None,
947 callback: None,
948 string_encoding: StringEncoding::Utf8,
949 },
950 }
951 }
952 wasmparser::CanonicalFunction::WaitableSetDrop => {
953 let func = self.core_func_signature(core_func_index)?;
954 core_func_index += 1;
955 LocalInitializer::WaitableSetDrop { func }
956 }
957 wasmparser::CanonicalFunction::WaitableJoin => {
958 let func = self.core_func_signature(core_func_index)?;
959 core_func_index += 1;
960 LocalInitializer::WaitableJoin { func }
961 }
962 wasmparser::CanonicalFunction::ThreadYield { cancellable } => {
963 let func = self.core_func_signature(core_func_index)?;
964 core_func_index += 1;
965 LocalInitializer::ThreadYield { func, cancellable }
966 }
967 wasmparser::CanonicalFunction::SubtaskDrop => {
968 let func = self.core_func_signature(core_func_index)?;
969 core_func_index += 1;
970 LocalInitializer::SubtaskDrop { func }
971 }
972 wasmparser::CanonicalFunction::SubtaskCancel { async_ } => {
973 let func = self.core_func_signature(core_func_index)?;
974 core_func_index += 1;
975 LocalInitializer::SubtaskCancel { func, async_ }
976 }
977 wasmparser::CanonicalFunction::StreamNew { ty } => {
978 let ty = self
979 .validator
980 .types(0)
981 .unwrap()
982 .component_defined_type_at(ty);
983 let func = self.core_func_signature(core_func_index)?;
984 core_func_index += 1;
985 LocalInitializer::StreamNew { ty, func }
986 }
987 wasmparser::CanonicalFunction::StreamRead { ty, options } => {
988 let ty = self
989 .validator
990 .types(0)
991 .unwrap()
992 .component_defined_type_at(ty);
993 let options = self.canonical_options(&options, core_func_index)?;
994 core_func_index += 1;
995 LocalInitializer::StreamRead { ty, options }
996 }
997 wasmparser::CanonicalFunction::StreamWrite { ty, options } => {
998 let ty = self
999 .validator
1000 .types(0)
1001 .unwrap()
1002 .component_defined_type_at(ty);
1003 let options = self.canonical_options(&options, core_func_index)?;
1004 core_func_index += 1;
1005 LocalInitializer::StreamWrite { ty, options }
1006 }
1007 wasmparser::CanonicalFunction::StreamCancelRead { ty, async_ } => {
1008 let ty = self
1009 .validator
1010 .types(0)
1011 .unwrap()
1012 .component_defined_type_at(ty);
1013 let func = self.core_func_signature(core_func_index)?;
1014 core_func_index += 1;
1015 LocalInitializer::StreamCancelRead { ty, func, async_ }
1016 }
1017 wasmparser::CanonicalFunction::StreamCancelWrite { ty, async_ } => {
1018 let ty = self
1019 .validator
1020 .types(0)
1021 .unwrap()
1022 .component_defined_type_at(ty);
1023 let func = self.core_func_signature(core_func_index)?;
1024 core_func_index += 1;
1025 LocalInitializer::StreamCancelWrite { ty, func, async_ }
1026 }
1027 wasmparser::CanonicalFunction::StreamDropReadable { ty } => {
1028 let ty = self
1029 .validator
1030 .types(0)
1031 .unwrap()
1032 .component_defined_type_at(ty);
1033 let func = self.core_func_signature(core_func_index)?;
1034 core_func_index += 1;
1035 LocalInitializer::StreamDropReadable { ty, func }
1036 }
1037 wasmparser::CanonicalFunction::StreamDropWritable { ty } => {
1038 let ty = self
1039 .validator
1040 .types(0)
1041 .unwrap()
1042 .component_defined_type_at(ty);
1043 let func = self.core_func_signature(core_func_index)?;
1044 core_func_index += 1;
1045 LocalInitializer::StreamDropWritable { ty, func }
1046 }
1047 wasmparser::CanonicalFunction::FutureNew { ty } => {
1048 let ty = self
1049 .validator
1050 .types(0)
1051 .unwrap()
1052 .component_defined_type_at(ty);
1053 let func = self.core_func_signature(core_func_index)?;
1054 core_func_index += 1;
1055 LocalInitializer::FutureNew { ty, func }
1056 }
1057 wasmparser::CanonicalFunction::FutureRead { ty, options } => {
1058 let ty = self
1059 .validator
1060 .types(0)
1061 .unwrap()
1062 .component_defined_type_at(ty);
1063 let options = self.canonical_options(&options, core_func_index)?;
1064 core_func_index += 1;
1065 LocalInitializer::FutureRead { ty, options }
1066 }
1067 wasmparser::CanonicalFunction::FutureWrite { ty, options } => {
1068 let ty = self
1069 .validator
1070 .types(0)
1071 .unwrap()
1072 .component_defined_type_at(ty);
1073 let options = self.canonical_options(&options, core_func_index)?;
1074 core_func_index += 1;
1075 LocalInitializer::FutureWrite { ty, options }
1076 }
1077 wasmparser::CanonicalFunction::FutureCancelRead { ty, async_ } => {
1078 let ty = self
1079 .validator
1080 .types(0)
1081 .unwrap()
1082 .component_defined_type_at(ty);
1083 let func = self.core_func_signature(core_func_index)?;
1084 core_func_index += 1;
1085 LocalInitializer::FutureCancelRead { ty, func, async_ }
1086 }
1087 wasmparser::CanonicalFunction::FutureCancelWrite { ty, async_ } => {
1088 let ty = self
1089 .validator
1090 .types(0)
1091 .unwrap()
1092 .component_defined_type_at(ty);
1093 let func = self.core_func_signature(core_func_index)?;
1094 core_func_index += 1;
1095 LocalInitializer::FutureCancelWrite { ty, func, async_ }
1096 }
1097 wasmparser::CanonicalFunction::FutureDropReadable { ty } => {
1098 let ty = self
1099 .validator
1100 .types(0)
1101 .unwrap()
1102 .component_defined_type_at(ty);
1103 let func = self.core_func_signature(core_func_index)?;
1104 core_func_index += 1;
1105 LocalInitializer::FutureDropReadable { ty, func }
1106 }
1107 wasmparser::CanonicalFunction::FutureDropWritable { ty } => {
1108 let ty = self
1109 .validator
1110 .types(0)
1111 .unwrap()
1112 .component_defined_type_at(ty);
1113 let func = self.core_func_signature(core_func_index)?;
1114 core_func_index += 1;
1115 LocalInitializer::FutureDropWritable { ty, func }
1116 }
1117 wasmparser::CanonicalFunction::ErrorContextNew { options } => {
1118 let options = self.canonical_options(&options, core_func_index)?;
1119 core_func_index += 1;
1120 LocalInitializer::ErrorContextNew { options }
1121 }
1122 wasmparser::CanonicalFunction::ErrorContextDebugMessage { options } => {
1123 let options = self.canonical_options(&options, core_func_index)?;
1124 core_func_index += 1;
1125 LocalInitializer::ErrorContextDebugMessage { options }
1126 }
1127 wasmparser::CanonicalFunction::ErrorContextDrop => {
1128 let func = self.core_func_signature(core_func_index)?;
1129 core_func_index += 1;
1130 LocalInitializer::ErrorContextDrop { func }
1131 }
1132 wasmparser::CanonicalFunction::ContextGet(i) => {
1133 let func = self.core_func_signature(core_func_index)?;
1134 core_func_index += 1;
1135 LocalInitializer::ContextGet { i, func }
1136 }
1137 wasmparser::CanonicalFunction::ContextSet(i) => {
1138 let func = self.core_func_signature(core_func_index)?;
1139 core_func_index += 1;
1140 LocalInitializer::ContextSet { i, func }
1141 }
1142 wasmparser::CanonicalFunction::ThreadIndex => {
1143 let func = self.core_func_signature(core_func_index)?;
1144 core_func_index += 1;
1145 LocalInitializer::ThreadIndex { func }
1146 }
1147 wasmparser::CanonicalFunction::ThreadNewIndirect {
1148 func_ty_index,
1149 table_index,
1150 } => {
1151 let func = self.core_func_signature(core_func_index)?;
1152 core_func_index += 1;
1153 LocalInitializer::ThreadNewIndirect {
1154 func,
1155 start_func_ty: ComponentTypeIndex::from_u32(func_ty_index),
1156 start_func_table_index: TableIndex::from_u32(table_index),
1157 }
1158 }
1159 wasmparser::CanonicalFunction::ThreadSwitchTo { cancellable } => {
1160 let func = self.core_func_signature(core_func_index)?;
1161 core_func_index += 1;
1162 LocalInitializer::ThreadSwitchTo { func, cancellable }
1163 }
1164 wasmparser::CanonicalFunction::ThreadSuspend { cancellable } => {
1165 let func = self.core_func_signature(core_func_index)?;
1166 core_func_index += 1;
1167 LocalInitializer::ThreadSuspend { func, cancellable }
1168 }
1169 wasmparser::CanonicalFunction::ThreadResumeLater => {
1170 let func = self.core_func_signature(core_func_index)?;
1171 core_func_index += 1;
1172 LocalInitializer::ThreadResumeLater { func }
1173 }
1174 wasmparser::CanonicalFunction::ThreadYieldTo { cancellable } => {
1175 let func = self.core_func_signature(core_func_index)?;
1176 core_func_index += 1;
1177 LocalInitializer::ThreadYieldTo { func, cancellable }
1178 }
1179 };
1180 self.result.initializers.push(init);
1181 }
1182 }
1183
1184 Payload::ModuleSection {
1193 parser,
1194 unchecked_range,
1195 } => {
1196 let index = self.validator.types(0).unwrap().module_count();
1197 self.validator.module_section(&unchecked_range)?;
1198 let static_module_index = self.static_modules.next_key();
1199 let translation = ModuleEnvironment::new(
1200 self.tunables,
1201 self.validator,
1202 self.types.module_types_builder(),
1203 static_module_index,
1204 )
1205 .translate(
1206 parser,
1207 component
1208 .get(unchecked_range.start..unchecked_range.end)
1209 .ok_or_else(|| {
1210 anyhow!(
1211 "section range {}..{} is out of bounds (bound = {})",
1212 unchecked_range.start,
1213 unchecked_range.end,
1214 component.len()
1215 )
1216 .context("wasm component contains an invalid module section")
1217 })?,
1218 )?;
1219 let static_module_index2 = self.static_modules.push(translation);
1220 assert_eq!(static_module_index, static_module_index2);
1221 let types = self.validator.types(0).unwrap();
1222 let ty = types.module_at(index);
1223 self.result
1224 .initializers
1225 .push(LocalInitializer::ModuleStatic(static_module_index, ty));
1226 return Ok(Action::Skip(unchecked_range.end - unchecked_range.start));
1227 }
1228
1229 Payload::ComponentSection {
1238 parser,
1239 unchecked_range,
1240 } => {
1241 self.validator.component_section(&unchecked_range)?;
1242 self.lexical_scopes.push(LexicalScope {
1243 parser: mem::replace(&mut self.parser, parser),
1244 translation: mem::take(&mut self.result),
1245 closure_args: ClosedOverVars::default(),
1246 });
1247 }
1248
1249 Payload::InstanceSection(s) => {
1254 self.validator.instance_section(&s)?;
1255 for instance in s {
1256 let init = match instance? {
1257 wasmparser::Instance::Instantiate { module_index, args } => {
1258 let index = ModuleIndex::from_u32(module_index);
1259 self.instantiate_module(index, &args)
1260 }
1261 wasmparser::Instance::FromExports(exports) => {
1262 self.instantiate_module_from_exports(&exports)
1263 }
1264 };
1265 self.result.initializers.push(init);
1266 }
1267 }
1268 Payload::ComponentInstanceSection(s) => {
1269 let mut index = self.validator.types(0).unwrap().component_instance_count();
1270 self.validator.component_instance_section(&s)?;
1271 for instance in s {
1272 let types = self.validator.types(0).unwrap();
1273 let ty = types.component_instance_at(index);
1274 let init = match instance? {
1275 wasmparser::ComponentInstance::Instantiate {
1276 component_index,
1277 args,
1278 } => {
1279 let index = ComponentIndex::from_u32(component_index);
1280 self.instantiate_component(index, &args, ty)?
1281 }
1282 wasmparser::ComponentInstance::FromExports(exports) => {
1283 self.instantiate_component_from_exports(&exports, ty)?
1284 }
1285 };
1286 self.result.initializers.push(init);
1287 index += 1;
1288 }
1289 }
1290
1291 Payload::ComponentExportSection(s) => {
1297 self.validator.component_export_section(&s)?;
1298 for export in s {
1299 let export = export?;
1300 let item = self.kind_to_item(export.kind, export.index)?;
1301 let prev = self.result.exports.insert(export.name.0, item);
1302 assert!(prev.is_none());
1303 self.result
1304 .initializers
1305 .push(LocalInitializer::Export(item));
1306 }
1307 }
1308
1309 Payload::ComponentStartSection { start, range } => {
1310 self.validator.component_start_section(&start, &range)?;
1311 unimplemented!("component start section");
1312 }
1313
1314 Payload::ComponentAliasSection(s) => {
1318 self.validator.component_alias_section(&s)?;
1319 for alias in s {
1320 let init = match alias? {
1321 wasmparser::ComponentAlias::InstanceExport {
1322 kind: _,
1323 instance_index,
1324 name,
1325 } => {
1326 let instance = ComponentInstanceIndex::from_u32(instance_index);
1327 LocalInitializer::AliasComponentExport(instance, name)
1328 }
1329 wasmparser::ComponentAlias::Outer { kind, count, index } => {
1330 self.alias_component_outer(kind, count, index);
1331 continue;
1332 }
1333 wasmparser::ComponentAlias::CoreInstanceExport {
1334 kind,
1335 instance_index,
1336 name,
1337 } => {
1338 let instance = ModuleInstanceIndex::from_u32(instance_index);
1339 self.alias_module_instance_export(kind, instance, name)
1340 }
1341 };
1342 self.result.initializers.push(init);
1343 }
1344 }
1345
1346 Payload::CustomSection { .. } => {}
1351
1352 other => {
1358 self.validator.payload(&other)?;
1359 panic!("unimplemented section {other:?}");
1360 }
1361 }
1362
1363 Ok(Action::KeepGoing)
1364 }
1365
1366 fn instantiate_module(
1367 &mut self,
1368 module: ModuleIndex,
1369 raw_args: &[wasmparser::InstantiationArg<'data>],
1370 ) -> LocalInitializer<'data> {
1371 let mut args = HashMap::with_capacity(raw_args.len());
1372 for arg in raw_args {
1373 match arg.kind {
1374 wasmparser::InstantiationArgKind::Instance => {
1375 let idx = ModuleInstanceIndex::from_u32(arg.index);
1376 args.insert(arg.name, idx);
1377 }
1378 }
1379 }
1380 LocalInitializer::ModuleInstantiate(module, args)
1381 }
1382
1383 fn instantiate_module_from_exports(
1386 &mut self,
1387 exports: &[wasmparser::Export<'data>],
1388 ) -> LocalInitializer<'data> {
1389 let mut map = HashMap::with_capacity(exports.len());
1390 for export in exports {
1391 let idx = match export.kind {
1392 wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
1393 let index = FuncIndex::from_u32(export.index);
1394 EntityIndex::Function(index)
1395 }
1396 wasmparser::ExternalKind::Table => {
1397 let index = TableIndex::from_u32(export.index);
1398 EntityIndex::Table(index)
1399 }
1400 wasmparser::ExternalKind::Memory => {
1401 let index = MemoryIndex::from_u32(export.index);
1402 EntityIndex::Memory(index)
1403 }
1404 wasmparser::ExternalKind::Global => {
1405 let index = GlobalIndex::from_u32(export.index);
1406 EntityIndex::Global(index)
1407 }
1408 wasmparser::ExternalKind::Tag => {
1409 let index = TagIndex::from_u32(export.index);
1410 EntityIndex::Tag(index)
1411 }
1412 };
1413 map.insert(export.name, idx);
1414 }
1415 LocalInitializer::ModuleSynthetic(map)
1416 }
1417
1418 fn instantiate_component(
1419 &mut self,
1420 component: ComponentIndex,
1421 raw_args: &[wasmparser::ComponentInstantiationArg<'data>],
1422 ty: ComponentInstanceTypeId,
1423 ) -> Result<LocalInitializer<'data>> {
1424 let mut args = HashMap::with_capacity(raw_args.len());
1425 for arg in raw_args {
1426 let idx = self.kind_to_item(arg.kind, arg.index)?;
1427 args.insert(arg.name, idx);
1428 }
1429
1430 Ok(LocalInitializer::ComponentInstantiate(component, args, ty))
1431 }
1432
1433 fn instantiate_component_from_exports(
1436 &mut self,
1437 exports: &[wasmparser::ComponentExport<'data>],
1438 ty: ComponentInstanceTypeId,
1439 ) -> Result<LocalInitializer<'data>> {
1440 let mut map = HashMap::with_capacity(exports.len());
1441 for export in exports {
1442 let idx = self.kind_to_item(export.kind, export.index)?;
1443 map.insert(export.name.0, idx);
1444 }
1445
1446 Ok(LocalInitializer::ComponentSynthetic(map, ty))
1447 }
1448
1449 fn kind_to_item(
1450 &mut self,
1451 kind: wasmparser::ComponentExternalKind,
1452 index: u32,
1453 ) -> Result<ComponentItem> {
1454 Ok(match kind {
1455 wasmparser::ComponentExternalKind::Func => {
1456 let index = ComponentFuncIndex::from_u32(index);
1457 ComponentItem::Func(index)
1458 }
1459 wasmparser::ComponentExternalKind::Module => {
1460 let index = ModuleIndex::from_u32(index);
1461 ComponentItem::Module(index)
1462 }
1463 wasmparser::ComponentExternalKind::Instance => {
1464 let index = ComponentInstanceIndex::from_u32(index);
1465 ComponentItem::ComponentInstance(index)
1466 }
1467 wasmparser::ComponentExternalKind::Component => {
1468 let index = ComponentIndex::from_u32(index);
1469 ComponentItem::Component(index)
1470 }
1471 wasmparser::ComponentExternalKind::Value => {
1472 unimplemented!("component values");
1473 }
1474 wasmparser::ComponentExternalKind::Type => {
1475 let types = self.validator.types(0).unwrap();
1476 let ty = types.component_any_type_at(index);
1477 ComponentItem::Type(ty)
1478 }
1479 })
1480 }
1481
1482 fn alias_module_instance_export(
1483 &mut self,
1484 kind: wasmparser::ExternalKind,
1485 instance: ModuleInstanceIndex,
1486 name: &'data str,
1487 ) -> LocalInitializer<'data> {
1488 match kind {
1489 wasmparser::ExternalKind::Func | wasmparser::ExternalKind::FuncExact => {
1490 LocalInitializer::AliasExportFunc(instance, name)
1491 }
1492 wasmparser::ExternalKind::Memory => LocalInitializer::AliasExportMemory(instance, name),
1493 wasmparser::ExternalKind::Table => LocalInitializer::AliasExportTable(instance, name),
1494 wasmparser::ExternalKind::Global => LocalInitializer::AliasExportGlobal(instance, name),
1495 wasmparser::ExternalKind::Tag => LocalInitializer::AliasExportTag(instance, name),
1496 }
1497 }
1498
1499 fn alias_component_outer(
1500 &mut self,
1501 kind: wasmparser::ComponentOuterAliasKind,
1502 count: u32,
1503 index: u32,
1504 ) {
1505 match kind {
1506 wasmparser::ComponentOuterAliasKind::CoreType
1507 | wasmparser::ComponentOuterAliasKind::Type => {}
1508
1509 wasmparser::ComponentOuterAliasKind::CoreModule => {
1516 let index = ModuleIndex::from_u32(index);
1517 let mut module = ClosedOverModule::Local(index);
1518 let depth = self.lexical_scopes.len() - (count as usize);
1519 for frame in self.lexical_scopes[depth..].iter_mut() {
1520 module = ClosedOverModule::Upvar(frame.closure_args.modules.push(module));
1521 }
1522
1523 self.result
1528 .initializers
1529 .push(LocalInitializer::AliasModule(module));
1530 }
1531 wasmparser::ComponentOuterAliasKind::Component => {
1532 let index = ComponentIndex::from_u32(index);
1533 let mut component = ClosedOverComponent::Local(index);
1534 let depth = self.lexical_scopes.len() - (count as usize);
1535 for frame in self.lexical_scopes[depth..].iter_mut() {
1536 component =
1537 ClosedOverComponent::Upvar(frame.closure_args.components.push(component));
1538 }
1539
1540 self.result
1541 .initializers
1542 .push(LocalInitializer::AliasComponent(component));
1543 }
1544 }
1545 }
1546
1547 fn canonical_options(
1548 &mut self,
1549 opts: &[wasmparser::CanonicalOption],
1550 core_func_index: u32,
1551 ) -> WasmResult<LocalCanonicalOptions> {
1552 let core_type = self.core_func_signature(core_func_index)?;
1553
1554 let mut string_encoding = StringEncoding::Utf8;
1555 let mut post_return = None;
1556 let mut async_ = false;
1557 let mut callback = None;
1558 let mut memory = None;
1559 let mut realloc = None;
1560 let mut gc = false;
1561
1562 for opt in opts {
1563 match opt {
1564 wasmparser::CanonicalOption::UTF8 => {
1565 string_encoding = StringEncoding::Utf8;
1566 }
1567 wasmparser::CanonicalOption::UTF16 => {
1568 string_encoding = StringEncoding::Utf16;
1569 }
1570 wasmparser::CanonicalOption::CompactUTF16 => {
1571 string_encoding = StringEncoding::CompactUtf16;
1572 }
1573 wasmparser::CanonicalOption::Memory(idx) => {
1574 let idx = MemoryIndex::from_u32(*idx);
1575 memory = Some(idx);
1576 }
1577 wasmparser::CanonicalOption::Realloc(idx) => {
1578 let idx = FuncIndex::from_u32(*idx);
1579 realloc = Some(idx);
1580 }
1581 wasmparser::CanonicalOption::PostReturn(idx) => {
1582 let idx = FuncIndex::from_u32(*idx);
1583 post_return = Some(idx);
1584 }
1585 wasmparser::CanonicalOption::Async => async_ = true,
1586 wasmparser::CanonicalOption::Callback(idx) => {
1587 let idx = FuncIndex::from_u32(*idx);
1588 callback = Some(idx);
1589 }
1590 wasmparser::CanonicalOption::CoreType(idx) => {
1591 if cfg!(debug_assertions) {
1592 let types = self.validator.types(0).unwrap();
1593 let core_ty_id = types.core_type_at_in_component(*idx).unwrap_sub();
1594 let interned = self
1595 .types
1596 .module_types_builder()
1597 .intern_type(types, core_ty_id)?;
1598 debug_assert_eq!(interned, core_type);
1599 }
1600 }
1601 wasmparser::CanonicalOption::Gc => {
1602 gc = true;
1603 }
1604 }
1605 }
1606
1607 Ok(LocalCanonicalOptions {
1608 string_encoding,
1609 post_return,
1610 cancellable: false,
1611 async_,
1612 callback,
1613 core_type,
1614 data_model: if gc {
1615 LocalDataModel::Gc {}
1616 } else {
1617 LocalDataModel::LinearMemory { memory, realloc }
1618 },
1619 })
1620 }
1621
1622 fn core_func_signature(&mut self, index: u32) -> WasmResult<ModuleInternedTypeIndex> {
1624 let types = self.validator.types(0).unwrap();
1625 let id = types.core_function_at(index);
1626 self.types.module_types_builder().intern_type(types, id)
1627 }
1628
1629 fn is_unsafe_intrinsics_import(&self, import: &str) -> bool {
1630 self.lexical_scopes.is_empty()
1631 && self
1632 .unsafe_intrinsics_import
1633 .is_some_and(|name| import == name)
1634 }
1635
1636 fn check_unsafe_intrinsics_import(&self, import: &str, ty: ComponentEntityType) -> Result<()> {
1637 let types = &self.validator.types(0).unwrap();
1638
1639 let ComponentEntityType::Instance(instance_ty) = ty else {
1640 bail!("bad unsafe intrinsics import: import `{import}` must be an instance import")
1641 };
1642 let instance_ty = &types[instance_ty];
1643
1644 ensure!(
1645 instance_ty.defined_resources.is_empty(),
1646 "bad unsafe intrinsics import: import `{import}` cannot define any resources"
1647 );
1648 ensure!(
1649 instance_ty.explicit_resources.is_empty(),
1650 "bad unsafe intrinsics import: import `{import}` cannot export any resources"
1651 );
1652
1653 for (name, ty) in &instance_ty.exports {
1654 let ComponentEntityType::Func(func_ty) = ty else {
1655 bail!(
1656 "bad unsafe intrinsics import: imported instance `{import}` must \
1657 only export functions"
1658 )
1659 };
1660 let func_ty = &types[*func_ty];
1661
1662 fn ty_eq(a: &InterfaceType, b: &wasmparser::component_types::ComponentValType) -> bool {
1663 use wasmparser::{PrimitiveValType as P, component_types::ComponentValType as C};
1664 match (a, b) {
1665 (InterfaceType::U8, C::Primitive(P::U8)) => true,
1666 (InterfaceType::U8, _) => false,
1667
1668 (InterfaceType::U16, C::Primitive(P::U16)) => true,
1669 (InterfaceType::U16, _) => false,
1670
1671 (InterfaceType::U32, C::Primitive(P::U32)) => true,
1672 (InterfaceType::U32, _) => false,
1673
1674 (InterfaceType::U64, C::Primitive(P::U64)) => true,
1675 (InterfaceType::U64, _) => false,
1676
1677 (ty, _) => unreachable!("no unsafe intrinsics use {ty:?}"),
1678 }
1679 }
1680
1681 fn check_types<'a>(
1682 expected: impl ExactSizeIterator<Item = &'a InterfaceType>,
1683 actual: impl ExactSizeIterator<Item = &'a wasmparser::component_types::ComponentValType>,
1684 kind: &str,
1685 import: &str,
1686 name: &str,
1687 ) -> core::result::Result<(), anyhow::Error> {
1688 let expected_len = expected.len();
1689 let actual_len = actual.len();
1690 ensure!(
1691 expected_len == actual_len,
1692 "bad unsafe intrinsics import at `{import}`: function `{name}` must have \
1693 {expected_len} {kind}, found {actual_len}"
1694 );
1695
1696 for (i, (actual_ty, expected_ty)) in actual.zip(expected).enumerate() {
1697 ensure!(
1698 ty_eq(expected_ty, actual_ty),
1699 "bad unsafe intrinsics import at `{import}`: {kind}[{i}] for function \
1700 `{name}` must be `{expected_ty:?}`, found `{actual_ty:?}`"
1701 );
1702 }
1703 Ok(())
1704 }
1705
1706 let intrinsic = UnsafeIntrinsic::from_str(name)
1707 .with_context(|| format!("bad unsafe intrinsics import at `{import}`"))?;
1708
1709 check_types(
1710 intrinsic.component_params().iter(),
1711 func_ty.params.iter().map(|(_name, ty)| ty),
1712 "parameters",
1713 &import,
1714 &name,
1715 )?;
1716 check_types(
1717 intrinsic.component_results().iter(),
1718 func_ty.result.iter(),
1719 "results",
1720 &import,
1721 &name,
1722 )?;
1723 }
1724
1725 Ok(())
1726 }
1727}
1728
1729impl Translation<'_> {
1730 fn types_ref(&self) -> wasmparser::types::TypesRef<'_> {
1731 self.types.as_ref().unwrap().as_ref()
1732 }
1733}
1734
1735mod pre_inlining {
1747 use super::*;
1748
1749 pub struct PreInliningComponentTypes<'a> {
1750 types: &'a mut ComponentTypesBuilder,
1751 }
1752
1753 impl<'a> PreInliningComponentTypes<'a> {
1754 pub fn new(types: &'a mut ComponentTypesBuilder) -> Self {
1755 Self { types }
1756 }
1757
1758 pub fn module_types_builder(&mut self) -> &mut ModuleTypesBuilder {
1759 self.types.module_types_builder_mut()
1760 }
1761
1762 pub fn types(&self) -> &ComponentTypesBuilder {
1763 self.types
1764 }
1765
1766 pub fn types_mut_for_inlining(&mut self) -> &mut ComponentTypesBuilder {
1769 self.types
1770 }
1771 }
1772
1773 impl TypeConvert for PreInliningComponentTypes<'_> {
1774 fn lookup_heap_type(&self, index: wasmparser::UnpackedIndex) -> WasmHeapType {
1775 self.types.lookup_heap_type(index)
1776 }
1777
1778 fn lookup_type_index(&self, index: wasmparser::UnpackedIndex) -> EngineOrModuleTypeIndex {
1779 self.types.lookup_type_index(index)
1780 }
1781 }
1782}
1783use pre_inlining::PreInliningComponentTypes;