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, ModuleInternedTypeIndex, PrimaryMap, WasmValType};
52use cranelift_entity::packed_option::PackedOption;
53use serde_derive::{Deserialize, Serialize};
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 tables (maximum `RuntimeTableIndex`) needed to
146 /// instantiate this component. See notes on `num_runtime_memories`.
147 pub num_runtime_tables: u32,
148
149 /// The number of runtime reallocs (maximum `RuntimeReallocIndex`) needed to
150 /// instantiate this component.
151 ///
152 /// Note that this many function pointers will be stored in the
153 /// `VMComponentContext`.
154 pub num_runtime_reallocs: u32,
155
156 /// The number of runtime async callbacks (maximum `RuntimeCallbackIndex`)
157 /// needed to instantiate this component.
158 pub num_runtime_callbacks: u32,
159
160 /// Same as `num_runtime_reallocs`, but for post-return functions.
161 pub num_runtime_post_returns: u32,
162
163 /// WebAssembly type signature of all trampolines.
164 pub trampolines: PrimaryMap<TrampolineIndex, ModuleInternedTypeIndex>,
165
166 /// A map from a `UnsafeIntrinsic::index()` to that intrinsic's
167 /// module-interned type.
168 pub unsafe_intrinsics: [PackedOption<ModuleInternedTypeIndex>; UnsafeIntrinsic::len() as usize],
169
170 /// The number of lowered host functions (maximum `LoweredIndex`) needed to
171 /// instantiate this component.
172 pub num_lowerings: u32,
173
174 /// Total number of resources both imported and defined within this
175 /// component.
176 pub num_resources: u32,
177
178 /// Maximal number of tables required at runtime for future-related
179 /// information in this component.
180 pub num_future_tables: usize,
181
182 /// Maximal number of tables required at runtime for stream-related
183 /// information in this component.
184 pub num_stream_tables: usize,
185
186 /// Maximal number of tables required at runtime for error-context-related
187 /// information in this component.
188 pub num_error_context_tables: usize,
189
190 /// Metadata about imported resources and where they are within the runtime
191 /// imports array.
192 ///
193 /// This map is only as large as the number of imported resources.
194 pub imported_resources: PrimaryMap<ResourceIndex, RuntimeImportIndex>,
195
196 /// Metadata about which component instances defined each resource within
197 /// this component.
198 ///
199 /// This is used to determine which set of instance flags are inspected when
200 /// testing reentrance.
201 pub defined_resource_instances: PrimaryMap<DefinedResourceIndex, RuntimeComponentInstanceIndex>,
202
203 /// All canonical options used by this component. Stored as a table here
204 /// from index-to-options so the options can be consulted at runtime.
205 pub options: PrimaryMap<OptionsIndex, CanonicalOptions>,
206}
207
208impl Component {
209 /// Attempts to convert a resource index into a defined index.
210 ///
211 /// Returns `None` if `idx` is for an imported resource in this component or
212 /// `Some` if it's a locally defined resource.
213 pub fn defined_resource_index(&self, idx: ResourceIndex) -> Option<DefinedResourceIndex> {
214 let idx = idx
215 .as_u32()
216 .checked_sub(self.imported_resources.len() as u32)?;
217 Some(DefinedResourceIndex::from_u32(idx))
218 }
219
220 /// Converts a defined resource index to a component-local resource index
221 /// which includes all imports.
222 pub fn resource_index(&self, idx: DefinedResourceIndex) -> ResourceIndex {
223 ResourceIndex::from_u32(self.imported_resources.len() as u32 + idx.as_u32())
224 }
225}
226
227/// GlobalInitializer instructions to get processed when instantiating a
228/// component.
229///
230/// The variants of this enum are processed during the instantiation phase of a
231/// component in-order from front-to-back. These are otherwise emitted as a
232/// component is parsed and read and translated.
233//
234// FIXME(#2639) if processing this list is ever a bottleneck we could
235// theoretically use cranelift to compile an initialization function which
236// performs all of these duties for us and skips the overhead of interpreting
237// all of these instructions.
238#[derive(Debug, Serialize, Deserialize)]
239pub enum GlobalInitializer {
240 /// A core wasm module is being instantiated.
241 ///
242 /// This will result in a new core wasm instance being created, which may
243 /// involve running the `start` function of the instance as well if it's
244 /// specified. This largely delegates to the same standard instantiation
245 /// process as the rest of the core wasm machinery already uses.
246 ///
247 /// The second field represents the component instance to which the module
248 /// belongs, if applicable. This will be `None` for adapter modules.
249 InstantiateModule(InstantiateModule, Option<RuntimeComponentInstanceIndex>),
250
251 /// A host function is being lowered, creating a core wasm function.
252 ///
253 /// This initializer entry is intended to be used to fill out the
254 /// `VMComponentContext` and information about this lowering such as the
255 /// cranelift-compiled trampoline function pointer, the host function
256 /// pointer the trampoline calls, and the canonical ABI options.
257 LowerImport {
258 /// The index of the lowered function that's being created.
259 ///
260 /// This is guaranteed to be the `n`th `LowerImport` instruction
261 /// if the index is `n`.
262 index: LoweredIndex,
263
264 /// The index of the imported host function that is being lowered.
265 ///
266 /// It's guaranteed that this `RuntimeImportIndex` points to a function.
267 import: RuntimeImportIndex,
268 },
269
270 /// A core wasm linear memory is going to be saved into the
271 /// `VMComponentContext`.
272 ///
273 /// This instruction indicates that a core wasm linear memory needs to be
274 /// extracted from the `export` and stored into the `VMComponentContext` at
275 /// the `index` specified. This lowering is then used in the future by
276 /// pointers from `CanonicalOptions`.
277 ExtractMemory(ExtractMemory),
278
279 /// Same as `ExtractMemory`, except it's extracting a function pointer to be
280 /// used as a `realloc` function.
281 ExtractRealloc(ExtractRealloc),
282
283 /// Same as `ExtractMemory`, except it's extracting a function pointer to be
284 /// used as an async `callback` function.
285 ExtractCallback(ExtractCallback),
286
287 /// Same as `ExtractMemory`, except it's extracting a function pointer to be
288 /// used as a `post-return` function.
289 ExtractPostReturn(ExtractPostReturn),
290
291 /// A core wasm table is going to be saved into the `VMComponentContext`.
292 ///
293 /// This instruction indicates that s core wasm table needs to be extracted
294 /// from its `export` and stored into the `VMComponentContext` at the
295 /// `index` specified. During this extraction, we will also capture the
296 /// table's containing instance pointer to access the table at runtime. This
297 /// extraction is useful for `thread.spawn-indirect`.
298 ExtractTable(ExtractTable),
299
300 /// Declares a new defined resource within this component.
301 ///
302 /// Contains information about the destructor, for example.
303 Resource(Resource),
304}
305
306/// Metadata for extraction of a memory; contains what's being extracted (the
307/// memory at `export`) and where it's going (the `index` within a
308/// `VMComponentContext`).
309#[derive(Debug, Serialize, Deserialize)]
310pub struct ExtractMemory {
311 /// The index of the memory being defined.
312 pub index: RuntimeMemoryIndex,
313 /// Where this memory is being extracted from.
314 pub export: CoreExport<MemoryIndex>,
315}
316
317/// Same as `ExtractMemory` but for the `realloc` canonical option.
318#[derive(Debug, Serialize, Deserialize)]
319pub struct ExtractRealloc {
320 /// The index of the realloc being defined.
321 pub index: RuntimeReallocIndex,
322 /// Where this realloc is being extracted from.
323 pub def: CoreDef,
324}
325
326/// Same as `ExtractMemory` but for the `callback` canonical option.
327#[derive(Debug, Serialize, Deserialize)]
328pub struct ExtractCallback {
329 /// The index of the callback being defined.
330 pub index: RuntimeCallbackIndex,
331 /// Where this callback is being extracted from.
332 pub def: CoreDef,
333}
334
335/// Same as `ExtractMemory` but for the `post-return` canonical option.
336#[derive(Debug, Serialize, Deserialize)]
337pub struct ExtractPostReturn {
338 /// The index of the post-return being defined.
339 pub index: RuntimePostReturnIndex,
340 /// Where this post-return is being extracted from.
341 pub def: CoreDef,
342}
343
344/// Metadata for extraction of a table.
345#[derive(Debug, Serialize, Deserialize)]
346pub struct ExtractTable {
347 /// The index of the table being defined in a `VMComponentContext`.
348 pub index: RuntimeTableIndex,
349 /// Where this table is being extracted from.
350 pub export: CoreExport<TableIndex>,
351}
352
353/// Different methods of instantiating a core wasm module.
354#[derive(Debug, Serialize, Deserialize)]
355pub enum InstantiateModule {
356 /// A module defined within this component is being instantiated.
357 ///
358 /// Note that this is distinct from the case of imported modules because the
359 /// order of imports required is statically known and can be pre-calculated
360 /// to avoid string lookups related to names at runtime, represented by the
361 /// flat list of arguments here.
362 Static(StaticModuleIndex, Box<[CoreDef]>),
363
364 /// An imported module is being instantiated.
365 ///
366 /// This is similar to `Upvar` but notably the imports are provided as a
367 /// two-level named map since import resolution order needs to happen at
368 /// runtime.
369 Import(
370 RuntimeImportIndex,
371 IndexMap<String, IndexMap<String, CoreDef>>,
372 ),
373}
374
375/// Definition of a core wasm item and where it can come from within a
376/// component.
377///
378/// Note that this is sort of a result of data-flow-like analysis on a component
379/// during compile time of the component itself. References to core wasm items
380/// are "compiled" to either referring to a previous instance or to some sort of
381/// lowered host import.
382#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
383pub enum CoreDef {
384 /// This item refers to an export of a previously instantiated core wasm
385 /// instance.
386 Export(CoreExport<EntityIndex>),
387 /// This is a reference to a wasm global which represents the
388 /// runtime-managed flags for a wasm instance.
389 InstanceFlags(RuntimeComponentInstanceIndex),
390 /// This is a reference to a Cranelift-generated trampoline which is
391 /// described in the `trampolines` array.
392 Trampoline(TrampolineIndex),
393 /// An intrinsic for compile-time builtins.
394 UnsafeIntrinsic(UnsafeIntrinsic),
395 /// Reference to a wasm global which represents a runtime-managed boolean
396 /// indicating whether the currently-running task may perform a blocking
397 /// operation.
398 TaskMayBlock,
399}
400
401impl<T> From<CoreExport<T>> for CoreDef
402where
403 EntityIndex: From<T>,
404{
405 fn from(export: CoreExport<T>) -> CoreDef {
406 CoreDef::Export(export.map_index(|i| i.into()))
407 }
408}
409
410/// Identifier of an exported item from a core WebAssembly module instance.
411///
412/// Note that the `T` here is the index type for exports which can be
413/// identified by index. The `T` is monomorphized with types like
414/// [`EntityIndex`] or [`FuncIndex`].
415#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
416pub struct CoreExport<T> {
417 /// The instance that this item is located within.
418 ///
419 /// Note that this is intended to index the `instances` map within a
420 /// component. It's validated ahead of time that all instance pointers
421 /// refer only to previously-created instances.
422 pub instance: RuntimeInstanceIndex,
423
424 /// The item that this export is referencing, either by name or by index.
425 pub item: ExportItem<T>,
426}
427
428impl<T> CoreExport<T> {
429 /// Maps the index type `T` to another type `U` if this export item indeed
430 /// refers to an index `T`.
431 pub fn map_index<U>(self, f: impl FnOnce(T) -> U) -> CoreExport<U> {
432 CoreExport {
433 instance: self.instance,
434 item: match self.item {
435 ExportItem::Index(i) => ExportItem::Index(f(i)),
436 ExportItem::Name(s) => ExportItem::Name(s),
437 },
438 }
439 }
440}
441
442/// An index at which to find an item within a runtime instance.
443#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
444pub enum ExportItem<T> {
445 /// An exact index that the target can be found at.
446 ///
447 /// This is used where possible to avoid name lookups at runtime during the
448 /// instantiation process. This can only be used on instances where the
449 /// module was statically known at compile time, however.
450 Index(T),
451
452 /// An item which is identified by a name, so at runtime we need to
453 /// perform a name lookup to determine the index that the item is located
454 /// at.
455 ///
456 /// This is used for instantiations of imported modules, for example, since
457 /// the precise shape of the module is not known.
458 Name(String),
459}
460
461/// Possible exports from a component.
462#[derive(Debug, Clone, Serialize, Deserialize)]
463pub enum Export {
464 /// A lifted function being exported which is an adaptation of a core wasm
465 /// function.
466 LiftedFunction {
467 /// The component function type of the function being created.
468 ty: TypeFuncIndex,
469 /// Which core WebAssembly export is being lifted.
470 func: CoreDef,
471 /// Any options, if present, associated with this lifting.
472 options: OptionsIndex,
473 },
474 /// A module defined within this component is exported.
475 ModuleStatic {
476 /// The type of this module
477 ty: TypeModuleIndex,
478 /// Which module this is referring to.
479 index: StaticModuleIndex,
480 },
481 /// A module imported into this component is exported.
482 ModuleImport {
483 /// Module type index
484 ty: TypeModuleIndex,
485 /// Module runtime import index
486 import: RuntimeImportIndex,
487 },
488 /// A nested instance is being exported which has recursively defined
489 /// `Export` items.
490 Instance {
491 /// Instance type index, if such is assigned
492 ty: TypeComponentInstanceIndex,
493 /// Instance export map
494 exports: NameMap<String, ExportIndex>,
495 },
496 /// An exported type from a component or instance, currently only
497 /// informational.
498 Type(TypeDef),
499}
500
501#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
502/// Data is stored in a linear memory.
503pub struct LinearMemoryOptions {
504 /// The memory used by these options, if specified.
505 pub memory: Option<RuntimeMemoryIndex>,
506 /// The realloc function used by these options, if specified.
507 pub realloc: Option<RuntimeReallocIndex>,
508}
509
510/// The data model for objects that are not unboxed in locals.
511#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
512pub enum CanonicalOptionsDataModel {
513 /// Data is stored in GC objects.
514 Gc {},
515
516 /// Data is stored in a linear memory.
517 LinearMemory(LinearMemoryOptions),
518}
519
520/// Canonical ABI options associated with a lifted or lowered function.
521#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct CanonicalOptions {
523 /// The component instance that this bundle was associated with.
524 pub instance: RuntimeComponentInstanceIndex,
525
526 /// The encoding used for strings.
527 pub string_encoding: StringEncoding,
528
529 /// The async callback function used by these options, if specified.
530 pub callback: Option<RuntimeCallbackIndex>,
531
532 /// The post-return function used by these options, if specified.
533 pub post_return: Option<RuntimePostReturnIndex>,
534
535 /// Whether to use the async ABI for lifting or lowering.
536 pub async_: bool,
537
538 /// Whether or not this function can consume a task cancellation
539 /// notification.
540 pub cancellable: bool,
541
542 /// The core function type that is being lifted from / lowered to.
543 pub core_type: ModuleInternedTypeIndex,
544
545 /// The data model (GC objects or linear memory) used with these canonical
546 /// options.
547 pub data_model: CanonicalOptionsDataModel,
548}
549
550impl CanonicalOptions {
551 /// Returns the memory referred to by these options, if any.
552 pub fn memory(&self) -> Option<RuntimeMemoryIndex> {
553 match self.data_model {
554 CanonicalOptionsDataModel::Gc {} => None,
555 CanonicalOptionsDataModel::LinearMemory(opts) => opts.memory,
556 }
557 }
558}
559
560/// Possible encodings of strings within the component model.
561#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
562#[expect(missing_docs, reason = "self-describing variants")]
563pub enum StringEncoding {
564 Utf8,
565 Utf16,
566 CompactUtf16,
567}
568
569impl StringEncoding {
570 /// Decodes the `u8` provided back into a `StringEncoding`, if it's valid.
571 pub fn from_u8(val: u8) -> Option<StringEncoding> {
572 if val == StringEncoding::Utf8 as u8 {
573 return Some(StringEncoding::Utf8);
574 }
575 if val == StringEncoding::Utf16 as u8 {
576 return Some(StringEncoding::Utf16);
577 }
578 if val == StringEncoding::CompactUtf16 as u8 {
579 return Some(StringEncoding::CompactUtf16);
580 }
581 None
582 }
583}
584
585/// Possible transcoding operations that must be provided by the host.
586///
587/// Note that each transcoding operation may have a unique signature depending
588/// on the precise operation.
589#[expect(missing_docs, reason = "self-describing variants")]
590#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
591pub enum Transcode {
592 Copy(FixedEncoding),
593 Latin1ToUtf16,
594 Latin1ToUtf8,
595 Utf16ToCompactProbablyUtf16,
596 Utf16ToCompactUtf16,
597 Utf16ToLatin1,
598 Utf16ToUtf8,
599 Utf8ToCompactUtf16,
600 Utf8ToLatin1,
601 Utf8ToUtf16,
602}
603
604impl Transcode {
605 /// Get this transcoding's symbol fragment.
606 pub fn symbol_fragment(&self) -> &'static str {
607 match self {
608 Transcode::Copy(x) => match x {
609 FixedEncoding::Utf8 => "copy_utf8",
610 FixedEncoding::Utf16 => "copy_utf16",
611 FixedEncoding::Latin1 => "copy_latin1",
612 },
613 Transcode::Latin1ToUtf16 => "latin1_to_utf16",
614 Transcode::Latin1ToUtf8 => "latin1_to_utf8",
615 Transcode::Utf16ToCompactProbablyUtf16 => "utf16_to_compact_probably_utf16",
616 Transcode::Utf16ToCompactUtf16 => "utf16_to_compact_utf16",
617 Transcode::Utf16ToLatin1 => "utf16_to_latin1",
618 Transcode::Utf16ToUtf8 => "utf16_to_utf8",
619 Transcode::Utf8ToCompactUtf16 => "utf8_to_compact_utf16",
620 Transcode::Utf8ToLatin1 => "utf8_to_latin1",
621 Transcode::Utf8ToUtf16 => "utf8_to_utf16",
622 }
623 }
624
625 /// Returns a human-readable description for this transcoding operation.
626 pub fn desc(&self) -> &'static str {
627 match self {
628 Transcode::Copy(FixedEncoding::Utf8) => "utf8-to-utf8",
629 Transcode::Copy(FixedEncoding::Utf16) => "utf16-to-utf16",
630 Transcode::Copy(FixedEncoding::Latin1) => "latin1-to-latin1",
631 Transcode::Latin1ToUtf16 => "latin1-to-utf16",
632 Transcode::Latin1ToUtf8 => "latin1-to-utf8",
633 Transcode::Utf16ToCompactProbablyUtf16 => "utf16-to-compact-probably-utf16",
634 Transcode::Utf16ToCompactUtf16 => "utf16-to-compact-utf16",
635 Transcode::Utf16ToLatin1 => "utf16-to-latin1",
636 Transcode::Utf16ToUtf8 => "utf16-to-utf8",
637 Transcode::Utf8ToCompactUtf16 => "utf8-to-compact-utf16",
638 Transcode::Utf8ToLatin1 => "utf8-to-latin1",
639 Transcode::Utf8ToUtf16 => "utf8-to-utf16",
640 }
641 }
642}
643
644#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
645#[expect(missing_docs, reason = "self-describing variants")]
646pub enum FixedEncoding {
647 Utf8,
648 Utf16,
649 Latin1,
650}
651
652impl FixedEncoding {
653 /// Returns the byte width of unit loads/stores for this encoding, for
654 /// example the unit length is multiplied by this return value to get the
655 /// byte width of a string.
656 pub fn width(&self) -> u8 {
657 match self {
658 FixedEncoding::Utf8 => 1,
659 FixedEncoding::Utf16 => 2,
660 FixedEncoding::Latin1 => 1,
661 }
662 }
663
664 /// Returns the alignment of strings using this encoding.
665 pub fn align(&self) -> u8 {
666 match self {
667 FixedEncoding::Utf8 => 1,
668 FixedEncoding::Utf16 => 2,
669 FixedEncoding::Latin1 => 2,
670 }
671 }
672}
673
674/// Description of a new resource declared in a `GlobalInitializer::Resource`
675/// variant.
676///
677/// This will have the effect of initializing runtime state for this resource,
678/// namely the destructor is fetched and stored.
679#[derive(Debug, Serialize, Deserialize)]
680pub struct Resource {
681 /// The local index of the resource being defined.
682 pub index: DefinedResourceIndex,
683 /// Core wasm representation of this resource.
684 pub rep: WasmValType,
685 /// Optionally-specified destructor and where it comes from.
686 pub dtor: Option<CoreDef>,
687 /// Which component instance this resource logically belongs to.
688 pub instance: RuntimeComponentInstanceIndex,
689}
690
691/// A list of all possible trampolines that may be required to compile a
692/// component completely.
693///
694/// These trampolines are used often as core wasm definitions and require
695/// Cranelift support to generate these functions. Each trampoline serves a
696/// different purpose for implementing bits and pieces of the component model.
697///
698/// All trampolines have a core wasm function signature associated with them
699/// which is stored in the `Component::trampolines` array.
700///
701/// Note that this type does not implement `Serialize` or `Deserialize` and
702/// that's intentional as this isn't stored in the final compilation artifact.
703#[derive(Debug)]
704pub enum Trampoline {
705 /// Description of a lowered import used in conjunction with
706 /// `GlobalInitializer::LowerImport`.
707 LowerImport {
708 /// The runtime lowering state that this trampoline will access.
709 index: LoweredIndex,
710
711 /// The type of the function that is being lowered, as perceived by the
712 /// component doing the lowering.
713 lower_ty: TypeFuncIndex,
714
715 /// The canonical ABI options used when lowering this function specified
716 /// in the original component.
717 options: OptionsIndex,
718 },
719
720 /// Information about a string transcoding function required by an adapter
721 /// module.
722 ///
723 /// A transcoder is used when strings are passed between adapter modules,
724 /// optionally changing string encodings at the same time. The transcoder is
725 /// implemented in a few different layers:
726 ///
727 /// * Each generated adapter module has some glue around invoking the
728 /// transcoder represented by this item. This involves bounds-checks and
729 /// handling `realloc` for example.
730 /// * Each transcoder gets a cranelift-generated trampoline which has the
731 /// appropriate signature for the adapter module in question. Existence of
732 /// this initializer indicates that this should be compiled by Cranelift.
733 /// * The cranelift-generated trampoline will invoke a "transcoder libcall"
734 /// which is implemented natively in Rust that has a signature independent
735 /// of memory64 configuration options for example.
736 Transcoder {
737 /// The transcoding operation being performed.
738 op: Transcode,
739 /// The linear memory that the string is being read from.
740 from: RuntimeMemoryIndex,
741 /// Whether or not the source linear memory is 64-bit or not.
742 from64: bool,
743 /// The linear memory that the string is being written to.
744 to: RuntimeMemoryIndex,
745 /// Whether or not the destination linear memory is 64-bit or not.
746 to64: bool,
747 },
748
749 /// A `resource.new` intrinsic which will inject a new resource into the
750 /// table specified.
751 ResourceNew {
752 /// The specific component instance which is calling the intrinsic.
753 instance: RuntimeComponentInstanceIndex,
754 /// The type of the resource.
755 ty: TypeResourceTableIndex,
756 },
757
758 /// Same as `ResourceNew`, but for the `resource.rep` intrinsic.
759 ResourceRep {
760 /// The specific component instance which is calling the intrinsic.
761 instance: RuntimeComponentInstanceIndex,
762 /// The type of the resource.
763 ty: TypeResourceTableIndex,
764 },
765
766 /// Same as `ResourceNew`, but for the `resource.drop` intrinsic.
767 ResourceDrop {
768 /// The specific component instance which is calling the intrinsic.
769 instance: RuntimeComponentInstanceIndex,
770 /// The type of the resource.
771 ty: TypeResourceTableIndex,
772 },
773
774 /// A `backpressure.inc` intrinsic.
775 BackpressureInc {
776 /// The specific component instance which is calling the intrinsic.
777 instance: RuntimeComponentInstanceIndex,
778 },
779
780 /// A `backpressure.dec` intrinsic.
781 BackpressureDec {
782 /// The specific component instance which is calling the intrinsic.
783 instance: RuntimeComponentInstanceIndex,
784 },
785
786 /// A `task.return` intrinsic, which returns a result to the caller of a
787 /// lifted export function. This allows the callee to continue executing
788 /// after returning a result.
789 TaskReturn {
790 /// The specific component instance which is calling the intrinsic.
791 instance: RuntimeComponentInstanceIndex,
792 /// Tuple representing the result types this intrinsic accepts.
793 results: TypeTupleIndex,
794 /// The canonical ABI options specified for this intrinsic.
795 options: OptionsIndex,
796 },
797
798 /// A `task.cancel` intrinsic, which acknowledges a `CANCELLED` event
799 /// delivered to a guest task previously created by a call to an async
800 /// export.
801 TaskCancel {
802 /// The specific component instance which is calling the intrinsic.
803 instance: RuntimeComponentInstanceIndex,
804 },
805
806 /// A `waitable-set.new` intrinsic.
807 WaitableSetNew {
808 /// The specific component instance which is calling the intrinsic.
809 instance: RuntimeComponentInstanceIndex,
810 },
811
812 /// A `waitable-set.wait` intrinsic, which waits for at least one
813 /// outstanding async task/stream/future to make progress, returning the
814 /// first such event.
815 WaitableSetWait {
816 /// The specific component instance which is calling the intrinsic.
817 instance: RuntimeComponentInstanceIndex,
818 /// Configuration options for this intrinsic call.
819 options: OptionsIndex,
820 },
821
822 /// A `waitable-set.poll` intrinsic, which checks whether any outstanding
823 /// async task/stream/future has made progress. Unlike `task.wait`, this
824 /// does not block and may return nothing if no such event has occurred.
825 WaitableSetPoll {
826 /// The specific component instance which is calling the intrinsic.
827 instance: RuntimeComponentInstanceIndex,
828 /// Configuration options for this intrinsic call.
829 options: OptionsIndex,
830 },
831
832 /// A `waitable-set.drop` intrinsic.
833 WaitableSetDrop {
834 /// The specific component instance which is calling the intrinsic.
835 instance: RuntimeComponentInstanceIndex,
836 },
837
838 /// A `waitable.join` intrinsic.
839 WaitableJoin {
840 /// The specific component instance which is calling the intrinsic.
841 instance: RuntimeComponentInstanceIndex,
842 },
843
844 /// A `thread.yield` intrinsic, which yields control to the host so that other
845 /// tasks are able to make progress, if any.
846 ThreadYield {
847 /// The specific component instance which is calling the intrinsic.
848 instance: RuntimeComponentInstanceIndex,
849 /// If `true`, indicates the caller instance may receive notification
850 /// of task cancellation.
851 cancellable: bool,
852 },
853
854 /// A `subtask.drop` intrinsic to drop a specified task which has completed.
855 SubtaskDrop {
856 /// The specific component instance which is calling the intrinsic.
857 instance: RuntimeComponentInstanceIndex,
858 },
859
860 /// A `subtask.cancel` intrinsic to drop an in-progress task.
861 SubtaskCancel {
862 /// The specific component instance which is calling the intrinsic.
863 instance: RuntimeComponentInstanceIndex,
864 /// If `false`, block until cancellation completes rather than return
865 /// `BLOCKED`.
866 async_: bool,
867 },
868
869 /// A `stream.new` intrinsic to create a new `stream` handle of the
870 /// specified type.
871 StreamNew {
872 /// The specific component instance which is calling the intrinsic.
873 instance: RuntimeComponentInstanceIndex,
874 /// The table index for the specific `stream` type and caller instance.
875 ty: TypeStreamTableIndex,
876 },
877
878 /// A `stream.read` intrinsic to read from a `stream` of the specified type.
879 StreamRead {
880 /// The specific component instance which is calling the intrinsic.
881 instance: RuntimeComponentInstanceIndex,
882 /// The table index for the specific `stream` type and caller instance.
883 ty: TypeStreamTableIndex,
884 /// Any options (e.g. string encoding) to use when storing values to
885 /// memory.
886 options: OptionsIndex,
887 },
888
889 /// A `stream.write` intrinsic to write to a `stream` of the specified type.
890 StreamWrite {
891 /// The specific component instance which is calling the intrinsic.
892 instance: RuntimeComponentInstanceIndex,
893 /// The table index for the specific `stream` type and caller instance.
894 ty: TypeStreamTableIndex,
895 /// Any options (e.g. string encoding) to use when storing values to
896 /// memory.
897 options: OptionsIndex,
898 },
899
900 /// A `stream.cancel-read` intrinsic to cancel an in-progress read from a
901 /// `stream` of the specified type.
902 StreamCancelRead {
903 /// The specific component instance which is calling the intrinsic.
904 instance: RuntimeComponentInstanceIndex,
905 /// The table index for the specific `stream` type and caller instance.
906 ty: TypeStreamTableIndex,
907 /// If `false`, block until cancellation completes rather than return
908 /// `BLOCKED`.
909 async_: bool,
910 },
911
912 /// A `stream.cancel-write` intrinsic to cancel an in-progress write from a
913 /// `stream` of the specified type.
914 StreamCancelWrite {
915 /// The specific component instance which is calling the intrinsic.
916 instance: RuntimeComponentInstanceIndex,
917 /// The table index for the specific `stream` type and caller instance.
918 ty: TypeStreamTableIndex,
919 /// If `false`, block until cancellation completes rather than return
920 /// `BLOCKED`.
921 async_: bool,
922 },
923
924 /// A `stream.drop-readable` intrinsic to drop the readable end of a
925 /// `stream` of the specified type.
926 StreamDropReadable {
927 /// The specific component instance which is calling the intrinsic.
928 instance: RuntimeComponentInstanceIndex,
929 /// The table index for the specific `stream` type and caller instance.
930 ty: TypeStreamTableIndex,
931 },
932
933 /// A `stream.drop-writable` intrinsic to drop the writable end of a
934 /// `stream` of the specified type.
935 StreamDropWritable {
936 /// The specific component instance which is calling the intrinsic.
937 instance: RuntimeComponentInstanceIndex,
938 /// The table index for the specific `stream` type and caller instance.
939 ty: TypeStreamTableIndex,
940 },
941
942 /// A `future.new` intrinsic to create a new `future` handle of the
943 /// specified type.
944 FutureNew {
945 /// The specific component instance which is calling the intrinsic.
946 instance: RuntimeComponentInstanceIndex,
947 /// The table index for the specific `future` type and caller instance.
948 ty: TypeFutureTableIndex,
949 },
950
951 /// A `future.read` intrinsic to read from a `future` of the specified type.
952 FutureRead {
953 /// The specific component instance which is calling the intrinsic.
954 instance: RuntimeComponentInstanceIndex,
955 /// The table index for the specific `future` type and caller instance.
956 ty: TypeFutureTableIndex,
957 /// Any options (e.g. string encoding) to use when storing values to
958 /// memory.
959 options: OptionsIndex,
960 },
961
962 /// A `future.write` intrinsic to write to a `future` of the specified type.
963 FutureWrite {
964 /// The specific component instance which is calling the intrinsic.
965 instance: RuntimeComponentInstanceIndex,
966 /// The table index for the specific `future` type and caller instance.
967 ty: TypeFutureTableIndex,
968 /// Any options (e.g. string encoding) to use when storing values to
969 /// memory.
970 options: OptionsIndex,
971 },
972
973 /// A `future.cancel-read` intrinsic to cancel an in-progress read from a
974 /// `future` of the specified type.
975 FutureCancelRead {
976 /// The specific component instance which is calling the intrinsic.
977 instance: RuntimeComponentInstanceIndex,
978 /// The table index for the specific `future` type and caller instance.
979 ty: TypeFutureTableIndex,
980 /// If `false`, block until cancellation completes rather than return
981 /// `BLOCKED`.
982 async_: bool,
983 },
984
985 /// A `future.cancel-write` intrinsic to cancel an in-progress write from a
986 /// `future` of the specified type.
987 FutureCancelWrite {
988 /// The specific component instance which is calling the intrinsic.
989 instance: RuntimeComponentInstanceIndex,
990 /// The table index for the specific `future` type and caller instance.
991 ty: TypeFutureTableIndex,
992 /// If `false`, block until cancellation completes rather than return
993 /// `BLOCKED`.
994 async_: bool,
995 },
996
997 /// A `future.drop-readable` intrinsic to drop the readable end of a
998 /// `future` of the specified type.
999 FutureDropReadable {
1000 /// The specific component instance which is calling the intrinsic.
1001 instance: RuntimeComponentInstanceIndex,
1002 /// The table index for the specific `future` type and caller instance.
1003 ty: TypeFutureTableIndex,
1004 },
1005
1006 /// A `future.drop-writable` intrinsic to drop the writable end of a
1007 /// `future` of the specified type.
1008 FutureDropWritable {
1009 /// The specific component instance which is calling the intrinsic.
1010 instance: RuntimeComponentInstanceIndex,
1011 /// The table index for the specific `future` type and caller instance.
1012 ty: TypeFutureTableIndex,
1013 },
1014
1015 /// A `error-context.new` intrinsic to create a new `error-context` with a
1016 /// specified debug message.
1017 ErrorContextNew {
1018 /// The specific component instance which is calling the intrinsic.
1019 instance: RuntimeComponentInstanceIndex,
1020 /// The table index for the `error-context` type in the caller instance.
1021 ty: TypeComponentLocalErrorContextTableIndex,
1022 /// String encoding, memory, etc. to use when loading debug message.
1023 options: OptionsIndex,
1024 },
1025
1026 /// A `error-context.debug-message` intrinsic to get the debug message for a
1027 /// specified `error-context`.
1028 ///
1029 /// Note that the debug message might not necessarily match what was passed
1030 /// to `error.new`.
1031 ErrorContextDebugMessage {
1032 /// The specific component instance which is calling the intrinsic.
1033 instance: RuntimeComponentInstanceIndex,
1034 /// The table index for the `error-context` type in the caller instance.
1035 ty: TypeComponentLocalErrorContextTableIndex,
1036 /// String encoding, memory, etc. to use when storing debug message.
1037 options: OptionsIndex,
1038 },
1039
1040 /// A `error-context.drop` intrinsic to drop a specified `error-context`.
1041 ErrorContextDrop {
1042 /// The specific component instance which is calling the intrinsic.
1043 instance: RuntimeComponentInstanceIndex,
1044 /// The table index for the `error-context` type in the caller instance.
1045 ty: TypeComponentLocalErrorContextTableIndex,
1046 },
1047
1048 /// An intrinsic used by FACT-generated modules which will transfer an owned
1049 /// resource from one table to another. Used in component-to-component
1050 /// adapter trampolines.
1051 ResourceTransferOwn,
1052
1053 /// Same as `ResourceTransferOwn` but for borrows.
1054 ResourceTransferBorrow,
1055
1056 /// An intrinsic used by FACT-generated modules to prepare a call involving
1057 /// an async-lowered import and/or an async-lifted export.
1058 PrepareCall {
1059 /// The memory used to verify that the memory specified for the
1060 /// `task.return` that is called at runtime matches the one specified in
1061 /// the lifted export.
1062 memory: Option<RuntimeMemoryIndex>,
1063 },
1064
1065 /// An intrinsic used by FACT-generated modules to start a call involving a
1066 /// sync-lowered import and async-lifted export.
1067 SyncStartCall {
1068 /// The callee's callback function, if any.
1069 callback: Option<RuntimeCallbackIndex>,
1070 },
1071
1072 /// An intrinsic used by FACT-generated modules to start a call involving
1073 /// an async-lowered import function.
1074 ///
1075 /// Note that `AsyncPrepareCall` and `AsyncStartCall` could theoretically be
1076 /// combined into a single `AsyncCall` intrinsic, but we separate them to
1077 /// allow the FACT-generated module to optionally call the callee directly
1078 /// without an intermediate host stack frame.
1079 AsyncStartCall {
1080 /// The callee's callback, if any.
1081 callback: Option<RuntimeCallbackIndex>,
1082 /// The callee's post-return function, if any.
1083 post_return: Option<RuntimePostReturnIndex>,
1084 },
1085
1086 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1087 /// ownership of a `future`.
1088 ///
1089 /// Transferring a `future` can either mean giving away the readable end
1090 /// while retaining the writable end or only the former, depending on the
1091 /// ownership status of the `future`.
1092 FutureTransfer,
1093
1094 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1095 /// ownership of a `stream`.
1096 ///
1097 /// Transferring a `stream` can either mean giving away the readable end
1098 /// while retaining the writable end or only the former, depending on the
1099 /// ownership status of the `stream`.
1100 StreamTransfer,
1101
1102 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1103 /// ownership of an `error-context`.
1104 ///
1105 /// Unlike futures, streams, and resource handles, `error-context` handles
1106 /// are reference counted, meaning that sharing the handle with another
1107 /// component does not invalidate the handle in the original component.
1108 ErrorContextTransfer,
1109
1110 /// An intrinsic used by FACT-generated modules to trap with a specified
1111 /// code.
1112 Trap,
1113
1114 /// An intrinsic used by FACT-generated modules to push a task onto the
1115 /// stack for a sync-to-sync, guest-to-guest call.
1116 EnterSyncCall,
1117 /// An intrinsic used by FACT-generated modules to pop the task previously
1118 /// pushed by `EnterSyncCall`.
1119 ExitSyncCall,
1120
1121 /// Intrinsic used to implement the `context.get` component model builtin.
1122 ///
1123 /// The payload here represents that this is accessing the Nth slot of local
1124 /// storage.
1125 ContextGet {
1126 /// The specific component instance which is calling the intrinsic.
1127 instance: RuntimeComponentInstanceIndex,
1128 /// Which slot to access.
1129 slot: u32,
1130 },
1131
1132 /// Intrinsic used to implement the `context.set` component model builtin.
1133 ///
1134 /// The payload here represents that this is accessing the Nth slot of local
1135 /// storage.
1136 ContextSet {
1137 /// The specific component instance which is calling the intrinsic.
1138 instance: RuntimeComponentInstanceIndex,
1139 /// Which slot to update.
1140 slot: u32,
1141 },
1142
1143 /// Intrinsic used to implement the `thread.index` component model builtin.
1144 ThreadIndex,
1145
1146 /// Intrinsic used to implement the `thread.new-indirect` component model builtin.
1147 ThreadNewIndirect {
1148 /// The specific component instance which is calling the intrinsic.
1149 instance: RuntimeComponentInstanceIndex,
1150 /// The type index for the start function of the thread.
1151 start_func_ty_idx: ComponentTypeIndex,
1152 /// The index of the table that stores the start function.
1153 start_func_table_idx: RuntimeTableIndex,
1154 },
1155
1156 /// Intrinsic used to implement the `thread.suspend-to-suspended` component model builtin.
1157 ThreadSuspendToSuspended {
1158 /// The specific component instance which is calling the intrinsic.
1159 instance: RuntimeComponentInstanceIndex,
1160 /// If `true`, indicates the caller instance may receive notification
1161 /// of task cancellation.
1162 cancellable: bool,
1163 },
1164
1165 /// Intrinsic used to implement the `thread.suspend-to` component model builtin.
1166 ThreadSuspendTo {
1167 /// The specific component instance which is calling the intrinsic.
1168 instance: RuntimeComponentInstanceIndex,
1169 /// If `true`, indicates the caller instance may receive notification
1170 /// of task cancellation.
1171 cancellable: bool,
1172 },
1173
1174 /// Intrinsic used to implement the `thread.suspend` component model builtin.
1175 ThreadSuspend {
1176 /// The specific component instance which is calling the intrinsic.
1177 instance: RuntimeComponentInstanceIndex,
1178 /// If `true`, indicates the caller instance may receive notification
1179 /// of task cancellation.
1180 cancellable: bool,
1181 },
1182
1183 /// Intrinsic used to implement the `thread.unsuspend` component model builtin.
1184 ThreadUnsuspend {
1185 /// The specific component instance which is calling the intrinsic.
1186 instance: RuntimeComponentInstanceIndex,
1187 },
1188
1189 /// Intrinsic used to implement the `thread.yield-to-suspended` component model builtin.
1190 ThreadYieldToSuspended {
1191 /// The specific component instance which is calling the intrinsic.
1192 instance: RuntimeComponentInstanceIndex,
1193 /// If `true`, indicates the caller instance may receive notification
1194 /// of task cancellation.
1195 cancellable: bool,
1196 },
1197}
1198
1199impl Trampoline {
1200 /// Returns the name to use for the symbol of this trampoline in the final
1201 /// compiled artifact
1202 pub fn symbol_name(&self) -> String {
1203 use Trampoline::*;
1204 match self {
1205 LowerImport { index, .. } => {
1206 format!("component-lower-import[{}]", index.as_u32())
1207 }
1208 Transcoder {
1209 op, from64, to64, ..
1210 } => {
1211 let op = op.symbol_fragment();
1212 let from = if *from64 { "64" } else { "32" };
1213 let to = if *to64 { "64" } else { "32" };
1214 format!("component-transcode-{op}-m{from}-m{to}")
1215 }
1216 ResourceNew { ty, .. } => format!("component-resource-new[{}]", ty.as_u32()),
1217 ResourceRep { ty, .. } => format!("component-resource-rep[{}]", ty.as_u32()),
1218 ResourceDrop { ty, .. } => format!("component-resource-drop[{}]", ty.as_u32()),
1219 BackpressureInc { .. } => format!("backpressure-inc"),
1220 BackpressureDec { .. } => format!("backpressure-dec"),
1221 TaskReturn { .. } => format!("task-return"),
1222 TaskCancel { .. } => format!("task-cancel"),
1223 WaitableSetNew { .. } => format!("waitable-set-new"),
1224 WaitableSetWait { .. } => format!("waitable-set-wait"),
1225 WaitableSetPoll { .. } => format!("waitable-set-poll"),
1226 WaitableSetDrop { .. } => format!("waitable-set-drop"),
1227 WaitableJoin { .. } => format!("waitable-join"),
1228 ThreadYield { .. } => format!("thread-yield"),
1229 SubtaskDrop { .. } => format!("subtask-drop"),
1230 SubtaskCancel { .. } => format!("subtask-cancel"),
1231 StreamNew { .. } => format!("stream-new"),
1232 StreamRead { .. } => format!("stream-read"),
1233 StreamWrite { .. } => format!("stream-write"),
1234 StreamCancelRead { .. } => format!("stream-cancel-read"),
1235 StreamCancelWrite { .. } => format!("stream-cancel-write"),
1236 StreamDropReadable { .. } => format!("stream-drop-readable"),
1237 StreamDropWritable { .. } => format!("stream-drop-writable"),
1238 FutureNew { .. } => format!("future-new"),
1239 FutureRead { .. } => format!("future-read"),
1240 FutureWrite { .. } => format!("future-write"),
1241 FutureCancelRead { .. } => format!("future-cancel-read"),
1242 FutureCancelWrite { .. } => format!("future-cancel-write"),
1243 FutureDropReadable { .. } => format!("future-drop-readable"),
1244 FutureDropWritable { .. } => format!("future-drop-writable"),
1245 ErrorContextNew { .. } => format!("error-context-new"),
1246 ErrorContextDebugMessage { .. } => format!("error-context-debug-message"),
1247 ErrorContextDrop { .. } => format!("error-context-drop"),
1248 ResourceTransferOwn => format!("component-resource-transfer-own"),
1249 ResourceTransferBorrow => format!("component-resource-transfer-borrow"),
1250 PrepareCall { .. } => format!("component-prepare-call"),
1251 SyncStartCall { .. } => format!("component-sync-start-call"),
1252 AsyncStartCall { .. } => format!("component-async-start-call"),
1253 FutureTransfer => format!("future-transfer"),
1254 StreamTransfer => format!("stream-transfer"),
1255 ErrorContextTransfer => format!("error-context-transfer"),
1256 Trap => format!("trap"),
1257 EnterSyncCall => format!("enter-sync-call"),
1258 ExitSyncCall => format!("exit-sync-call"),
1259 ContextGet { .. } => format!("context-get"),
1260 ContextSet { .. } => format!("context-set"),
1261 ThreadIndex => format!("thread-index"),
1262 ThreadNewIndirect { .. } => format!("thread-new-indirect"),
1263 ThreadSuspendToSuspended { .. } => format!("thread-suspend-to-suspended"),
1264 ThreadSuspendTo { .. } => format!("thread-suspend-to"),
1265 ThreadSuspend { .. } => format!("thread-suspend"),
1266 ThreadUnsuspend { .. } => format!("thread-unsuspend"),
1267 ThreadYieldToSuspended { .. } => format!("thread-yield-to-suspended"),
1268 }
1269 }
1270}