/rust/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.12.6/src/component/encode.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use super::*; |
2 | | use wasm_encoder::{ComponentExportKind, ComponentOuterAliasKind, ExportKind}; |
3 | | use wasmparser::types::KebabStr; |
4 | | |
5 | | impl Component { |
6 | | /// Encode this Wasm component into bytes. |
7 | 0 | pub fn to_bytes(&self) -> Vec<u8> { |
8 | 0 | self.encoded().finish() |
9 | 0 | } |
10 | | |
11 | 0 | fn encoded(&self) -> wasm_encoder::Component { |
12 | 0 | let mut component = wasm_encoder::Component::new(); |
13 | 0 | for section in &self.sections { |
14 | 0 | section.encode(&mut component); |
15 | 0 | } |
16 | 0 | component |
17 | 0 | } |
18 | | } |
19 | | |
20 | | impl Section { |
21 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
22 | 0 | match self { |
23 | 0 | Self::Custom(sec) => sec.encode(component), |
24 | 0 | Self::CoreModule(module) => { |
25 | 0 | let bytes = module.to_bytes(); |
26 | 0 | component.section(&wasm_encoder::RawSection { |
27 | 0 | id: wasm_encoder::ComponentSectionId::CoreModule as u8, |
28 | 0 | data: &bytes, |
29 | 0 | }); |
30 | 0 | } |
31 | 0 | Self::CoreInstance(_) => todo!(), |
32 | 0 | Self::CoreType(sec) => sec.encode(component), |
33 | 0 | Self::Component(comp) => { |
34 | 0 | let bytes = comp.to_bytes(); |
35 | 0 | component.section(&wasm_encoder::RawSection { |
36 | 0 | id: wasm_encoder::ComponentSectionId::Component as u8, |
37 | 0 | data: &bytes, |
38 | 0 | }); |
39 | 0 | } |
40 | 0 | Self::Instance(_) => todo!(), |
41 | 0 | Self::Alias(_) => todo!(), |
42 | 0 | Self::Type(sec) => sec.encode(component), |
43 | 0 | Self::Canonical(sec) => sec.encode(component), |
44 | 0 | Self::Start(_) => todo!(), |
45 | 0 | Self::Import(sec) => sec.encode(component), |
46 | 0 | Self::Export(_) => todo!(), |
47 | | } |
48 | 0 | } |
49 | | } |
50 | | |
51 | | impl CustomSection { |
52 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
53 | 0 | component.section(&wasm_encoder::CustomSection { |
54 | 0 | name: &self.name, |
55 | 0 | data: &self.data, |
56 | 0 | }); |
57 | 0 | } |
58 | | } |
59 | | |
60 | | impl TypeSection { |
61 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
62 | 0 | let mut sec = wasm_encoder::ComponentTypeSection::new(); |
63 | 0 | for ty in &self.types { |
64 | 0 | ty.encode(sec.ty()); |
65 | 0 | } |
66 | 0 | component.section(&sec); |
67 | 0 | } |
68 | | } |
69 | | |
70 | | impl ImportSection { |
71 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
72 | 0 | let mut sec = wasm_encoder::ComponentImportSection::new(); |
73 | 0 | for imp in &self.imports { |
74 | 0 | sec.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty); |
75 | 0 | } |
76 | 0 | component.section(&sec); |
77 | 0 | } |
78 | | } |
79 | | |
80 | | impl CanonicalSection { |
81 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
82 | 0 | let mut sec = wasm_encoder::CanonicalFunctionSection::new(); |
83 | 0 | for func in &self.funcs { |
84 | 0 | match func { |
85 | | Func::CanonLift { |
86 | 0 | func_ty, |
87 | 0 | options, |
88 | 0 | core_func_index, |
89 | 0 | } => { |
90 | 0 | let options = translate_canon_opt(options); |
91 | 0 | sec.lift(*core_func_index, *func_ty, options); |
92 | 0 | } |
93 | | Func::CanonLower { |
94 | 0 | options, |
95 | 0 | func_index, |
96 | 0 | } => { |
97 | 0 | let options = translate_canon_opt(options); |
98 | 0 | sec.lower(*func_index, options); |
99 | 0 | } |
100 | | } |
101 | | } |
102 | 0 | component.section(&sec); |
103 | 0 | } |
104 | | } |
105 | | |
106 | | impl CoreTypeSection { |
107 | 0 | fn encode(&self, component: &mut wasm_encoder::Component) { |
108 | 0 | let mut sec = wasm_encoder::CoreTypeSection::new(); |
109 | 0 | for ty in &self.types { |
110 | 0 | ty.encode(sec.ty()); |
111 | 0 | } |
112 | 0 | component.section(&sec); |
113 | 0 | } |
114 | | } |
115 | | |
116 | | impl CoreType { |
117 | 0 | fn encode(&self, enc: wasm_encoder::CoreTypeEncoder<'_>) { |
118 | 0 | match self { |
119 | 0 | Self::Func(ty) => { |
120 | 0 | enc.function(ty.params.iter().copied(), ty.results.iter().copied()); |
121 | 0 | } |
122 | 0 | Self::Module(mod_ty) => { |
123 | 0 | let mut enc_mod_ty = wasm_encoder::ModuleType::new(); |
124 | 0 | for def in &mod_ty.defs { |
125 | 0 | match def { |
126 | 0 | ModuleTypeDef::TypeDef(crate::core::Type::Func(func_ty)) => { |
127 | 0 | enc_mod_ty.ty().function( |
128 | 0 | func_ty.params.iter().copied(), |
129 | 0 | func_ty.results.iter().copied(), |
130 | 0 | ); |
131 | 0 | } |
132 | 0 | ModuleTypeDef::OuterAlias { count, i, kind } => match kind { |
133 | 0 | CoreOuterAliasKind::Type(_) => { |
134 | 0 | enc_mod_ty.alias_outer_core_type(*count, *i); |
135 | 0 | } |
136 | | }, |
137 | 0 | ModuleTypeDef::Import(imp) => { |
138 | 0 | enc_mod_ty.import( |
139 | 0 | &imp.module, |
140 | 0 | &imp.field, |
141 | 0 | crate::core::encode::translate_entity_type(&imp.entity_type), |
142 | 0 | ); |
143 | 0 | } |
144 | 0 | ModuleTypeDef::Export(name, ty) => { |
145 | 0 | enc_mod_ty.export(name, crate::core::encode::translate_entity_type(ty)); |
146 | 0 | } |
147 | | } |
148 | | } |
149 | 0 | enc.module(&enc_mod_ty); |
150 | | } |
151 | | } |
152 | 0 | } |
153 | | } |
154 | | |
155 | | impl Type { |
156 | 0 | fn encode(&self, enc: wasm_encoder::ComponentTypeEncoder<'_>) { |
157 | 0 | match self { |
158 | 0 | Self::Defined(ty) => { |
159 | 0 | ty.encode(enc.defined_type()); |
160 | 0 | } |
161 | 0 | Self::Func(func_ty) => { |
162 | 0 | let mut f = enc.function(); |
163 | 0 |
|
164 | 0 | f.params(func_ty.params.iter().map(|(name, ty)| (name.as_str(), *ty))); |
165 | | |
166 | 0 | if let Some(ty) = func_ty.unnamed_result_ty() { |
167 | 0 | f.result(ty); |
168 | 0 | } else { |
169 | 0 | f.results( |
170 | 0 | func_ty.results.iter().map(|(name, ty)| { |
171 | 0 | (name.as_deref().map(KebabStr::as_str).unwrap(), *ty) |
172 | 0 | }), |
173 | 0 | ); |
174 | 0 | } |
175 | | } |
176 | 0 | Self::Component(comp_ty) => { |
177 | 0 | let mut enc_comp_ty = wasm_encoder::ComponentType::new(); |
178 | 0 | for def in &comp_ty.defs { |
179 | 0 | match def { |
180 | 0 | ComponentTypeDef::Import(imp) => { |
181 | 0 | enc_comp_ty.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty); |
182 | 0 | } |
183 | 0 | ComponentTypeDef::CoreType(ty) => { |
184 | 0 | ty.encode(enc_comp_ty.core_type()); |
185 | 0 | } |
186 | 0 | ComponentTypeDef::Type(ty) => { |
187 | 0 | ty.encode(enc_comp_ty.ty()); |
188 | 0 | } |
189 | 0 | ComponentTypeDef::Export { name, url, ty } => { |
190 | 0 | enc_comp_ty.export(name, url.as_deref().unwrap_or(""), *ty); |
191 | 0 | } |
192 | 0 | ComponentTypeDef::Alias(a) => { |
193 | 0 | enc_comp_ty.alias(translate_alias(a)); |
194 | 0 | } |
195 | | } |
196 | | } |
197 | 0 | enc.component(&enc_comp_ty); |
198 | | } |
199 | 0 | Self::Instance(inst_ty) => { |
200 | 0 | let mut enc_inst_ty = wasm_encoder::InstanceType::new(); |
201 | 0 | for def in &inst_ty.defs { |
202 | 0 | match def { |
203 | 0 | InstanceTypeDecl::CoreType(ty) => { |
204 | 0 | ty.encode(enc_inst_ty.core_type()); |
205 | 0 | } |
206 | 0 | InstanceTypeDecl::Type(ty) => { |
207 | 0 | ty.encode(enc_inst_ty.ty()); |
208 | 0 | } |
209 | 0 | InstanceTypeDecl::Export { name, url, ty } => { |
210 | 0 | enc_inst_ty.export(name, url.as_deref().unwrap_or(""), *ty); |
211 | 0 | } |
212 | 0 | InstanceTypeDecl::Alias(a) => { |
213 | 0 | enc_inst_ty.alias(translate_alias(a)); |
214 | 0 | } |
215 | | } |
216 | | } |
217 | 0 | enc.instance(&enc_inst_ty); |
218 | | } |
219 | | } |
220 | 0 | } |
221 | | } |
222 | | |
223 | | impl DefinedType { |
224 | 0 | fn encode(&self, enc: wasm_encoder::ComponentDefinedTypeEncoder<'_>) { |
225 | 0 | match self { |
226 | 0 | Self::Primitive(ty) => enc.primitive(*ty), |
227 | 0 | Self::Record(ty) => { |
228 | 0 | enc.record(ty.fields.iter().map(|(name, ty)| (name.as_str(), *ty))); |
229 | 0 | } |
230 | 0 | Self::Variant(ty) => { |
231 | 0 | enc.variant( |
232 | 0 | ty.cases |
233 | 0 | .iter() |
234 | 0 | .map(|(name, ty, refines)| (name.as_str(), *ty, *refines)), |
235 | 0 | ); |
236 | 0 | } |
237 | 0 | Self::List(ty) => { |
238 | 0 | enc.list(ty.elem_ty); |
239 | 0 | } |
240 | 0 | Self::Tuple(ty) => { |
241 | 0 | enc.tuple(ty.fields.iter().copied()); |
242 | 0 | } |
243 | 0 | Self::Flags(ty) => { |
244 | 0 | enc.flags(ty.fields.iter().map(|f| f.as_str())); |
245 | 0 | } |
246 | 0 | Self::Enum(ty) => { |
247 | 0 | enc.enum_type(ty.variants.iter().map(|v| v.as_str())); |
248 | 0 | } |
249 | 0 | Self::Union(ty) => { |
250 | 0 | enc.union(ty.variants.iter().copied()); |
251 | 0 | } |
252 | 0 | Self::Option(ty) => { |
253 | 0 | enc.option(ty.inner_ty); |
254 | 0 | } |
255 | 0 | Self::Result(ty) => { |
256 | 0 | enc.result(ty.ok_ty, ty.err_ty); |
257 | 0 | } |
258 | | } |
259 | 0 | } |
260 | | } |
261 | | |
262 | 0 | fn translate_canon_opt(options: &[CanonOpt]) -> Vec<wasm_encoder::CanonicalOption> { |
263 | 0 | options |
264 | 0 | .iter() |
265 | 0 | .map(|o| match o { |
266 | 0 | CanonOpt::StringUtf8 => wasm_encoder::CanonicalOption::UTF8, |
267 | 0 | CanonOpt::StringUtf16 => wasm_encoder::CanonicalOption::UTF16, |
268 | 0 | CanonOpt::StringLatin1Utf16 => wasm_encoder::CanonicalOption::CompactUTF16, |
269 | 0 | CanonOpt::Memory(idx) => wasm_encoder::CanonicalOption::Memory(*idx), |
270 | 0 | CanonOpt::Realloc(idx) => wasm_encoder::CanonicalOption::Realloc(*idx), |
271 | 0 | CanonOpt::PostReturn(idx) => wasm_encoder::CanonicalOption::PostReturn(*idx), |
272 | 0 | }) |
273 | 0 | .collect() |
274 | 0 | } |
275 | | |
276 | 0 | fn translate_alias(alias: &Alias) -> wasm_encoder::Alias<'_> { |
277 | 0 | match alias { |
278 | | Alias::InstanceExport { |
279 | 0 | instance, |
280 | 0 | name, |
281 | 0 | kind, |
282 | 0 | } => wasm_encoder::Alias::InstanceExport { |
283 | 0 | instance: *instance, |
284 | 0 | name, |
285 | 0 | kind: match kind { |
286 | 0 | InstanceExportAliasKind::Module => ComponentExportKind::Module, |
287 | 0 | InstanceExportAliasKind::Component => ComponentExportKind::Component, |
288 | 0 | InstanceExportAliasKind::Instance => ComponentExportKind::Instance, |
289 | 0 | InstanceExportAliasKind::Func => ComponentExportKind::Func, |
290 | 0 | InstanceExportAliasKind::Value => ComponentExportKind::Value, |
291 | | }, |
292 | | }, |
293 | | Alias::CoreInstanceExport { |
294 | 0 | instance, |
295 | 0 | name, |
296 | 0 | kind, |
297 | 0 | } => wasm_encoder::Alias::CoreInstanceExport { |
298 | 0 | instance: *instance, |
299 | 0 | name, |
300 | 0 | kind: match kind { |
301 | 0 | CoreInstanceExportAliasKind::Func => ExportKind::Func, |
302 | 0 | CoreInstanceExportAliasKind::Table => ExportKind::Table, |
303 | 0 | CoreInstanceExportAliasKind::Global => ExportKind::Global, |
304 | 0 | CoreInstanceExportAliasKind::Memory => ExportKind::Memory, |
305 | 0 | CoreInstanceExportAliasKind::Tag => ExportKind::Tag, |
306 | | }, |
307 | | }, |
308 | 0 | Alias::Outer { count, i, kind } => wasm_encoder::Alias::Outer { |
309 | 0 | count: *count, |
310 | 0 | index: *i, |
311 | 0 | kind: match kind { |
312 | 0 | OuterAliasKind::Module => ComponentOuterAliasKind::CoreModule, |
313 | 0 | OuterAliasKind::Component => ComponentOuterAliasKind::Component, |
314 | 0 | OuterAliasKind::Type(_) => ComponentOuterAliasKind::Type, |
315 | 0 | OuterAliasKind::CoreType(_) => ComponentOuterAliasKind::CoreType, |
316 | | }, |
317 | | }, |
318 | | } |
319 | 0 | } |