Next Generation WASM Microkernel Operating System
at trap_handler 1006 lines 32 kB view raw
1use crate::component::*; 2use crate::kw; 3use crate::parser::{Cursor, Lookahead1, Parse, Parser, Peek, Result}; 4use crate::token::{Id, Index, LParen, NameAnnotation, Span}; 5use alloc::vec::Vec; 6 7/// A declared core function. 8/// 9/// This is a member of both the core alias and canon sections. 10#[derive(Debug)] 11pub struct CoreFunc<'a> { 12 /// Where this `core func` was defined. 13 pub span: Span, 14 /// An identifier that this function is resolved with (optionally) for name 15 /// resolution. 16 pub id: Option<Id<'a>>, 17 /// An optional name for this function stored in the custom `name` section. 18 pub name: Option<NameAnnotation<'a>>, 19 /// The kind of core function. 20 pub kind: CoreFuncKind<'a>, 21} 22 23impl<'a> Parse<'a> for CoreFunc<'a> { 24 fn parse(parser: Parser<'a>) -> Result<Self> { 25 let span = parser.parse::<kw::core>()?.0; 26 parser.parse::<kw::func>()?; 27 let id = parser.parse()?; 28 let name = parser.parse()?; 29 let kind = parser.parens(|p| p.parse())?; 30 31 Ok(Self { 32 span, 33 id, 34 name, 35 kind, 36 }) 37 } 38} 39 40/// Represents the kind of core functions. 41#[derive(Debug)] 42#[allow(missing_docs)] 43pub enum CoreFuncKind<'a> { 44 /// The core function is defined in terms of lowering a component function. 45 /// 46 /// The core function is actually a member of the canon section. 47 Lower(CanonLower<'a>), 48 /// The core function is defined in terms of aliasing a module instance export. 49 /// 50 /// The core function is actually a member of the core alias section. 51 Alias(InlineExportAlias<'a, true>), 52 ResourceNew(CanonResourceNew<'a>), 53 ResourceDrop(CanonResourceDrop<'a>), 54 ResourceRep(CanonResourceRep<'a>), 55 ThreadSpawnRef(CanonThreadSpawnRef<'a>), 56 ThreadSpawnIndirect(CanonThreadSpawnIndirect<'a>), 57 ThreadAvailableParallelism(CanonThreadAvailableParallelism), 58 BackpressureSet, 59 TaskReturn(CanonTaskReturn<'a>), 60 ContextGet(u32), 61 ContextSet(u32), 62 Yield(CanonYield), 63 SubtaskDrop, 64 StreamNew(CanonStreamNew<'a>), 65 StreamRead(CanonStreamRead<'a>), 66 StreamWrite(CanonStreamWrite<'a>), 67 StreamCancelRead(CanonStreamCancelRead<'a>), 68 StreamCancelWrite(CanonStreamCancelWrite<'a>), 69 StreamCloseReadable(CanonStreamCloseReadable<'a>), 70 StreamCloseWritable(CanonStreamCloseWritable<'a>), 71 FutureNew(CanonFutureNew<'a>), 72 FutureRead(CanonFutureRead<'a>), 73 FutureWrite(CanonFutureWrite<'a>), 74 FutureCancelRead(CanonFutureCancelRead<'a>), 75 FutureCancelWrite(CanonFutureCancelWrite<'a>), 76 FutureCloseReadable(CanonFutureCloseReadable<'a>), 77 FutureCloseWritable(CanonFutureCloseWritable<'a>), 78 ErrorContextNew(CanonErrorContextNew<'a>), 79 ErrorContextDebugMessage(CanonErrorContextDebugMessage<'a>), 80 ErrorContextDrop, 81 WaitableSetNew, 82 WaitableSetWait(CanonWaitableSetWait<'a>), 83 WaitableSetPoll(CanonWaitableSetPoll<'a>), 84 WaitableSetDrop, 85 WaitableJoin, 86} 87 88impl<'a> Parse<'a> for CoreFuncKind<'a> { 89 fn parse(parser: Parser<'a>) -> Result<Self> { 90 let mut l = parser.lookahead1(); 91 if l.peek::<kw::canon>()? { 92 parser.parse::<kw::canon>()?; 93 } else if l.peek::<kw::alias>()? { 94 return Ok(Self::Alias(parser.parse()?)); 95 } else { 96 return Err(l.error()); 97 } 98 99 CoreFuncKind::parse_lookahead(parser.lookahead1()) 100 } 101} 102 103impl<'a> CoreFuncKind<'a> { 104 fn parse_lookahead(mut l: Lookahead1<'a>) -> Result<CoreFuncKind<'a>> { 105 let parser = l.parser(); 106 if l.peek::<kw::lower>()? { 107 Ok(CoreFuncKind::Lower(parser.parse()?)) 108 } else if l.peek::<kw::resource_new>()? { 109 Ok(CoreFuncKind::ResourceNew(parser.parse()?)) 110 } else if l.peek::<kw::resource_drop>()? { 111 Ok(CoreFuncKind::ResourceDrop(parser.parse()?)) 112 } else if l.peek::<kw::resource_rep>()? { 113 Ok(CoreFuncKind::ResourceRep(parser.parse()?)) 114 } else if l.peek::<kw::thread_spawn_ref>()? { 115 Ok(CoreFuncKind::ThreadSpawnRef(parser.parse()?)) 116 } else if l.peek::<kw::thread_spawn_indirect>()? { 117 Ok(CoreFuncKind::ThreadSpawnIndirect(parser.parse()?)) 118 } else if l.peek::<kw::thread_available_parallelism>()? { 119 Ok(CoreFuncKind::ThreadAvailableParallelism(parser.parse()?)) 120 } else if l.peek::<kw::backpressure_set>()? { 121 parser.parse::<kw::backpressure_set>()?; 122 Ok(CoreFuncKind::BackpressureSet) 123 } else if l.peek::<kw::task_return>()? { 124 Ok(CoreFuncKind::TaskReturn(parser.parse()?)) 125 } else if l.peek::<kw::context_get>()? { 126 parser.parse::<kw::context_get>()?; 127 parser.parse::<kw::i32>()?; 128 Ok(CoreFuncKind::ContextGet(parser.parse()?)) 129 } else if l.peek::<kw::context_set>()? { 130 parser.parse::<kw::context_set>()?; 131 parser.parse::<kw::i32>()?; 132 Ok(CoreFuncKind::ContextSet(parser.parse()?)) 133 } else if l.peek::<kw::yield_>()? { 134 Ok(CoreFuncKind::Yield(parser.parse()?)) 135 } else if l.peek::<kw::subtask_drop>()? { 136 parser.parse::<kw::subtask_drop>()?; 137 Ok(CoreFuncKind::SubtaskDrop) 138 } else if l.peek::<kw::stream_new>()? { 139 Ok(CoreFuncKind::StreamNew(parser.parse()?)) 140 } else if l.peek::<kw::stream_read>()? { 141 Ok(CoreFuncKind::StreamRead(parser.parse()?)) 142 } else if l.peek::<kw::stream_write>()? { 143 Ok(CoreFuncKind::StreamWrite(parser.parse()?)) 144 } else if l.peek::<kw::stream_cancel_read>()? { 145 Ok(CoreFuncKind::StreamCancelRead(parser.parse()?)) 146 } else if l.peek::<kw::stream_cancel_write>()? { 147 Ok(CoreFuncKind::StreamCancelWrite(parser.parse()?)) 148 } else if l.peek::<kw::stream_close_readable>()? { 149 Ok(CoreFuncKind::StreamCloseReadable(parser.parse()?)) 150 } else if l.peek::<kw::stream_close_writable>()? { 151 Ok(CoreFuncKind::StreamCloseWritable(parser.parse()?)) 152 } else if l.peek::<kw::future_new>()? { 153 Ok(CoreFuncKind::FutureNew(parser.parse()?)) 154 } else if l.peek::<kw::future_read>()? { 155 Ok(CoreFuncKind::FutureRead(parser.parse()?)) 156 } else if l.peek::<kw::future_write>()? { 157 Ok(CoreFuncKind::FutureWrite(parser.parse()?)) 158 } else if l.peek::<kw::future_cancel_read>()? { 159 Ok(CoreFuncKind::FutureCancelRead(parser.parse()?)) 160 } else if l.peek::<kw::future_cancel_write>()? { 161 Ok(CoreFuncKind::FutureCancelWrite(parser.parse()?)) 162 } else if l.peek::<kw::future_close_readable>()? { 163 Ok(CoreFuncKind::FutureCloseReadable(parser.parse()?)) 164 } else if l.peek::<kw::future_close_writable>()? { 165 Ok(CoreFuncKind::FutureCloseWritable(parser.parse()?)) 166 } else if l.peek::<kw::error_context_new>()? { 167 Ok(CoreFuncKind::ErrorContextNew(parser.parse()?)) 168 } else if l.peek::<kw::error_context_debug_message>()? { 169 Ok(CoreFuncKind::ErrorContextDebugMessage(parser.parse()?)) 170 } else if l.peek::<kw::error_context_drop>()? { 171 parser.parse::<kw::error_context_drop>()?; 172 Ok(CoreFuncKind::ErrorContextDrop) 173 } else if l.peek::<kw::waitable_set_new>()? { 174 parser.parse::<kw::waitable_set_new>()?; 175 Ok(CoreFuncKind::WaitableSetNew) 176 } else if l.peek::<kw::waitable_set_wait>()? { 177 Ok(CoreFuncKind::WaitableSetWait(parser.parse()?)) 178 } else if l.peek::<kw::waitable_set_poll>()? { 179 Ok(CoreFuncKind::WaitableSetPoll(parser.parse()?)) 180 } else if l.peek::<kw::waitable_set_drop>()? { 181 parser.parse::<kw::waitable_set_drop>()?; 182 Ok(CoreFuncKind::WaitableSetDrop) 183 } else if l.peek::<kw::waitable_join>()? { 184 parser.parse::<kw::waitable_join>()?; 185 Ok(CoreFuncKind::WaitableJoin) 186 } else { 187 Err(l.error()) 188 } 189 } 190} 191 192/// A declared component function. 193/// 194/// This may be a member of the import, alias, or canon sections. 195#[derive(Debug)] 196pub struct Func<'a> { 197 /// Where this `func` was defined. 198 pub span: Span, 199 /// An identifier that this function is resolved with (optionally) for name 200 /// resolution. 201 pub id: Option<Id<'a>>, 202 /// An optional name for this function stored in the custom `name` section. 203 pub name: Option<NameAnnotation<'a>>, 204 /// If present, inline export annotations which indicate names this 205 /// definition should be exported under. 206 pub exports: InlineExport<'a>, 207 /// The kind of function. 208 pub kind: FuncKind<'a>, 209} 210 211impl<'a> Parse<'a> for Func<'a> { 212 fn parse(parser: Parser<'a>) -> Result<Self> { 213 let span = parser.parse::<kw::func>()?.0; 214 let id = parser.parse()?; 215 let name = parser.parse()?; 216 let exports = parser.parse()?; 217 let kind = parser.parse()?; 218 219 Ok(Self { 220 span, 221 id, 222 name, 223 exports, 224 kind, 225 }) 226 } 227} 228 229/// Represents the kind of component functions. 230#[derive(Debug)] 231pub enum FuncKind<'a> { 232 /// A function which is actually defined as an import, such as: 233 /// 234 /// ```text 235 /// (func (import "foo") (param string)) 236 /// ``` 237 Import { 238 /// The import name of this import. 239 import: InlineImport<'a>, 240 /// The type that this function will have. 241 ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>, 242 }, 243 /// The function is defined in terms of lifting a core function. 244 /// 245 /// The function is actually a member of the canon section. 246 Lift { 247 /// The lifted function's type. 248 ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>, 249 /// Information relating to the lifting of the core function. 250 info: CanonLift<'a>, 251 }, 252 /// The function is defined in terms of aliasing a component instance export. 253 /// 254 /// The function is actually a member of the alias section. 255 Alias(InlineExportAlias<'a, false>), 256} 257 258impl<'a> Parse<'a> for FuncKind<'a> { 259 fn parse(parser: Parser<'a>) -> Result<Self> { 260 if let Some(import) = parser.parse()? { 261 Ok(Self::Import { 262 import, 263 ty: parser.parse()?, 264 }) 265 } else if parser.peek::<LParen>()? && parser.peek2::<kw::alias>()? { 266 parser.parens(|parser| Ok(Self::Alias(parser.parse()?))) 267 } else { 268 Ok(Self::Lift { 269 ty: parser.parse()?, 270 info: parser.parens(|parser| { 271 parser.parse::<kw::canon>()?; 272 parser.parse() 273 })?, 274 }) 275 } 276 } 277} 278 279/// A WebAssembly canonical function to be inserted into a component. 280/// 281/// This is a member of the canonical section. 282#[derive(Debug)] 283pub struct CanonicalFunc<'a> { 284 /// Where this `func` was defined. 285 pub span: Span, 286 /// An identifier that this function is resolved with (optionally) for name 287 /// resolution. 288 pub id: Option<Id<'a>>, 289 /// An optional name for this function stored in the custom `name` section. 290 pub name: Option<NameAnnotation<'a>>, 291 /// What kind of function this is, be it a lowered or lifted function. 292 pub kind: CanonicalFuncKind<'a>, 293} 294 295impl<'a> Parse<'a> for CanonicalFunc<'a> { 296 fn parse(parser: Parser<'a>) -> Result<Self> { 297 let span = parser.parse::<kw::canon>()?.0; 298 let mut l = parser.lookahead1(); 299 300 if l.peek::<kw::lift>()? { 301 let info = parser.parse()?; 302 let (id, name, ty) = parser.parens(|parser| { 303 parser.parse::<kw::func>()?; 304 let id = parser.parse()?; 305 let name = parser.parse()?; 306 let ty = parser.parse()?; 307 Ok((id, name, ty)) 308 })?; 309 310 Ok(Self { 311 span, 312 id, 313 name, 314 kind: CanonicalFuncKind::Lift { info, ty }, 315 }) 316 } else { 317 let kind = CoreFuncKind::parse_lookahead(l)?; 318 let (id, name) = parser.parens(|parser| { 319 parser.parse::<kw::core>()?; 320 parser.parse::<kw::func>()?; 321 let id = parser.parse()?; 322 let name = parser.parse()?; 323 Ok((id, name)) 324 })?; 325 326 Ok(Self { 327 span, 328 id, 329 name, 330 kind: CanonicalFuncKind::Core(kind), 331 }) 332 } 333 } 334} 335 336/// Possible ways to define a canonical function in the text format. 337#[derive(Debug)] 338#[allow(missing_docs)] 339pub enum CanonicalFuncKind<'a> { 340 /// A canonical function that is defined in terms of lifting a core function. 341 Lift { 342 /// The lifted function's type. 343 ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>, 344 /// Information relating to the lifting of the core function. 345 info: CanonLift<'a>, 346 }, 347 348 /// A canonical function that defines a core function, whose variants are 349 /// delegated to `CoreFuncKind`. 350 Core(CoreFuncKind<'a>), 351} 352 353/// Information relating to lifting a core function. 354#[derive(Debug)] 355pub struct CanonLift<'a> { 356 /// The core function being lifted. 357 pub func: CoreItemRef<'a, kw::func>, 358 /// The canonical options for the lifting. 359 pub opts: Vec<CanonOpt<'a>>, 360} 361 362impl<'a> Parse<'a> for CanonLift<'a> { 363 fn parse(parser: Parser<'a>) -> Result<Self> { 364 parser.parse::<kw::lift>()?; 365 366 Ok(Self { 367 func: parser.parens(|parser| { 368 parser.parse::<kw::core>()?; 369 parser.parse() 370 })?, 371 opts: parser.parse()?, 372 }) 373 } 374} 375 376impl Default for CanonLift<'_> { 377 fn default() -> Self { 378 let span = Span::from_offset(0); 379 Self { 380 func: CoreItemRef { 381 kind: kw::func(span), 382 idx: Index::Num(0, span), 383 export_name: None, 384 }, 385 opts: Vec::new(), 386 } 387 } 388} 389 390/// Information relating to lowering a component function. 391#[derive(Debug)] 392pub struct CanonLower<'a> { 393 /// The function being lowered. 394 pub func: ItemRef<'a, kw::func>, 395 /// The canonical options for the lowering. 396 pub opts: Vec<CanonOpt<'a>>, 397} 398 399impl<'a> Parse<'a> for CanonLower<'a> { 400 fn parse(parser: Parser<'a>) -> Result<Self> { 401 parser.parse::<kw::lower>()?; 402 403 Ok(Self { 404 func: parser.parens(|parser| parser.parse())?, 405 opts: parser.parse()?, 406 }) 407 } 408} 409 410impl Default for CanonLower<'_> { 411 fn default() -> Self { 412 let span = Span::from_offset(0); 413 Self { 414 func: ItemRef { 415 kind: kw::func(span), 416 idx: Index::Num(0, span), 417 export_names: Vec::new(), 418 }, 419 opts: Vec::new(), 420 } 421 } 422} 423 424/// Information relating to the `resource.new` intrinsic. 425#[derive(Debug)] 426pub struct CanonResourceNew<'a> { 427 /// The resource type that this intrinsic creates an owned reference to. 428 pub ty: Index<'a>, 429} 430 431impl<'a> Parse<'a> for CanonResourceNew<'a> { 432 fn parse(parser: Parser<'a>) -> Result<Self> { 433 parser.parse::<kw::resource_new>()?; 434 435 Ok(Self { 436 ty: parser.parse()?, 437 }) 438 } 439} 440 441/// Information relating to the `resource.drop` intrinsic. 442#[derive(Debug)] 443pub struct CanonResourceDrop<'a> { 444 /// The resource type that this intrinsic is dropping. 445 pub ty: Index<'a>, 446 /// Whether or not this function is async 447 pub async_: bool, 448} 449 450impl<'a> Parse<'a> for CanonResourceDrop<'a> { 451 fn parse(parser: Parser<'a>) -> Result<Self> { 452 parser.parse::<kw::resource_drop>()?; 453 454 Ok(Self { 455 ty: parser.parse()?, 456 async_: parser.parse::<Option<kw::r#async>>()?.is_some(), 457 }) 458 } 459} 460 461/// Information relating to the `resource.rep` intrinsic. 462#[derive(Debug)] 463pub struct CanonResourceRep<'a> { 464 /// The resource type that this intrinsic is accessing. 465 pub ty: Index<'a>, 466} 467 468impl<'a> Parse<'a> for CanonResourceRep<'a> { 469 fn parse(parser: Parser<'a>) -> Result<Self> { 470 parser.parse::<kw::resource_rep>()?; 471 472 Ok(Self { 473 ty: parser.parse()?, 474 }) 475 } 476} 477 478/// Information relating to the `thread.spawn_ref` intrinsic. 479#[derive(Debug)] 480pub struct CanonThreadSpawnRef<'a> { 481 /// The function type that is being spawned. 482 pub ty: Index<'a>, 483} 484 485impl<'a> Parse<'a> for CanonThreadSpawnRef<'a> { 486 fn parse(parser: Parser<'a>) -> Result<Self> { 487 parser.parse::<kw::thread_spawn_ref>()?; 488 489 Ok(Self { 490 ty: parser.parse()?, 491 }) 492 } 493} 494 495/// Information relating to the `thread.spawn_indirect` intrinsic. 496/// 497/// This should look quite similar to parsing of `CallIndirect`. 498#[derive(Debug)] 499pub struct CanonThreadSpawnIndirect<'a> { 500 /// The function type that is being spawned. 501 pub ty: Index<'a>, 502 /// The table that this spawn is going to be indexing. 503 pub table: CoreItemRef<'a, kw::table>, 504} 505 506impl<'a> Parse<'a> for CanonThreadSpawnIndirect<'a> { 507 fn parse(parser: Parser<'a>) -> Result<Self> { 508 parser.parse::<kw::thread_spawn_indirect>()?; 509 let ty = parser.parse()?; 510 let table = parser.parens(|p| p.parse())?; 511 Ok(Self { ty, table }) 512 } 513} 514 515/// Information relating to the `thread.spawn` intrinsic. 516#[derive(Debug)] 517pub struct CanonThreadAvailableParallelism; 518 519impl<'a> Parse<'a> for CanonThreadAvailableParallelism { 520 fn parse(parser: Parser<'a>) -> Result<Self> { 521 parser.parse::<kw::thread_available_parallelism>()?; 522 Ok(Self) 523 } 524} 525 526/// Information relating to the `task.return` intrinsic. 527#[derive(Debug)] 528pub struct CanonTaskReturn<'a> { 529 /// The type of the result which may be returned with this intrinsic. 530 pub result: Option<ComponentValType<'a>>, 531 /// The canonical options for storing values. 532 pub opts: Vec<CanonOpt<'a>>, 533} 534 535impl<'a> Parse<'a> for CanonTaskReturn<'a> { 536 fn parse(parser: Parser<'a>) -> Result<Self> { 537 parser.parse::<kw::task_return>()?; 538 539 Ok(Self { 540 result: if parser.peek2::<kw::result>()? { 541 Some(parser.parens(|p| { 542 p.parse::<kw::result>()?.0; 543 p.parse() 544 })?) 545 } else { 546 None 547 }, 548 opts: parser.parse()?, 549 }) 550 } 551} 552 553/// Information relating to the `waitable-set.wait` intrinsic. 554#[derive(Debug)] 555pub struct CanonWaitableSetWait<'a> { 556 /// If true, the component instance may be reentered during a call to this 557 /// intrinsic. 558 pub async_: bool, 559 /// The memory to use when returning an event to the caller. 560 pub memory: CoreItemRef<'a, kw::memory>, 561} 562 563impl<'a> Parse<'a> for CanonWaitableSetWait<'a> { 564 fn parse(parser: Parser<'a>) -> Result<Self> { 565 parser.parse::<kw::waitable_set_wait>()?; 566 let async_ = parser.parse::<Option<kw::r#async>>()?.is_some(); 567 let memory = parser.parens(|p| p.parse())?; 568 569 Ok(Self { async_, memory }) 570 } 571} 572 573/// Information relating to the `waitable-set.poll` intrinsic. 574#[derive(Debug)] 575pub struct CanonWaitableSetPoll<'a> { 576 /// If true, the component instance may be reentered during a call to this 577 /// intrinsic. 578 pub async_: bool, 579 /// The memory to use when returning an event to the caller. 580 pub memory: CoreItemRef<'a, kw::memory>, 581} 582 583impl<'a> Parse<'a> for CanonWaitableSetPoll<'a> { 584 fn parse(parser: Parser<'a>) -> Result<Self> { 585 parser.parse::<kw::waitable_set_poll>()?; 586 let async_ = parser.parse::<Option<kw::r#async>>()?.is_some(); 587 let memory = parser.parens(|p| p.parse())?; 588 589 Ok(Self { async_, memory }) 590 } 591} 592 593/// Information relating to the `task.yield` intrinsic. 594#[derive(Debug)] 595pub struct CanonYield { 596 /// If true, the component instance may be reentered during a call to this 597 /// intrinsic. 598 pub async_: bool, 599} 600 601impl<'a> Parse<'a> for CanonYield { 602 fn parse(parser: Parser<'a>) -> Result<Self> { 603 parser.parse::<kw::yield_>()?; 604 let async_ = parser.parse::<Option<kw::r#async>>()?.is_some(); 605 606 Ok(Self { async_ }) 607 } 608} 609 610/// Information relating to the `stream.new` intrinsic. 611#[derive(Debug)] 612pub struct CanonStreamNew<'a> { 613 /// The stream type to instantiate. 614 pub ty: Index<'a>, 615} 616 617impl<'a> Parse<'a> for CanonStreamNew<'a> { 618 fn parse(parser: Parser<'a>) -> Result<Self> { 619 parser.parse::<kw::stream_new>()?; 620 621 Ok(Self { 622 ty: parser.parse()?, 623 }) 624 } 625} 626 627/// Information relating to the `stream.read` intrinsic. 628#[derive(Debug)] 629pub struct CanonStreamRead<'a> { 630 /// The stream type to instantiate. 631 pub ty: Index<'a>, 632 /// The canonical options for storing values. 633 pub opts: Vec<CanonOpt<'a>>, 634} 635 636impl<'a> Parse<'a> for CanonStreamRead<'a> { 637 fn parse(parser: Parser<'a>) -> Result<Self> { 638 parser.parse::<kw::stream_read>()?; 639 640 Ok(Self { 641 ty: parser.parse()?, 642 opts: parser.parse()?, 643 }) 644 } 645} 646 647/// Information relating to the `stream.write` intrinsic. 648#[derive(Debug)] 649pub struct CanonStreamWrite<'a> { 650 /// The stream type to instantiate. 651 pub ty: Index<'a>, 652 /// The canonical options for loading values. 653 pub opts: Vec<CanonOpt<'a>>, 654} 655 656impl<'a> Parse<'a> for CanonStreamWrite<'a> { 657 fn parse(parser: Parser<'a>) -> Result<Self> { 658 parser.parse::<kw::stream_write>()?; 659 660 Ok(Self { 661 ty: parser.parse()?, 662 opts: parser.parse()?, 663 }) 664 } 665} 666 667/// Information relating to the `stream.cancel-read` intrinsic. 668#[derive(Debug)] 669pub struct CanonStreamCancelRead<'a> { 670 /// The stream type to instantiate. 671 pub ty: Index<'a>, 672 /// If false, block until cancel is finished; otherwise return BLOCKED if 673 /// necessary. 674 pub async_: bool, 675} 676 677impl<'a> Parse<'a> for CanonStreamCancelRead<'a> { 678 fn parse(parser: Parser<'a>) -> Result<Self> { 679 parser.parse::<kw::stream_cancel_read>()?; 680 681 Ok(Self { 682 ty: parser.parse()?, 683 async_: parser.parse::<Option<kw::r#async>>()?.is_some(), 684 }) 685 } 686} 687 688/// Information relating to the `stream.cancel-write` intrinsic. 689#[derive(Debug)] 690pub struct CanonStreamCancelWrite<'a> { 691 /// The stream type to instantiate. 692 pub ty: Index<'a>, 693 /// If false, block until cancel is finished; otherwise return BLOCKED if 694 /// necessary. 695 pub async_: bool, 696} 697 698impl<'a> Parse<'a> for CanonStreamCancelWrite<'a> { 699 fn parse(parser: Parser<'a>) -> Result<Self> { 700 parser.parse::<kw::stream_cancel_write>()?; 701 702 Ok(Self { 703 ty: parser.parse()?, 704 async_: parser.parse::<Option<kw::r#async>>()?.is_some(), 705 }) 706 } 707} 708 709/// Information relating to the `stream.close-readable` intrinsic. 710#[derive(Debug)] 711pub struct CanonStreamCloseReadable<'a> { 712 /// The stream type to close. 713 pub ty: Index<'a>, 714} 715 716impl<'a> Parse<'a> for CanonStreamCloseReadable<'a> { 717 fn parse(parser: Parser<'a>) -> Result<Self> { 718 parser.parse::<kw::stream_close_readable>()?; 719 720 Ok(Self { 721 ty: parser.parse()?, 722 }) 723 } 724} 725 726/// Information relating to the `stream.close-writable` intrinsic. 727#[derive(Debug)] 728pub struct CanonStreamCloseWritable<'a> { 729 /// The stream type to close. 730 pub ty: Index<'a>, 731} 732 733impl<'a> Parse<'a> for CanonStreamCloseWritable<'a> { 734 fn parse(parser: Parser<'a>) -> Result<Self> { 735 parser.parse::<kw::stream_close_writable>()?; 736 737 Ok(Self { 738 ty: parser.parse()?, 739 }) 740 } 741} 742 743/// Information relating to the `future.new` intrinsic. 744#[derive(Debug)] 745pub struct CanonFutureNew<'a> { 746 /// The future type to instantiate. 747 pub ty: Index<'a>, 748} 749 750impl<'a> Parse<'a> for CanonFutureNew<'a> { 751 fn parse(parser: Parser<'a>) -> Result<Self> { 752 parser.parse::<kw::future_new>()?; 753 754 Ok(Self { 755 ty: parser.parse()?, 756 }) 757 } 758} 759 760/// Information relating to the `future.read` intrinsic. 761#[derive(Debug)] 762pub struct CanonFutureRead<'a> { 763 /// The future type to instantiate. 764 pub ty: Index<'a>, 765 /// The canonical options for storing values. 766 pub opts: Vec<CanonOpt<'a>>, 767} 768 769impl<'a> Parse<'a> for CanonFutureRead<'a> { 770 fn parse(parser: Parser<'a>) -> Result<Self> { 771 parser.parse::<kw::future_read>()?; 772 773 Ok(Self { 774 ty: parser.parse()?, 775 opts: parser.parse()?, 776 }) 777 } 778} 779 780/// Information relating to the `future.write` intrinsic. 781#[derive(Debug)] 782pub struct CanonFutureWrite<'a> { 783 /// The future type to instantiate. 784 pub ty: Index<'a>, 785 /// The canonical options for loading values. 786 pub opts: Vec<CanonOpt<'a>>, 787} 788 789impl<'a> Parse<'a> for CanonFutureWrite<'a> { 790 fn parse(parser: Parser<'a>) -> Result<Self> { 791 parser.parse::<kw::future_write>()?; 792 793 Ok(Self { 794 ty: parser.parse()?, 795 opts: parser.parse()?, 796 }) 797 } 798} 799 800/// Information relating to the `future.cancel-read` intrinsic. 801#[derive(Debug)] 802pub struct CanonFutureCancelRead<'a> { 803 /// The future type to instantiate. 804 pub ty: Index<'a>, 805 /// If false, block until cancel is finished; otherwise return BLOCKED if 806 /// necessary. 807 pub async_: bool, 808} 809 810impl<'a> Parse<'a> for CanonFutureCancelRead<'a> { 811 fn parse(parser: Parser<'a>) -> Result<Self> { 812 parser.parse::<kw::future_cancel_read>()?; 813 814 Ok(Self { 815 ty: parser.parse()?, 816 async_: parser.parse::<Option<kw::r#async>>()?.is_some(), 817 }) 818 } 819} 820 821/// Information relating to the `future.cancel-write` intrinsic. 822#[derive(Debug)] 823pub struct CanonFutureCancelWrite<'a> { 824 /// The future type to instantiate. 825 pub ty: Index<'a>, 826 /// If false, block until cancel is finished; otherwise return BLOCKED if 827 /// necessary. 828 pub async_: bool, 829} 830 831impl<'a> Parse<'a> for CanonFutureCancelWrite<'a> { 832 fn parse(parser: Parser<'a>) -> Result<Self> { 833 parser.parse::<kw::future_cancel_write>()?; 834 835 Ok(Self { 836 ty: parser.parse()?, 837 async_: parser.parse::<Option<kw::r#async>>()?.is_some(), 838 }) 839 } 840} 841 842/// Information relating to the `future.close-readable` intrinsic. 843#[derive(Debug)] 844pub struct CanonFutureCloseReadable<'a> { 845 /// The future type to close. 846 pub ty: Index<'a>, 847} 848 849impl<'a> Parse<'a> for CanonFutureCloseReadable<'a> { 850 fn parse(parser: Parser<'a>) -> Result<Self> { 851 parser.parse::<kw::future_close_readable>()?; 852 853 Ok(Self { 854 ty: parser.parse()?, 855 }) 856 } 857} 858 859/// Information relating to the `future.close-writable` intrinsic. 860#[derive(Debug)] 861pub struct CanonFutureCloseWritable<'a> { 862 /// The future type to close. 863 pub ty: Index<'a>, 864} 865 866impl<'a> Parse<'a> for CanonFutureCloseWritable<'a> { 867 fn parse(parser: Parser<'a>) -> Result<Self> { 868 parser.parse::<kw::future_close_writable>()?; 869 870 Ok(Self { 871 ty: parser.parse()?, 872 }) 873 } 874} 875 876/// Information relating to the `error-context.new` intrinsic. 877#[derive(Debug)] 878pub struct CanonErrorContextNew<'a> { 879 /// The canonical options for loading the debug message. 880 pub opts: Vec<CanonOpt<'a>>, 881} 882 883impl<'a> Parse<'a> for CanonErrorContextNew<'a> { 884 fn parse(parser: Parser<'a>) -> Result<Self> { 885 parser.parse::<kw::error_context_new>()?; 886 887 Ok(Self { 888 opts: parser.parse()?, 889 }) 890 } 891} 892 893/// Information relating to the `error-context.debug-message` intrinsic. 894#[derive(Debug)] 895pub struct CanonErrorContextDebugMessage<'a> { 896 /// The canonical options for storing the debug message. 897 pub opts: Vec<CanonOpt<'a>>, 898} 899 900impl<'a> Parse<'a> for CanonErrorContextDebugMessage<'a> { 901 fn parse(parser: Parser<'a>) -> Result<Self> { 902 parser.parse::<kw::error_context_debug_message>()?; 903 904 Ok(Self { 905 opts: parser.parse()?, 906 }) 907 } 908} 909 910#[derive(Debug)] 911/// Canonical ABI options. 912pub enum CanonOpt<'a> { 913 /// Encode strings as UTF-8. 914 StringUtf8, 915 /// Encode strings as UTF-16. 916 StringUtf16, 917 /// Encode strings as "compact UTF-16". 918 StringLatin1Utf16, 919 /// Use the specified memory for canonical ABI memory access. 920 Memory(CoreItemRef<'a, kw::memory>), 921 /// Use the specified reallocation function for memory allocations. 922 Realloc(CoreItemRef<'a, kw::func>), 923 /// Call the specified function after the lifted function has returned. 924 PostReturn(CoreItemRef<'a, kw::func>), 925 /// Use the async ABI for lifting or lowering. 926 Async, 927 /// Use the specified function to deliver async events to stackless coroutines. 928 Callback(CoreItemRef<'a, kw::func>), 929} 930 931impl<'a> Parse<'a> for CanonOpt<'a> { 932 fn parse(parser: Parser<'a>) -> Result<Self> { 933 let mut l = parser.lookahead1(); 934 if l.peek::<kw::string_utf8>()? { 935 parser.parse::<kw::string_utf8>()?; 936 Ok(Self::StringUtf8) 937 } else if l.peek::<kw::string_utf16>()? { 938 parser.parse::<kw::string_utf16>()?; 939 Ok(Self::StringUtf16) 940 } else if l.peek::<kw::string_latin1_utf16>()? { 941 parser.parse::<kw::string_latin1_utf16>()?; 942 Ok(Self::StringLatin1Utf16) 943 } else if l.peek::<kw::r#async>()? { 944 parser.parse::<kw::r#async>()?; 945 Ok(Self::Async) 946 } else if l.peek::<LParen>()? { 947 parser.parens(|parser| { 948 let mut l = parser.lookahead1(); 949 if l.peek::<kw::memory>()? { 950 Ok(CanonOpt::Memory(parser.parse()?)) 951 } else if l.peek::<kw::realloc>()? { 952 parser.parse::<kw::realloc>()?; 953 Ok(CanonOpt::Realloc( 954 parser.parse::<IndexOrCoreRef<'_, _>>()?.0, 955 )) 956 } else if l.peek::<kw::post_return>()? { 957 parser.parse::<kw::post_return>()?; 958 Ok(CanonOpt::PostReturn( 959 parser.parse::<IndexOrCoreRef<'_, _>>()?.0, 960 )) 961 } else if l.peek::<kw::callback>()? { 962 parser.parse::<kw::callback>()?; 963 Ok(CanonOpt::Callback( 964 parser.parse::<IndexOrCoreRef<'_, _>>()?.0, 965 )) 966 } else { 967 Err(l.error()) 968 } 969 }) 970 } else { 971 Err(l.error()) 972 } 973 } 974} 975 976impl Peek for CanonOpt<'_> { 977 fn peek(cursor: Cursor<'_>) -> Result<bool> { 978 Ok(kw::string_utf8::peek(cursor)? 979 || kw::string_utf16::peek(cursor)? 980 || kw::string_latin1_utf16::peek(cursor)? 981 || kw::r#async::peek(cursor)? 982 || match cursor.lparen()? { 983 Some(next) => { 984 kw::memory::peek(next)? 985 || kw::realloc::peek(next)? 986 || kw::post_return::peek(next)? 987 || kw::callback::peek(next)? 988 } 989 None => false, 990 }) 991 } 992 993 fn display() -> &'static str { 994 "canonical option" 995 } 996} 997 998impl<'a> Parse<'a> for Vec<CanonOpt<'a>> { 999 fn parse(parser: Parser<'a>) -> Result<Self> { 1000 let mut funcs = Vec::new(); 1001 while parser.peek::<CanonOpt<'_>>()? { 1002 funcs.push(parser.parse()?); 1003 } 1004 Ok(funcs) 1005 } 1006}