wast/component/
func.rs

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