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