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