summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wast/src/ast/instance.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wast/src/ast/instance.rs')
-rw-r--r--third_party/rust/wast/src/ast/instance.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/third_party/rust/wast/src/ast/instance.rs b/third_party/rust/wast/src/ast/instance.rs
new file mode 100644
index 0000000000..6b41f477a9
--- /dev/null
+++ b/third_party/rust/wast/src/ast/instance.rs
@@ -0,0 +1,86 @@
+use crate::ast::{self, kw};
+use crate::parser::{Parse, Parser, Result};
+
+/// A nested WebAssembly instance to be created as part of a module.
+#[derive(Debug)]
+pub struct Instance<'a> {
+ /// Where this `instance` was defined.
+ pub span: ast::Span,
+ /// An identifier that this instance is resolved with (optionally) for name
+ /// resolution.
+ pub id: Option<ast::Id<'a>>,
+ /// If present, inline export annotations which indicate names this
+ /// definition should be exported under.
+ pub exports: ast::InlineExport<'a>,
+ /// What kind of instance this is, be it an inline-defined or imported one.
+ pub kind: InstanceKind<'a>,
+}
+
+/// Possible ways to define a instance in the text format.
+#[derive(Debug)]
+pub enum InstanceKind<'a> {
+ /// An instance which is actually defined as an import, such as:
+ Import {
+ /// Where we're importing from
+ import: ast::InlineImport<'a>,
+ /// The type that this instance will have.
+ ty: ast::TypeUse<'a, ast::InstanceType<'a>>,
+ },
+
+ /// Instances whose instantiation is defined inline.
+ Inline {
+ /// Module that we're instantiating
+ module: ast::ItemRef<'a, kw::module>,
+ /// Arguments used to instantiate the instance
+ args: Vec<InstanceArg<'a>>,
+ },
+}
+
+/// Arguments to the `instantiate` instruction
+#[derive(Debug)]
+#[allow(missing_docs)]
+pub struct InstanceArg<'a> {
+ pub name: &'a str,
+ pub index: ast::ItemRef<'a, ast::ExportKind>,
+}
+
+impl<'a> Parse<'a> for Instance<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ let span = parser.parse::<kw::instance>()?.0;
+ let id = parser.parse()?;
+ let exports = parser.parse()?;
+
+ let kind = if let Some(import) = parser.parse()? {
+ InstanceKind::Import {
+ import,
+ ty: parser.parse()?,
+ }
+ } else {
+ parser.parens(|p| {
+ p.parse::<kw::instantiate>()?;
+ let module = p.parse::<ast::IndexOrRef<_>>()?.0;
+ let mut args = Vec::new();
+ while !p.is_empty() {
+ args.push(p.parse()?);
+ }
+ Ok(InstanceKind::Inline { module, args })
+ })?
+ };
+
+ Ok(Instance {
+ span,
+ id,
+ exports,
+ kind,
+ })
+ }
+}
+
+impl<'a> Parse<'a> for InstanceArg<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ Ok(InstanceArg {
+ name: parser.parse()?,
+ index: parser.parse()?,
+ })
+ }
+}