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