Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make wast parse results serializable #1432

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions crates/wast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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
20 changes: 20 additions & 0 deletions crates/wast/src/component/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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<Id<'a>>,
/// An optional name for this alias stored in the custom `name` section.
pub name: Option<NameAnnotation<'a>>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
14 changes: 11 additions & 3 deletions crates/wast/src/component/binary.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -731,14 +733,18 @@ impl From<Index<'_>> for u32 {
}
}

impl<T> 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<T> 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"),
Expand All @@ -747,7 +753,9 @@ impl<T> From<&CoreTypeUse<'_, T>> for u32 {
}
}

impl<T> 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"),
Expand Down
26 changes: 26 additions & 0 deletions crates/wast/src/component/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Id<'a>>,
/// An optional `@name` annotation for this component
pub name: Option<NameAnnotation<'a>>,
Expand All @@ -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<ComponentField<'a>>),
/// A component that had its raw binary bytes defined via the `binary`
/// directive.
Expand Down Expand Up @@ -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>),
Expand Down Expand Up @@ -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<ItemRef<'a, kw::value>>,
Expand Down Expand Up @@ -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<Id<'a>>,
/// An optional `@name` annotation for this component
pub name: Option<NameAnnotation<'a>>,
Expand All @@ -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>>,
Expand Down
3 changes: 3 additions & 0 deletions crates/wast/src/component/custom.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
12 changes: 10 additions & 2 deletions crates/wast/src/component/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -599,7 +601,10 @@ impl<'a> Expander<'a> {
*ty = ComponentValType::Ref(idx);
}

fn expand_core_type_use<T>(
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>
Expand Down Expand Up @@ -652,7 +657,10 @@ impl<'a> Expander<'a> {
ret
}

fn expand_component_type_use<T>(
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>
Expand Down
12 changes: 12 additions & 0 deletions crates/wast/src/component/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Id<'a>>,
/// An optional name for this instance stored in the custom `name` section.
pub debug_name: Option<NameAnnotation<'a>>,
Expand Down Expand Up @@ -55,11 +59,17 @@ impl<'a> Parse<'a> for Vec<ComponentExport<'a>> {

/// 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>),
Expand Down Expand Up @@ -171,8 +181,10 @@ impl Peek for ComponentExportKind<'_> {
/// A listing of inline `(export "foo" <url>)` 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<ComponentExternName<'a>>,
}

Expand Down
Loading
Loading