1 | use crate::core::*; |
2 | use crate::kw; |
3 | use crate::parser::{Parse, Parser, Result}; |
4 | use crate::token::{Id, NameAnnotation, Span}; |
5 | |
6 | /// A WebAssembly global in a module |
7 | #[derive (Debug)] |
8 | pub struct Global<'a> { |
9 | /// Where this `global` was defined. |
10 | pub span: Span, |
11 | /// An optional name to reference this global by |
12 | pub id: Option<Id<'a>>, |
13 | /// An optional name for this function stored in the custom `name` section. |
14 | pub name: Option<NameAnnotation<'a>>, |
15 | /// If present, inline export annotations which indicate names this |
16 | /// definition should be exported under. |
17 | pub exports: InlineExport<'a>, |
18 | /// The type of this global, both its value type and whether it's mutable. |
19 | pub ty: GlobalType<'a>, |
20 | /// What kind of global this defined as. |
21 | pub kind: GlobalKind<'a>, |
22 | } |
23 | |
24 | /// Different kinds of globals that can be defined in a module. |
25 | #[derive (Debug)] |
26 | pub enum GlobalKind<'a> { |
27 | /// A global which is actually defined as an import, such as: |
28 | /// |
29 | /// ```text |
30 | /// (global i32 (import "foo" "bar")) |
31 | /// ``` |
32 | Import(InlineImport<'a>), |
33 | |
34 | /// A global defined inline in the module itself |
35 | Inline(Expression<'a>), |
36 | } |
37 | |
38 | impl<'a> Parse<'a> for Global<'a> { |
39 | fn parse(parser: Parser<'a>) -> Result<Self> { |
40 | let span: Span = parser.parse::<kw::global>()?.0; |
41 | let id: Option> = parser.parse()?; |
42 | let name: Option> = parser.parse()?; |
43 | let exports: InlineExport<'_> = parser.parse()?; |
44 | |
45 | let (ty: GlobalType<'_>, kind: GlobalKind<'_>) = if let Some(import: InlineImport<'_>) = parser.parse()? { |
46 | (parser.parse()?, GlobalKind::Import(import)) |
47 | } else { |
48 | (parser.parse()?, GlobalKind::Inline(parser.parse()?)) |
49 | }; |
50 | Ok(Global { |
51 | span, |
52 | id, |
53 | name, |
54 | exports, |
55 | ty, |
56 | kind, |
57 | }) |
58 | } |
59 | } |
60 | |