summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wast/src/component/instance.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wast/src/component/instance.rs')
-rw-r--r--third_party/rust/wast/src/component/instance.rs296
1 files changed, 296 insertions, 0 deletions
diff --git a/third_party/rust/wast/src/component/instance.rs b/third_party/rust/wast/src/component/instance.rs
new file mode 100644
index 0000000000..888f4ee9f9
--- /dev/null
+++ b/third_party/rust/wast/src/component/instance.rs
@@ -0,0 +1,296 @@
+use crate::component::*;
+use crate::core;
+use crate::kw;
+use crate::parser::{Parse, Parser, Result};
+use crate::token::{Id, LParen, NameAnnotation, Span};
+
+/// A core instance defined by instantiation or exporting core items.
+#[derive(Debug)]
+pub struct CoreInstance<'a> {
+ /// Where this `core instance` was defined.
+ pub span: Span,
+ /// An identifier that this instance is resolved with (optionally) for name
+ /// resolution.
+ pub id: Option<Id<'a>>,
+ /// An optional name for this instance stored in the custom `name` section.
+ pub name: Option<NameAnnotation<'a>>,
+ /// What kind of instance this is.
+ pub kind: CoreInstanceKind<'a>,
+}
+
+impl<'a> Parse<'a> for CoreInstance<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ let span = parser.parse::<kw::core>()?.0;
+ parser.parse::<kw::instance>()?;
+ let id = parser.parse()?;
+ let name = parser.parse()?;
+ let kind = parser.parse()?;
+
+ Ok(Self {
+ span,
+ id,
+ name,
+ kind,
+ })
+ }
+}
+
+/// The kinds of core instances in the text format.
+#[derive(Debug)]
+pub enum CoreInstanceKind<'a> {
+ /// Instantiate a core module.
+ Instantiate {
+ /// The module being instantiated.
+ module: ItemRef<'a, kw::module>,
+ /// Arguments used to instantiate the instance.
+ args: Vec<CoreInstantiationArg<'a>>,
+ },
+ /// The instance is defined by exporting local items as an instance.
+ BundleOfExports(Vec<CoreInstanceExport<'a>>),
+}
+
+impl<'a> Parse<'a> for CoreInstanceKind<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ if parser.peek::<LParen>() && parser.peek2::<kw::instantiate>() {
+ parser.parens(|parser| {
+ parser.parse::<kw::instantiate>()?;
+ Ok(Self::Instantiate {
+ module: parser.parse::<IndexOrRef<'_, _>>()?.0,
+ args: parser.parse()?,
+ })
+ })
+ } else {
+ Ok(Self::BundleOfExports(parser.parse()?))
+ }
+ }
+}
+
+impl Default for kw::module {
+ fn default() -> kw::module {
+ kw::module(Span::from_offset(0))
+ }
+}
+
+/// An argument to instantiate a core module.
+#[derive(Debug)]
+pub struct CoreInstantiationArg<'a> {
+ /// The name of the instantiation argument.
+ pub name: &'a str,
+ /// The kind of core instantiation argument.
+ pub kind: CoreInstantiationArgKind<'a>,
+}
+
+impl<'a> Parse<'a> for CoreInstantiationArg<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ parser.parse::<kw::with>()?;
+ Ok(Self {
+ name: parser.parse()?,
+ kind: parser.parse()?,
+ })
+ }
+}
+
+impl<'a> Parse<'a> for Vec<CoreInstantiationArg<'a>> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ let mut args = Vec::new();
+ while !parser.is_empty() {
+ args.push(parser.parens(|parser| parser.parse())?);
+ }
+ Ok(args)
+ }
+}
+
+/// The kind of core instantiation argument.
+#[derive(Debug)]
+pub enum CoreInstantiationArgKind<'a> {
+ /// The argument is a reference to an instance.
+ Instance(CoreItemRef<'a, kw::instance>),
+ /// The argument is an instance created from local exported core items.
+ ///
+ /// This is syntactic sugar for defining a core instance and also using it
+ /// as an instantiation argument.
+ BundleOfExports(Span, Vec<CoreInstanceExport<'a>>),
+}
+
+impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ parser.parens(|parser| {
+ if let Some(r) = parser.parse()? {
+ Ok(Self::Instance(r))
+ } else {
+ let span = parser.parse::<kw::instance>()?.0;
+ Ok(Self::BundleOfExports(span, parser.parse()?))
+ }
+ })
+ }
+}
+
+/// An exported item as part of a core instance.
+#[derive(Debug)]
+pub struct CoreInstanceExport<'a> {
+ /// Where this export was defined.
+ pub span: Span,
+ /// The name of this export from the instance.
+ pub name: &'a str,
+ /// What's being exported from the instance.
+ pub item: CoreItemRef<'a, core::ExportKind>,
+}
+
+impl<'a> Parse<'a> for CoreInstanceExport<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ Ok(Self {
+ span: parser.parse::<kw::export>()?.0,
+ name: parser.parse()?,
+ item: parser.parens(|parser| parser.parse())?,
+ })
+ }
+}
+
+impl<'a> Parse<'a> for Vec<CoreInstanceExport<'a>> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ let mut exports = Vec::new();
+ while !parser.is_empty() {
+ exports.push(parser.parens(|parser| parser.parse())?);
+ }
+ Ok(exports)
+ }
+}
+
+/// A component instance defined by instantiation or exporting items.
+#[derive(Debug)]
+pub struct Instance<'a> {
+ /// Where this `instance` was defined.
+ pub span: Span,
+ /// An identifier that this instance is resolved with (optionally) for name
+ /// resolution.
+ pub id: Option<Id<'a>>,
+ /// An optional name for this instance stored in the custom `name` section.
+ pub name: Option<NameAnnotation<'a>>,
+ /// If present, inline export annotations which indicate names this
+ /// definition should be exported under.
+ pub exports: InlineExport<'a>,
+ /// What kind of instance this is.
+ pub kind: InstanceKind<'a>,
+}
+
+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 name = parser.parse()?;
+ let exports = parser.parse()?;
+ let kind = parser.parse()?;
+
+ Ok(Self {
+ span,
+ id,
+ name,
+ exports,
+ kind,
+ })
+ }
+}
+
+/// The kinds of instances in the text format.
+#[derive(Debug)]
+pub enum InstanceKind<'a> {
+ /// The `(instance (import "x"))` sugar syntax
+ Import {
+ /// The name of the import
+ import: InlineImport<'a>,
+ /// The type of the instance being imported
+ ty: ComponentTypeUse<'a, InstanceType<'a>>,
+ },
+ /// Instantiate a component.
+ Instantiate {
+ /// The component being instantiated.
+ component: ItemRef<'a, kw::component>,
+ /// Arguments used to instantiate the instance.
+ args: Vec<InstantiationArg<'a>>,
+ },
+ /// The instance is defined by exporting local items as an instance.
+ BundleOfExports(Vec<ComponentExport<'a>>),
+}
+
+impl<'a> Parse<'a> for InstanceKind<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ if let Some(import) = parser.parse()? {
+ return Ok(Self::Import {
+ import,
+ ty: parser.parse()?,
+ });
+ }
+
+ if parser.peek::<LParen>() && parser.peek2::<kw::instantiate>() {
+ parser.parens(|parser| {
+ parser.parse::<kw::instantiate>()?;
+ Ok(Self::Instantiate {
+ component: parser.parse::<IndexOrRef<'_, _>>()?.0,
+ args: parser.parse()?,
+ })
+ })
+ } else {
+ Ok(Self::BundleOfExports(parser.parse()?))
+ }
+ }
+}
+
+impl Default for kw::component {
+ fn default() -> kw::component {
+ kw::component(Span::from_offset(0))
+ }
+}
+
+/// An argument to instantiate a component.
+#[derive(Debug)]
+pub struct InstantiationArg<'a> {
+ /// The name of the instantiation argument.
+ pub name: &'a str,
+ /// The kind of instantiation argument.
+ pub kind: InstantiationArgKind<'a>,
+}
+
+impl<'a> Parse<'a> for InstantiationArg<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ parser.parse::<kw::with>()?;
+ Ok(Self {
+ name: parser.parse()?,
+ kind: parser.parse()?,
+ })
+ }
+}
+
+impl<'a> Parse<'a> for Vec<InstantiationArg<'a>> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ let mut args = Vec::new();
+ while !parser.is_empty() {
+ args.push(parser.parens(|parser| parser.parse())?);
+ }
+ Ok(args)
+ }
+}
+
+/// The kind of instantiation argument.
+#[derive(Debug)]
+pub enum InstantiationArgKind<'a> {
+ /// The argument is a reference to a component item.
+ Item(ComponentExportKind<'a>),
+ /// The argument is an instance created from local exported items.
+ ///
+ /// This is syntactic sugar for defining an instance and also using it
+ /// as an instantiation argument.
+ BundleOfExports(Span, Vec<ComponentExport<'a>>),
+}
+
+impl<'a> Parse<'a> for InstantiationArgKind<'a> {
+ fn parse(parser: Parser<'a>) -> Result<Self> {
+ if let Some(item) = parser.parse()? {
+ Ok(Self::Item(item))
+ } else {
+ parser.parens(|parser| {
+ let span = parser.parse::<kw::instance>()?.0;
+ Ok(Self::BundleOfExports(span, parser.parse()?))
+ })
+ }
+ }
+}