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 to prepare a call involving 1048 /// an async-lowered import and/or an async-lifted export. 1049 PrepareCall { 1050 /// The memory used to verify that the memory specified for the 1051 /// `task.return` that is called at runtime matches the one specified in 1052 /// the lifted export. 1053 memory: Option<RuntimeMemoryIndex>, 1054 }, 1055 1056 /// An intrinsic used by FACT-generated modules to start a call involving a 1057 /// sync-lowered import and async-lifted export. 1058 SyncStartCall { 1059 /// The callee's callback function, if any. 1060 callback: Option<RuntimeCallbackIndex>, 1061 }, 1062 1063 /// An intrinsic used by FACT-generated modules to start a call involving 1064 /// an async-lowered import function. 1065 /// 1066 /// Note that `AsyncPrepareCall` and `AsyncStartCall` could theoretically be 1067 /// combined into a single `AsyncCall` intrinsic, but we separate them to 1068 /// allow the FACT-generated module to optionally call the callee directly 1069 /// without an intermediate host stack frame. 1070 AsyncStartCall { 1071 /// The callee's callback, if any. 1072 callback: Option<RuntimeCallbackIndex>, 1073 /// The callee's post-return function, if any. 1074 post_return: Option<RuntimePostReturnIndex>, 1075 }, 1076 1077 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer 1078 /// ownership of a `future`. 1079 /// 1080 /// Transferring a `future` can either mean giving away the readable end 1081 /// while retaining the writable end or only the former, depending on the 1082 /// ownership status of the `future`. 1083 FutureTransfer, 1084 1085 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer 1086 /// ownership of a `stream`. 1087 /// 1088 /// Transferring a `stream` can either mean giving away the readable end 1089 /// while retaining the writable end or only the former, depending on the 1090 /// ownership status of the `stream`. 1091 StreamTransfer, 1092 1093 /// An intrinisic used by FACT-generated modules to (partially or entirely) transfer 1094 /// ownership of an `error-context`. 1095 /// 1096 /// Unlike futures, streams, and resource handles, `error-context` handles 1097 /// are reference counted, meaning that sharing the handle with another 1098 /// component does not invalidate the handle in the original component. 1099 ErrorContextTransfer, 1100 1101 /// An intrinsic used by FACT-generated modules to trap with a specified 1102 /// code. 1103 Trap, 1104 1105 /// An intrinsic used by FACT-generated modules to push a task onto the 1106 /// stack for a sync-to-sync, guest-to-guest call. 1107 EnterSyncCall, 1108 /// An intrinsic used by FACT-generated modules to pop the task previously 1109 /// pushed by `EnterSyncCall`. 1110 ExitSyncCall, 1111 1112 /// Intrinsic used to implement the `context.get` component model builtin. 1113 /// 1114 /// The payload here represents that this is accessing the Nth slot of local 1115 /// storage. 1116 ContextGet { 1117 /// The specific component instance which is calling the intrinsic. 1118 instance: RuntimeComponentInstanceIndex, 1119 /// Which slot to access. 1120 slot: u32, 1121 }, 1122 1123 /// Intrinsic used to implement the `context.set` component model builtin. 1124 /// 1125 /// The payload here represents that this is accessing the Nth slot of local 1126 /// storage. 1127 ContextSet { 1128 /// The specific component instance which is calling the intrinsic. 1129 instance: RuntimeComponentInstanceIndex, 1130 /// Which slot to update. 1131 slot: u32, 1132 }, 1133 1134 /// Intrinsic used to implement the `thread.index` component model builtin. 1135 ThreadIndex, 1136 1137 /// Intrinsic used to implement the `thread.new-indirect` component model builtin. 1138 ThreadNewIndirect { 1139 /// The specific component instance which is calling the intrinsic. 1140 instance: RuntimeComponentInstanceIndex, 1141 /// The type index for the start function of the thread. 1142 start_func_ty_idx: ComponentTypeIndex, 1143 /// The index of the table that stores the start function. 1144 start_func_table_idx: RuntimeTableIndex, 1145 }, 1146 1147 /// Intrinsic used to implement the `thread.suspend-to-suspended` component model builtin. 1148 ThreadSuspendToSuspended { 1149 /// The specific component instance which is calling the intrinsic. 1150 instance: RuntimeComponentInstanceIndex, 1151 /// If `true`, indicates the caller instance may receive notification 1152 /// of task cancellation. 1153 cancellable: bool, 1154 }, 1155 1156 /// Intrinsic used to implement the `thread.suspend-to` component model builtin. 1157 ThreadSuspendTo { 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` component model builtin. 1166 ThreadSuspend { 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.unsuspend` component model builtin. 1175 ThreadUnsuspend { 1176 /// The specific component instance which is calling the intrinsic. 1177 instance: RuntimeComponentInstanceIndex, 1178 }, 1179 1180 /// Intrinsic used to implement the `thread.yield-to-suspended` component model builtin. 1181 ThreadYieldToSuspended { 1182 /// The specific component instance which is calling the intrinsic. 1183 instance: RuntimeComponentInstanceIndex, 1184 /// If `true`, indicates the caller instance may receive notification 1185 /// of task cancellation. 1186 cancellable: bool, 1187 }, 1188 } 1189 1190 impl Trampoline { 1191 /// Returns the name to use for the symbol of this trampoline in the final 1192 /// compiled artifact 1193 pub fn symbol_name(&self) -> String { 1194 use Trampoline::*; 1195 match self { 1196 LowerImport { index, .. } => { 1197 format!("component-lower-import[{}]", index.as_u32()) 1198 } 1199 Transcoder { 1200 op, from64, to64, .. 1201 } => { 1202 let op = op.symbol_fragment(); 1203 let from = if *from64 { "64" } else { "32" }; 1204 let to = if *to64 { "64" } else { "32" }; 1205 format!("component-transcode-{op}-m{from}-m{to}") 1206 } 1207 ResourceNew { ty, .. } => format!("component-resource-new[{}]", ty.as_u32()), 1208 ResourceRep { ty, .. } => format!("component-resource-rep[{}]", ty.as_u32()), 1209 ResourceDrop { ty, .. } => format!("component-resource-drop[{}]", ty.as_u32()), 1210 BackpressureInc { .. } => format!("backpressure-inc"), 1211 BackpressureDec { .. } => format!("backpressure-dec"), 1212 TaskReturn { .. } => format!("task-return"), 1213 TaskCancel { .. } => format!("task-cancel"), 1214 WaitableSetNew { .. } => format!("waitable-set-new"), 1215 WaitableSetWait { .. } => format!("waitable-set-wait"), 1216 WaitableSetPoll { .. } => format!("waitable-set-poll"), 1217 WaitableSetDrop { .. } => format!("waitable-set-drop"), 1218 WaitableJoin { .. } => format!("waitable-join"), 1219 ThreadYield { .. } => format!("thread-yield"), 1220 SubtaskDrop { .. } => format!("subtask-drop"), 1221 SubtaskCancel { .. } => format!("subtask-cancel"), 1222 StreamNew { .. } => format!("stream-new"), 1223 StreamRead { .. } => format!("stream-read"), 1224 StreamWrite { .. } => format!("stream-write"), 1225 StreamCancelRead { .. } => format!("stream-cancel-read"), 1226 StreamCancelWrite { .. } => format!("stream-cancel-write"), 1227 StreamDropReadable { .. } => format!("stream-drop-readable"), 1228 StreamDropWritable { .. } => format!("stream-drop-writable"), 1229 FutureNew { .. } => format!("future-new"), 1230 FutureRead { .. } => format!("future-read"), 1231 FutureWrite { .. } => format!("future-write"), 1232 FutureCancelRead { .. } => format!("future-cancel-read"), 1233 FutureCancelWrite { .. } => format!("future-cancel-write"), 1234 FutureDropReadable { .. } => format!("future-drop-readable"), 1235 FutureDropWritable { .. } => format!("future-drop-writable"), 1236 ErrorContextNew { .. } => format!("error-context-new"), 1237 ErrorContextDebugMessage { .. } => format!("error-context-debug-message"), 1238 ErrorContextDrop { .. } => format!("error-context-drop"), 1239 ResourceTransferOwn => format!("component-resource-transfer-own"), 1240 ResourceTransferBorrow => format!("component-resource-transfer-borrow"), 1241 PrepareCall { .. } => format!("component-prepare-call"), 1242 SyncStartCall { .. } => format!("component-sync-start-call"), 1243 AsyncStartCall { .. } => format!("component-async-start-call"), 1244 FutureTransfer => format!("future-transfer"), 1245 StreamTransfer => format!("stream-transfer"), 1246 ErrorContextTransfer => format!("error-context-transfer"), 1247 Trap => format!("trap"), 1248 EnterSyncCall => format!("enter-sync-call"), 1249 ExitSyncCall => format!("exit-sync-call"), 1250 ContextGet { .. } => format!("context-get"), 1251 ContextSet { .. } => format!("context-set"), 1252 ThreadIndex => format!("thread-index"), 1253 ThreadNewIndirect { .. } => format!("thread-new-indirect"), 1254 ThreadSuspendToSuspended { .. } => format!("thread-suspend-to-suspended"), 1255 ThreadSuspendTo { .. } => format!("thread-suspend-to"), 1256 ThreadSuspend { .. } => format!("thread-suspend"), 1257 ThreadUnsuspend { .. } => format!("thread-unsuspend"), 1258 ThreadYieldToSuspended { .. } => format!("thread-yield-to-suspended"), 1259 } 1260 } 1261 } 1262