1use crate::core::*;
2use crate::kw;
3use crate::parser::{Parse, Parser, Result};
4use crate::token::{Id, NameAnnotation, Span};
5
6/// A WebAssembly global in a module
7#[derive(Debug)]
8pub 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)]
26pub 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
38impl<'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