wast/component/
func.rs

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 = parser.parse::<kw::core>()?.0;
25        parser.parse::<kw::func>()?;
26        let id = parser.parse()?;
27        let name = parser.parse()?;
28        let kind = 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    ThreadAvailableParallelism(CanonThreadAvailableParallelism),
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_available_parallelism>()? {
104                Ok(CoreFuncKind::ThreadAvailableParallelism(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 = parser.parse::<kw::func>()?.0;
183        let id = parser.parse()?;
184        let name = parser.parse()?;
185        let exports = parser.parse()?;
186        let kind = 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) = 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| Ok(Self::Alias(parser.parse()?)))
236        } else {
237            Ok(Self::Lift {
238                ty: parser.parse()?,
239                info: parser.parens(|parser| {
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    ThreadAvailableParallelism(CanonThreadAvailableParallelism),
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| {
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::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.parse())?,
423            opts: parser.parse()?,
424        })
425    }
426}
427
428impl Default for CanonLower<'_> {
429    fn default() -> Self {
430        let 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 CanonThreadAvailableParallelism;
513
514impl<'a> Parse<'a> for CanonThreadAvailableParallelism {
515    fn parse(parser: Parser<'a>) -> Result<Self> {
516        parser.parse::<kw::thread_available_parallelism>()?;
517        Ok(Self)
518    }
519}
520
521/// Information relating to the `task.return` intrinsic.
522#[derive(Debug)]
523pub struct CanonTaskReturn<'a> {
524    /// The type of the result which may be returned with this intrinsic.
525    pub result: Option<ComponentValType<'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        let result = if parser.peek2::<kw::result>()? {
533            Some(parser.parens(|p| {
534                p.parse::<kw::result>()?.0;
535                p.parse()
536            })?)
537        } else {
538            None
539        };
540
541        Ok(Self { result })
542    }
543}
544
545/// Information relating to the `task.wait` intrinsic.
546#[derive(Debug)]
547pub struct CanonTaskWait<'a> {
548    /// If true, the component instance may be reentered during a call to this
549    /// intrinsic.
550    pub async_: bool,
551    /// The memory to use when returning an event to the caller.
552    pub memory: CoreItemRef<'a, kw::memory>,
553}
554
555impl<'a> Parse<'a> for CanonTaskWait<'a> {
556    fn parse(parser: Parser<'a>) -> Result<Self> {
557        parser.parse::<kw::task_wait>()?;
558        let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
559        let memory = parser.parens(|parser| {
560            let span = parser.parse::<kw::memory>()?.0;
561            parse_trailing_item_ref(kw::memory(span), parser)
562        })?;
563
564        Ok(Self { async_, memory })
565    }
566}
567
568/// Information relating to the `task.poll` intrinsic.
569#[derive(Debug)]
570pub struct CanonTaskPoll<'a> {
571    /// If true, the component instance may be reentered during a call to this
572    /// intrinsic.
573    pub async_: bool,
574    /// The memory to use when returning an event to the caller.
575    pub memory: CoreItemRef<'a, kw::memory>,
576}
577
578impl<'a> Parse<'a> for CanonTaskPoll<'a> {
579    fn parse(parser: Parser<'a>) -> Result<Self> {
580        parser.parse::<kw::task_poll>()?;
581        let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
582        let memory = parser.parens(|parser| {
583            let span = parser.parse::<kw::memory>()?.0;
584            parse_trailing_item_ref(kw::memory(span), parser)
585        })?;
586
587        Ok(Self { async_, memory })
588    }
589}
590
591/// Information relating to the `task.yield` intrinsic.
592#[derive(Debug)]
593pub struct CanonTaskYield {
594    /// If true, the component instance may be reentered during a call to this
595    /// intrinsic.
596    pub async_: bool,
597}
598
599impl<'a> Parse<'a> for CanonTaskYield {
600    fn parse(parser: Parser<'a>) -> Result<Self> {
601        parser.parse::<kw::task_yield>()?;
602        let async_ = parser.parse::<Option<kw::r#async>>()?.is_some();
603
604        Ok(Self { async_ })
605    }
606}
607
608/// Information relating to the `stream.new` intrinsic.
609#[derive(Debug)]
610pub struct CanonStreamNew<'a> {
611    /// The stream type to instantiate.
612    pub ty: Index<'a>,
613}
614
615impl<'a> Parse<'a> for CanonStreamNew<'a> {
616    fn parse(parser: Parser<'a>) -> Result<Self> {
617        parser.parse::<kw::stream_new>()?;
618
619        Ok(Self {
620            ty: parser.parse()?,
621        })
622    }
623}
624
625/// Information relating to the `stream.read` intrinsic.
626#[derive(Debug)]
627pub struct CanonStreamRead<'a> {
628    /// The stream type to instantiate.
629    pub ty: Index<'a>,
630    /// The canonical options for storing values.
631    pub opts: Vec<CanonOpt<'a>>,
632}
633
634impl<'a> Parse<'a> for CanonStreamRead<'a> {
635    fn parse(parser: Parser<'a>) -> Result<Self> {
636        parser.parse::<kw::stream_read>()?;
637
638        Ok(Self {
639            ty: parser.parse()?,
640            opts: parser.parse()?,
641        })
642    }
643}
644
645/// Information relating to the `stream.write` intrinsic.
646#[derive(Debug)]
647pub struct CanonStreamWrite<'a> {
648    /// The stream type to instantiate.
649    pub ty: Index<'a>,
650    /// The canonical options for loading values.
651    pub opts: Vec<CanonOpt<'a>>,
652}
653
654impl<'a> Parse<'a> for CanonStreamWrite<'a> {
655    fn parse(parser: Parser<'a>) -> Result<Self> {
656        parser.parse::<kw::stream_write>()?;
657
658        Ok(Self {
659            ty: parser.parse()?,
660            opts: parser.parse()?,
661        })
662    }
663}
664
665/// Information relating to the `stream.cancel-read` intrinsic.
666#[derive(Debug)]
667pub struct CanonStreamCancelRead<'a> {
668    /// The stream type to instantiate.
669    pub ty: Index<'a>,
670    /// If false, block until cancel is finished; otherwise return BLOCKED if
671    /// necessary.
672    pub async_: bool,
673}
674
675impl<'a> Parse<'a> for CanonStreamCancelRead<'a> {
676    fn parse(parser: Parser<'a>) -> Result<Self> {
677        parser.parse::<kw::stream_cancel_read>()?;
678
679        Ok(Self {
680            ty: parser.parse()?,
681            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
682        })
683    }
684}
685
686/// Information relating to the `stream.cancel-write` intrinsic.
687#[derive(Debug)]
688pub struct CanonStreamCancelWrite<'a> {
689    /// The stream type to instantiate.
690    pub ty: Index<'a>,
691    /// If false, block until cancel is finished; otherwise return BLOCKED if
692    /// necessary.
693    pub async_: bool,
694}
695
696impl<'a> Parse<'a> for CanonStreamCancelWrite<'a> {
697    fn parse(parser: Parser<'a>) -> Result<Self> {
698        parser.parse::<kw::stream_cancel_write>()?;
699
700        Ok(Self {
701            ty: parser.parse()?,
702            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
703        })
704    }
705}
706
707/// Information relating to the `stream.close-readable` intrinsic.
708#[derive(Debug)]
709pub struct CanonStreamCloseReadable<'a> {
710    /// The stream type to close.
711    pub ty: Index<'a>,
712}
713
714impl<'a> Parse<'a> for CanonStreamCloseReadable<'a> {
715    fn parse(parser: Parser<'a>) -> Result<Self> {
716        parser.parse::<kw::stream_close_readable>()?;
717
718        Ok(Self {
719            ty: parser.parse()?,
720        })
721    }
722}
723
724/// Information relating to the `stream.close-writable` intrinsic.
725#[derive(Debug)]
726pub struct CanonStreamCloseWritable<'a> {
727    /// The stream type to close.
728    pub ty: Index<'a>,
729}
730
731impl<'a> Parse<'a> for CanonStreamCloseWritable<'a> {
732    fn parse(parser: Parser<'a>) -> Result<Self> {
733        parser.parse::<kw::stream_close_writable>()?;
734
735        Ok(Self {
736            ty: parser.parse()?,
737        })
738    }
739}
740
741/// Information relating to the `future.new` intrinsic.
742#[derive(Debug)]
743pub struct CanonFutureNew<'a> {
744    /// The future type to instantiate.
745    pub ty: Index<'a>,
746}
747
748impl<'a> Parse<'a> for CanonFutureNew<'a> {
749    fn parse(parser: Parser<'a>) -> Result<Self> {
750        parser.parse::<kw::future_new>()?;
751
752        Ok(Self {
753            ty: parser.parse()?,
754        })
755    }
756}
757
758/// Information relating to the `future.read` intrinsic.
759#[derive(Debug)]
760pub struct CanonFutureRead<'a> {
761    /// The future type to instantiate.
762    pub ty: Index<'a>,
763    /// The canonical options for storing values.
764    pub opts: Vec<CanonOpt<'a>>,
765}
766
767impl<'a> Parse<'a> for CanonFutureRead<'a> {
768    fn parse(parser: Parser<'a>) -> Result<Self> {
769        parser.parse::<kw::future_read>()?;
770
771        Ok(Self {
772            ty: parser.parse()?,
773            opts: parser.parse()?,
774        })
775    }
776}
777
778/// Information relating to the `future.write` intrinsic.
779#[derive(Debug)]
780pub struct CanonFutureWrite<'a> {
781    /// The future type to instantiate.
782    pub ty: Index<'a>,
783    /// The canonical options for loading values.
784    pub opts: Vec<CanonOpt<'a>>,
785}
786
787impl<'a> Parse<'a> for CanonFutureWrite<'a> {
788    fn parse(parser: Parser<'a>) -> Result<Self> {
789        parser.parse::<kw::future_write>()?;
790
791        Ok(Self {
792            ty: parser.parse()?,
793            opts: parser.parse()?,
794        })
795    }
796}
797
798/// Information relating to the `future.cancel-read` intrinsic.
799#[derive(Debug)]
800pub struct CanonFutureCancelRead<'a> {
801    /// The future type to instantiate.
802    pub ty: Index<'a>,
803    /// If false, block until cancel is finished; otherwise return BLOCKED if
804    /// necessary.
805    pub async_: bool,
806}
807
808impl<'a> Parse<'a> for CanonFutureCancelRead<'a> {
809    fn parse(parser: Parser<'a>) -> Result<Self> {
810        parser.parse::<kw::future_cancel_read>()?;
811
812        Ok(Self {
813            ty: parser.parse()?,
814            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
815        })
816    }
817}
818
819/// Information relating to the `future.cancel-write` intrinsic.
820#[derive(Debug)]
821pub struct CanonFutureCancelWrite<'a> {
822    /// The future type to instantiate.
823    pub ty: Index<'a>,
824    /// If false, block until cancel is finished; otherwise return BLOCKED if
825    /// necessary.
826    pub async_: bool,
827}
828
829impl<'a> Parse<'a> for CanonFutureCancelWrite<'a> {
830    fn parse(parser: Parser<'a>) -> Result<Self> {
831        parser.parse::<kw::future_cancel_write>()?;
832
833        Ok(Self {
834            ty: parser.parse()?,
835            async_: parser.parse::<Option<kw::r#async>>()?.is_some(),
836        })
837    }
838}
839
840/// Information relating to the `future.close-readable` intrinsic.
841#[derive(Debug)]
842pub struct CanonFutureCloseReadable<'a> {
843    /// The future type to close.
844    pub ty: Index<'a>,
845}
846
847impl<'a> Parse<'a> for CanonFutureCloseReadable<'a> {
848    fn parse(parser: Parser<'a>) -> Result<Self> {
849        parser.parse::<kw::future_close_readable>()?;
850
851        Ok(Self {
852            ty: parser.parse()?,
853        })
854    }
855}
856
857/// Information relating to the `future.close-writable` intrinsic.
858#[derive(Debug)]
859pub struct CanonFutureCloseWritable<'a> {
860    /// The future type to close.
861    pub ty: Index<'a>,
862}
863
864impl<'a> Parse<'a> for CanonFutureCloseWritable<'a> {
865    fn parse(parser: Parser<'a>) -> Result<Self> {
866        parser.parse::<kw::future_close_writable>()?;
867
868        Ok(Self {
869            ty: parser.parse()?,
870        })
871    }
872}
873
874/// Information relating to the `error-context.new` intrinsic.
875#[derive(Debug)]
876pub struct CanonErrorContextNew<'a> {
877    /// The canonical options for loading the debug message.
878    pub opts: Vec<CanonOpt<'a>>,
879}
880
881impl<'a> Parse<'a> for CanonErrorContextNew<'a> {
882    fn parse(parser: Parser<'a>) -> Result<Self> {
883        parser.parse::<kw::error_context_new>()?;
884
885        Ok(Self {
886            opts: parser.parse()?,
887        })
888    }
889}
890
891/// Information relating to the `error-context.debug-message` intrinsic.
892#[derive(Debug)]
893pub struct CanonErrorContextDebugMessage<'a> {
894    /// The canonical options for storing the debug message.
895    pub opts: Vec<CanonOpt<'a>>,
896}
897
898impl<'a> Parse<'a> for CanonErrorContextDebugMessage<'a> {
899    fn parse(parser: Parser<'a>) -> Result<Self> {
900        parser.parse::<kw::error_context_debug_message>()?;
901
902        Ok(Self {
903            opts: parser.parse()?,
904        })
905    }
906}
907
908#[derive(Debug)]
909/// Canonical ABI options.
910pub enum CanonOpt<'a> {
911    /// Encode strings as UTF-8.
912    StringUtf8,
913    /// Encode strings as UTF-16.
914    StringUtf16,
915    /// Encode strings as "compact UTF-16".
916    StringLatin1Utf16,
917    /// Use the specified memory for canonical ABI memory access.
918    Memory(CoreItemRef<'a, kw::memory>),
919    /// Use the specified reallocation function for memory allocations.
920    Realloc(CoreItemRef<'a, kw::func>),
921    /// Call the specified function after the lifted function has returned.
922    PostReturn(CoreItemRef<'a, kw::func>),
923    /// Use the async ABI for lifting or lowering.
924    Async,
925    /// Use the specified function to deliver async events to stackless coroutines.
926    Callback(CoreItemRef<'a, kw::func>),
927}
928
929impl<'a> Parse<'a> for CanonOpt<'a> {
930    fn parse(parser: Parser<'a>) -> Result<Self> {
931        let mut l = parser.lookahead1();
932        if l.peek::<kw::string_utf8>()? {
933            parser.parse::<kw::string_utf8>()?;
934            Ok(Self::StringUtf8)
935        } else if l.peek::<kw::string_utf16>()? {
936            parser.parse::<kw::string_utf16>()?;
937            Ok(Self::StringUtf16)
938        } else if l.peek::<kw::string_latin1_utf16>()? {
939            parser.parse::<kw::string_latin1_utf16>()?;
940            Ok(Self::StringLatin1Utf16)
941        } else if l.peek::<kw::r#async>()? {
942            parser.parse::<kw::r#async>()?;
943            Ok(Self::Async)
944        } else if l.peek::<LParen>()? {
945            parser.parens(|parser| {
946                let mut l = parser.lookahead1();
947                if l.peek::<kw::memory>()? {
948                    let span = parser.parse::<kw::memory>()?.0;
949                    Ok(CanonOpt::Memory(parse_trailing_item_ref(
950                        kw::memory(span),
951                        parser,
952                    )?))
953                } else if l.peek::<kw::realloc>()? {
954                    parser.parse::<kw::realloc>()?;
955                    Ok(CanonOpt::Realloc(
956                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
957                    ))
958                } else if l.peek::<kw::post_return>()? {
959                    parser.parse::<kw::post_return>()?;
960                    Ok(CanonOpt::PostReturn(
961                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
962                    ))
963                } else if l.peek::<kw::callback>()? {
964                    parser.parse::<kw::callback>()?;
965                    Ok(CanonOpt::Callback(
966                        parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
967                    ))
968                } else {
969                    Err(l.error())
970                }
971            })
972        } else {
973            Err(l.error())
974        }
975    }
976}
977
978fn parse_trailing_item_ref<T>(kind: T, parser: Parser) -> Result<CoreItemRef<T>> {
979    Ok(CoreItemRef {
980        kind,
981        idx: parser.parse()?,
982        export_name: parser.parse()?,
983    })
984}
985
986impl<'a> Parse<'a> for Vec<CanonOpt<'a>> {
987    fn parse(parser: Parser<'a>) -> Result<Self> {
988        let mut funcs = Vec::new();
989        while !parser.is_empty() {
990            funcs.push(parser.parse()?);
991        }
992        Ok(funcs)
993    }
994}