golem_wasm_ast/
customization.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::core::{
16    CoreIndexSpace, CoreSectionType, Custom, Data, Expr, ExprSource, RetainsCustomSection,
17    TryFromExprSource,
18};
19use crate::Section;
20use std::fmt::Debug;
21
22/// A trait for customizing some of the data types used in the WASM AST.
23///
24/// Three types are customizable:
25/// - `Expr`: The type of the expression nodes in the AST, holding sequence of WASM instructions.
26/// - `Data`: The type of the data section in the AST.
27/// - `Custom`: The type of the custom section in the AST.
28///
29/// Use one of the predefined customization types or create your own:
30/// - [DefaultAst] uses the real AST nodes, keeping all parsed information
31/// - [IgnoreAll] ignores all instructions, custom sections and data sections
32/// - [IgnoreAllButMetadata] ignores all instructions, data sections and custom sections except those that hold information parsable by the `wasm-metadata` crate.
33pub trait AstCustomization: Debug + Clone + PartialEq {
34    type Expr: Debug + Clone + PartialEq;
35    type Data: Debug + Clone + PartialEq + Section<CoreIndexSpace, CoreSectionType>;
36
37    #[cfg(not(feature = "component"))]
38    type Custom: Debug + Clone + PartialEq + Section<CoreIndexSpace, CoreSectionType>;
39    #[cfg(feature = "component")]
40    type Custom: Debug
41        + Clone
42        + PartialEq
43        + Section<CoreIndexSpace, CoreSectionType>
44        + Section<crate::component::ComponentIndexSpace, crate::component::ComponentSectionType>;
45}
46
47/// The default AST customization, using the real AST nodes.
48#[derive(Debug, Clone, PartialEq)]
49pub struct DefaultAst;
50
51impl AstCustomization for DefaultAst {
52    type Expr = Expr;
53    type Data = Data<Expr>;
54    type Custom = Custom;
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub struct IgnoredExpr;
59
60impl TryFromExprSource for IgnoredExpr {
61    fn try_from<S: ExprSource>(_value: S) -> Result<Self, String>
62    where
63        Self: Sized,
64    {
65        Ok(IgnoredExpr)
66    }
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub struct IgnoredData;
71
72impl From<Data<IgnoredExpr>> for IgnoredData {
73    fn from(_value: Data<IgnoredExpr>) -> Self {
74        IgnoredData
75    }
76}
77
78impl Section<CoreIndexSpace, CoreSectionType> for IgnoredData {
79    fn index_space(&self) -> CoreIndexSpace {
80        CoreIndexSpace::Data
81    }
82
83    fn section_type(&self) -> CoreSectionType {
84        CoreSectionType::Data
85    }
86}
87
88#[derive(Debug, Clone, PartialEq)]
89pub struct IgnoredCustom;
90
91impl From<Custom> for IgnoredCustom {
92    fn from(_value: Custom) -> Self {
93        IgnoredCustom
94    }
95}
96
97impl Section<CoreIndexSpace, CoreSectionType> for IgnoredCustom {
98    fn index_space(&self) -> CoreIndexSpace {
99        CoreIndexSpace::Custom
100    }
101
102    fn section_type(&self) -> CoreSectionType {
103        CoreSectionType::Custom
104    }
105}
106
107#[cfg(feature = "component")]
108impl Section<crate::component::ComponentIndexSpace, crate::component::ComponentSectionType>
109    for IgnoredCustom
110{
111    fn index_space(&self) -> crate::component::ComponentIndexSpace {
112        crate::component::ComponentIndexSpace::Custom
113    }
114
115    fn section_type(&self) -> crate::component::ComponentSectionType {
116        crate::component::ComponentSectionType::Custom
117    }
118}
119
120/// An AST customization that ignores all instructions, custom sections and data sections.
121#[derive(Debug, Clone, PartialEq)]
122pub struct IgnoreAll;
123
124impl AstCustomization for IgnoreAll {
125    type Expr = IgnoredExpr;
126    type Data = IgnoredData;
127    type Custom = IgnoredCustom;
128}
129
130#[derive(Debug, Clone, PartialEq)]
131pub enum MetadataOnlyCustom {
132    Metadata(Custom),
133    Ignored,
134}
135
136impl RetainsCustomSection for MetadataOnlyCustom {
137    fn name(&self) -> &str {
138        match self {
139            MetadataOnlyCustom::Metadata(custom) => custom.name(),
140            MetadataOnlyCustom::Ignored => "ignored",
141        }
142    }
143
144    fn data(&self) -> &[u8] {
145        match self {
146            MetadataOnlyCustom::Metadata(custom) => custom.data(),
147            MetadataOnlyCustom::Ignored => &[],
148        }
149    }
150}
151
152impl From<Custom> for MetadataOnlyCustom {
153    fn from(value: Custom) -> Self {
154        if value.name == "producers"
155            || value.name == "registry-metadata"
156            || value.name == "name"
157            || value.name == "component-name"
158        {
159            MetadataOnlyCustom::Metadata(value)
160        } else {
161            MetadataOnlyCustom::Ignored
162        }
163    }
164}
165
166impl Section<CoreIndexSpace, CoreSectionType> for MetadataOnlyCustom {
167    fn index_space(&self) -> CoreIndexSpace {
168        CoreIndexSpace::Custom
169    }
170
171    fn section_type(&self) -> CoreSectionType {
172        CoreSectionType::Custom
173    }
174}
175
176#[cfg(feature = "component")]
177impl Section<crate::component::ComponentIndexSpace, crate::component::ComponentSectionType>
178    for MetadataOnlyCustom
179{
180    fn index_space(&self) -> crate::component::ComponentIndexSpace {
181        crate::component::ComponentIndexSpace::Custom
182    }
183
184    fn section_type(&self) -> crate::component::ComponentSectionType {
185        crate::component::ComponentSectionType::Custom
186    }
187}
188
189/// An AST customization that ignores all instructions, data sections and custom sections except those that hold information parsable by the `wasm-metadata` crate.
190#[derive(Debug, Clone, PartialEq)]
191pub struct IgnoreAllButMetadata;
192
193impl AstCustomization for IgnoreAllButMetadata {
194    type Expr = IgnoredExpr;
195    type Data = IgnoredData;
196    type Custom = MetadataOnlyCustom;
197}