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