wasmtime_environ/component/info.rs
1// General runtime type-information about a component.
2//
3// Compared to the `Module` structure for core wasm this type is pretty
4// significantly different. The core wasm `Module` corresponds roughly 1-to-1
5// with the structure of the wasm module itself, but instead a `Component` is
6// more of a "compiled" representation where the original structure is thrown
7// away in favor of a more optimized representation. The considerations for this
8// are:
9//
10// * This representation of a `Component` avoids the need to create a
11// `PrimaryMap` of some form for each of the index spaces within a component.
12// This is less so an issue about allocations and more so that this information
13// generally just isn't needed any time after instantiation. Avoiding creating
14// these altogether helps components be lighter weight at runtime and
15// additionally accelerates instantiation.
16//
17// * Components can have arbitrary nesting and internally do instantiations via
18// string-based matching. At instantiation-time, though, we want to do as few
19// string-lookups in hash maps as much as we can since they're significantly
20// slower than index-based lookups. Furthermore while the imports of a
21// component are not statically known the rest of the structure of the
22// component is statically known which enables the ability to track precisely
23// what matches up where and do all the string lookups at compile time instead
24// of instantiation time.
25//
26// * Finally by performing this sort of dataflow analysis we are capable of
27// identifying what adapters need trampolines for compilation or fusion. For
28// example this tracks when host functions are lowered which enables us to
29// enumerate what trampolines are required to enter into a component.
30// Additionally (eventually) this will track all of the "fused" adapter
31// functions where a function from one component instance is lifted and then
32// lowered into another component instance. Altogether this enables Wasmtime's
33// AOT-compilation where the artifact from compilation is suitable for use in
34// running the component without the support of a compiler at runtime.
35//
36// Note, however, that the current design of `Component` has fundamental
37// limitations which it was not designed for. For example there is no feasible
38// way to implement either importing or exporting a component itself from the
39// root component. Currently we rely on the ability to have static knowledge of
40// what's coming from the host which at this point can only be either functions
41// or core wasm modules. Additionally one flat list of initializers for a
42// component are produced instead of initializers-per-component which would
43// otherwise be required to export a component from a component.
44//
45// For now this tradeoff is made as it aligns well with the intended use case
46// for components in an embedding. This may need to be revisited though if the
47// requirements of embeddings change over time.
48
49use crate::component::*;
50use crate::prelude::*;
51use crate::{EntityIndex, PrimaryMap, WasmValType};
52use serde_derive::{Deserialize, Serialize};
53use wasmtime_types::ModuleInternedTypeIndex;
54
55/// Metadata as a result of compiling a component.
56pub struct ComponentTranslation {
57 /// Serializable information that will be emitted into the final artifact.
58 pub component: Component,
59
60 /// Metadata about required trampolines and what they're supposed to do.
61 pub trampolines: PrimaryMap<TrampolineIndex, Trampoline>,
62}
63
64/// Run-time-type-information about a `Component`, its structure, and how to
65/// instantiate it.
66///
67/// This type is intended to mirror the `Module` type in this crate which
68/// provides all the runtime information about the structure of a module and
69/// how it works.
70///
71/// NB: Lots of the component model is not yet implemented in the runtime so
72/// this is going to undergo a lot of churn.
73#[derive(Default, Debug, Serialize, Deserialize)]
74pub struct Component {
75 /// A list of typed values that this component imports.
76 ///
77 /// Note that each name is given an `ImportIndex` here for the next map to
78 /// refer back to.
79 pub import_types: PrimaryMap<ImportIndex, (String, TypeDef)>,
80
81 /// A list of "flattened" imports that are used by this instance.
82 ///
83 /// This import map represents extracting imports, as necessary, from the
84 /// general imported types by this component. The flattening here refers to
85 /// extracting items from instances. Currently the flat imports are either a
86 /// host function or a core wasm module.
87 ///
88 /// For example if `ImportIndex(0)` pointed to an instance then this import
89 /// map represent extracting names from that map, for example extracting an
90 /// exported module or an exported function.
91 ///
92 /// Each import item is keyed by a `RuntimeImportIndex` which is referred to
93 /// by types below whenever something refers to an import. The value for
94 /// each `RuntimeImportIndex` in this map is the `ImportIndex` for where
95 /// this items comes from (which can be associated with a name above in the
96 /// `import_types` array) as well as the list of export names if
97 /// `ImportIndex` refers to an instance. The export names array represents
98 /// recursively fetching names within an instance.
99 //
100 // TODO: this is probably a lot of `String` storage and may be something
101 // that needs optimization in the future. For example instead of lots of
102 // different `String` allocations this could instead be a pointer/length
103 // into one large string allocation for the entire component. Alternatively
104 // strings could otherwise be globally intern'd via some other mechanism to
105 // avoid `Linker`-specific intern-ing plus intern-ing here. Unsure what the
106 // best route is or whether such an optimization is even necessary here.
107 pub imports: PrimaryMap<RuntimeImportIndex, (ImportIndex, Vec<String>)>,
108
109 /// This component's own root exports from the component itself.
110 pub exports: NameMap<String, ExportIndex>,
111
112 /// All exports of this component and exported instances of this component.
113 ///
114 /// This is indexed by `ExportIndex` for fast lookup and `Export::Instance`
115 /// will refer back into this list.
116 pub export_items: PrimaryMap<ExportIndex, Export>,
117
118 /// Initializers that must be processed when instantiating this component.
119 ///
120 /// This list of initializers does not correspond directly to the component
121 /// itself. The general goal with this is that the recursive nature of
122 /// components is "flattened" with an array like this which is a linear
123 /// sequence of instructions of how to instantiate a component. This will
124 /// have instantiations, for example, in addition to entries which
125 /// initialize `VMComponentContext` fields with previously instantiated
126 /// instances.
127 pub initializers: Vec<GlobalInitializer>,
128
129 /// The number of runtime instances (maximum `RuntimeInstanceIndex`) created
130 /// when instantiating this component.
131 pub num_runtime_instances: u32,
132
133 /// Same as `num_runtime_instances`, but for `RuntimeComponentInstanceIndex`
134 /// instead.
135 pub num_runtime_component_instances: u32,
136
137 /// The number of runtime memories (maximum `RuntimeMemoryIndex`) needed to
138 /// instantiate this component.
139 ///
140 /// Note that this many memories will be stored in the `VMComponentContext`
141 /// and each memory is intended to be unique (e.g. the same memory isn't
142 /// stored in two different locations).
143 pub num_runtime_memories: u32,
144
145 /// The number of runtime reallocs (maximum `RuntimeReallocIndex`) needed to
146 /// instantiate this component.
147 ///
148 /// Note that this many function pointers will be stored in the
149 /// `VMComponentContext`.
150 pub num_runtime_reallocs: u32,
151
152 /// Same as `num_runtime_reallocs`, but for post-return functions.
153 pub num_runtime_post_returns: u32,
154
155 /// WebAssembly type signature of all trampolines.
156 pub trampolines: PrimaryMap<TrampolineIndex, ModuleInternedTypeIndex>,
157
158 /// The number of lowered host functions (maximum `LoweredIndex`) needed to
159 /// instantiate this component.
160 pub num_lowerings: u32,
161
162 /// Maximal number of tables that required at runtime for resource-related
163 /// information in this component.
164 pub num_resource_tables: usize,
165
166 /// Total number of resources both imported and defined within this
167 /// component.
168 pub num_resources: u32,
169
170 /// Metadata about imported resources and where they are within the runtime
171 /// imports array.
172 ///
173 /// This map is only as large as the number of imported resources.
174 pub imported_resources: PrimaryMap<ResourceIndex, RuntimeImportIndex>,
175
176 /// Metadata about which component instances defined each resource within
177 /// this component.
178 ///
179 /// This is used to determine which set of instance flags are inspected when
180 /// testing reentrance.
181 pub defined_resource_instances: PrimaryMap<DefinedResourceIndex, RuntimeComponentInstanceIndex>,
182}
183
184impl Component {
185 /// Attempts to convert a resource index into a defined index.
186 ///
187 /// Returns `None` if `idx` is for an imported resource in this component or
188 /// `Some` if it's a locally defined resource.
189 pub fn defined_resource_index(&self, idx: ResourceIndex) -> Option<DefinedResourceIndex> {
190 let idx = idx
191 .as_u32()
192 .checked_sub(self.imported_resources.len() as u32)?;
193 Some(DefinedResourceIndex::from_u32(idx))
194 }
195
196 /// Converts a defined resource index to a component-local resource index
197 /// which includes all imports.
198 pub fn resource_index(&self, idx: DefinedResourceIndex) -> ResourceIndex {
199 ResourceIndex::from_u32(self.imported_resources.len() as u32 + idx.as_u32())
200 }
201}
202
203/// GlobalInitializer instructions to get processed when instantiating a component
204///
205/// The variants of this enum are processed during the instantiation phase of
206/// a component in-order from front-to-back. These are otherwise emitted as a
207/// component is parsed and read and translated.
208//
209// FIXME(#2639) if processing this list is ever a bottleneck we could
210// theoretically use cranelift to compile an initialization function which
211// performs all of these duties for us and skips the overhead of interpreting
212// all of these instructions.
213#[derive(Debug, Serialize, Deserialize)]
214pub enum GlobalInitializer {
215 /// A core wasm module is being instantiated.
216 ///
217 /// This will result in a new core wasm instance being created, which may
218 /// involve running the `start` function of the instance as well if it's
219 /// specified. This largely delegates to the same standard instantiation
220 /// process as the rest of the core wasm machinery already uses.
221 InstantiateModule(InstantiateModule),
222
223 /// A host function is being lowered, creating a core wasm function.
224 ///
225 /// This initializer entry is intended to be used to fill out the
226 /// `VMComponentContext` and information about this lowering such as the
227 /// cranelift-compiled trampoline function pointer, the host function
228 /// pointer the trampoline calls, and the canonical ABI options.
229 LowerImport {
230 /// The index of the lowered function that's being created.
231 ///
232 /// This is guaranteed to be the `n`th `LowerImport` instruction
233 /// if the index is `n`.
234 index: LoweredIndex,
235
236 /// The index of the imported host function that is being lowered.
237 ///
238 /// It's guaranteed that this `RuntimeImportIndex` points to a function.
239 import: RuntimeImportIndex,
240 },
241
242 /// A core wasm linear memory is going to be saved into the
243 /// `VMComponentContext`.
244 ///
245 /// This instruction indicates that the `index`th core wasm linear memory
246 /// needs to be extracted from the `export` specified, a pointer to a
247 /// previously created module instance, and stored into the
248 /// `VMComponentContext` at the `index` specified. This lowering is then
249 /// used in the future by pointers from `CanonicalOptions`.
250 ExtractMemory(ExtractMemory),
251
252 /// Same as `ExtractMemory`, except it's extracting a function pointer to be
253 /// used as a `realloc` function.
254 ExtractRealloc(ExtractRealloc),
255
256 /// Same as `ExtractMemory`, except it's extracting a function pointer to be
257 /// used as a `post-return` function.
258 ExtractPostReturn(ExtractPostReturn),
259
260 /// Declares a new defined resource within this component.
261 ///
262 /// Contains information about the destructor, for example.
263 Resource(Resource),
264}
265
266/// Metadata for extraction of a memory of what's being extracted and where it's
267/// going.
268#[derive(Debug, Serialize, Deserialize)]
269pub struct ExtractMemory {
270 /// The index of the memory being defined.
271 pub index: RuntimeMemoryIndex,
272 /// Where this memory is being extracted from.
273 pub export: CoreExport<MemoryIndex>,
274}
275
276/// Same as `ExtractMemory` but for the `realloc` canonical option.
277#[derive(Debug, Serialize, Deserialize)]
278pub struct ExtractRealloc {
279 /// The index of the realloc being defined.
280 pub index: RuntimeReallocIndex,
281 /// Where this realloc is being extracted from.
282 pub def: CoreDef,
283}
284
285/// Same as `ExtractMemory` but for the `post-return` canonical option.
286#[derive(Debug, Serialize, Deserialize)]
287pub struct ExtractPostReturn {
288 /// The index of the post-return being defined.
289 pub index: RuntimePostReturnIndex,
290 /// Where this post-return is being extracted from.
291 pub def: CoreDef,
292}
293
294/// Different methods of instantiating a core wasm module.
295#[derive(Debug, Serialize, Deserialize)]
296pub enum InstantiateModule {
297 /// A module defined within this component is being instantiated.
298 ///
299 /// Note that this is distinct from the case of imported modules because the
300 /// order of imports required is statically known and can be pre-calculated
301 /// to avoid string lookups related to names at runtime, represented by the
302 /// flat list of arguments here.
303 Static(StaticModuleIndex, Box<[CoreDef]>),
304
305 /// An imported module is being instantiated.
306 ///
307 /// This is similar to `Upvar` but notably the imports are provided as a
308 /// two-level named map since import resolution order needs to happen at
309 /// runtime.
310 Import(
311 RuntimeImportIndex,
312 IndexMap<String, IndexMap<String, CoreDef>>,
313 ),
314}
315
316/// Definition of a core wasm item and where it can come from within a
317/// component.
318///
319/// Note that this is sort of a result of data-flow-like analysis on a component
320/// during compile time of the component itself. References to core wasm items
321/// are "compiled" to either referring to a previous instance or to some sort of
322/// lowered host import.
323#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
324pub enum CoreDef {
325 /// This item refers to an export of a previously instantiated core wasm
326 /// instance.
327 Export(CoreExport<EntityIndex>),
328 /// This is a reference to a wasm global which represents the
329 /// runtime-managed flags for a wasm instance.
330 InstanceFlags(RuntimeComponentInstanceIndex),
331 /// This is a reference to a Cranelift-generated trampoline which is
332 /// described in the `trampolines` array.
333 Trampoline(TrampolineIndex),
334}
335
336impl<T> From<CoreExport<T>> for CoreDef
337where
338 EntityIndex: From<T>,
339{
340 fn from(export: CoreExport<T>) -> CoreDef {
341 CoreDef::Export(export.map_index(|i| i.into()))
342 }
343}
344
345/// Identifier of an exported item from a core WebAssembly module instance.
346///
347/// Note that the `T` here is the index type for exports which can be
348/// identified by index. The `T` is monomorphized with types like
349/// [`EntityIndex`] or [`FuncIndex`].
350#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
351pub struct CoreExport<T> {
352 /// The instance that this item is located within.
353 ///
354 /// Note that this is intended to index the `instances` map within a
355 /// component. It's validated ahead of time that all instance pointers
356 /// refer only to previously-created instances.
357 pub instance: RuntimeInstanceIndex,
358
359 /// The item that this export is referencing, either by name or by index.
360 pub item: ExportItem<T>,
361}
362
363impl<T> CoreExport<T> {
364 /// Maps the index type `T` to another type `U` if this export item indeed
365 /// refers to an index `T`.
366 pub fn map_index<U>(self, f: impl FnOnce(T) -> U) -> CoreExport<U> {
367 CoreExport {
368 instance: self.instance,
369 item: match self.item {
370 ExportItem::Index(i) => ExportItem::Index(f(i)),
371 ExportItem::Name(s) => ExportItem::Name(s),
372 },
373 }
374 }
375}
376
377/// An index at which to find an item within a runtime instance.
378#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
379pub enum ExportItem<T> {
380 /// An exact index that the target can be found at.
381 ///
382 /// This is used where possible to avoid name lookups at runtime during the
383 /// instantiation process. This can only be used on instances where the
384 /// module was statically known at compile time, however.
385 Index(T),
386
387 /// An item which is identified by a name, so at runtime we need to
388 /// perform a name lookup to determine the index that the item is located
389 /// at.
390 ///
391 /// This is used for instantiations of imported modules, for example, since
392 /// the precise shape of the module is not known.
393 Name(String),
394}
395
396/// Possible exports from a component.
397#[derive(Debug, Clone, Serialize, Deserialize)]
398pub enum Export {
399 /// A lifted function being exported which is an adaptation of a core wasm
400 /// function.
401 LiftedFunction {
402 /// The component function type of the function being created.
403 ty: TypeFuncIndex,
404 /// Which core WebAssembly export is being lifted.
405 func: CoreDef,
406 /// Any options, if present, associated with this lifting.
407 options: CanonicalOptions,
408 },
409 /// A module defined within this component is exported.
410 ModuleStatic {
411 /// The type of this module
412 ty: TypeModuleIndex,
413 /// Which module this is referring to.
414 index: StaticModuleIndex,
415 },
416 /// A module imported into this component is exported.
417 ModuleImport {
418 /// Module type index
419 ty: TypeModuleIndex,
420 /// Module runtime import index
421 import: RuntimeImportIndex,
422 },
423 /// A nested instance is being exported which has recursively defined
424 /// `Export` items.
425 Instance {
426 /// Instance type index, if such is assigned
427 ty: TypeComponentInstanceIndex,
428 /// Instance export map
429 exports: NameMap<String, ExportIndex>,
430 },
431 /// An exported type from a component or instance, currently only
432 /// informational.
433 Type(TypeDef),
434}
435
436/// Canonical ABI options associated with a lifted or lowered function.
437#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct CanonicalOptions {
439 /// The component instance that this bundle was associated with.
440 pub instance: RuntimeComponentInstanceIndex,
441
442 /// The encoding used for strings.
443 pub string_encoding: StringEncoding,
444
445 /// The memory used by these options, if specified.
446 pub memory: Option<RuntimeMemoryIndex>,
447
448 /// The realloc function used by these options, if specified.
449 pub realloc: Option<RuntimeReallocIndex>,
450
451 /// The post-return function used by these options, if specified.
452 pub post_return: Option<RuntimePostReturnIndex>,
453}
454
455/// Possible encodings of strings within the component model.
456//
457// Note that the `repr(u8)` is load-bearing here since this is used in an
458// `extern "C" fn()` function argument which is called from cranelift-compiled
459// code so we must know the representation of this.
460#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
461#[allow(missing_docs)]
462#[repr(u8)]
463pub enum StringEncoding {
464 Utf8,
465 Utf16,
466 CompactUtf16,
467}
468
469/// Possible transcoding operations that must be provided by the host.
470///
471/// Note that each transcoding operation may have a unique signature depending
472/// on the precise operation.
473#[allow(missing_docs)]
474#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
475pub enum Transcode {
476 Copy(FixedEncoding),
477 Latin1ToUtf16,
478 Latin1ToUtf8,
479 Utf16ToCompactProbablyUtf16,
480 Utf16ToCompactUtf16,
481 Utf16ToLatin1,
482 Utf16ToUtf8,
483 Utf8ToCompactUtf16,
484 Utf8ToLatin1,
485 Utf8ToUtf16,
486}
487
488impl Transcode {
489 /// Get this transcoding's symbol fragment.
490 pub fn symbol_fragment(&self) -> &'static str {
491 match self {
492 Transcode::Copy(x) => match x {
493 FixedEncoding::Utf8 => "copy_utf8",
494 FixedEncoding::Utf16 => "copy_utf16",
495 FixedEncoding::Latin1 => "copy_latin1",
496 },
497 Transcode::Latin1ToUtf16 => "latin1_to_utf16",
498 Transcode::Latin1ToUtf8 => "latin1_to_utf8",
499 Transcode::Utf16ToCompactProbablyUtf16 => "utf16_to_compact_probably_utf16",
500 Transcode::Utf16ToCompactUtf16 => "utf16_to_compact_utf16",
501 Transcode::Utf16ToLatin1 => "utf16_to_latin1",
502 Transcode::Utf16ToUtf8 => "utf16_to_utf8",
503 Transcode::Utf8ToCompactUtf16 => "utf8_to_compact_utf16",
504 Transcode::Utf8ToLatin1 => "utf8_to_latin1",
505 Transcode::Utf8ToUtf16 => "utf8_to_utf16",
506 }
507 }
508
509 /// Returns a human-readable description for this transcoding operation.
510 pub fn desc(&self) -> &'static str {
511 match self {
512 Transcode::Copy(FixedEncoding::Utf8) => "utf8-to-utf8",
513 Transcode::Copy(FixedEncoding::Utf16) => "utf16-to-utf16",
514 Transcode::Copy(FixedEncoding::Latin1) => "latin1-to-latin1",
515 Transcode::Latin1ToUtf16 => "latin1-to-utf16",
516 Transcode::Latin1ToUtf8 => "latin1-to-utf8",
517 Transcode::Utf16ToCompactProbablyUtf16 => "utf16-to-compact-probably-utf16",
518 Transcode::Utf16ToCompactUtf16 => "utf16-to-compact-utf16",
519 Transcode::Utf16ToLatin1 => "utf16-to-latin1",
520 Transcode::Utf16ToUtf8 => "utf16-to-utf8",
521 Transcode::Utf8ToCompactUtf16 => "utf8-to-compact-utf16",
522 Transcode::Utf8ToLatin1 => "utf8-to-latin1",
523 Transcode::Utf8ToUtf16 => "utf8-to-utf16",
524 }
525 }
526}
527
528#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
529#[allow(missing_docs)]
530pub enum FixedEncoding {
531 Utf8,
532 Utf16,
533 Latin1,
534}
535
536impl FixedEncoding {
537 /// Returns the byte width of unit loads/stores for this encoding, for
538 /// example the unit length is multiplied by this return value to get the
539 /// byte width of a string.
540 pub fn width(&self) -> u8 {
541 match self {
542 FixedEncoding::Utf8 => 1,
543 FixedEncoding::Utf16 => 2,
544 FixedEncoding::Latin1 => 1,
545 }
546 }
547}
548
549/// Description of a new resource declared in a `GlobalInitializer::Resource`
550/// variant.
551///
552/// This will have the effect of initializing runtime state for this resource,
553/// namely the destructor is fetched and stored.
554#[derive(Debug, Serialize, Deserialize)]
555pub struct Resource {
556 /// The local index of the resource being defined.
557 pub index: DefinedResourceIndex,
558 /// Core wasm representation of this resource.
559 pub rep: WasmValType,
560 /// Optionally-specified destructor and where it comes from.
561 pub dtor: Option<CoreDef>,
562 /// Which component instance this resource logically belongs to.
563 pub instance: RuntimeComponentInstanceIndex,
564}
565
566/// A list of all possible trampolines that may be required to compile a
567/// component completely.
568///
569/// These trampolines are used often as core wasm definitions and require
570/// Cranelift support to generate these functions. Each trampoline serves a
571/// different purpose for implementing bits and pieces of the component model.
572///
573/// All trampolines have a core wasm function signature associated with them
574/// which is stored in the `Component::trampolines` array.
575///
576/// Note that this type does not implement `Serialize` or `Deserialize` and
577/// that's intentional as this isn't stored in the final compilation artifact.
578pub enum Trampoline {
579 /// Description of a lowered import used in conjunction with
580 /// `GlobalInitializer::LowerImport`.
581 LowerImport {
582 /// The runtime lowering state that this trampoline will access.
583 index: LoweredIndex,
584
585 /// The type of the function that is being lowered, as perceived by the
586 /// component doing the lowering.
587 lower_ty: TypeFuncIndex,
588
589 /// The canonical ABI options used when lowering this function specified
590 /// in the original component.
591 options: CanonicalOptions,
592 },
593
594 /// Information about a string transcoding function required by an adapter
595 /// module.
596 ///
597 /// A transcoder is used when strings are passed between adapter modules,
598 /// optionally changing string encodings at the same time. The transcoder is
599 /// implemented in a few different layers:
600 ///
601 /// * Each generated adapter module has some glue around invoking the
602 /// transcoder represented by this item. This involves bounds-checks and
603 /// handling `realloc` for example.
604 /// * Each transcoder gets a cranelift-generated trampoline which has the
605 /// appropriate signature for the adapter module in question. Existence of
606 /// this initializer indicates that this should be compiled by Cranelift.
607 /// * The cranelift-generated trampoline will invoke a "transcoder libcall"
608 /// which is implemented natively in Rust that has a signature independent
609 /// of memory64 configuration options for example.
610 Transcoder {
611 /// The transcoding operation being performed.
612 op: Transcode,
613 /// The linear memory that the string is being read from.
614 from: RuntimeMemoryIndex,
615 /// Whether or not the source linear memory is 64-bit or not.
616 from64: bool,
617 /// The linear memory that the string is being written to.
618 to: RuntimeMemoryIndex,
619 /// Whether or not the destination linear memory is 64-bit or not.
620 to64: bool,
621 },
622
623 /// A small adapter which simply traps, used for degenerate lift/lower
624 /// combinations.
625 AlwaysTrap,
626
627 /// A `resource.new` intrinsic which will inject a new resource into the
628 /// table specified.
629 ResourceNew(TypeResourceTableIndex),
630
631 /// Same as `ResourceNew`, but for the `resource.rep` intrinsic.
632 ResourceRep(TypeResourceTableIndex),
633
634 /// Same as `ResourceNew`, but for the `resource.drop` intrinsic.
635 ResourceDrop(TypeResourceTableIndex),
636
637 /// An intrinsic used by FACT-generated modules which will transfer an owned
638 /// resource from one table to another. Used in component-to-component
639 /// adapter trampolines.
640 ResourceTransferOwn,
641
642 /// Same as `ResourceTransferOwn` but for borrows.
643 ResourceTransferBorrow,
644
645 /// An intrinsic used by FACT-generated modules which indicates that a call
646 /// is being entered and resource-related metadata needs to be configured.
647 ///
648 /// Note that this is currently only invoked when borrowed resources are
649 /// detected, otherwise this is "optimized out".
650 ResourceEnterCall,
651
652 /// Same as `ResourceEnterCall` except for when exiting a call.
653 ResourceExitCall,
654}
655
656impl Trampoline {
657 /// Returns the name to use for the symbol of this trampoline in the final
658 /// compiled artifact
659 pub fn symbol_name(&self) -> String {
660 use Trampoline::*;
661 match self {
662 LowerImport { index, .. } => {
663 format!("component-lower-import[{}]", index.as_u32())
664 }
665 Transcoder {
666 op, from64, to64, ..
667 } => {
668 let op = op.symbol_fragment();
669 let from = if *from64 { "64" } else { "32" };
670 let to = if *to64 { "64" } else { "32" };
671 format!("component-transcode-{op}-m{from}-m{to}")
672 }
673 AlwaysTrap => format!("component-always-trap"),
674 ResourceNew(i) => format!("component-resource-new[{}]", i.as_u32()),
675 ResourceRep(i) => format!("component-resource-rep[{}]", i.as_u32()),
676 ResourceDrop(i) => format!("component-resource-drop[{}]", i.as_u32()),
677 ResourceTransferOwn => format!("component-resource-transfer-own"),
678 ResourceTransferBorrow => format!("component-resource-transfer-borrow"),
679 ResourceEnterCall => format!("component-resource-enter-call"),
680 ResourceExitCall => format!("component-resource-exit-call"),
681 }
682 }
683}