Skip to main content

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