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