1use crate::component::*;
31use crate::prelude::*;
32use crate::{EntityIndex, EntityRef, ModuleInternedTypeIndex, PrimaryMap, WasmValType};
33use anyhow::Result;
34use indexmap::IndexMap;
35use std::collections::HashMap;
36use std::hash::Hash;
37use std::ops::Index;
38use wasmparser::component_types::ComponentCoreModuleTypeId;
39
40#[derive(Default)]
42pub struct ComponentDfg {
43 pub import_types: PrimaryMap<ImportIndex, (String, TypeDef)>,
45
46 pub imports: PrimaryMap<RuntimeImportIndex, (ImportIndex, Vec<String>)>,
48
49 pub exports: IndexMap<String, Export>,
51
52 pub trampolines: Intern<TrampolineIndex, (ModuleInternedTypeIndex, Trampoline)>,
55
56 pub reallocs: Intern<ReallocId, CoreDef>,
59
60 pub callbacks: Intern<CallbackId, CoreDef>,
62
63 pub post_returns: Intern<PostReturnId, CoreDef>,
65
66 pub memories: Intern<MemoryId, CoreExport<MemoryIndex>>,
68
69 pub adapters: Intern<AdapterId, Adapter>,
75
76 pub instances: PrimaryMap<InstanceId, Instance>,
83
84 pub num_runtime_component_instances: u32,
87
88 pub adapter_modules: PrimaryMap<AdapterModuleId, (StaticModuleIndex, Vec<CoreDef>)>,
98
99 pub adapter_partitionings: PrimaryMap<AdapterId, (AdapterModuleId, EntityIndex)>,
110
111 pub resources: PrimaryMap<DefinedResourceIndex, Resource>,
117
118 pub imported_resources: PrimaryMap<ResourceIndex, RuntimeImportIndex>,
122
123 pub num_resource_tables: usize,
127
128 pub num_future_tables: usize,
130
131 pub num_stream_tables: usize,
133
134 pub num_error_context_tables: usize,
137
138 pub side_effects: Vec<SideEffect>,
145}
146
147pub enum SideEffect {
149 Instance(InstanceId),
156
157 Resource(DefinedResourceIndex),
164}
165
166macro_rules! id {
167 ($(pub struct $name:ident(u32);)*) => ($(
168 #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
169 #[allow(missing_docs, reason = "tedious to document")]
170 pub struct $name(u32);
171 cranelift_entity::entity_impl!($name);
172 )*)
173}
174
175id! {
176 pub struct InstanceId(u32);
177 pub struct MemoryId(u32);
178 pub struct ReallocId(u32);
179 pub struct CallbackId(u32);
180 pub struct AdapterId(u32);
181 pub struct PostReturnId(u32);
182 pub struct AdapterModuleId(u32);
183}
184
185#[allow(missing_docs, reason = "tedious to document variants")]
187pub enum Instance {
188 Static(StaticModuleIndex, Box<[CoreDef]>),
189 Import(
190 RuntimeImportIndex,
191 IndexMap<String, IndexMap<String, CoreDef>>,
192 ),
193}
194
195#[allow(missing_docs, reason = "tedious to document variants")]
197pub enum Export {
198 LiftedFunction {
199 ty: TypeFuncIndex,
200 func: CoreDef,
201 options: CanonicalOptions,
202 },
203 ModuleStatic {
204 ty: ComponentCoreModuleTypeId,
205 index: StaticModuleIndex,
206 },
207 ModuleImport {
208 ty: TypeModuleIndex,
209 import: RuntimeImportIndex,
210 },
211 Instance {
212 ty: TypeComponentInstanceIndex,
213 exports: IndexMap<String, Export>,
214 },
215 Type(TypeDef),
216}
217
218#[derive(Debug, Clone, Hash, Eq, PartialEq)]
220#[allow(missing_docs, reason = "tedious to document variants")]
221pub enum CoreDef {
222 Export(CoreExport<EntityIndex>),
223 InstanceFlags(RuntimeComponentInstanceIndex),
224 Trampoline(TrampolineIndex),
225 Adapter(AdapterId),
234}
235
236impl<T> From<CoreExport<T>> for CoreDef
237where
238 EntityIndex: From<T>,
239{
240 fn from(export: CoreExport<T>) -> CoreDef {
241 CoreDef::Export(export.map_index(|i| i.into()))
242 }
243}
244
245#[derive(Debug, Clone, Hash, Eq, PartialEq)]
247#[allow(missing_docs, reason = "self-describing fields")]
248pub struct CoreExport<T> {
249 pub instance: InstanceId,
250 pub item: ExportItem<T>,
251}
252
253impl<T> CoreExport<T> {
254 #[allow(missing_docs, reason = "self-describing function")]
255 pub fn map_index<U>(self, f: impl FnOnce(T) -> U) -> CoreExport<U> {
256 CoreExport {
257 instance: self.instance,
258 item: match self.item {
259 ExportItem::Index(i) => ExportItem::Index(f(i)),
260 ExportItem::Name(s) => ExportItem::Name(s),
261 },
262 }
263 }
264}
265
266#[derive(Clone, PartialEq, Eq, Hash)]
268#[allow(missing_docs, reason = "self-describing fields")]
269pub enum Trampoline {
270 LowerImport {
271 import: RuntimeImportIndex,
272 options: CanonicalOptions,
273 lower_ty: TypeFuncIndex,
274 },
275 Transcoder {
276 op: Transcode,
277 from: MemoryId,
278 from64: bool,
279 to: MemoryId,
280 to64: bool,
281 },
282 AlwaysTrap,
283 ResourceNew(TypeResourceTableIndex),
284 ResourceRep(TypeResourceTableIndex),
285 ResourceDrop(TypeResourceTableIndex),
286 TaskBackpressure {
287 instance: RuntimeComponentInstanceIndex,
288 },
289 TaskReturn,
290 TaskWait {
291 instance: RuntimeComponentInstanceIndex,
292 async_: bool,
293 memory: MemoryId,
294 },
295 TaskPoll {
296 instance: RuntimeComponentInstanceIndex,
297 async_: bool,
298 memory: MemoryId,
299 },
300 TaskYield {
301 async_: bool,
302 },
303 SubtaskDrop {
304 instance: RuntimeComponentInstanceIndex,
305 },
306 StreamNew {
307 ty: TypeStreamTableIndex,
308 },
309 StreamRead {
310 ty: TypeStreamTableIndex,
311 options: CanonicalOptions,
312 },
313 StreamWrite {
314 ty: TypeStreamTableIndex,
315 options: CanonicalOptions,
316 },
317 StreamCancelRead {
318 ty: TypeStreamTableIndex,
319 async_: bool,
320 },
321 StreamCancelWrite {
322 ty: TypeStreamTableIndex,
323 async_: bool,
324 },
325 StreamCloseReadable {
326 ty: TypeStreamTableIndex,
327 },
328 StreamCloseWritable {
329 ty: TypeStreamTableIndex,
330 },
331 FutureNew {
332 ty: TypeFutureTableIndex,
333 },
334 FutureRead {
335 ty: TypeFutureTableIndex,
336 options: CanonicalOptions,
337 },
338 FutureWrite {
339 ty: TypeFutureTableIndex,
340 options: CanonicalOptions,
341 },
342 FutureCancelRead {
343 ty: TypeFutureTableIndex,
344 async_: bool,
345 },
346 FutureCancelWrite {
347 ty: TypeFutureTableIndex,
348 async_: bool,
349 },
350 FutureCloseReadable {
351 ty: TypeFutureTableIndex,
352 },
353 FutureCloseWritable {
354 ty: TypeFutureTableIndex,
355 },
356 ErrorContextNew {
357 ty: TypeComponentLocalErrorContextTableIndex,
358 options: CanonicalOptions,
359 },
360 ErrorContextDebugMessage {
361 ty: TypeComponentLocalErrorContextTableIndex,
362 options: CanonicalOptions,
363 },
364 ErrorContextDrop {
365 ty: TypeComponentLocalErrorContextTableIndex,
366 },
367 ResourceTransferOwn,
368 ResourceTransferBorrow,
369 ResourceEnterCall,
370 ResourceExitCall,
371 AsyncEnterCall,
372 AsyncExitCall {
373 callback: Option<CallbackId>,
374 post_return: Option<PostReturnId>,
375 },
376 FutureTransfer,
377 StreamTransfer,
378 ErrorContextTransfer,
379}
380
381#[derive(Copy, Clone, Hash, Eq, PartialEq)]
382#[allow(missing_docs, reason = "self-describing fields")]
383pub struct FutureInfo {
384 pub instance: RuntimeComponentInstanceIndex,
385 pub payload_type: Option<InterfaceType>,
386}
387
388#[derive(Copy, Clone, Hash, Eq, PartialEq)]
389#[allow(missing_docs, reason = "self-describing fields")]
390pub struct StreamInfo {
391 pub instance: RuntimeComponentInstanceIndex,
392 pub payload_type: InterfaceType,
393}
394
395#[derive(Clone, Hash, Eq, PartialEq)]
397#[allow(missing_docs, reason = "self-describing fields")]
398pub struct CanonicalOptions {
399 pub instance: RuntimeComponentInstanceIndex,
400 pub string_encoding: StringEncoding,
401 pub memory: Option<MemoryId>,
402 pub realloc: Option<ReallocId>,
403 pub callback: Option<CallbackId>,
404 pub post_return: Option<PostReturnId>,
405 pub async_: bool,
406}
407
408#[allow(missing_docs, reason = "self-describing fields")]
410pub struct Resource {
411 pub rep: WasmValType,
412 pub dtor: Option<CoreDef>,
413 pub instance: RuntimeComponentInstanceIndex,
414}
415
416pub struct Intern<K: EntityRef, V> {
422 intern_map: HashMap<V, K>,
423 key_map: PrimaryMap<K, V>,
424}
425
426impl<K, V> Intern<K, V>
427where
428 K: EntityRef,
429{
430 pub fn push(&mut self, value: V) -> K
437 where
438 V: Hash + Eq + Clone,
439 {
440 *self
441 .intern_map
442 .entry(value.clone())
443 .or_insert_with(|| self.key_map.push(value))
444 }
445
446 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
448 self.key_map.iter()
449 }
450}
451
452impl<K: EntityRef, V> Index<K> for Intern<K, V> {
453 type Output = V;
454 fn index(&self, key: K) -> &V {
455 &self.key_map[key]
456 }
457}
458
459impl<K: EntityRef, V> Default for Intern<K, V> {
460 fn default() -> Intern<K, V> {
461 Intern {
462 intern_map: HashMap::new(),
463 key_map: PrimaryMap::new(),
464 }
465 }
466}
467
468impl ComponentDfg {
469 pub fn finish(
472 self,
473 wasmtime_types: &mut ComponentTypesBuilder,
474 wasmparser_types: wasmparser::types::TypesRef<'_>,
475 ) -> Result<ComponentTranslation> {
476 let mut linearize = LinearizeDfg {
477 dfg: &self,
478 initializers: Vec::new(),
479 runtime_memories: Default::default(),
480 runtime_post_return: Default::default(),
481 runtime_reallocs: Default::default(),
482 runtime_callbacks: Default::default(),
483 runtime_instances: Default::default(),
484 num_lowerings: 0,
485 trampolines: Default::default(),
486 trampoline_defs: Default::default(),
487 trampoline_map: Default::default(),
488 };
489
490 for item in linearize.dfg.side_effects.iter() {
494 linearize.side_effect(item);
495 }
496
497 let mut export_items = PrimaryMap::new();
500 let mut exports = NameMap::default();
501 for (name, export) in self.exports.iter() {
502 let export =
503 linearize.export(export, &mut export_items, wasmtime_types, wasmparser_types)?;
504 exports.insert(name, &mut NameMapNoIntern, false, export)?;
505 }
506
507 Ok(ComponentTranslation {
512 trampolines: linearize.trampoline_defs,
513 component: Component {
514 exports,
515 export_items,
516 initializers: linearize.initializers,
517 trampolines: linearize.trampolines,
518 num_lowerings: linearize.num_lowerings,
519
520 num_runtime_memories: linearize.runtime_memories.len() as u32,
521 num_runtime_post_returns: linearize.runtime_post_return.len() as u32,
522 num_runtime_reallocs: linearize.runtime_reallocs.len() as u32,
523 num_runtime_callbacks: linearize.runtime_callbacks.len() as u32,
524 num_runtime_instances: linearize.runtime_instances.len() as u32,
525 imports: self.imports,
526 import_types: self.import_types,
527 num_runtime_component_instances: self.num_runtime_component_instances,
528 num_resource_tables: self.num_resource_tables,
529 num_future_tables: self.num_future_tables,
530 num_stream_tables: self.num_stream_tables,
531 num_error_context_tables: self.num_error_context_tables,
532 num_resources: (self.resources.len() + self.imported_resources.len()) as u32,
533 imported_resources: self.imported_resources,
534 defined_resource_instances: self
535 .resources
536 .iter()
537 .map(|(_, r)| r.instance)
538 .collect(),
539 },
540 })
541 }
542
543 pub fn resource_index(&self, defined: DefinedResourceIndex) -> ResourceIndex {
546 ResourceIndex::from_u32(defined.as_u32() + (self.imported_resources.len() as u32))
547 }
548}
549
550struct LinearizeDfg<'a> {
551 dfg: &'a ComponentDfg,
552 initializers: Vec<GlobalInitializer>,
553 trampolines: PrimaryMap<TrampolineIndex, ModuleInternedTypeIndex>,
554 trampoline_defs: PrimaryMap<TrampolineIndex, info::Trampoline>,
555 trampoline_map: HashMap<TrampolineIndex, TrampolineIndex>,
556 runtime_memories: HashMap<MemoryId, RuntimeMemoryIndex>,
557 runtime_reallocs: HashMap<ReallocId, RuntimeReallocIndex>,
558 runtime_callbacks: HashMap<CallbackId, RuntimeCallbackIndex>,
559 runtime_post_return: HashMap<PostReturnId, RuntimePostReturnIndex>,
560 runtime_instances: HashMap<RuntimeInstance, RuntimeInstanceIndex>,
561 num_lowerings: u32,
562}
563
564#[derive(Copy, Clone, Hash, Eq, PartialEq)]
565enum RuntimeInstance {
566 Normal(InstanceId),
567 Adapter(AdapterModuleId),
568}
569
570impl LinearizeDfg<'_> {
571 fn side_effect(&mut self, effect: &SideEffect) {
572 match effect {
573 SideEffect::Instance(i) => {
574 self.instantiate(*i, &self.dfg.instances[*i]);
575 }
576 SideEffect::Resource(i) => {
577 self.resource(*i, &self.dfg.resources[*i]);
578 }
579 }
580 }
581
582 fn instantiate(&mut self, instance: InstanceId, args: &Instance) {
583 log::trace!("creating instance {instance:?}");
584 let instantiation = match args {
585 Instance::Static(index, args) => InstantiateModule::Static(
586 *index,
587 args.iter().map(|def| self.core_def(def)).collect(),
588 ),
589 Instance::Import(index, args) => InstantiateModule::Import(
590 *index,
591 args.iter()
592 .map(|(module, values)| {
593 let values = values
594 .iter()
595 .map(|(name, def)| (name.clone(), self.core_def(def)))
596 .collect();
597 (module.clone(), values)
598 })
599 .collect(),
600 ),
601 };
602 let index = RuntimeInstanceIndex::new(self.runtime_instances.len());
603 self.initializers
604 .push(GlobalInitializer::InstantiateModule(instantiation));
605 let prev = self
606 .runtime_instances
607 .insert(RuntimeInstance::Normal(instance), index);
608 assert!(prev.is_none());
609 }
610
611 fn resource(&mut self, index: DefinedResourceIndex, resource: &Resource) {
612 let dtor = resource.dtor.as_ref().map(|dtor| self.core_def(dtor));
613 self.initializers
614 .push(GlobalInitializer::Resource(info::Resource {
615 dtor,
616 index,
617 rep: resource.rep,
618 instance: resource.instance,
619 }));
620 }
621
622 fn export(
623 &mut self,
624 export: &Export,
625 items: &mut PrimaryMap<ExportIndex, info::Export>,
626 wasmtime_types: &mut ComponentTypesBuilder,
627 wasmparser_types: wasmparser::types::TypesRef<'_>,
628 ) -> Result<ExportIndex> {
629 let item = match export {
630 Export::LiftedFunction { ty, func, options } => {
631 let func = self.core_def(func);
632 let options = self.options(options);
633 info::Export::LiftedFunction {
634 ty: *ty,
635 func,
636 options,
637 }
638 }
639 Export::ModuleStatic { ty, index } => info::Export::ModuleStatic {
640 ty: wasmtime_types.convert_module(wasmparser_types, *ty)?,
641 index: *index,
642 },
643 Export::ModuleImport { ty, import } => info::Export::ModuleImport {
644 ty: *ty,
645 import: *import,
646 },
647 Export::Instance { ty, exports } => info::Export::Instance {
648 ty: *ty,
649 exports: {
650 let mut map = NameMap::default();
651 for (name, export) in exports {
652 let export =
653 self.export(export, items, wasmtime_types, wasmparser_types)?;
654 map.insert(name, &mut NameMapNoIntern, false, export)?;
655 }
656 map
657 },
658 },
659 Export::Type(def) => info::Export::Type(*def),
660 };
661 Ok(items.push(item))
662 }
663
664 fn options(&mut self, options: &CanonicalOptions) -> info::CanonicalOptions {
665 let memory = options.memory.map(|mem| self.runtime_memory(mem));
666 let realloc = options.realloc.map(|mem| self.runtime_realloc(mem));
667 let callback = options.callback.map(|mem| self.runtime_callback(mem));
668 let post_return = options.post_return.map(|mem| self.runtime_post_return(mem));
669 info::CanonicalOptions {
670 instance: options.instance,
671 string_encoding: options.string_encoding,
672 memory,
673 realloc,
674 callback,
675 post_return,
676 async_: options.async_,
677 }
678 }
679
680 fn runtime_memory(&mut self, mem: MemoryId) -> RuntimeMemoryIndex {
681 self.intern(
682 mem,
683 |me| &mut me.runtime_memories,
684 |me, mem| me.core_export(&me.dfg.memories[mem]),
685 |index, export| GlobalInitializer::ExtractMemory(ExtractMemory { index, export }),
686 )
687 }
688
689 fn runtime_realloc(&mut self, realloc: ReallocId) -> RuntimeReallocIndex {
690 self.intern(
691 realloc,
692 |me| &mut me.runtime_reallocs,
693 |me, realloc| me.core_def(&me.dfg.reallocs[realloc]),
694 |index, def| GlobalInitializer::ExtractRealloc(ExtractRealloc { index, def }),
695 )
696 }
697
698 fn runtime_callback(&mut self, callback: CallbackId) -> RuntimeCallbackIndex {
699 self.intern(
700 callback,
701 |me| &mut me.runtime_callbacks,
702 |me, callback| me.core_def(&me.dfg.callbacks[callback]),
703 |index, def| GlobalInitializer::ExtractCallback(ExtractCallback { index, def }),
704 )
705 }
706
707 fn runtime_post_return(&mut self, post_return: PostReturnId) -> RuntimePostReturnIndex {
708 self.intern(
709 post_return,
710 |me| &mut me.runtime_post_return,
711 |me, post_return| me.core_def(&me.dfg.post_returns[post_return]),
712 |index, def| GlobalInitializer::ExtractPostReturn(ExtractPostReturn { index, def }),
713 )
714 }
715
716 fn core_def(&mut self, def: &CoreDef) -> info::CoreDef {
717 match def {
718 CoreDef::Export(e) => info::CoreDef::Export(self.core_export(e)),
719 CoreDef::InstanceFlags(i) => info::CoreDef::InstanceFlags(*i),
720 CoreDef::Adapter(id) => info::CoreDef::Export(self.adapter(*id)),
721 CoreDef::Trampoline(index) => info::CoreDef::Trampoline(self.trampoline(*index)),
722 }
723 }
724
725 fn trampoline(&mut self, index: TrampolineIndex) -> TrampolineIndex {
726 if let Some(idx) = self.trampoline_map.get(&index) {
727 return *idx;
728 }
729 let (signature, trampoline) = &self.dfg.trampolines[index];
730 let trampoline = match trampoline {
731 Trampoline::LowerImport {
732 import,
733 options,
734 lower_ty,
735 } => {
736 let index = LoweredIndex::from_u32(self.num_lowerings);
737 self.num_lowerings += 1;
738 self.initializers.push(GlobalInitializer::LowerImport {
739 index,
740 import: *import,
741 });
742 info::Trampoline::LowerImport {
743 index,
744 options: self.options(options),
745 lower_ty: *lower_ty,
746 }
747 }
748 Trampoline::Transcoder {
749 op,
750 from,
751 from64,
752 to,
753 to64,
754 } => info::Trampoline::Transcoder {
755 op: *op,
756 from: self.runtime_memory(*from),
757 from64: *from64,
758 to: self.runtime_memory(*to),
759 to64: *to64,
760 },
761 Trampoline::AlwaysTrap => info::Trampoline::AlwaysTrap,
762 Trampoline::ResourceNew(ty) => info::Trampoline::ResourceNew(*ty),
763 Trampoline::ResourceDrop(ty) => info::Trampoline::ResourceDrop(*ty),
764 Trampoline::ResourceRep(ty) => info::Trampoline::ResourceRep(*ty),
765 Trampoline::TaskBackpressure { instance } => info::Trampoline::TaskBackpressure {
766 instance: *instance,
767 },
768 Trampoline::TaskReturn => info::Trampoline::TaskReturn,
769 Trampoline::TaskWait {
770 instance,
771 async_,
772 memory,
773 } => info::Trampoline::TaskWait {
774 instance: *instance,
775 async_: *async_,
776 memory: self.runtime_memory(*memory),
777 },
778 Trampoline::TaskPoll {
779 instance,
780 async_,
781 memory,
782 } => info::Trampoline::TaskPoll {
783 instance: *instance,
784 async_: *async_,
785 memory: self.runtime_memory(*memory),
786 },
787 Trampoline::TaskYield { async_ } => info::Trampoline::TaskYield { async_: *async_ },
788 Trampoline::SubtaskDrop { instance } => info::Trampoline::SubtaskDrop {
789 instance: *instance,
790 },
791 Trampoline::StreamNew { ty } => info::Trampoline::StreamNew { ty: *ty },
792 Trampoline::StreamRead { ty, options } => info::Trampoline::StreamRead {
793 ty: *ty,
794 options: self.options(options),
795 },
796 Trampoline::StreamWrite { ty, options } => info::Trampoline::StreamWrite {
797 ty: *ty,
798 options: self.options(options),
799 },
800 Trampoline::StreamCancelRead { ty, async_ } => info::Trampoline::StreamCancelRead {
801 ty: *ty,
802 async_: *async_,
803 },
804 Trampoline::StreamCancelWrite { ty, async_ } => info::Trampoline::StreamCancelWrite {
805 ty: *ty,
806 async_: *async_,
807 },
808 Trampoline::StreamCloseReadable { ty } => {
809 info::Trampoline::StreamCloseReadable { ty: *ty }
810 }
811 Trampoline::StreamCloseWritable { ty } => {
812 info::Trampoline::StreamCloseWritable { ty: *ty }
813 }
814 Trampoline::FutureNew { ty } => info::Trampoline::FutureNew { ty: *ty },
815 Trampoline::FutureRead { ty, options } => info::Trampoline::FutureRead {
816 ty: *ty,
817 options: self.options(options),
818 },
819 Trampoline::FutureWrite { ty, options } => info::Trampoline::FutureWrite {
820 ty: *ty,
821 options: self.options(options),
822 },
823 Trampoline::FutureCancelRead { ty, async_ } => info::Trampoline::FutureCancelRead {
824 ty: *ty,
825 async_: *async_,
826 },
827 Trampoline::FutureCancelWrite { ty, async_ } => info::Trampoline::FutureCancelWrite {
828 ty: *ty,
829 async_: *async_,
830 },
831 Trampoline::FutureCloseReadable { ty } => {
832 info::Trampoline::FutureCloseReadable { ty: *ty }
833 }
834 Trampoline::FutureCloseWritable { ty } => {
835 info::Trampoline::FutureCloseWritable { ty: *ty }
836 }
837 Trampoline::ErrorContextNew { ty, options } => info::Trampoline::ErrorContextNew {
838 ty: *ty,
839 options: self.options(options),
840 },
841 Trampoline::ErrorContextDebugMessage { ty, options } => {
842 info::Trampoline::ErrorContextDebugMessage {
843 ty: *ty,
844 options: self.options(options),
845 }
846 }
847 Trampoline::ErrorContextDrop { ty } => info::Trampoline::ErrorContextDrop { ty: *ty },
848 Trampoline::ResourceTransferOwn => info::Trampoline::ResourceTransferOwn,
849 Trampoline::ResourceTransferBorrow => info::Trampoline::ResourceTransferBorrow,
850 Trampoline::ResourceEnterCall => info::Trampoline::ResourceEnterCall,
851 Trampoline::ResourceExitCall => info::Trampoline::ResourceExitCall,
852 Trampoline::AsyncEnterCall => info::Trampoline::AsyncEnterCall,
853 Trampoline::AsyncExitCall {
854 callback,
855 post_return,
856 } => info::Trampoline::AsyncExitCall {
857 callback: callback.map(|v| self.runtime_callback(v)),
858 post_return: post_return.map(|v| self.runtime_post_return(v)),
859 },
860 Trampoline::FutureTransfer => info::Trampoline::FutureTransfer,
861 Trampoline::StreamTransfer => info::Trampoline::StreamTransfer,
862 Trampoline::ErrorContextTransfer => info::Trampoline::ErrorContextTransfer,
863 };
864 let i1 = self.trampolines.push(*signature);
865 let i2 = self.trampoline_defs.push(trampoline);
866 assert_eq!(i1, i2);
867 self.trampoline_map.insert(index, i1);
868 i1
869 }
870
871 fn core_export<T>(&mut self, export: &CoreExport<T>) -> info::CoreExport<T>
872 where
873 T: Clone,
874 {
875 let instance = export.instance;
876 log::trace!("referencing export of {instance:?}");
877 info::CoreExport {
878 instance: self.runtime_instances[&RuntimeInstance::Normal(instance)],
879 item: export.item.clone(),
880 }
881 }
882
883 fn adapter(&mut self, adapter: AdapterId) -> info::CoreExport<EntityIndex> {
884 let (adapter_module, entity_index) = self.dfg.adapter_partitionings[adapter];
885
886 let instance = self.adapter_module(adapter_module);
890
891 info::CoreExport {
893 instance,
894 item: ExportItem::Index(entity_index),
895 }
896 }
897
898 fn adapter_module(&mut self, adapter_module: AdapterModuleId) -> RuntimeInstanceIndex {
899 self.intern(
900 RuntimeInstance::Adapter(adapter_module),
901 |me| &mut me.runtime_instances,
902 |me, _| {
903 log::debug!("instantiating {adapter_module:?}");
904 let (module_index, args) = &me.dfg.adapter_modules[adapter_module];
905 let args = args.iter().map(|arg| me.core_def(arg)).collect();
906 let instantiate = InstantiateModule::Static(*module_index, args);
907 GlobalInitializer::InstantiateModule(instantiate)
908 },
909 |_, init| init,
910 )
911 }
912
913 fn intern<K, V, T>(
928 &mut self,
929 key: K,
930 map: impl Fn(&mut Self) -> &mut HashMap<K, V>,
931 generate: impl FnOnce(&mut Self, K) -> T,
932 init: impl FnOnce(V, T) -> GlobalInitializer,
933 ) -> V
934 where
935 K: Hash + Eq + Copy,
936 V: EntityRef,
937 {
938 if let Some(val) = map(self).get(&key) {
939 return *val;
940 }
941 let tmp = generate(self, key);
942 let index = V::new(map(self).len());
943 self.initializers.push(init(index, tmp));
944 let prev = map(self).insert(key, index);
945 assert!(prev.is_none());
946 index
947 }
948}