diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c4e3a61521..db9c850b02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -162,6 +162,7 @@ jobs: - run: cargo check --no-default-features -p wit-parser --features serde - run: cargo check --no-default-features -p wit-parser --features decoding - run: cargo check --no-default-features -p wit-parser --features serde,decoding,wat + - run: cargo check --no-default-features -p wast --features serde,wasm-module - run: | if cargo tree -p wasm-smith --no-default-features -e no-dev | grep wasmparser; then echo wasm-smith without default features should not depend on wasmparser diff --git a/Cargo.lock b/Cargo.lock index 014a6db7da..5b519f30e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2224,6 +2224,9 @@ dependencies = [ "leb128", "memchr", "rayon", + "serde", + "serde_derive", + "serde_json", "unicode-width", "wasm-encoder 0.201.0", "wasmparser 0.201.0", diff --git a/crates/wast/Cargo.toml b/crates/wast/Cargo.toml index c173450b54..2292ba4c0e 100644 --- a/crates/wast/Cargo.toml +++ b/crates/wast/Cargo.toml @@ -21,6 +21,9 @@ unicode-width = "0.1.9" memchr = "2.4.1" wasm-encoder = { workspace = true } bumpalo = "3.14.0" +serde_json = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +serde_derive = { workspace = true, optional = true } [dev-dependencies] anyhow = { workspace = true } @@ -39,6 +42,9 @@ default = ['wasm-module'] # This feature is turned on by default. wasm-module = [] +# Includes support for serializing and deserializing the `Wat` type. +serde = ['dep:serde', 'dep:serde_derive', 'dep:serde_json'] + [[test]] name = "parse-fail" harness = false diff --git a/crates/wast/src/component/alias.rs b/crates/wast/src/component/alias.rs index dffcda1445..b58534bc92 100644 --- a/crates/wast/src/component/alias.rs +++ b/crates/wast/src/component/alias.rs @@ -2,11 +2,14 @@ use crate::core::ExportKind; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, Index, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A inline alias for component exported items. /// /// Handles both `core export` and `export` aliases #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InlineExportAlias<'a, const CORE: bool> { /// The instance to alias the export from. pub instance: Index<'a>, @@ -29,11 +32,13 @@ impl<'a, const CORE: bool> Parse<'a> for InlineExportAlias<'a, CORE> { /// An alias to a component item. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Alias<'a> { /// Where this `alias` was defined. pub span: Span, /// An identifier that this alias is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this alias stored in the custom `name` section. pub name: Option>, @@ -137,6 +142,11 @@ impl<'a> Parse<'a> for Alias<'a> { /// Represents the kind of instance export alias. #[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentExportAliasKind { /// The alias is to a core module export. CoreModule, @@ -187,6 +197,11 @@ impl<'a> Parse<'a> for ComponentExportAliasKind { /// Represents the kind of outer alias. #[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentOuterAliasKind { /// The alias is to an outer core module. CoreModule, @@ -227,6 +242,11 @@ impl<'a> Parse<'a> for ComponentOuterAliasKind { /// The target of a component alias. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum AliasTarget<'a> { /// The alias is to an export of a component instance. Export { diff --git a/crates/wast/src/component/binary.rs b/crates/wast/src/component/binary.rs index a57cc0f912..b419a14acc 100644 --- a/crates/wast/src/component/binary.rs +++ b/crates/wast/src/component/binary.rs @@ -1,6 +1,8 @@ use crate::component::*; use crate::core; use crate::token::{Id, Index, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; use wasm_encoder::{ CanonicalFunctionSection, ComponentAliasSection, ComponentDefinedTypeEncoder, ComponentExportSection, ComponentImportSection, ComponentInstanceSection, ComponentNameSection, @@ -731,14 +733,18 @@ impl From> for u32 { } } -impl From<&ItemRef<'_, T>> for u32 { +impl<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> + From<&ItemRef<'_, T>> for u32 +{ fn from(i: &ItemRef<'_, T>) -> Self { assert!(i.export_names.is_empty()); i.idx.into() } } -impl From<&CoreTypeUse<'_, T>> for u32 { +impl<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> + From<&CoreTypeUse<'_, T>> for u32 +{ fn from(u: &CoreTypeUse<'_, T>) -> Self { match u { CoreTypeUse::Inline(_) => unreachable!("should be expanded already"), @@ -747,7 +753,9 @@ impl From<&CoreTypeUse<'_, T>> for u32 { } } -impl From<&ComponentTypeUse<'_, T>> for u32 { +impl<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> + From<&ComponentTypeUse<'_, T>> for u32 +{ fn from(u: &ComponentTypeUse<'_, T>) -> Self { match u { ComponentTypeUse::Inline(_) => unreachable!("should be expanded already"), diff --git a/crates/wast/src/component/component.rs b/crates/wast/src/component/component.rs index cc9171b505..153f3305dd 100644 --- a/crates/wast/src/component/component.rs +++ b/crates/wast/src/component/component.rs @@ -5,13 +5,17 @@ use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::Index; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A parsed WebAssembly component module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Component<'a> { /// Where this `component` was defined pub span: Span, /// An optional identifier this component is known by + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional `@name` annotation for this component pub name: Option>, @@ -21,8 +25,14 @@ pub struct Component<'a> { /// The different kinds of ways to define a component. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentKind<'a> { /// A component defined in the textual s-expression format. + #[cfg_attr(feature = "serde", serde(borrow))] Text(Vec>), /// A component that had its raw binary bytes defined via the `binary` /// directive. @@ -139,7 +149,13 @@ impl<'a> Parse<'a> for Component<'a> { /// A listing of all possible fields that can make up a WebAssembly component. #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentField<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] CoreModule(CoreModule<'a>), CoreInstance(CoreInstance<'a>), CoreType(CoreType<'a>), @@ -220,8 +236,10 @@ impl<'a> Parse<'a> for ComponentField<'a> { /// A function to call at instantiation time. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Start<'a> { /// The function to call. + #[cfg_attr(feature = "serde", serde(borrow))] pub func: Index<'a>, /// The arguments to pass to the function. pub args: Vec>, @@ -259,10 +277,12 @@ impl<'a> Parse<'a> for Start<'a> { /// A nested WebAssembly component. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct NestedComponent<'a> { /// Where this `component` was defined pub span: Span, /// An optional identifier this component is known by + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional `@name` annotation for this component pub name: Option>, @@ -275,10 +295,16 @@ pub struct NestedComponent<'a> { /// The different kinds of ways to define a nested component. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum NestedComponentKind<'a> { /// This is actually an inline import of a component Import { /// The information about where this is being imported from. + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, /// The type of component being imported. ty: ComponentTypeUse<'a, ComponentType<'a>>, diff --git a/crates/wast/src/component/custom.rs b/crates/wast/src/component/custom.rs index b17a7fafb4..5b6a3bf56e 100644 --- a/crates/wast/src/component/custom.rs +++ b/crates/wast/src/component/custom.rs @@ -1,9 +1,12 @@ use crate::annotation; use crate::parser::{Parse, Parser, Result}; use crate::token::Span; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A custom section within a component. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Custom<'a> { /// Where this `@custom` was defined. pub span: Span, diff --git a/crates/wast/src/component/expand.rs b/crates/wast/src/component/expand.rs index 10523eacc8..690d958188 100644 --- a/crates/wast/src/component/expand.rs +++ b/crates/wast/src/component/expand.rs @@ -4,6 +4,8 @@ use crate::gensym; use crate::kw; use crate::token::Id; use crate::token::{Index, Span}; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; use std::collections::HashMap; use std::mem; @@ -599,7 +601,10 @@ impl<'a> Expander<'a> { *ty = ComponentValType::Ref(idx); } - fn expand_core_type_use( + fn expand_core_type_use< + #[cfg(feature = "serde")] T: SerializeT, + #[cfg(not(feature = "serde"))] T, + >( &mut self, item: &mut CoreTypeUse<'a, T>, ) -> CoreItemRef<'a, kw::r#type> @@ -652,7 +657,10 @@ impl<'a> Expander<'a> { ret } - fn expand_component_type_use( + fn expand_component_type_use< + #[cfg(feature = "serde")] T: SerializeT, + #[cfg(not(feature = "serde"))] T, + >( &mut self, item: &mut ComponentTypeUse<'a, T>, ) -> ItemRef<'a, kw::r#type> diff --git a/crates/wast/src/component/export.rs b/crates/wast/src/component/export.rs index d9e2ae4b4c..349a75ca5f 100644 --- a/crates/wast/src/component/export.rs +++ b/crates/wast/src/component/export.rs @@ -2,13 +2,17 @@ use super::{ComponentExternName, ItemRef, ItemSigNoName}; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Id, Index, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// An entry in a WebAssembly component's export section. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentExport<'a> { /// Where this export was defined. pub span: Span, /// Optional identifier bound to this export. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this instance stored in the custom `name` section. pub debug_name: Option>, @@ -55,11 +59,17 @@ impl<'a> Parse<'a> for Vec> { /// The kind of exported item. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentExportKind<'a> { /// The export is a core module. /// /// Note this isn't a core item ref as currently only /// components can export core modules. + #[cfg_attr(feature = "serde", serde(borrow))] CoreModule(ItemRef<'a, kw::module>), /// The export is a function. Func(ItemRef<'a, kw::func>), @@ -171,8 +181,10 @@ impl Peek for ComponentExportKind<'_> { /// A listing of inline `(export "foo" )` statements on a WebAssembly /// component item in its textual format. #[derive(Debug, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InlineExport<'a> { /// The extra names to export an item as, if any. + #[cfg_attr(feature = "serde", serde(borrow))] pub names: Vec>, } diff --git a/crates/wast/src/component/func.rs b/crates/wast/src/component/func.rs index 24cbb3eb67..a89b957864 100644 --- a/crates/wast/src/component/func.rs +++ b/crates/wast/src/component/func.rs @@ -2,16 +2,22 @@ use crate::component::*; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, Index, LParen, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A declared core function. /// /// This is a member of both the core alias and canon sections. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CoreFunc<'a> { /// Where this `core func` was defined. pub span: Span, /// An identifier that this function is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -39,10 +45,16 @@ impl<'a> Parse<'a> for CoreFunc<'a> { /// Represents the kind of core functions. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CoreFuncKind<'a> { /// The core function is defined in terms of lowering a component function. /// /// The core function is actually a member of the canon section. + #[cfg_attr(feature = "serde", serde(borrow))] Lower(CanonLower<'a>), /// The core function is defined in terms of aliasing a module instance export. /// @@ -84,11 +96,13 @@ impl<'a> Parse<'a> for CoreFuncKind<'a> { /// /// This may be a member of the import, alias, or canon sections. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Func<'a> { /// Where this `func` was defined. pub span: Span, /// An identifier that this function is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -119,6 +133,11 @@ impl<'a> Parse<'a> for Func<'a> { /// Represents the kind of component functions. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum FuncKind<'a> { /// A function which is actually defined as an import, such as: /// @@ -127,6 +146,7 @@ pub enum FuncKind<'a> { /// ``` Import { /// The import name of this import. + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, /// The type that this function will have. ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>, @@ -171,11 +191,13 @@ impl<'a> Parse<'a> for FuncKind<'a> { /// /// This is a member of the canonical section. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonicalFunc<'a> { /// Where this `func` was defined. pub span: Span, /// An identifier that this function is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -247,10 +269,16 @@ impl<'a> CanonicalFunc<'a> { /// Possible ways to define a canonical function in the text format. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CanonicalFuncKind<'a> { /// A canonical function that is defined in terms of lifting a core function. Lift { /// The lifted function's type. + #[cfg_attr(feature = "serde", serde(borrow))] ty: ComponentTypeUse<'a, ComponentFunctionType<'a>>, /// Information relating to the lifting of the core function. info: CanonLift<'a>, @@ -265,8 +293,10 @@ pub enum CanonicalFuncKind<'a> { /// Information relating to lifting a core function. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonLift<'a> { /// The core function being lifted. + #[cfg_attr(feature = "serde", serde(borrow))] pub func: CoreItemRef<'a, kw::func>, /// The canonical options for the lifting. pub opts: Vec>, @@ -302,8 +332,10 @@ impl Default for CanonLift<'_> { /// Information relating to lowering a component function. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonLower<'a> { /// The function being lowered. + #[cfg_attr(feature = "serde", serde(borrow))] pub func: ItemRef<'a, kw::func>, /// The canonical options for the lowering. pub opts: Vec>, @@ -336,8 +368,10 @@ impl Default for CanonLower<'_> { /// Information relating to the `resource.new` intrinsic. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonResourceNew<'a> { /// The resource type that this intrinsic creates an owned reference to. + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: Index<'a>, } @@ -361,8 +395,10 @@ impl Default for CanonResourceNew<'_> { /// Information relating to the `resource.drop` intrinsic. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonResourceDrop<'a> { /// The resource type that this intrinsic is dropping. + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: Index<'a>, } @@ -386,8 +422,10 @@ impl Default for CanonResourceDrop<'_> { /// Information relating to the `resource.rep` intrinsic. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CanonResourceRep<'a> { /// The resource type that this intrinsic is accessing. + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: Index<'a>, } @@ -411,6 +449,11 @@ impl Default for CanonResourceRep<'_> { #[derive(Debug)] /// Canonical ABI options. +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CanonOpt<'a> { /// Encode strings as UTF-8. StringUtf8, @@ -419,6 +462,7 @@ pub enum CanonOpt<'a> { /// Encode strings as "compact UTF-16". StringLatin1Utf16, /// Use the specified memory for canonical ABI memory access. + #[cfg_attr(feature = "serde", serde(borrow))] Memory(CoreItemRef<'a, kw::memory>), /// Use the specified reallocation function for memory allocations. Realloc(CoreItemRef<'a, kw::func>), @@ -467,7 +511,13 @@ impl<'a> Parse<'a> for CanonOpt<'a> { } } -fn parse_trailing_item_ref(kind: T, parser: Parser) -> Result> { +fn parse_trailing_item_ref< + #[cfg(feature = "serde")] T: SerializeT, + #[cfg(not(feature = "serde"))] T, +>( + kind: T, + parser: Parser, +) -> Result> { Ok(CoreItemRef { kind, idx: parser.parse()?, diff --git a/crates/wast/src/component/import.rs b/crates/wast/src/component/import.rs index 6689f4a765..f2b9f8efe6 100644 --- a/crates/wast/src/component/import.rs +++ b/crates/wast/src/component/import.rs @@ -2,13 +2,17 @@ use crate::component::*; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Id, Index, LParen, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// An `import` statement and entry in a WebAssembly component. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentImport<'a> { /// Where this `import` was defined pub span: Span, /// The name of the item being imported. + #[cfg_attr(feature = "serde", serde(borrow))] pub name: ComponentExternName<'a>, /// The item that's being imported. pub item: ItemSig<'a>, @@ -25,6 +29,7 @@ impl<'a> Parse<'a> for ComponentImport<'a> { /// The different ways an import can be named. #[derive(Debug, Copy, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentExternName<'a>(pub &'a str); impl<'a> Parse<'a> for ComponentExternName<'a> { @@ -49,11 +54,13 @@ impl<'a> Parse<'a> for ComponentExternName<'a> { /// An item signature for imported items. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ItemSig<'a> { /// Where this item is defined in the source. pub span: Span, /// An optional identifier used during name resolution to refer to this item /// from the rest of the component. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name which, for functions, will be stored in the /// custom `name` section. @@ -70,7 +77,8 @@ impl<'a> Parse<'a> for ItemSig<'a> { /// An item signature for imported items. #[derive(Debug)] -pub struct ItemSigNoName<'a>(pub ItemSig<'a>); +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ItemSigNoName<'a>(#[cfg_attr(feature = "serde", serde(borrow))] pub ItemSig<'a>); impl<'a> Parse<'a> for ItemSigNoName<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -114,8 +122,14 @@ fn parse_item_sig<'a>(parser: Parser<'a>, name: bool) -> Result> { /// The kind of signatures for imported items. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ItemSigKind<'a> { /// The item signature is for a core module. + #[cfg_attr(feature = "serde", serde(borrow))] CoreModule(CoreTypeUse<'a, ModuleType<'a>>), /// The item signature is for a function. Func(ComponentTypeUse<'a, ComponentFunctionType<'a>>), @@ -131,8 +145,14 @@ pub enum ItemSigKind<'a> { /// Represents the bounds applied to types being imported. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TypeBounds<'a> { /// The equality type bounds. + #[cfg_attr(feature = "serde", serde(borrow))] Eq(Index<'a>), /// A resource type is imported/exported, SubResource, @@ -159,8 +179,10 @@ impl<'a> Parse<'a> for TypeBounds<'a> { /// This is the same as `core::InlineImport` except only one string import is /// required. #[derive(Debug, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InlineImport<'a> { /// The name of the item being imported. + #[cfg_attr(feature = "serde", serde(borrow))] pub name: ComponentExternName<'a>, } diff --git a/crates/wast/src/component/instance.rs b/crates/wast/src/component/instance.rs index dc7b3faf44..f2caa08528 100644 --- a/crates/wast/src/component/instance.rs +++ b/crates/wast/src/component/instance.rs @@ -3,14 +3,18 @@ use crate::core; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, LParen, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A core instance defined by instantiation or exporting core items. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 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. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this instance stored in the custom `name` section. pub name: Option>, @@ -37,10 +41,16 @@ impl<'a> Parse<'a> for CoreInstance<'a> { /// The kinds of core instances in the text format. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CoreInstanceKind<'a> { /// Instantiate a core module. Instantiate { /// The module being instantiated. + #[cfg_attr(feature = "serde", serde(borrow))] module: ItemRef<'a, kw::module>, /// Arguments used to instantiate the instance. args: Vec>, @@ -73,6 +83,7 @@ impl Default for kw::module { /// An argument to instantiate a core module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CoreInstantiationArg<'a> { /// The name of the instantiation argument. pub name: &'a str, @@ -102,8 +113,14 @@ impl<'a> Parse<'a> for Vec> { /// The kind of core instantiation argument. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CoreInstantiationArgKind<'a> { /// The argument is a reference to an instance. + #[cfg_attr(feature = "serde", serde(borrow))] Instance(CoreItemRef<'a, kw::instance>), /// The argument is an instance created from local exported core items. /// @@ -127,6 +144,7 @@ impl<'a> Parse<'a> for CoreInstantiationArgKind<'a> { /// An exported item as part of a core instance. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CoreInstanceExport<'a> { /// Where this export was defined. pub span: Span, @@ -158,11 +176,13 @@ impl<'a> Parse<'a> for Vec> { /// A component instance defined by instantiation or exporting items. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Instance<'a> { /// Where this `instance` was defined. pub span: Span, /// An identifier that this instance is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this instance stored in the custom `name` section. pub name: Option>, @@ -193,10 +213,16 @@ impl<'a> Parse<'a> for Instance<'a> { /// The kinds of instances in the text format. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum InstanceKind<'a> { /// The `(instance (import "x"))` sugar syntax Import { /// The name of the import + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, /// The type of the instance being imported ty: ComponentTypeUse<'a, InstanceType<'a>>, @@ -243,6 +269,7 @@ impl Default for kw::component { /// An argument to instantiate a component. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InstantiationArg<'a> { /// The name of the instantiation argument. pub name: &'a str, @@ -272,8 +299,14 @@ impl<'a> Parse<'a> for Vec> { /// The kind of instantiation argument. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum InstantiationArgKind<'a> { /// The argument is a reference to a component item. + #[cfg_attr(feature = "serde", serde(borrow))] Item(ComponentExportKind<'a>), /// The argument is an instance created from local exported items. /// diff --git a/crates/wast/src/component/item_ref.rs b/crates/wast/src/component/item_ref.rs index cc8edc9b5b..6871a606ac 100644 --- a/crates/wast/src/component/item_ref.rs +++ b/crates/wast/src/component/item_ref.rs @@ -1,5 +1,9 @@ use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::Index; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; fn peek(cursor: Cursor) -> Result { // This is a little fancy because when parsing something like: @@ -39,7 +43,12 @@ fn peek(cursor: Cursor) -> Result { /// Parses core item references. #[derive(Clone, Debug)] -pub struct CoreItemRef<'a, K> { +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct CoreItemRef< + 'a, + #[cfg(feature = "serde")] K: SerializeT, + #[cfg(not(feature = "serde"))] K, +> { /// The item kind being parsed. pub kind: K, /// The item or instance reference. @@ -48,7 +57,12 @@ pub struct CoreItemRef<'a, K> { pub export_name: Option<&'a str>, } -impl<'a, K: Parse<'a>> Parse<'a> for CoreItemRef<'a, K> { +impl< + 'a, + #[cfg(feature = "serde")] K: Parse<'a> + SerializeT, + #[cfg(not(feature = "serde"))] K: Parse<'a>, + > Parse<'a> for CoreItemRef<'a, K> +{ fn parse(parser: Parser<'a>) -> Result { // This does not parse the surrounding `(` and `)` because // core prefix is context dependent and only the caller knows if it should be @@ -64,7 +78,12 @@ impl<'a, K: Parse<'a>> Parse<'a> for CoreItemRef<'a, K> { } } -impl<'a, K: Peek> Peek for CoreItemRef<'a, K> { +impl< + 'a, + #[cfg(feature = "serde")] K: Peek + SerializeT, + #[cfg(not(feature = "serde"))] K: Peek, + > Peek for CoreItemRef<'a, K> +{ fn peek(cursor: Cursor<'_>) -> Result { peek::(cursor) } @@ -76,16 +95,23 @@ impl<'a, K: Peek> Peek for CoreItemRef<'a, K> { /// Parses component item references. #[derive(Clone, Debug)] -pub struct ItemRef<'a, K> { +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ItemRef<'a, #[cfg(feature = "serde")] K: SerializeT, #[cfg(not(feature = "serde"))] K> { /// The item kind being parsed. pub kind: K, /// The item or instance reference. + #[cfg_attr(feature = "serde", serde(borrow))] pub idx: Index<'a>, /// Export names to resolve the item from. pub export_names: Vec<&'a str>, } -impl<'a, K: Parse<'a>> Parse<'a> for ItemRef<'a, K> { +impl< + 'a, + #[cfg(feature = "serde")] K: Parse<'a> + SerializeT, + #[cfg(not(feature = "serde"))] K: Parse<'a>, + > Parse<'a> for ItemRef<'a, K> +{ fn parse(parser: Parser<'a>) -> Result { let kind = parser.parse::()?; let idx = parser.parse()?; @@ -101,7 +127,12 @@ impl<'a, K: Parse<'a>> Parse<'a> for ItemRef<'a, K> { } } -impl<'a, K: Peek> Peek for ItemRef<'a, K> { +impl< + 'a, + #[cfg(feature = "serde")] K: Peek + SerializeT, + #[cfg(not(feature = "serde"))] K: Peek, + > Peek for ItemRef<'a, K> +{ fn peek(cursor: Cursor<'_>) -> Result { peek::(cursor) } @@ -113,9 +144,12 @@ impl<'a, K: Peek> Peek for ItemRef<'a, K> { /// Convenience structure to parse `$f` or `(item $f)`. #[derive(Clone, Debug)] -pub struct IndexOrRef<'a, K>(pub ItemRef<'a, K>); +pub struct IndexOrRef<'a, #[cfg(feature = "serde")] K: SerializeT, #[cfg(not(feature = "serde"))] K>( + pub ItemRef<'a, K>, +); -impl<'a, K> Parse<'a> for IndexOrRef<'a, K> +impl<'a, #[cfg(feature = "serde")] K: SerializeT, #[cfg(not(feature = "serde"))] K> Parse<'a> + for IndexOrRef<'a, K> where K: Parse<'a> + Default, { @@ -134,9 +168,14 @@ where /// Convenience structure to parse `$f` or `(item $f)`. #[derive(Clone, Debug)] -pub struct IndexOrCoreRef<'a, K>(pub CoreItemRef<'a, K>); - -impl<'a, K> Parse<'a> for IndexOrCoreRef<'a, K> +pub struct IndexOrCoreRef< + 'a, + #[cfg(feature = "serde")] K: SerializeT, + #[cfg(not(feature = "serde"))] K, +>(pub CoreItemRef<'a, K>); + +impl<'a, #[cfg(feature = "serde")] K: SerializeT, #[cfg(not(feature = "serde"))] K> Parse<'a> + for IndexOrCoreRef<'a, K> where K: Parse<'a> + Default, { diff --git a/crates/wast/src/component/module.rs b/crates/wast/src/component/module.rs index 6871af8d4c..c1082157a5 100644 --- a/crates/wast/src/component/module.rs +++ b/crates/wast/src/component/module.rs @@ -3,16 +3,20 @@ use crate::core; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A core WebAssembly module to be created as part of a component. /// /// This is a member of the core module section. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CoreModule<'a> { /// Where this `core module` was defined. pub span: Span, /// An identifier that this module is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this module stored in the custom `name` section. pub name: Option>, @@ -25,10 +29,16 @@ pub struct CoreModule<'a> { /// Possible ways to define a core module in the text format. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CoreModuleKind<'a> { /// A core module which is actually defined as an import Import { /// Where this core module is imported from + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, /// The type that this core module will have. ty: CoreTypeUse<'a, ModuleType<'a>>, diff --git a/crates/wast/src/component/resolve.rs b/crates/wast/src/component/resolve.rs index c0122ef73f..f157903830 100644 --- a/crates/wast/src/component/resolve.rs +++ b/crates/wast/src/component/resolve.rs @@ -5,6 +5,8 @@ use crate::names::Namespace; use crate::token::Span; use crate::token::{Id, Index}; use crate::Error; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; /// Resolve the fields of a component and everything nested within it, changing /// `Index::Id` to `Index::Num` and expanding alias syntax sugar. @@ -391,7 +393,10 @@ impl<'a> Resolver<'a> { Ok(()) } - fn core_type_use(&mut self, ty: &mut CoreTypeUse<'a, T>) -> Result<(), Error> { + fn core_type_use<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T>( + &mut self, + ty: &mut CoreTypeUse<'a, T>, + ) -> Result<(), Error> { let item = match ty { CoreTypeUse::Ref(r) => r, CoreTypeUse::Inline(_) => { @@ -401,7 +406,13 @@ impl<'a> Resolver<'a> { self.core_item_ref(item) } - fn component_type_use(&mut self, ty: &mut ComponentTypeUse<'a, T>) -> Result<(), Error> { + fn component_type_use< + #[cfg(feature = "serde")] T: SerializeT, + #[cfg(not(feature = "serde"))] T, + >( + &mut self, + ty: &mut ComponentTypeUse<'a, T>, + ) -> Result<(), Error> { let item = match ty { ComponentTypeUse::Ref(r) => r, ComponentTypeUse::Inline(_) => { @@ -607,7 +618,10 @@ impl<'a> Resolver<'a> { ) } - fn core_item_ref(&mut self, item: &mut CoreItemRef<'a, K>) -> Result<(), Error> + fn core_item_ref<#[cfg(feature = "serde")] K: SerializeT, #[cfg(not(feature = "serde"))] K>( + &mut self, + item: &mut CoreItemRef<'a, K>, + ) -> Result<(), Error> where K: CoreItem + Copy, { @@ -643,7 +657,13 @@ impl<'a> Resolver<'a> { Ok(()) } - fn component_item_ref(&mut self, item: &mut ItemRef<'a, K>) -> Result<(), Error> + fn component_item_ref< + #[cfg(feature = "serde")] K: SerializeT, + #[cfg(not(feature = "serde"))] K, + >( + &mut self, + item: &mut ItemRef<'a, K>, + ) -> Result<(), Error> where K: ComponentItem + Copy, { diff --git a/crates/wast/src/component/types.rs b/crates/wast/src/component/types.rs index 72eced02a8..b82683befc 100644 --- a/crates/wast/src/component/types.rs +++ b/crates/wast/src/component/types.rs @@ -7,14 +7,20 @@ use crate::parser::{Parse, Parser, Result}; use crate::token::Index; use crate::token::LParen; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde::Serialize as SerializeT; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A core type declaration. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CoreType<'a> { /// Where this type was defined. pub span: Span, /// An optional identifier to refer to this `core type` by as part of name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this type stored in the custom `name` section. pub name: Option>, @@ -44,8 +50,14 @@ impl<'a> Parse<'a> for CoreType<'a> { /// In the future this may be removed when module types are a part of /// a core module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CoreTypeDef<'a> { /// The type definition is one of the core types. + #[cfg_attr(feature = "serde", serde(borrow))] Def(core::TypeDef<'a>), /// The type definition is a module type. Module(ModuleType<'a>), @@ -64,8 +76,10 @@ impl<'a> Parse<'a> for CoreTypeDef<'a> { /// A type definition for a core module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ModuleType<'a> { /// The declarations of the module type. + #[cfg_attr(feature = "serde", serde(borrow))] pub decls: Vec>, } @@ -80,6 +94,11 @@ impl<'a> Parse<'a> for ModuleType<'a> { /// The declarations of a [`ModuleType`]. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ModuleTypeDecl<'a> { /// A core type. Type(core::Type<'a>), @@ -123,11 +142,13 @@ impl<'a> Parse<'a> for Vec> { /// A type declaration in a component. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Type<'a> { /// Where this type was defined. pub span: Span, /// An optional identifier to refer to this `type` by as part of name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this type stored in the custom `name` section. pub name: Option>, @@ -172,8 +193,14 @@ impl<'a> Type<'a> { /// A definition of a component type. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TypeDef<'a> { /// A defined value type. + #[cfg_attr(feature = "serde", serde(borrow))] Defined(ComponentDefinedType<'a>), /// A component function type. Func(ComponentFunctionType<'a>), @@ -220,6 +247,11 @@ impl<'a> Parse<'a> for TypeDef<'a> { /// A primitive value type. #[allow(missing_docs)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum PrimitiveValType { Bool, S8, @@ -312,8 +344,14 @@ impl Peek for PrimitiveValType { /// A component value type. #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentValType<'a> { /// The value type is an inline defined type. + #[cfg_attr(feature = "serde", serde(borrow))] Inline(ComponentDefinedType<'a>), /// The value type is an index reference to a defined type. Ref(Index<'a>), @@ -344,7 +382,10 @@ impl Peek for ComponentValType<'_> { /// This variation does not parse type indexes. #[allow(missing_docs)] #[derive(Debug)] -pub struct InlineComponentValType<'a>(ComponentDefinedType<'a>); +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct InlineComponentValType<'a>( + #[cfg_attr(feature = "serde", serde(borrow))] ComponentDefinedType<'a>, +); impl<'a> Parse<'a> for InlineComponentValType<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -364,8 +405,14 @@ impl<'a> Parse<'a> for InlineComponentValType<'a> { // A component defined type. #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentDefinedType<'a> { Primitive(PrimitiveValType), + #[cfg_attr(feature = "serde", serde(borrow))] Record(Record<'a>), Variant(Variant<'a>), List(List<'a>), @@ -446,8 +493,10 @@ impl Peek for ComponentDefinedType<'_> { /// A record defined type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Record<'a> { /// The fields of the record. + #[cfg_attr(feature = "serde", serde(borrow))] pub fields: Vec>, } @@ -464,6 +513,7 @@ impl<'a> Parse<'a> for Record<'a> { /// A record type field. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RecordField<'a> { /// The name of the field. pub name: &'a str, @@ -483,8 +533,10 @@ impl<'a> Parse<'a> for RecordField<'a> { /// A variant defined type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Variant<'a> { /// The cases of the variant type. + #[cfg_attr(feature = "serde", serde(borrow))] pub cases: Vec>, } @@ -501,6 +553,7 @@ impl<'a> Parse<'a> for Variant<'a> { /// A case of a variant type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct VariantCase<'a> { /// Where this `case` was defined pub span: Span, @@ -538,9 +591,17 @@ impl<'a> Parse<'a> for VariantCase<'a> { /// A refinement for a variant case. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum Refinement<'a> { /// The refinement is referenced by index. - Index(Span, Index<'a>), + Index( + Span, + #[cfg_attr(feature = "serde", serde(borrow))] Index<'a>, + ), /// The refinement has been resolved to an index into /// the cases of the variant. Resolved(u32), @@ -558,8 +619,10 @@ impl<'a> Parse<'a> for Refinement<'a> { /// A list type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct List<'a> { /// The element type of the array. + #[cfg_attr(feature = "serde", serde(borrow))] pub element: Box>, } @@ -574,8 +637,10 @@ impl<'a> Parse<'a> for List<'a> { /// A tuple type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Tuple<'a> { /// The types of the fields of the tuple. + #[cfg_attr(feature = "serde", serde(borrow))] pub fields: Vec>, } @@ -592,8 +657,10 @@ impl<'a> Parse<'a> for Tuple<'a> { /// A flags type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Flags<'a> { /// The names of the individual flags. + #[cfg_attr(feature = "serde", serde(borrow))] pub names: Vec<&'a str>, } @@ -610,8 +677,10 @@ impl<'a> Parse<'a> for Flags<'a> { /// An enum type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Enum<'a> { /// The tag names of the enum. + #[cfg_attr(feature = "serde", serde(borrow))] pub names: Vec<&'a str>, } @@ -628,8 +697,10 @@ impl<'a> Parse<'a> for Enum<'a> { /// An optional type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct OptionType<'a> { /// The type of the value, when a value is present. + #[cfg_attr(feature = "serde", serde(borrow))] pub element: Box>, } @@ -644,8 +715,10 @@ impl<'a> Parse<'a> for OptionType<'a> { /// A result type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ResultType<'a> { /// The type on success. + #[cfg_attr(feature = "serde", serde(borrow))] pub ok: Option>>, /// The type on failure. pub err: Option>>, @@ -674,9 +747,11 @@ impl<'a> Parse<'a> for ResultType<'a> { /// A component function type with parameters and result. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentFunctionType<'a> { /// The parameters of a function, optionally each having an identifier for /// name resolution and a name for the custom `name` section. + #[cfg_attr(feature = "serde", serde(borrow))] pub params: Box<[ComponentFunctionParam<'a>]>, /// The result of a function, optionally each having an identifier for /// name resolution and a name for the custom `name` section. @@ -704,6 +779,7 @@ impl<'a> Parse<'a> for ComponentFunctionType<'a> { /// A parameter of a [`ComponentFunctionType`]. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentFunctionParam<'a> { /// The name of the parameter pub name: &'a str, @@ -723,6 +799,7 @@ impl<'a> Parse<'a> for ComponentFunctionParam<'a> { /// A result of a [`ComponentFunctionType`]. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentFunctionResult<'a> { /// An optionally-specified name of this result pub name: Option<&'a str>, @@ -742,10 +819,12 @@ impl<'a> Parse<'a> for ComponentFunctionResult<'a> { /// The type of an exported item from an component or instance type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentExportType<'a> { /// Where this export was defined. pub span: Span, /// The name of this export. + #[cfg_attr(feature = "serde", serde(borrow))] pub name: ComponentExternName<'a>, /// The signature of the item. pub item: ItemSig<'a>, @@ -769,8 +848,10 @@ impl<'a> Parse<'a> for ComponentExportType<'a> { /// A type definition for a component type. #[derive(Debug, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ComponentType<'a> { /// The declarations of the component type. + #[cfg_attr(feature = "serde", serde(borrow))] pub decls: Vec>, } @@ -785,8 +866,14 @@ impl<'a> Parse<'a> for ComponentType<'a> { /// A declaration of a component type. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ComponentTypeDecl<'a> { /// A core type definition local to the component type. + #[cfg_attr(feature = "serde", serde(borrow))] CoreType(CoreType<'a>), /// A type definition local to the component type. Type(Type<'a>), @@ -829,8 +916,10 @@ impl<'a> Parse<'a> for Vec> { /// A type definition for an instance type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InstanceType<'a> { /// The declarations of the instance type. + #[cfg_attr(feature = "serde", serde(borrow))] pub decls: Vec>, } @@ -845,8 +934,14 @@ impl<'a> Parse<'a> for InstanceType<'a> { /// A declaration of an instance type. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum InstanceTypeDecl<'a> { /// A core type definition local to the component type. + #[cfg_attr(feature = "serde", serde(borrow))] CoreType(CoreType<'a>), /// A type definition local to the instance type. Type(Type<'a>), @@ -885,8 +980,10 @@ impl<'a> Parse<'a> for Vec> { /// A type definition for an instance type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ResourceType<'a> { /// Representation, in core WebAssembly, of this resource. + #[cfg_attr(feature = "serde", serde(borrow))] pub rep: core::ValType<'a>, /// The declarations of the instance type. pub dtor: Option>, @@ -912,7 +1009,10 @@ impl<'a> Parse<'a> for ResourceType<'a> { /// A value type declaration used for values in import signatures. #[derive(Debug)] -pub struct ComponentValTypeUse<'a>(pub ComponentValType<'a>); +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ComponentValTypeUse<'a>( + #[cfg_attr(feature = "serde", serde(borrow))] pub ComponentValType<'a>, +); impl<'a> Parse<'a> for ComponentValTypeUse<'a> { fn parse(parser: Parser<'a>) -> Result { @@ -928,14 +1028,26 @@ impl<'a> Parse<'a> for ComponentValTypeUse<'a> { /// This is the same as `TypeUse`, but accepts `$T` as shorthand for /// `(type $T)`. #[derive(Debug, Clone)] -pub enum CoreTypeUse<'a, T> { +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] +pub enum CoreTypeUse<'a, #[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> +{ /// The type that we're referencing. + #[cfg_attr(feature = "serde", serde(borrow))] Ref(CoreItemRef<'a, kw::r#type>), /// The inline type. Inline(T), } -impl<'a, T: Parse<'a>> Parse<'a> for CoreTypeUse<'a, T> { +impl< + 'a, + #[cfg(feature = "serde")] T: Parse<'a> + SerializeT, + #[cfg(not(feature = "serde"))] T: Parse<'a>, + > Parse<'a> for CoreTypeUse<'a, T> +{ fn parse(parser: Parser<'a>) -> Result { // Here the core context is assumed, so no core prefix is expected if parser.peek::()? && parser.peek2::>()? { @@ -946,7 +1058,9 @@ impl<'a, T: Parse<'a>> Parse<'a> for CoreTypeUse<'a, T> { } } -impl Default for CoreTypeUse<'_, T> { +impl<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> Default + for CoreTypeUse<'_, T> +{ fn default() -> Self { let span = Span::from_offset(0); Self::Ref(CoreItemRef { @@ -962,14 +1076,29 @@ impl Default for CoreTypeUse<'_, T> { /// This is the same as `TypeUse`, but accepts `$T` as shorthand for /// `(type $T)`. #[derive(Debug, Clone)] -pub enum ComponentTypeUse<'a, T> { +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] +pub enum ComponentTypeUse< + 'a, + #[cfg(feature = "serde")] T: SerializeT, + #[cfg(not(feature = "serde"))] T, +> { /// The type that we're referencing. + #[cfg_attr(feature = "serde", serde(borrow))] Ref(ItemRef<'a, kw::r#type>), /// The inline type. Inline(T), } -impl<'a, T: Parse<'a>> Parse<'a> for ComponentTypeUse<'a, T> { +impl< + 'a, + #[cfg(feature = "serde")] T: Parse<'a> + SerializeT, + #[cfg(not(feature = "serde"))] T: Parse<'a>, + > Parse<'a> for ComponentTypeUse<'a, T> +{ fn parse(parser: Parser<'a>) -> Result { if parser.peek::()? && parser.peek2::>()? { Ok(Self::Ref(parser.parens(|parser| parser.parse())?)) @@ -979,7 +1108,9 @@ impl<'a, T: Parse<'a>> Parse<'a> for ComponentTypeUse<'a, T> { } } -impl Default for ComponentTypeUse<'_, T> { +impl<#[cfg(feature = "serde")] T: SerializeT, #[cfg(not(feature = "serde"))] T> Default + for ComponentTypeUse<'_, T> +{ fn default() -> Self { let span = Span::from_offset(0); Self::Ref(ItemRef { diff --git a/crates/wast/src/core/custom.rs b/crates/wast/src/core/custom.rs index 2205bf514c..dacf5a0877 100644 --- a/crates/wast/src/core/custom.rs +++ b/crates/wast/src/core/custom.rs @@ -1,11 +1,19 @@ use crate::parser::{Parse, Parser, Result}; use crate::token::{self, Span}; use crate::{annotation, kw}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A custom section within a wasm module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum Custom<'a> { /// A raw custom section with the manual placement and bytes specified. + #[cfg_attr(feature = "serde", serde(borrow))] Raw(RawCustomSection<'a>), /// A producers custom section. Producers(Producers<'a>), @@ -47,6 +55,7 @@ impl<'a> Parse<'a> for Custom<'a> { /// A wasm custom section within a module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RawCustomSection<'a> { /// Where this `@custom` was defined. pub span: Span, @@ -63,6 +72,11 @@ pub struct RawCustomSection<'a> { /// Possible locations to place a custom section within a module. #[derive(Debug, PartialEq, Copy, Clone)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CustomPlace { /// This custom section will appear before the first section in the module. BeforeFirst, @@ -77,6 +91,11 @@ pub enum CustomPlace { /// Known sections that custom sections can be placed relative to. #[derive(Debug, PartialEq, Eq, Copy, Clone)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum CustomPlaceAnchor { Type, Import, @@ -196,7 +215,9 @@ impl<'a> Parse<'a> for CustomPlaceAnchor { /// A producers custom section #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Producers<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub fields: Vec<(&'a str, Vec<(&'a str, &'a str)>)>, } @@ -244,13 +265,20 @@ impl<'a> Parse<'a> for Producers<'a> { /// A `dylink.0` custom section #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Dylink0<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub subsections: Vec>, } /// Possible subsections of the `dylink.0` custom section #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum Dylink0Subsection<'a> { MemInfo { memory_size: u32, @@ -258,6 +286,7 @@ pub enum Dylink0Subsection<'a> { table_size: u32, table_align: u32, }, + #[cfg_attr(feature = "serde", serde(borrow))] Needed(Vec<&'a str>), ExportInfo(Vec<(&'a str, u32)>), ImportInfo(Vec<(&'a str, &'a str, u32)>), diff --git a/crates/wast/src/core/export.rs b/crates/wast/src/core/export.rs index 19765d36df..7a6916b276 100644 --- a/crates/wast/src/core/export.rs +++ b/crates/wast/src/core/export.rs @@ -1,9 +1,12 @@ use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Index, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A entry in a WebAssembly module's export section. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Export<'a> { /// Where this export was defined. pub span: Span, @@ -19,6 +22,11 @@ pub struct Export<'a> { /// contained in an [`Export`]. #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ExportKind { Func, Table, @@ -105,8 +113,10 @@ kw_conversions! { /// A listing of inline `(export "foo")` statements on a WebAssembly item in /// its textual format. #[derive(Debug, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InlineExport<'a> { /// The extra names to export an item as, if any. + #[cfg_attr(feature = "serde", serde(borrow))] pub names: Vec<&'a str>, } diff --git a/crates/wast/src/core/expr.rs b/crates/wast/src/core/expr.rs index b45950b896..95464be588 100644 --- a/crates/wast/src/core/expr.rs +++ b/crates/wast/src/core/expr.rs @@ -4,6 +4,8 @@ use crate::encode::Encode; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Result}; use crate::token::*; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; use std::mem; /// An expression, or a list of instructions, in the WebAssembly text format. @@ -13,7 +15,9 @@ use std::mem; /// at the end of an expression is not included in the `instrs` field. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Expression<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub instrs: Box<[Instruction<'a>]>, pub branch_hints: Vec, } @@ -23,6 +27,7 @@ pub struct Expression<'a> { /// is to store the offset of the following instruction and check that /// it's followed by `br_if` or `if`. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BranchHint { /// Index of instructions in `instrs` field of `Expression` that this hint /// appplies to. @@ -352,6 +357,7 @@ macro_rules! instructions { /// that this crate currently parses. #[derive(Debug)] #[allow(missing_docs)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(tag = "type", content = "val"))] pub enum Instruction<'a> { $( $(#[$doc])* @@ -446,6 +452,7 @@ macro_rules! instructions { instructions! { pub enum Instruction<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] Block(Box>) : [0x02] : "block", If(Box>) : [0x04] : "if", Else(Option>) : [0x05] : "else", @@ -1125,7 +1132,9 @@ impl<'a> Instruction<'a> { /// the block. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BlockType<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub label: Option>, pub label_name: Option>, pub ty: TypeUse<'a, FunctionType<'a>>, @@ -1145,7 +1154,9 @@ impl<'a> Parse<'a> for BlockType<'a> { #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TryTable<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub block: Box>, pub catches: Vec>, } @@ -1189,8 +1200,14 @@ impl<'a> Parse<'a> for TryTable<'a> { #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TryTableCatchKind<'a> { // Catch a tagged exception, do not capture an exnref. + #[cfg_attr(feature = "serde", serde(borrow))] Catch(Index<'a>), // Catch a tagged exception, and capture the exnref. CatchRef(Index<'a>), @@ -1212,7 +1229,9 @@ impl<'a> TryTableCatchKind<'a> { #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TryTableCatch<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub kind: TryTableCatchKind<'a>, pub label: Index<'a>, } @@ -1220,7 +1239,9 @@ pub struct TryTableCatch<'a> { /// Extra information associated with the func.bind instruction. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct FuncBindType<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: TypeUse<'a, FunctionType<'a>>, } @@ -1237,7 +1258,9 @@ impl<'a> Parse<'a> for FuncBindType<'a> { /// Extra information associated with the let instruction. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LetType<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub block: Box>, pub locals: Box<[Local<'a>]>, } @@ -1254,7 +1277,9 @@ impl<'a> Parse<'a> for LetType<'a> { /// Extra information associated with the `br_table` instruction. #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BrTableIndices<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] pub labels: Vec>, pub default: Index<'a>, } @@ -1272,6 +1297,7 @@ impl<'a> Parse<'a> for BrTableIndices<'a> { /// Payload for lane-related instructions. Unsigned with no + prefix. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LaneArg { /// The lane argument. pub lane: u8, @@ -1300,6 +1326,7 @@ impl<'a> Parse<'a> for LaneArg { /// Payload for memory-related instructions indicating offset/alignment of /// memory accesses. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MemArg<'a> { /// The alignment of this access. /// @@ -1309,6 +1336,7 @@ pub struct MemArg<'a> { /// The offset, in bytes of this access. pub offset: u64, /// The memory index we're accessing + #[cfg_attr(feature = "serde", serde(borrow))] pub memory: Index<'a>, } @@ -1375,8 +1403,10 @@ impl<'a> MemArg<'a> { /// Extra data associated with the `loadN_lane` and `storeN_lane` instructions. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LoadOrStoreLane<'a> { /// The memory argument for this instruction. + #[cfg_attr(feature = "serde", serde(borrow))] pub memarg: MemArg<'a>, /// The lane argument for this instruction. pub lane: LaneArg, @@ -1429,8 +1459,10 @@ impl<'a> LoadOrStoreLane<'a> { /// Extra data associated with the `call_indirect` instruction. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CallIndirect<'a> { /// The table that this call is going to be indexing. + #[cfg_attr(feature = "serde", serde(borrow))] pub table: Index<'a>, /// Type type signature that this `call_indirect` instruction is using. pub ty: TypeUse<'a, FunctionType<'a>>, @@ -1450,8 +1482,10 @@ impl<'a> Parse<'a> for CallIndirect<'a> { /// Extra data associated with the `table.init` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TableInit<'a> { /// The index of the table we're copying into. + #[cfg_attr(feature = "serde", serde(borrow))] pub table: Index<'a>, /// The index of the element segment we're copying into a table. pub elem: Index<'a>, @@ -1472,8 +1506,10 @@ impl<'a> Parse<'a> for TableInit<'a> { /// Extra data associated with the `table.copy` instruction. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TableCopy<'a> { /// The index of the destination table to copy into. + #[cfg_attr(feature = "serde", serde(borrow))] pub dst: Index<'a>, /// The index of the source table to copy from. pub src: Index<'a>, @@ -1494,8 +1530,10 @@ impl<'a> Parse<'a> for TableCopy<'a> { /// Extra data associated with unary table instructions. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TableArg<'a> { /// The index of the table argument. + #[cfg_attr(feature = "serde", serde(borrow))] pub dst: Index<'a>, } @@ -1512,8 +1550,10 @@ impl<'a> Parse<'a> for TableArg<'a> { /// Extra data associated with unary memory instructions. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MemoryArg<'a> { /// The index of the memory space. + #[cfg_attr(feature = "serde", serde(borrow))] pub mem: Index<'a>, } @@ -1530,8 +1570,10 @@ impl<'a> Parse<'a> for MemoryArg<'a> { /// Extra data associated with the `memory.init` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MemoryInit<'a> { /// The index of the data segment we're copying into memory. + #[cfg_attr(feature = "serde", serde(borrow))] pub data: Index<'a>, /// The index of the memory we're copying into, pub mem: Index<'a>, @@ -1552,8 +1594,10 @@ impl<'a> Parse<'a> for MemoryInit<'a> { /// Extra data associated with the `memory.copy` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MemoryCopy<'a> { /// The index of the memory we're copying from. + #[cfg_attr(feature = "serde", serde(borrow))] pub src: Index<'a>, /// The index of the memory we're copying to. pub dst: Index<'a>, @@ -1574,8 +1618,10 @@ impl<'a> Parse<'a> for MemoryCopy<'a> { /// Extra data associated with the `struct.get/set` instructions #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct StructAccess<'a> { /// The index of the struct type we're accessing. + #[cfg_attr(feature = "serde", serde(borrow))] pub r#struct: Index<'a>, /// The index of the field of the struct we're accessing pub field: Index<'a>, @@ -1592,8 +1638,10 @@ impl<'a> Parse<'a> for StructAccess<'a> { /// Extra data associated with the `array.fill` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayFill<'a> { /// The index of the array type we're filling. + #[cfg_attr(feature = "serde", serde(borrow))] pub array: Index<'a>, } @@ -1607,8 +1655,10 @@ impl<'a> Parse<'a> for ArrayFill<'a> { /// Extra data associated with the `array.copy` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayCopy<'a> { /// The index of the array type we're copying to. + #[cfg_attr(feature = "serde", serde(borrow))] pub dest_array: Index<'a>, /// The index of the array type we're copying from. pub src_array: Index<'a>, @@ -1625,8 +1675,10 @@ impl<'a> Parse<'a> for ArrayCopy<'a> { /// Extra data associated with the `array.init_[data/elem]` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayInit<'a> { /// The index of the array type we're initializing. + #[cfg_attr(feature = "serde", serde(borrow))] pub array: Index<'a>, /// The index of the data or elem segment we're reading from. pub segment: Index<'a>, @@ -1643,8 +1695,10 @@ impl<'a> Parse<'a> for ArrayInit<'a> { /// Extra data associated with the `array.new_fixed` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayNewFixed<'a> { /// The index of the array type we're accessing. + #[cfg_attr(feature = "serde", serde(borrow))] pub array: Index<'a>, /// The amount of values to initialize the array with. pub length: u32, @@ -1661,8 +1715,10 @@ impl<'a> Parse<'a> for ArrayNewFixed<'a> { /// Extra data associated with the `array.new_data` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayNewData<'a> { /// The index of the array type we're accessing. + #[cfg_attr(feature = "serde", serde(borrow))] pub array: Index<'a>, /// The data segment to initialize from. pub data_idx: Index<'a>, @@ -1679,8 +1735,10 @@ impl<'a> Parse<'a> for ArrayNewData<'a> { /// Extra data associated with the `array.new_elem` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayNewElem<'a> { /// The index of the array type we're accessing. + #[cfg_attr(feature = "serde", serde(borrow))] pub array: Index<'a>, /// The elem segment to initialize from. pub elem_idx: Index<'a>, @@ -1697,8 +1755,10 @@ impl<'a> Parse<'a> for ArrayNewElem<'a> { /// Extra data associated with the `ref.cast` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RefCast<'a> { /// The type to cast to. + #[cfg_attr(feature = "serde", serde(borrow))] pub r#type: RefType<'a>, } @@ -1712,8 +1772,10 @@ impl<'a> Parse<'a> for RefCast<'a> { /// Extra data associated with the `ref.test` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RefTest<'a> { /// The type to test for. + #[cfg_attr(feature = "serde", serde(borrow))] pub r#type: RefType<'a>, } @@ -1727,8 +1789,10 @@ impl<'a> Parse<'a> for RefTest<'a> { /// Extra data associated with the `br_on_cast` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BrOnCast<'a> { /// The label to branch to. + #[cfg_attr(feature = "serde", serde(borrow))] pub label: Index<'a>, /// The type we're casting from. pub from_type: RefType<'a>, @@ -1748,8 +1812,10 @@ impl<'a> Parse<'a> for BrOnCast<'a> { /// Extra data associated with the `br_on_cast_fail` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct BrOnCastFail<'a> { /// The label to branch to. + #[cfg_attr(feature = "serde", serde(borrow))] pub label: Index<'a>, /// The type we're casting from. pub from_type: RefType<'a>, @@ -1770,6 +1836,11 @@ impl<'a> Parse<'a> for BrOnCastFail<'a> { /// Different ways to specify a `v128.const` instruction #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum V128Const { I8x16([i8; 16]), I16x8([i16; 8]), @@ -1935,6 +2006,7 @@ impl<'a> Parse<'a> for V128Const { /// Lanes being shuffled in the `i8x16.shuffle` instruction #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct I8x16Shuffle { #[allow(missing_docs)] pub lanes: [u8; 16], @@ -1967,8 +2039,10 @@ impl<'a> Parse<'a> for I8x16Shuffle { /// Payload of the `select` instructions #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SelectTypes<'a> { #[allow(missing_docs)] + #[cfg_attr(feature = "serde", serde(borrow))] pub tys: Option>>, } diff --git a/crates/wast/src/core/func.rs b/crates/wast/src/core/func.rs index 24cc2993ca..1a716e19e0 100644 --- a/crates/wast/src/core/func.rs +++ b/crates/wast/src/core/func.rs @@ -2,16 +2,20 @@ use crate::core::*; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A WebAssembly function to be inserted into a module. /// /// This is a member of both the function and code sections. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Func<'a> { /// Where this `func` was defined. pub span: Span, /// An identifier that this function is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -27,12 +31,18 @@ pub struct Func<'a> { /// Possible ways to define a function in the text format. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum FuncKind<'a> { /// A function which is actually defined as an import, such as: /// /// ```text /// (func (type 3) (import "foo" "bar")) /// ``` + #[cfg_attr(feature = "serde", serde(borrow))] Import(InlineImport<'a>), /// Almost all functions, those defined inline in a wasm module. @@ -82,9 +92,11 @@ impl<'a> Parse<'a> for Func<'a> { /// Each local has an optional identifier for name resolution, an optional name /// for the custom `name` section, and a value type. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Local<'a> { /// An identifier that this local is resolved with (optionally) for name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this local stored in the custom `name` section. pub name: Option>, diff --git a/crates/wast/src/core/global.rs b/crates/wast/src/core/global.rs index b8ce287fd8..add4a93c58 100644 --- a/crates/wast/src/core/global.rs +++ b/crates/wast/src/core/global.rs @@ -2,13 +2,17 @@ use crate::core::*; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A WebAssembly global in a module #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Global<'a> { /// Where this `global` was defined. pub span: Span, /// An optional name to reference this global by + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -23,12 +27,18 @@ pub struct Global<'a> { /// Different kinds of globals that can be defined in a module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum GlobalKind<'a> { /// A global which is actually defined as an import, such as: /// /// ```text /// (global i32 (import "foo" "bar")) /// ``` + #[cfg_attr(feature = "serde", serde(borrow))] Import(InlineImport<'a>), /// A global defined inline in the module itself diff --git a/crates/wast/src/core/import.rs b/crates/wast/src/core/import.rs index e7c49bb862..6f1a0b9b45 100644 --- a/crates/wast/src/core/import.rs +++ b/crates/wast/src/core/import.rs @@ -2,9 +2,12 @@ use crate::core::*; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// An `import` statement and entry in a WebAssembly module. #[derive(Debug, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Import<'a> { /// Where this `import` was defined pub span: Span, @@ -33,11 +36,13 @@ impl<'a> Parse<'a> for Import<'a> { #[derive(Debug, Clone)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ItemSig<'a> { /// Where this item is defined in the source. pub span: Span, /// An optional identifier used during name resolution to refer to this item /// from the rest of the module. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name which, for functions, will be stored in the /// custom `name` section. @@ -48,7 +53,13 @@ pub struct ItemSig<'a> { #[derive(Debug, Clone)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ItemKind<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] Func(TypeUse<'a, FunctionType<'a>>), Table(TableType<'a>), Memory(MemoryType), @@ -113,6 +124,7 @@ impl<'a> Parse<'a> for ItemSig<'a> { /// `Peek` rather than `Option`. #[derive(Debug, Copy, Clone)] #[allow(missing_docs)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InlineImport<'a> { pub module: &'a str, pub field: &'a str, diff --git a/crates/wast/src/core/memory.rs b/crates/wast/src/core/memory.rs index eb1baa1a95..0ad782b849 100644 --- a/crates/wast/src/core/memory.rs +++ b/crates/wast/src/core/memory.rs @@ -2,13 +2,17 @@ use crate::core::*; use crate::kw; use crate::parser::{Lookahead1, Parse, Parser, Peek, Result}; use crate::token::*; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A defined WebAssembly memory instance inside of a module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Memory<'a> { /// Where this `memory` was defined pub span: Span, /// An optional name to refer to this memory by. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -21,10 +25,16 @@ pub struct Memory<'a> { /// Different syntactical ways a memory can be defined in a module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum MemoryKind<'a> { /// This memory is actually an inlined import definition. #[allow(missing_docs)] Import { + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, ty: MemoryType, }, @@ -91,11 +101,13 @@ impl<'a> Parse<'a> for Memory<'a> { /// A `data` directive in a WebAssembly module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Data<'a> { /// Where this `data` was defined pub span: Span, /// The optional name of this data segment + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this data stored in the custom `name` section. @@ -111,6 +123,11 @@ pub struct Data<'a> { /// Different kinds of data segments, either passive or active. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum DataKind<'a> { /// A passive data segment which isn't associated with a memory and is /// referenced from various instructions. @@ -120,6 +137,7 @@ pub enum DataKind<'a> { /// memory on module instantiation. Active { /// The memory that this `Data` will be associated with. + #[cfg_attr(feature = "serde", serde(borrow))] memory: Index<'a>, /// Initial offset to load this data segment at @@ -209,6 +227,11 @@ impl<'a> Parse<'a> for Data<'a> { /// Differnet ways the value of a data segment can be defined. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum DataVal<'a> { String(&'a [u8]), Integral(Vec), diff --git a/crates/wast/src/core/module.rs b/crates/wast/src/core/module.rs index f74ce6b619..fcecd0f53f 100644 --- a/crates/wast/src/core/module.rs +++ b/crates/wast/src/core/module.rs @@ -2,15 +2,19 @@ use crate::core::*; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, Index, NameAnnotation, Span}; use crate::{annotation, kw}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; pub use crate::core::resolve::Names; /// A parsed WebAssembly core module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Module<'a> { /// Where this `module` was defined pub span: Span, /// An optional identifier this module is known by + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional `@name` annotation for this module pub name: Option>, @@ -20,8 +24,14 @@ pub struct Module<'a> { /// The different kinds of ways to define a module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ModuleKind<'a> { /// A module defined in the textual s-expression format. + #[cfg_attr(feature = "serde", serde(borrow))] Text(Vec>), /// A module that had its raw binary bytes defined via the `binary` /// directive. @@ -142,7 +152,13 @@ impl<'a> Parse<'a> for Module<'a> { /// A listing of all possible fields that can make up a WebAssembly module. #[allow(missing_docs)] #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ModuleField<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] Type(Type<'a>), Rec(Rec<'a>), Import(Import<'a>), diff --git a/crates/wast/src/core/table.rs b/crates/wast/src/core/table.rs index e7f0b0f974..85847bf244 100644 --- a/crates/wast/src/core/table.rs +++ b/crates/wast/src/core/table.rs @@ -2,13 +2,17 @@ use crate::core::*; use crate::kw; use crate::parser::{Parse, Parser, Peek, Result}; use crate::token::{Id, Index, LParen, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A WebAssembly `table` directive in a module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Table<'a> { /// Where this table was defined. pub span: Span, /// An optional name to refer to this table by. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -21,10 +25,16 @@ pub struct Table<'a> { /// Different ways to textually define a table. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TableKind<'a> { /// This table is actually an inlined import definition. #[allow(missing_docs)] Import { + #[cfg_attr(feature = "serde", serde(borrow))] import: InlineImport<'a>, ty: TableType<'a>, }, @@ -100,10 +110,12 @@ impl<'a> Parse<'a> for Table<'a> { /// An `elem` segment in a WebAssembly module. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Elem<'a> { /// Where this `elem` was defined. pub span: Span, /// An optional name by which to refer to this segment. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this element stored in the custom `name` section. pub name: Option>, @@ -115,6 +127,11 @@ pub struct Elem<'a> { /// Different ways to define an element segment in an mdoule. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ElemKind<'a> { /// A passive segment that isn't associated with a table and can be used in /// various bulk-memory instructions. @@ -127,6 +144,7 @@ pub enum ElemKind<'a> { /// An active segment associated with a table. Active { /// The table this `elem` is initializing. + #[cfg_attr(feature = "serde", serde(borrow))] table: Index<'a>, /// The offset within `table` that we'll initialize at. offset: Expression<'a>, @@ -135,8 +153,14 @@ pub enum ElemKind<'a> { /// Different ways to define the element segment payload in a module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ElemPayload<'a> { /// This element segment has a contiguous list of function indices + #[cfg_attr(feature = "serde", serde(borrow))] Indices(Vec>), /// This element segment has a list of optional function indices, diff --git a/crates/wast/src/core/tag.rs b/crates/wast/src/core/tag.rs index 233b5e4cd0..faa3adc7d1 100644 --- a/crates/wast/src/core/tag.rs +++ b/crates/wast/src/core/tag.rs @@ -2,13 +2,17 @@ use crate::core::*; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::{Id, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A WebAssembly tag directive, part of the exception handling proposal. #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Tag<'a> { /// Where this tag was defined pub span: Span, /// An optional name by which to refer to this tag in name resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -22,20 +26,32 @@ pub struct Tag<'a> { /// Listing of various types of tags that can be defined in a wasm module. #[derive(Clone, Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TagType<'a> { /// An exception tag, where the payload is the type signature of the tag /// (constructor parameters, etc). + #[cfg_attr(feature = "serde", serde(borrow))] Exception(TypeUse<'a, FunctionType<'a>>), } /// Different kinds of tags that can be defined in a module. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TagKind<'a> { /// An tag which is actually defined as an import, such as: /// /// ```text /// (tag (type 0) (import "foo" "bar")) /// ``` + #[cfg_attr(feature = "serde", serde(borrow))] Import(InlineImport<'a>), /// A tag defined inline in the module itself diff --git a/crates/wast/src/core/types.rs b/crates/wast/src/core/types.rs index 179a62b9b8..434363b70a 100644 --- a/crates/wast/src/core/types.rs +++ b/crates/wast/src/core/types.rs @@ -2,17 +2,25 @@ use crate::core::*; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Id, Index, LParen, NameAnnotation, Span}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; use std::mem; /// The value types for a wasm module. #[allow(missing_docs)] #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum ValType<'a> { I32, I64, F32, F64, V128, + #[cfg_attr(feature = "serde", serde(borrow))] Ref(RefType<'a>), } @@ -59,6 +67,11 @@ impl<'a> Peek for ValType<'a> { /// A heap type for a reference type #[allow(missing_docs)] #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum HeapType<'a> { /// An untyped function reference: funcref. This is part of the reference /// types proposal. @@ -88,6 +101,7 @@ pub enum HeapType<'a> { None, /// A reference to a concrete function, struct, or array type defined by /// Wasm: `ref T`. This is part of the function references and GC proposals. + #[cfg_attr(feature = "serde", serde(borrow))] Concrete(Index<'a>), } @@ -158,8 +172,10 @@ impl<'a> Peek for HeapType<'a> { /// A reference type in a wasm module. #[allow(missing_docs)] #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct RefType<'a> { pub nullable: bool, + #[cfg_attr(feature = "serde", serde(borrow))] pub heap: HeapType<'a>, } @@ -338,9 +354,15 @@ impl<'a> Peek for RefType<'a> { /// The types of values that may be used in a struct or array. #[allow(missing_docs)] #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum StorageType<'a> { I8, I16, + #[cfg_attr(feature = "serde", serde(borrow))] Val(ValType<'a>), } @@ -363,8 +385,10 @@ impl<'a> Parse<'a> for StorageType<'a> { /// Type for a `global` in a wasm module #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct GlobalType<'a> { /// The element type of this `global` + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: ValType<'a>, /// Whether or not the global is mutable or not. pub mutable: bool, @@ -391,6 +415,7 @@ impl<'a> Parse<'a> for GlobalType<'a> { /// Min/max limits used for tables/memories. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Limits { /// The minimum number of units for this type. pub min: u32, @@ -412,6 +437,7 @@ impl<'a> Parse<'a> for Limits { /// Min/max limits used for 64-bit memories #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Limits64 { /// The minimum number of units for this type. pub min: u64, @@ -433,10 +459,12 @@ impl<'a> Parse<'a> for Limits64 { /// Configuration for a table of a wasm mdoule #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TableType<'a> { /// Limits on the element sizes of this table pub limits: Limits, /// The type of element stored in this table + #[cfg_attr(feature = "serde", serde(borrow))] pub elem: RefType<'a>, } @@ -451,6 +479,11 @@ impl<'a> Parse<'a> for TableType<'a> { /// Configuration for a memory of a wasm module #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum MemoryType { /// A 32-bit memory B32 { @@ -486,9 +519,11 @@ impl<'a> Parse<'a> for MemoryType { /// A function type with parameters and results. #[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct FunctionType<'a> { /// The parameters of a function, optionally each having an identifier for /// name resolution and a name for the custom `name` section. + #[cfg_attr(feature = "serde", serde(borrow))] pub params: Box<[(Option>, Option>, ValType<'a>)]>, /// The results types of a function. pub results: Box<[ValType<'a>]>, @@ -601,8 +636,10 @@ impl<'a> From> for FunctionType<'a> { /// A struct type with fields. #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct StructType<'a> { /// The fields of the struct + #[cfg_attr(feature = "serde", serde(borrow))] pub fields: Vec>, } @@ -630,8 +667,10 @@ impl<'a> Parse<'a> for StructType<'a> { /// A field of a struct type. #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct StructField<'a> { /// An optional identifier for name resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// Whether this field may be mutated or not. pub mutable: bool, @@ -657,10 +696,12 @@ impl<'a> StructField<'a> { /// An array type with fields. #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ArrayType<'a> { /// Whether this field may be mutated or not. pub mutable: bool, /// The storage type stored in this field. + #[cfg_attr(feature = "serde", serde(borrow))] pub ty: StorageType<'a>, } @@ -701,8 +742,14 @@ impl<'a> Parse<'a> for ExportType<'a> { /// A definition of a type. #[derive(Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum TypeDef<'a> { /// A function type definition. + #[cfg_attr(feature = "serde", serde(borrow))] Func(FunctionType<'a>), /// A struct type definition. Struct(StructType<'a>), @@ -730,11 +777,13 @@ impl<'a> Parse<'a> for TypeDef<'a> { /// A type declaration in a module #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Type<'a> { /// Where this type was defined. pub span: Span, /// An optional identifier to refer to this `type` by as part of name /// resolution. + #[cfg_attr(feature = "serde", serde(borrow))] pub id: Option>, /// An optional name for this function stored in the custom `name` section. pub name: Option>, @@ -797,10 +846,12 @@ impl<'a> Parse<'a> for Type<'a> { /// A recursion group declaration in a module #[derive(Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Rec<'a> { /// Where this recursion group was defined. pub span: Span, /// The types that we're defining in this group. + #[cfg_attr(feature = "serde", serde(borrow))] pub types: Vec>, } @@ -817,8 +868,10 @@ impl<'a> Parse<'a> for Rec<'a> { /// A reference to a type defined in this module. #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct TypeUse<'a, T> { /// The type that we're referencing, if it was present. + #[cfg_attr(feature = "serde", serde(borrow))] pub index: Option>, /// The inline type, if present. pub inline: Option, diff --git a/crates/wast/src/lib.rs b/crates/wast/src/lib.rs index bb16574177..b1fc97f7d7 100644 --- a/crates/wast/src/lib.rs +++ b/crates/wast/src/lib.rs @@ -96,6 +96,7 @@ macro_rules! custom_keyword { #[allow(non_camel_case_types)] #[allow(missing_docs)] #[derive(Debug, Copy, Clone)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct $name(pub $crate::token::Span); impl<'a> $crate::parser::Parse<'a> for $name { @@ -373,6 +374,9 @@ id! { /// Common keyword used to parse WebAssembly text files. pub mod kw { + #[cfg(feature = "serde")] + use serde_derive::{Deserialize, Serialize}; + custom_keyword!(after); custom_keyword!(alias); custom_keyword!(any); diff --git a/crates/wast/src/token.rs b/crates/wast/src/token.rs index 9dd15f97a8..26a61c72ef 100644 --- a/crates/wast/src/token.rs +++ b/crates/wast/src/token.rs @@ -5,12 +5,15 @@ use crate::lexer::{Float, Lexer, TokenKind}; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::{annotation, Error}; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; use std::fmt; use std::hash::{Hash, Hasher}; use std::str; /// A position in the original source stream, used to render errors. #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Span { pub(crate) offset: usize, } @@ -51,6 +54,7 @@ impl Span { /// An identifier is used to symbolically refer to items in a a wasm module, /// typically via the [`Index`] type. #[derive(Copy, Clone)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Id<'a> { name: &'a str, gen: u32, @@ -162,12 +166,18 @@ impl Peek for Id<'_> { /// The emission phase of a module will ensure that `Index::Id` is never used /// and switch them all to `Index::Num`. #[derive(Copy, Clone, Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum Index<'a> { /// A numerical index that this references. The index space this is /// referencing is implicit based on where this [`Index`] is stored. Num(u32, Span), /// A human-readable identifier this references. Like `Num`, the namespace /// this references is based on where this is stored. + #[cfg_attr(feature = "serde", serde(borrow))] Id(Id<'a>), } @@ -276,6 +286,7 @@ impl<'a, K: Peek> Peek for ItemRef<'a, K> { /// An `@name` annotation in source, currently of the form `@name "foo"` #[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct NameAnnotation<'a> { /// The name specified for the item pub name: &'a str, @@ -400,6 +411,7 @@ macro_rules! float { })*) => ($( /// A parsed floating-point type #[derive(Debug, Copy, Clone)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct $name { /// The raw bits that this floating point number represents. pub bits: $int, diff --git a/crates/wast/src/wat.rs b/crates/wast/src/wat.rs index 6d9a233359..4ad576f9fe 100644 --- a/crates/wast/src/wat.rs +++ b/crates/wast/src/wat.rs @@ -3,6 +3,8 @@ use crate::core::{Module, ModuleField, ModuleKind}; use crate::kw; use crate::parser::{Parse, Parser, Result}; use crate::token::Span; +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; /// A `*.wat` file parser, or a parser for one parenthesized module. /// @@ -11,7 +13,13 @@ use crate::token::Span; /// of s-expressions that are module fields. #[derive(Debug)] #[allow(missing_docs)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(tag = "type", content = "val") +)] pub enum Wat<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] Module(Module<'a>), Component(Component<'a>), }