Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/environ/src/component/info.rs
3050 views
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
49
use crate::component::*;
50
use crate::prelude::*;
51
use crate::{EntityIndex, ModuleInternedTypeIndex, PrimaryMap, WasmValType};
52
use cranelift_entity::packed_option::PackedOption;
53
use serde_derive::{Deserialize, Serialize};
54
55
/// Metadata as a result of compiling a component.
56
pub 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)]
74
pub 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
208
impl 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)]
239
pub 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)]
310
pub 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)]
319
pub 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)]
328
pub 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)]
337
pub 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)]
346
pub 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)]
355
pub 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)]
383
pub 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
401
impl<T> From<CoreExport<T>> for CoreDef
402
where
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)]
416
pub 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
428
impl<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)]
444
pub 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)]
463
pub 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.
503
pub 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)]
512
pub 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)]
522
pub 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
550
impl 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")]
563
pub enum StringEncoding {
564
Utf8,
565
Utf16,
566
CompactUtf16,
567
}
568
569
impl 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)]
591
pub 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
604
impl 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")]
646
pub enum FixedEncoding {
647
Utf8,
648
Utf16,
649
Latin1,
650
}
651
652
impl 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
665
/// Description of a new resource declared in a `GlobalInitializer::Resource`
666
/// variant.
667
///
668
/// This will have the effect of initializing runtime state for this resource,
669
/// namely the destructor is fetched and stored.
670
#[derive(Debug, Serialize, Deserialize)]
671
pub struct Resource {
672
/// The local index of the resource being defined.
673
pub index: DefinedResourceIndex,
674
/// Core wasm representation of this resource.
675
pub rep: WasmValType,
676
/// Optionally-specified destructor and where it comes from.
677
pub dtor: Option<CoreDef>,
678
/// Which component instance this resource logically belongs to.
679
pub instance: RuntimeComponentInstanceIndex,
680
}
681
682
/// A list of all possible trampolines that may be required to compile a
683
/// component completely.
684
///
685
/// These trampolines are used often as core wasm definitions and require
686
/// Cranelift support to generate these functions. Each trampoline serves a
687
/// different purpose for implementing bits and pieces of the component model.
688
///
689
/// All trampolines have a core wasm function signature associated with them
690
/// which is stored in the `Component::trampolines` array.
691
///
692
/// Note that this type does not implement `Serialize` or `Deserialize` and
693
/// that's intentional as this isn't stored in the final compilation artifact.
694
#[derive(Debug)]
695
pub enum Trampoline {
696
/// Description of a lowered import used in conjunction with
697
/// `GlobalInitializer::LowerImport`.
698
LowerImport {
699
/// The runtime lowering state that this trampoline will access.
700
index: LoweredIndex,
701
702
/// The type of the function that is being lowered, as perceived by the
703
/// component doing the lowering.
704
lower_ty: TypeFuncIndex,
705
706
/// The canonical ABI options used when lowering this function specified
707
/// in the original component.
708
options: OptionsIndex,
709
},
710
711
/// Information about a string transcoding function required by an adapter
712
/// module.
713
///
714
/// A transcoder is used when strings are passed between adapter modules,
715
/// optionally changing string encodings at the same time. The transcoder is
716
/// implemented in a few different layers:
717
///
718
/// * Each generated adapter module has some glue around invoking the
719
/// transcoder represented by this item. This involves bounds-checks and
720
/// handling `realloc` for example.
721
/// * Each transcoder gets a cranelift-generated trampoline which has the
722
/// appropriate signature for the adapter module in question. Existence of
723
/// this initializer indicates that this should be compiled by Cranelift.
724
/// * The cranelift-generated trampoline will invoke a "transcoder libcall"
725
/// which is implemented natively in Rust that has a signature independent
726
/// of memory64 configuration options for example.
727
Transcoder {
728
/// The transcoding operation being performed.
729
op: Transcode,
730
/// The linear memory that the string is being read from.
731
from: RuntimeMemoryIndex,
732
/// Whether or not the source linear memory is 64-bit or not.
733
from64: bool,
734
/// The linear memory that the string is being written to.
735
to: RuntimeMemoryIndex,
736
/// Whether or not the destination linear memory is 64-bit or not.
737
to64: bool,
738
},
739
740
/// A `resource.new` intrinsic which will inject a new resource into the
741
/// table specified.
742
ResourceNew {
743
/// The specific component instance which is calling the intrinsic.
744
instance: RuntimeComponentInstanceIndex,
745
/// The type of the resource.
746
ty: TypeResourceTableIndex,
747
},
748
749
/// Same as `ResourceNew`, but for the `resource.rep` intrinsic.
750
ResourceRep {
751
/// The specific component instance which is calling the intrinsic.
752
instance: RuntimeComponentInstanceIndex,
753
/// The type of the resource.
754
ty: TypeResourceTableIndex,
755
},
756
757
/// Same as `ResourceNew`, but for the `resource.drop` intrinsic.
758
ResourceDrop {
759
/// The specific component instance which is calling the intrinsic.
760
instance: RuntimeComponentInstanceIndex,
761
/// The type of the resource.
762
ty: TypeResourceTableIndex,
763
},
764
765
/// A `backpressure.inc` intrinsic.
766
BackpressureInc {
767
/// The specific component instance which is calling the intrinsic.
768
instance: RuntimeComponentInstanceIndex,
769
},
770
771
/// A `backpressure.dec` intrinsic.
772
BackpressureDec {
773
/// The specific component instance which is calling the intrinsic.
774
instance: RuntimeComponentInstanceIndex,
775
},
776
777
/// A `task.return` intrinsic, which returns a result to the caller of a
778
/// lifted export function. This allows the callee to continue executing
779
/// after returning a result.
780
TaskReturn {
781
/// The specific component instance which is calling the intrinsic.
782
instance: RuntimeComponentInstanceIndex,
783
/// Tuple representing the result types this intrinsic accepts.
784
results: TypeTupleIndex,
785
/// The canonical ABI options specified for this intrinsic.
786
options: OptionsIndex,
787
},
788
789
/// A `task.cancel` intrinsic, which acknowledges a `CANCELLED` event
790
/// delivered to a guest task previously created by a call to an async
791
/// export.
792
TaskCancel {
793
/// The specific component instance which is calling the intrinsic.
794
instance: RuntimeComponentInstanceIndex,
795
},
796
797
/// A `waitable-set.new` intrinsic.
798
WaitableSetNew {
799
/// The specific component instance which is calling the intrinsic.
800
instance: RuntimeComponentInstanceIndex,
801
},
802
803
/// A `waitable-set.wait` intrinsic, which waits for at least one
804
/// outstanding async task/stream/future to make progress, returning the
805
/// first such event.
806
WaitableSetWait {
807
/// The specific component instance which is calling the intrinsic.
808
instance: RuntimeComponentInstanceIndex,
809
/// Configuration options for this intrinsic call.
810
options: OptionsIndex,
811
},
812
813
/// A `waitable-set.poll` intrinsic, which checks whether any outstanding
814
/// async task/stream/future has made progress. Unlike `task.wait`, this
815
/// does not block and may return nothing if no such event has occurred.
816
WaitableSetPoll {
817
/// The specific component instance which is calling the intrinsic.
818
instance: RuntimeComponentInstanceIndex,
819
/// Configuration options for this intrinsic call.
820
options: OptionsIndex,
821
},
822
823
/// A `waitable-set.drop` intrinsic.
824
WaitableSetDrop {
825
/// The specific component instance which is calling the intrinsic.
826
instance: RuntimeComponentInstanceIndex,
827
},
828
829
/// A `waitable.join` intrinsic.
830
WaitableJoin {
831
/// The specific component instance which is calling the intrinsic.
832
instance: RuntimeComponentInstanceIndex,
833
},
834
835
/// A `thread.yield` intrinsic, which yields control to the host so that other
836
/// tasks are able to make progress, if any.
837
ThreadYield {
838
/// The specific component instance which is calling the intrinsic.
839
instance: RuntimeComponentInstanceIndex,
840
/// If `true`, indicates the caller instance may receive notification
841
/// of task cancellation.
842
cancellable: bool,
843
},
844
845
/// A `subtask.drop` intrinsic to drop a specified task which has completed.
846
SubtaskDrop {
847
/// The specific component instance which is calling the intrinsic.
848
instance: RuntimeComponentInstanceIndex,
849
},
850
851
/// A `subtask.cancel` intrinsic to drop an in-progress task.
852
SubtaskCancel {
853
/// The specific component instance which is calling the intrinsic.
854
instance: RuntimeComponentInstanceIndex,
855
/// If `false`, block until cancellation completes rather than return
856
/// `BLOCKED`.
857
async_: bool,
858
},
859
860
/// A `stream.new` intrinsic to create a new `stream` handle of the
861
/// specified type.
862
StreamNew {
863
/// The specific component instance which is calling the intrinsic.
864
instance: RuntimeComponentInstanceIndex,
865
/// The table index for the specific `stream` type and caller instance.
866
ty: TypeStreamTableIndex,
867
},
868
869
/// A `stream.read` intrinsic to read from a `stream` of the specified type.
870
StreamRead {
871
/// The specific component instance which is calling the intrinsic.
872
instance: RuntimeComponentInstanceIndex,
873
/// The table index for the specific `stream` type and caller instance.
874
ty: TypeStreamTableIndex,
875
/// Any options (e.g. string encoding) to use when storing values to
876
/// memory.
877
options: OptionsIndex,
878
},
879
880
/// A `stream.write` intrinsic to write to a `stream` of the specified type.
881
StreamWrite {
882
/// The specific component instance which is calling the intrinsic.
883
instance: RuntimeComponentInstanceIndex,
884
/// The table index for the specific `stream` type and caller instance.
885
ty: TypeStreamTableIndex,
886
/// Any options (e.g. string encoding) to use when storing values to
887
/// memory.
888
options: OptionsIndex,
889
},
890
891
/// A `stream.cancel-read` intrinsic to cancel an in-progress read from a
892
/// `stream` of the specified type.
893
StreamCancelRead {
894
/// The specific component instance which is calling the intrinsic.
895
instance: RuntimeComponentInstanceIndex,
896
/// The table index for the specific `stream` type and caller instance.
897
ty: TypeStreamTableIndex,
898
/// If `false`, block until cancellation completes rather than return
899
/// `BLOCKED`.
900
async_: bool,
901
},
902
903
/// A `stream.cancel-write` intrinsic to cancel an in-progress write from a
904
/// `stream` of the specified type.
905
StreamCancelWrite {
906
/// The specific component instance which is calling the intrinsic.
907
instance: RuntimeComponentInstanceIndex,
908
/// The table index for the specific `stream` type and caller instance.
909
ty: TypeStreamTableIndex,
910
/// If `false`, block until cancellation completes rather than return
911
/// `BLOCKED`.
912
async_: bool,
913
},
914
915
/// A `stream.drop-readable` intrinsic to drop the readable end of a
916
/// `stream` of the specified type.
917
StreamDropReadable {
918
/// The specific component instance which is calling the intrinsic.
919
instance: RuntimeComponentInstanceIndex,
920
/// The table index for the specific `stream` type and caller instance.
921
ty: TypeStreamTableIndex,
922
},
923
924
/// A `stream.drop-writable` intrinsic to drop the writable end of a
925
/// `stream` of the specified type.
926
StreamDropWritable {
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 `future.new` intrinsic to create a new `future` handle of the
934
/// specified type.
935
FutureNew {
936
/// The specific component instance which is calling the intrinsic.
937
instance: RuntimeComponentInstanceIndex,
938
/// The table index for the specific `future` type and caller instance.
939
ty: TypeFutureTableIndex,
940
},
941
942
/// A `future.read` intrinsic to read from a `future` of the specified type.
943
FutureRead {
944
/// The specific component instance which is calling the intrinsic.
945
instance: RuntimeComponentInstanceIndex,
946
/// The table index for the specific `future` type and caller instance.
947
ty: TypeFutureTableIndex,
948
/// Any options (e.g. string encoding) to use when storing values to
949
/// memory.
950
options: OptionsIndex,
951
},
952
953
/// A `future.write` intrinsic to write to a `future` of the specified type.
954
FutureWrite {
955
/// The specific component instance which is calling the intrinsic.
956
instance: RuntimeComponentInstanceIndex,
957
/// The table index for the specific `future` type and caller instance.
958
ty: TypeFutureTableIndex,
959
/// Any options (e.g. string encoding) to use when storing values to
960
/// memory.
961
options: OptionsIndex,
962
},
963
964
/// A `future.cancel-read` intrinsic to cancel an in-progress read from a
965
/// `future` of the specified type.
966
FutureCancelRead {
967
/// The specific component instance which is calling the intrinsic.
968
instance: RuntimeComponentInstanceIndex,
969
/// The table index for the specific `future` type and caller instance.
970
ty: TypeFutureTableIndex,
971
/// If `false`, block until cancellation completes rather than return
972
/// `BLOCKED`.
973
async_: bool,
974
},
975
976
/// A `future.cancel-write` intrinsic to cancel an in-progress write from a
977
/// `future` of the specified type.
978
FutureCancelWrite {
979
/// The specific component instance which is calling the intrinsic.
980
instance: RuntimeComponentInstanceIndex,
981
/// The table index for the specific `future` type and caller instance.
982
ty: TypeFutureTableIndex,
983
/// If `false`, block until cancellation completes rather than return
984
/// `BLOCKED`.
985
async_: bool,
986
},
987
988
/// A `future.drop-readable` intrinsic to drop the readable end of a
989
/// `future` of the specified type.
990
FutureDropReadable {
991
/// The specific component instance which is calling the intrinsic.
992
instance: RuntimeComponentInstanceIndex,
993
/// The table index for the specific `future` type and caller instance.
994
ty: TypeFutureTableIndex,
995
},
996
997
/// A `future.drop-writable` intrinsic to drop the writable end of a
998
/// `future` of the specified type.
999
FutureDropWritable {
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 `error-context.new` intrinsic to create a new `error-context` with a
1007
/// specified debug message.
1008
ErrorContextNew {
1009
/// The specific component instance which is calling the intrinsic.
1010
instance: RuntimeComponentInstanceIndex,
1011
/// The table index for the `error-context` type in the caller instance.
1012
ty: TypeComponentLocalErrorContextTableIndex,
1013
/// String encoding, memory, etc. to use when loading debug message.
1014
options: OptionsIndex,
1015
},
1016
1017
/// A `error-context.debug-message` intrinsic to get the debug message for a
1018
/// specified `error-context`.
1019
///
1020
/// Note that the debug message might not necessarily match what was passed
1021
/// to `error.new`.
1022
ErrorContextDebugMessage {
1023
/// The specific component instance which is calling the intrinsic.
1024
instance: RuntimeComponentInstanceIndex,
1025
/// The table index for the `error-context` type in the caller instance.
1026
ty: TypeComponentLocalErrorContextTableIndex,
1027
/// String encoding, memory, etc. to use when storing debug message.
1028
options: OptionsIndex,
1029
},
1030
1031
/// A `error-context.drop` intrinsic to drop a specified `error-context`.
1032
ErrorContextDrop {
1033
/// The specific component instance which is calling the intrinsic.
1034
instance: RuntimeComponentInstanceIndex,
1035
/// The table index for the `error-context` type in the caller instance.
1036
ty: TypeComponentLocalErrorContextTableIndex,
1037
},
1038
1039
/// An intrinsic used by FACT-generated modules which will transfer an owned
1040
/// resource from one table to another. Used in component-to-component
1041
/// adapter trampolines.
1042
ResourceTransferOwn,
1043
1044
/// Same as `ResourceTransferOwn` but for borrows.
1045
ResourceTransferBorrow,
1046
1047
/// An intrinsic used by FACT-generated modules which indicates that a call
1048
/// is being entered and resource-related metadata needs to be configured.
1049
///
1050
/// Note that this is currently only invoked when borrowed resources are
1051
/// detected, otherwise this is "optimized out".
1052
ResourceEnterCall,
1053
1054
/// Same as `ResourceEnterCall` except for when exiting a call.
1055
ResourceExitCall,
1056
1057
/// An intrinsic used by FACT-generated modules to prepare a call involving
1058
/// an async-lowered import and/or an async-lifted export.
1059
PrepareCall {
1060
/// The memory used to verify that the memory specified for the
1061
/// `task.return` that is called at runtime matches the one specified in
1062
/// the lifted export.
1063
memory: Option<RuntimeMemoryIndex>,
1064
},
1065
1066
/// An intrinsic used by FACT-generated modules to start a call involving a
1067
/// sync-lowered import and async-lifted export.
1068
SyncStartCall {
1069
/// The callee's callback function, if any.
1070
callback: Option<RuntimeCallbackIndex>,
1071
},
1072
1073
/// An intrinsic used by FACT-generated modules to start a call involving
1074
/// an async-lowered import function.
1075
///
1076
/// Note that `AsyncPrepareCall` and `AsyncStartCall` could theoretically be
1077
/// combined into a single `AsyncCall` intrinsic, but we separate them to
1078
/// allow the FACT-generated module to optionally call the callee directly
1079
/// without an intermediate host stack frame.
1080
AsyncStartCall {
1081
/// The callee's callback, if any.
1082
callback: Option<RuntimeCallbackIndex>,
1083
/// The callee's post-return function, if any.
1084
post_return: Option<RuntimePostReturnIndex>,
1085
},
1086
1087
/// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1088
/// ownership of a `future`.
1089
///
1090
/// Transferring a `future` can either mean giving away the readable end
1091
/// while retaining the writable end or only the former, depending on the
1092
/// ownership status of the `future`.
1093
FutureTransfer,
1094
1095
/// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1096
/// ownership of a `stream`.
1097
///
1098
/// Transferring a `stream` can either mean giving away the readable end
1099
/// while retaining the writable end or only the former, depending on the
1100
/// ownership status of the `stream`.
1101
StreamTransfer,
1102
1103
/// An intrinisic used by FACT-generated modules to (partially or entirely) transfer
1104
/// ownership of an `error-context`.
1105
///
1106
/// Unlike futures, streams, and resource handles, `error-context` handles
1107
/// are reference counted, meaning that sharing the handle with another
1108
/// component does not invalidate the handle in the original component.
1109
ErrorContextTransfer,
1110
1111
/// An intrinsic used by FACT-generated modules to trap with a specified
1112
/// code.
1113
Trap,
1114
1115
/// An intrinsic used by FACT-generated modules to push a task onto the
1116
/// stack for a sync-to-sync, guest-to-guest call.
1117
EnterSyncCall,
1118
/// An intrinsic used by FACT-generated modules to pop the task previously
1119
/// pushed by `EnterSyncCall`.
1120
ExitSyncCall,
1121
1122
/// Intrinsic used to implement the `context.get` component model builtin.
1123
///
1124
/// The payload here represents that this is accessing the Nth slot of local
1125
/// storage.
1126
ContextGet {
1127
/// The specific component instance which is calling the intrinsic.
1128
instance: RuntimeComponentInstanceIndex,
1129
/// Which slot to access.
1130
slot: u32,
1131
},
1132
1133
/// Intrinsic used to implement the `context.set` component model builtin.
1134
///
1135
/// The payload here represents that this is accessing the Nth slot of local
1136
/// storage.
1137
ContextSet {
1138
/// The specific component instance which is calling the intrinsic.
1139
instance: RuntimeComponentInstanceIndex,
1140
/// Which slot to update.
1141
slot: u32,
1142
},
1143
1144
/// Intrinsic used to implement the `thread.index` component model builtin.
1145
ThreadIndex,
1146
1147
/// Intrinsic used to implement the `thread.new-indirect` component model builtin.
1148
ThreadNewIndirect {
1149
/// The specific component instance which is calling the intrinsic.
1150
instance: RuntimeComponentInstanceIndex,
1151
/// The type index for the start function of the thread.
1152
start_func_ty_idx: ComponentTypeIndex,
1153
/// The index of the table that stores the start function.
1154
start_func_table_idx: RuntimeTableIndex,
1155
},
1156
1157
/// Intrinsic used to implement the `thread.switch-to` component model builtin.
1158
ThreadSwitchTo {
1159
/// The specific component instance which is calling the intrinsic.
1160
instance: RuntimeComponentInstanceIndex,
1161
/// If `true`, indicates the caller instance may receive notification
1162
/// of task cancellation.
1163
cancellable: bool,
1164
},
1165
1166
/// Intrinsic used to implement the `thread.suspend` component model builtin.
1167
ThreadSuspend {
1168
/// The specific component instance which is calling the intrinsic.
1169
instance: RuntimeComponentInstanceIndex,
1170
/// If `true`, indicates the caller instance may receive notification
1171
/// of task cancellation.
1172
cancellable: bool,
1173
},
1174
1175
/// Intrinsic used to implement the `thread.resume-later` component model builtin.
1176
ThreadResumeLater {
1177
/// The specific component instance which is calling the intrinsic.
1178
instance: RuntimeComponentInstanceIndex,
1179
},
1180
1181
/// Intrinsic used to implement the `thread.yield-to` component model builtin.
1182
ThreadYieldTo {
1183
/// The specific component instance which is calling the intrinsic.
1184
instance: RuntimeComponentInstanceIndex,
1185
/// If `true`, indicates the caller instance may receive notification
1186
/// of task cancellation.
1187
cancellable: bool,
1188
},
1189
}
1190
1191
impl Trampoline {
1192
/// Returns the name to use for the symbol of this trampoline in the final
1193
/// compiled artifact
1194
pub fn symbol_name(&self) -> String {
1195
use Trampoline::*;
1196
match self {
1197
LowerImport { index, .. } => {
1198
format!("component-lower-import[{}]", index.as_u32())
1199
}
1200
Transcoder {
1201
op, from64, to64, ..
1202
} => {
1203
let op = op.symbol_fragment();
1204
let from = if *from64 { "64" } else { "32" };
1205
let to = if *to64 { "64" } else { "32" };
1206
format!("component-transcode-{op}-m{from}-m{to}")
1207
}
1208
ResourceNew { ty, .. } => format!("component-resource-new[{}]", ty.as_u32()),
1209
ResourceRep { ty, .. } => format!("component-resource-rep[{}]", ty.as_u32()),
1210
ResourceDrop { ty, .. } => format!("component-resource-drop[{}]", ty.as_u32()),
1211
BackpressureInc { .. } => format!("backpressure-inc"),
1212
BackpressureDec { .. } => format!("backpressure-dec"),
1213
TaskReturn { .. } => format!("task-return"),
1214
TaskCancel { .. } => format!("task-cancel"),
1215
WaitableSetNew { .. } => format!("waitable-set-new"),
1216
WaitableSetWait { .. } => format!("waitable-set-wait"),
1217
WaitableSetPoll { .. } => format!("waitable-set-poll"),
1218
WaitableSetDrop { .. } => format!("waitable-set-drop"),
1219
WaitableJoin { .. } => format!("waitable-join"),
1220
ThreadYield { .. } => format!("thread-yield"),
1221
SubtaskDrop { .. } => format!("subtask-drop"),
1222
SubtaskCancel { .. } => format!("subtask-cancel"),
1223
StreamNew { .. } => format!("stream-new"),
1224
StreamRead { .. } => format!("stream-read"),
1225
StreamWrite { .. } => format!("stream-write"),
1226
StreamCancelRead { .. } => format!("stream-cancel-read"),
1227
StreamCancelWrite { .. } => format!("stream-cancel-write"),
1228
StreamDropReadable { .. } => format!("stream-drop-readable"),
1229
StreamDropWritable { .. } => format!("stream-drop-writable"),
1230
FutureNew { .. } => format!("future-new"),
1231
FutureRead { .. } => format!("future-read"),
1232
FutureWrite { .. } => format!("future-write"),
1233
FutureCancelRead { .. } => format!("future-cancel-read"),
1234
FutureCancelWrite { .. } => format!("future-cancel-write"),
1235
FutureDropReadable { .. } => format!("future-drop-readable"),
1236
FutureDropWritable { .. } => format!("future-drop-writable"),
1237
ErrorContextNew { .. } => format!("error-context-new"),
1238
ErrorContextDebugMessage { .. } => format!("error-context-debug-message"),
1239
ErrorContextDrop { .. } => format!("error-context-drop"),
1240
ResourceTransferOwn => format!("component-resource-transfer-own"),
1241
ResourceTransferBorrow => format!("component-resource-transfer-borrow"),
1242
ResourceEnterCall => format!("component-resource-enter-call"),
1243
ResourceExitCall => format!("component-resource-exit-call"),
1244
PrepareCall { .. } => format!("component-prepare-call"),
1245
SyncStartCall { .. } => format!("component-sync-start-call"),
1246
AsyncStartCall { .. } => format!("component-async-start-call"),
1247
FutureTransfer => format!("future-transfer"),
1248
StreamTransfer => format!("stream-transfer"),
1249
ErrorContextTransfer => format!("error-context-transfer"),
1250
Trap => format!("trap"),
1251
EnterSyncCall => format!("enter-sync-call"),
1252
ExitSyncCall => format!("exit-sync-call"),
1253
ContextGet { .. } => format!("context-get"),
1254
ContextSet { .. } => format!("context-set"),
1255
ThreadIndex => format!("thread-index"),
1256
ThreadNewIndirect { .. } => format!("thread-new-indirect"),
1257
ThreadSwitchTo { .. } => format!("thread-switch-to"),
1258
ThreadSuspend { .. } => format!("thread-suspend"),
1259
ThreadResumeLater { .. } => format!("thread-resume-later"),
1260
ThreadYieldTo { .. } => format!("thread-yield-to"),
1261
}
1262
}
1263
}
1264
1265