Coverage Report

Created: 2023-04-25 07:07

/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
}