Coverage Report

Created: 2023-04-25 07:07

/rust/registry/src/index.crates.io-6f17d22bba15001f/wast-56.0.0/src/component/binary.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::component::*;
2
use crate::core;
3
use crate::token::{Id, Index, NameAnnotation};
4
use wasm_encoder::{
5
    CanonicalFunctionSection, ComponentAliasSection, ComponentDefinedTypeEncoder,
6
    ComponentExportSection, ComponentImportSection, ComponentInstanceSection, ComponentNameSection,
7
    ComponentSection, ComponentSectionId, ComponentStartSection, ComponentTypeEncoder,
8
    ComponentTypeSection, CoreTypeEncoder, CoreTypeSection, InstanceSection, NameMap,
9
    NestedComponentSection, RawSection, SectionId,
10
};
11
12
0
pub fn encode(component: &Component<'_>) -> Vec<u8> {
13
0
    match &component.kind {
14
0
        ComponentKind::Text(fields) => {
15
0
            encode_fields(&component.id, &component.name, fields).finish()
16
        }
17
0
        ComponentKind::Binary(bytes) => bytes.iter().flat_map(|b| b.iter().copied()).collect(),
18
    }
19
0
}
20
21
0
fn encode_fields(
22
0
    // TODO: use the id and name for a future names section
23
0
    component_id: &Option<Id<'_>>,
24
0
    component_name: &Option<NameAnnotation<'_>>,
25
0
    fields: &[ComponentField<'_>],
26
0
) -> wasm_encoder::Component {
27
0
    let mut e = Encoder::default();
28
29
0
    for field in fields {
30
0
        match field {
31
0
            ComponentField::CoreModule(m) => e.encode_core_module(m),
32
0
            ComponentField::CoreInstance(i) => e.encode_core_instance(i),
33
0
            ComponentField::CoreType(t) => e.encode_core_type(t),
34
0
            ComponentField::Component(c) => e.encode_component(c),
35
0
            ComponentField::Instance(i) => e.encode_instance(i),
36
0
            ComponentField::Alias(a) => e.encode_alias(a),
37
0
            ComponentField::Type(t) => e.encode_type(t),
38
0
            ComponentField::CanonicalFunc(f) => e.encode_canonical_func(f),
39
            ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
40
0
                unreachable!("should be expanded already")
41
            }
42
0
            ComponentField::Start(s) => e.encode_start(s),
43
0
            ComponentField::Import(i) => e.encode_import(i),
44
0
            ComponentField::Export(ex) => e.encode_export(ex),
45
0
            ComponentField::Custom(c) => e.encode_custom(c),
46
        }
47
    }
48
49
0
    e.flush(None);
50
0
    e.encode_names(component_id, component_name);
51
0
52
0
    e.component
53
0
}
54
55
0
fn encode_core_type(encoder: CoreTypeEncoder, ty: &CoreTypeDef) {
56
0
    match ty {
57
0
        CoreTypeDef::Def(core::TypeDef::Func(f)) => {
58
0
            encoder.function(
59
0
                f.params.iter().map(|(_, _, ty)| (*ty).into()),
60
0
                f.results.iter().copied().map(Into::into),
61
0
            );
62
0
        }
63
        CoreTypeDef::Def(core::TypeDef::Struct(_)) | CoreTypeDef::Def(core::TypeDef::Array(_)) => {
64
0
            todo!("encoding of GC proposal types not yet implemented")
65
        }
66
0
        CoreTypeDef::Module(t) => {
67
0
            encoder.module(&t.into());
68
0
        }
69
    }
70
0
}
71
72
0
fn encode_type(encoder: ComponentTypeEncoder, ty: &TypeDef) {
73
0
    match ty {
74
0
        TypeDef::Defined(t) => {
75
0
            encode_defined_type(encoder.defined_type(), t);
76
0
        }
77
0
        TypeDef::Func(f) => {
78
0
            let mut encoder = encoder.function();
79
0
            encoder.params(f.params.iter().map(|p| (p.name, &p.ty)));
80
0
81
0
            if f.results.len() == 1 && f.results[0].name.is_none() {
82
0
                encoder.result(&f.results[0].ty);
83
0
            } else {
84
0
                encoder.results(f.results.iter().map(|r| (r.name.unwrap_or(""), &r.ty)));
85
0
            }
86
        }
87
0
        TypeDef::Component(c) => {
88
0
            encoder.component(&c.into());
89
0
        }
90
0
        TypeDef::Instance(i) => {
91
0
            encoder.instance(&i.into());
92
0
        }
93
    }
94
0
}
95
96
0
fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefinedType) {
97
0
    match ty {
98
0
        ComponentDefinedType::Primitive(p) => encoder.primitive((*p).into()),
99
0
        ComponentDefinedType::Record(r) => {
100
0
            encoder.record(r.fields.iter().map(|f| (f.name, &f.ty)));
101
0
        }
102
0
        ComponentDefinedType::Variant(v) => {
103
0
            encoder.variant(v.cases.iter().map(|c| {
104
0
                (
105
0
                    c.name,
106
0
                    c.ty.as_ref().map(Into::into),
107
0
                    c.refines.as_ref().map(Into::into),
108
0
                )
109
0
            }));
110
0
        }
111
0
        ComponentDefinedType::List(l) => {
112
0
            encoder.list(l.element.as_ref());
113
0
        }
114
0
        ComponentDefinedType::Tuple(t) => {
115
0
            encoder.tuple(t.fields.iter());
116
0
        }
117
0
        ComponentDefinedType::Flags(f) => {
118
0
            encoder.flags(f.names.iter().copied());
119
0
        }
120
0
        ComponentDefinedType::Enum(e) => {
121
0
            encoder.enum_type(e.names.iter().copied());
122
0
        }
123
0
        ComponentDefinedType::Union(u) => encoder.union(u.types.iter()),
124
0
        ComponentDefinedType::Option(o) => {
125
0
            encoder.option(o.element.as_ref());
126
0
        }
127
0
        ComponentDefinedType::Result(e) => {
128
0
            encoder.result(
129
0
                e.ok.as_deref().map(Into::into),
130
0
                e.err.as_deref().map(Into::into),
131
0
            );
132
0
        }
133
    }
134
0
}
135
136
0
#[derive(Default)]
137
struct Encoder<'a> {
138
    component: wasm_encoder::Component,
139
    current_section_id: Option<u8>,
140
141
    // Core sections
142
    // Note: module sections are written immediately
143
    core_instances: InstanceSection,
144
    core_types: CoreTypeSection,
145
146
    // Component sections
147
    // Note: custom, component, start sections are written immediately
148
    instances: ComponentInstanceSection,
149
    aliases: ComponentAliasSection,
150
    types: ComponentTypeSection,
151
    funcs: CanonicalFunctionSection,
152
    imports: ComponentImportSection,
153
    exports: ComponentExportSection,
154
155
    core_func_names: Vec<Option<&'a str>>,
156
    core_table_names: Vec<Option<&'a str>>,
157
    core_memory_names: Vec<Option<&'a str>>,
158
    core_global_names: Vec<Option<&'a str>>,
159
    core_type_names: Vec<Option<&'a str>>,
160
    core_module_names: Vec<Option<&'a str>>,
161
    core_instance_names: Vec<Option<&'a str>>,
162
    func_names: Vec<Option<&'a str>>,
163
    value_names: Vec<Option<&'a str>>,
164
    type_names: Vec<Option<&'a str>>,
165
    component_names: Vec<Option<&'a str>>,
166
    instance_names: Vec<Option<&'a str>>,
167
}
168
169
impl<'a> Encoder<'a> {
170
0
    fn encode_custom(&mut self, custom: &Custom) {
171
0
        // Flush any in-progress section before encoding the customs section
172
0
        self.flush(None);
173
0
        self.component.section(custom);
174
0
    }
175
176
0
    fn encode_core_module(&mut self, module: &CoreModule<'a>) {
177
0
        // Flush any in-progress section before encoding the module
178
0
        self.flush(None);
179
0
180
0
        self.core_module_names
181
0
            .push(get_name(&module.id, &module.name));
182
0
183
0
        match &module.kind {
184
0
            CoreModuleKind::Import { .. } => unreachable!("should be expanded already"),
185
0
            CoreModuleKind::Inline { fields } => {
186
0
                // TODO: replace this with a wasm-encoder based encoding (should return `wasm_encoder::Module`)
187
0
                let data = crate::core::binary::encode(&module.id, &module.name, fields);
188
0
                self.component.section(&RawSection {
189
0
                    id: ComponentSectionId::CoreModule.into(),
190
0
                    data: &data,
191
0
                });
192
0
            }
193
0
        }
194
0
    }
195
196
0
    fn encode_core_instance(&mut self, instance: &CoreInstance<'a>) {
197
0
        self.core_instance_names
198
0
            .push(get_name(&instance.id, &instance.name));
199
0
        match &instance.kind {
200
0
            CoreInstanceKind::Instantiate { module, args } => {
201
0
                self.core_instances.instantiate(
202
0
                    module.into(),
203
0
                    args.iter().map(|arg| (arg.name, (&arg.kind).into())),
204
0
                );
205
0
            }
206
0
            CoreInstanceKind::BundleOfExports(exports) => {
207
0
                self.core_instances.export_items(exports.iter().map(|e| {
208
0
                    let (kind, index) = (&e.item).into();
209
0
                    (e.name, kind, index)
210
0
                }));
211
0
            }
212
        }
213
214
0
        self.flush(Some(self.core_instances.id()));
215
0
    }
216
217
0
    fn encode_core_type(&mut self, ty: &CoreType<'a>) {
218
0
        self.core_type_names.push(get_name(&ty.id, &ty.name));
219
0
        encode_core_type(self.core_types.ty(), &ty.def);
220
0
        self.flush(Some(self.core_types.id()));
221
0
    }
222
223
0
    fn encode_component(&mut self, component: &NestedComponent<'a>) {
224
0
        self.component_names
225
0
            .push(get_name(&component.id, &component.name));
226
0
        // Flush any in-progress section before encoding the component
227
0
        self.flush(None);
228
0
229
0
        match &component.kind {
230
0
            NestedComponentKind::Import { .. } => unreachable!("should be expanded already"),
231
0
            NestedComponentKind::Inline(fields) => {
232
0
                self.component
233
0
                    .section(&NestedComponentSection(&encode_fields(
234
0
                        &component.id,
235
0
                        &component.name,
236
0
                        fields,
237
0
                    )));
238
0
            }
239
0
        }
240
0
    }
241
242
0
    fn encode_instance(&mut self, instance: &Instance<'a>) {
243
0
        self.instance_names
244
0
            .push(get_name(&instance.id, &instance.name));
245
0
        match &instance.kind {
246
0
            InstanceKind::Import { .. } => unreachable!("should be expanded already"),
247
0
            InstanceKind::Instantiate { component, args } => {
248
0
                self.instances.instantiate(
249
0
                    component.into(),
250
0
                    args.iter().map(|arg| {
251
0
                        let (kind, index) = (&arg.kind).into();
252
0
                        (arg.name, kind, index)
253
0
                    }),
254
0
                );
255
0
            }
256
0
            InstanceKind::BundleOfExports(exports) => {
257
0
                self.instances.export_items(exports.iter().map(|e| {
258
0
                    let (kind, index) = (&e.kind).into();
259
0
                    (e.name, kind, index)
260
0
                }));
261
0
            }
262
        }
263
264
0
        self.flush(Some(self.instances.id()));
265
0
    }
266
267
0
    fn encode_alias(&mut self, alias: &Alias<'a>) {
268
0
        let name = get_name(&alias.id, &alias.name);
269
0
        self.aliases.alias((&alias.target).into());
270
0
        match &alias.target {
271
0
            AliasTarget::Export { kind, .. } => {
272
0
                self.names_for_component_export_alias(*kind).push(name);
273
0
            }
274
0
            AliasTarget::CoreExport { kind, .. } => {
275
0
                self.names_for_core_export_alias(*kind).push(name);
276
0
            }
277
0
            AliasTarget::Outer { kind, .. } => {
278
0
                self.names_for_component_outer_alias(*kind).push(name);
279
0
            }
280
        }
281
282
0
        self.flush(Some(self.aliases.id()));
283
0
    }
284
285
0
    fn encode_start(&mut self, start: &Start) {
286
0
        // Flush any in-progress section before encoding the start section
287
0
        self.flush(None);
288
0
289
0
        self.component.section(&ComponentStartSection {
290
0
            function_index: start.func.into(),
291
0
            args: start.args.iter().map(|a| a.idx.into()).collect::<Vec<_>>(),
292
0
            results: start.results.len() as u32,
293
0
        });
294
0
    }
295
296
0
    fn encode_type(&mut self, ty: &Type<'a>) {
297
0
        self.type_names.push(get_name(&ty.id, &ty.name));
298
0
        encode_type(self.types.ty(), &ty.def);
299
0
        self.flush(Some(self.types.id()));
300
0
    }
301
302
0
    fn encode_canonical_func(&mut self, func: &CanonicalFunc<'a>) {
303
0
        let name = get_name(&func.id, &func.name);
304
0
        match &func.kind {
305
0
            CanonicalFuncKind::Lift { ty, info } => {
306
0
                self.func_names.push(name);
307
0
                self.funcs.lift(
308
0
                    info.func.idx.into(),
309
0
                    ty.into(),
310
0
                    info.opts.iter().map(Into::into),
311
0
                );
312
0
            }
313
0
            CanonicalFuncKind::Lower(info) => {
314
0
                self.core_func_names.push(name);
315
0
                self.funcs
316
0
                    .lower(info.func.idx.into(), info.opts.iter().map(Into::into));
317
0
            }
318
        }
319
320
0
        self.flush(Some(self.funcs.id()));
321
0
    }
322
323
0
    fn encode_import(&mut self, import: &ComponentImport<'a>) {
324
0
        let name = get_name(&import.item.id, &import.item.name);
325
0
        self.names_for_item_kind(&import.item.kind).push(name);
326
0
        self.imports.import(
327
0
            import.name,
328
0
            import.url.unwrap_or(""),
329
0
            (&import.item.kind).into(),
330
0
        );
331
0
        self.flush(Some(self.imports.id()));
332
0
    }
333
334
0
    fn encode_export(&mut self, export: &ComponentExport<'a>) {
335
0
        let name = get_name(&export.id, &export.debug_name);
336
0
        let (kind, index) = (&export.kind).into();
337
0
        self.exports.export(
338
0
            export.name,
339
0
            export.url.unwrap_or(""),
340
0
            kind,
341
0
            index,
342
0
            export.ty.as_ref().map(|ty| (&ty.0.kind).into()),
343
0
        );
344
0
        match &export.kind {
345
0
            ComponentExportKind::CoreModule(_) => self.core_module_names.push(name),
346
0
            ComponentExportKind::Func(_) => self.func_names.push(name),
347
0
            ComponentExportKind::Instance(_) => self.instance_names.push(name),
348
0
            ComponentExportKind::Value(_) => self.value_names.push(name),
349
0
            ComponentExportKind::Component(_) => self.component_names.push(name),
350
0
            ComponentExportKind::Type(_) => self.type_names.push(name),
351
        }
352
0
        self.flush(Some(self.exports.id()));
353
0
    }
354
355
0
    fn flush(&mut self, section_id: Option<u8>) {
356
0
        if self.current_section_id == section_id {
357
0
            return;
358
0
        }
359
360
0
        if let Some(id) = self.current_section_id {
361
0
            match id {
362
                // 0 => custom sections are written immediately
363
                // 1 => core modules sections are written immediately
364
                2 => {
365
0
                    assert_eq!(id, self.core_instances.id());
366
0
                    self.component.section(&self.core_instances);
367
0
                    self.core_instances = Default::default();
368
                }
369
                3 => {
370
0
                    assert_eq!(id, self.core_types.id());
371
0
                    self.component.section(&self.core_types);
372
0
                    self.core_types = Default::default();
373
                }
374
                // 4 => components sections are written immediately
375
                5 => {
376
0
                    assert_eq!(id, self.instances.id());
377
0
                    self.component.section(&self.instances);
378
0
                    self.instances = Default::default();
379
                }
380
                6 => {
381
0
                    assert_eq!(id, self.aliases.id());
382
0
                    self.component.section(&self.aliases);
383
0
                    self.aliases = Default::default();
384
                }
385
                7 => {
386
0
                    assert_eq!(id, self.types.id());
387
0
                    self.component.section(&self.types);
388
0
                    self.types = Default::default();
389
                }
390
                8 => {
391
0
                    assert_eq!(id, self.funcs.id());
392
0
                    self.component.section(&self.funcs);
393
0
                    self.funcs = Default::default();
394
                }
395
                // 9 => start sections are written immediately
396
                10 => {
397
0
                    assert_eq!(id, self.imports.id());
398
0
                    self.component.section(&self.imports);
399
0
                    self.imports = Default::default();
400
                }
401
                11 => {
402
0
                    assert_eq!(id, self.exports.id());
403
0
                    self.component.section(&self.exports);
404
0
                    self.exports = Default::default();
405
                }
406
0
                _ => unreachable!("unknown incremental component section id: {}", id),
407
            }
408
0
        }
409
410
0
        self.current_section_id = section_id
411
0
    }
412
413
0
    fn encode_names(
414
0
        &mut self,
415
0
        component_id: &Option<Id<'_>>,
416
0
        component_name: &Option<NameAnnotation<'_>>,
417
0
    ) {
418
0
        let mut names = ComponentNameSection::new();
419
0
        if let Some(name) = get_name(component_id, component_name) {
420
0
            names.component(name);
421
0
        }
422
423
0
        let mut funcs = |list: &[Option<&str>], append: fn(&mut ComponentNameSection, &NameMap)| {
424
0
            let mut map = NameMap::new();
425
0
            for (i, entry) in list.iter().enumerate() {
426
0
                if let Some(name) = entry {
427
0
                    map.append(i as u32, name);
428
0
                }
429
            }
430
0
            if !map.is_empty() {
431
0
                append(&mut names, &map);
432
0
            }
433
0
        };
434
435
0
        funcs(&self.core_func_names, ComponentNameSection::core_funcs);
436
0
        funcs(&self.core_table_names, ComponentNameSection::core_tables);
437
0
        funcs(&self.core_memory_names, ComponentNameSection::core_memories);
438
0
        funcs(&self.core_global_names, ComponentNameSection::core_globals);
439
0
        funcs(&self.core_type_names, ComponentNameSection::core_types);
440
0
        funcs(&self.core_module_names, ComponentNameSection::core_modules);
441
0
        funcs(
442
0
            &self.core_instance_names,
443
0
            ComponentNameSection::core_instances,
444
0
        );
445
0
        funcs(&self.func_names, ComponentNameSection::funcs);
446
0
        funcs(&self.value_names, ComponentNameSection::values);
447
0
        funcs(&self.type_names, ComponentNameSection::types);
448
0
        funcs(&self.component_names, ComponentNameSection::components);
449
0
        funcs(&self.instance_names, ComponentNameSection::instances);
450
0
451
0
        if !names.is_empty() {
452
0
            self.component.section(&names);
453
0
        }
454
0
    }
455
456
0
    fn names_for_component_export_alias(
457
0
        &mut self,
458
0
        kind: ComponentExportAliasKind,
459
0
    ) -> &mut Vec<Option<&'a str>> {
460
0
        match kind {
461
0
            ComponentExportAliasKind::Func => &mut self.func_names,
462
0
            ComponentExportAliasKind::CoreModule => &mut self.core_module_names,
463
0
            ComponentExportAliasKind::Value => &mut self.value_names,
464
0
            ComponentExportAliasKind::Type => &mut self.type_names,
465
0
            ComponentExportAliasKind::Component => &mut self.component_names,
466
0
            ComponentExportAliasKind::Instance => &mut self.instance_names,
467
        }
468
0
    }
469
470
0
    fn names_for_component_outer_alias(
471
0
        &mut self,
472
0
        kind: ComponentOuterAliasKind,
473
0
    ) -> &mut Vec<Option<&'a str>> {
474
0
        match kind {
475
0
            ComponentOuterAliasKind::CoreModule => &mut self.core_module_names,
476
0
            ComponentOuterAliasKind::CoreType => &mut self.core_type_names,
477
0
            ComponentOuterAliasKind::Component => &mut self.component_names,
478
0
            ComponentOuterAliasKind::Type => &mut self.type_names,
479
        }
480
0
    }
481
482
0
    fn names_for_core_export_alias(&mut self, kind: core::ExportKind) -> &mut Vec<Option<&'a str>> {
483
0
        match kind {
484
0
            core::ExportKind::Func => &mut self.core_func_names,
485
0
            core::ExportKind::Global => &mut self.core_global_names,
486
0
            core::ExportKind::Table => &mut self.core_table_names,
487
0
            core::ExportKind::Memory => &mut self.core_memory_names,
488
0
            core::ExportKind::Tag => unimplemented!(),
489
        }
490
0
    }
491
492
0
    fn names_for_item_kind(&mut self, kind: &ItemSigKind) -> &mut Vec<Option<&'a str>> {
493
0
        match kind {
494
0
            ItemSigKind::CoreModule(_) => &mut self.core_module_names,
495
0
            ItemSigKind::Func(_) => &mut self.func_names,
496
0
            ItemSigKind::Component(_) => &mut self.component_names,
497
0
            ItemSigKind::Instance(_) => &mut self.instance_names,
498
0
            ItemSigKind::Value(_) => &mut self.value_names,
499
0
            ItemSigKind::Type(_) => &mut self.type_names,
500
        }
501
0
    }
502
}
503
504
0
fn get_name<'a>(id: &Option<Id<'a>>, name: &Option<NameAnnotation<'a>>) -> Option<&'a str> {
505
0
    name.as_ref().map(|n| n.name).or_else(|| {
506
0
        id.and_then(|id| {
507
0
            if id.is_gensym() {
508
0
                None
509
            } else {
510
0
                Some(id.name())
511
            }
512
0
        })
513
0
    })
514
0
}
515
516
// This implementation is much like `wasm_encoder::CustomSection`, except
517
// that it extends via a list of slices instead of a single slice.
518
impl wasm_encoder::Encode for Custom<'_> {
519
0
    fn encode(&self, sink: &mut Vec<u8>) {
520
0
        let mut buf = [0u8; 5];
521
0
        let encoded_name_len =
522
0
            leb128::write::unsigned(&mut &mut buf[..], u64::try_from(self.name.len()).unwrap())
523
0
                .unwrap();
524
0
        let data_len = self.data.iter().fold(0, |acc, s| acc + s.len());
525
0
526
0
        // name length
527
0
        (encoded_name_len + self.name.len() + data_len).encode(sink);
528
0
529
0
        // name
530
0
        self.name.encode(sink);
531
532
        // data
533
0
        for s in &self.data {
534
0
            sink.extend(*s);
535
0
        }
536
0
    }
537
}
538
539
impl wasm_encoder::ComponentSection for Custom<'_> {
540
0
    fn id(&self) -> u8 {
541
0
        SectionId::Custom.into()
542
0
    }
543
}
544
545
// TODO: move these core conversion functions to the core module
546
// once we update core encoding to use wasm-encoder.
547
impl From<core::ValType<'_>> for wasm_encoder::ValType {
548
0
    fn from(ty: core::ValType) -> Self {
549
0
        match ty {
550
0
            core::ValType::I32 => Self::I32,
551
0
            core::ValType::I64 => Self::I64,
552
0
            core::ValType::F32 => Self::F32,
553
0
            core::ValType::F64 => Self::F64,
554
0
            core::ValType::V128 => Self::V128,
555
0
            core::ValType::Ref(r) => Self::Ref(r.into()),
556
        }
557
0
    }
558
}
559
560
impl From<core::RefType<'_>> for wasm_encoder::RefType {
561
0
    fn from(r: core::RefType<'_>) -> Self {
562
0
        wasm_encoder::RefType {
563
0
            nullable: r.nullable,
564
0
            heap_type: r.heap.into(),
565
0
        }
566
0
    }
567
}
568
569
impl From<core::HeapType<'_>> for wasm_encoder::HeapType {
570
0
    fn from(r: core::HeapType<'_>) -> Self {
571
0
        match r {
572
0
            core::HeapType::Func => Self::Func,
573
0
            core::HeapType::Extern => Self::Extern,
574
0
            core::HeapType::Index(Index::Num(i, _)) => Self::TypedFunc(i),
575
0
            core::HeapType::Index(_) => panic!("unresolved index"),
576
            core::HeapType::Any
577
            | core::HeapType::Eq
578
            | core::HeapType::Struct
579
            | core::HeapType::Array
580
            | core::HeapType::NoFunc
581
            | core::HeapType::NoExtern
582
            | core::HeapType::None
583
            | core::HeapType::I31 => {
584
0
                todo!("encoding of GC proposal types not yet implemented")
585
            }
586
        }
587
0
    }
588
}
589
590
impl From<&core::ItemKind<'_>> for wasm_encoder::EntityType {
591
0
    fn from(kind: &core::ItemKind) -> Self {
592
0
        match kind {
593
0
            core::ItemKind::Func(t) => Self::Function(t.into()),
594
0
            core::ItemKind::Table(t) => Self::Table((*t).into()),
595
0
            core::ItemKind::Memory(t) => Self::Memory((*t).into()),
596
0
            core::ItemKind::Global(t) => Self::Global((*t).into()),
597
0
            core::ItemKind::Tag(t) => Self::Tag(t.into()),
598
        }
599
0
    }
600
}
601
602
impl From<core::TableType<'_>> for wasm_encoder::TableType {
603
0
    fn from(ty: core::TableType) -> Self {
604
0
        Self {
605
0
            element_type: ty.elem.into(),
606
0
            minimum: ty.limits.min,
607
0
            maximum: ty.limits.max,
608
0
        }
609
0
    }
610
}
611
612
impl From<core::MemoryType> for wasm_encoder::MemoryType {
613
0
    fn from(ty: core::MemoryType) -> Self {
614
0
        let (minimum, maximum, memory64, shared) = match ty {
615
0
            core::MemoryType::B32 { limits, shared } => {
616
0
                (limits.min.into(), limits.max.map(Into::into), false, shared)
617
            }
618
0
            core::MemoryType::B64 { limits, shared } => (limits.min, limits.max, true, shared),
619
        };
620
621
0
        Self {
622
0
            minimum,
623
0
            maximum,
624
0
            memory64,
625
0
            shared,
626
0
        }
627
0
    }
628
}
629
630
impl From<core::GlobalType<'_>> for wasm_encoder::GlobalType {
631
0
    fn from(ty: core::GlobalType) -> Self {
632
0
        Self {
633
0
            val_type: ty.ty.into(),
634
0
            mutable: ty.mutable,
635
0
        }
636
0
    }
637
}
638
639
impl From<&core::TagType<'_>> for wasm_encoder::TagType {
640
0
    fn from(ty: &core::TagType) -> Self {
641
0
        match ty {
642
0
            core::TagType::Exception(r) => Self {
643
0
                kind: wasm_encoder::TagKind::Exception,
644
0
                func_type_idx: r.into(),
645
0
            },
646
0
        }
647
0
    }
648
}
649
650
impl<T: std::fmt::Debug> From<&core::TypeUse<'_, T>> for u32 {
651
0
    fn from(u: &core::TypeUse<'_, T>) -> Self {
652
0
        match &u.index {
653
0
            Some(i) => (*i).into(),
654
0
            None => unreachable!("unresolved type use in encoding: {:?}", u),
655
        }
656
0
    }
657
}
658
659
impl From<&CoreInstantiationArgKind<'_>> for wasm_encoder::ModuleArg {
660
0
    fn from(kind: &CoreInstantiationArgKind) -> Self {
661
0
        match kind {
662
0
            CoreInstantiationArgKind::Instance(i) => {
663
0
                wasm_encoder::ModuleArg::Instance(i.idx.into())
664
            }
665
            CoreInstantiationArgKind::BundleOfExports(..) => {
666
0
                unreachable!("should be expanded already")
667
            }
668
        }
669
0
    }
670
}
671
672
impl From<&CoreItemRef<'_, core::ExportKind>> for (wasm_encoder::ExportKind, u32) {
673
0
    fn from(item: &CoreItemRef<'_, core::ExportKind>) -> Self {
674
0
        match &item.kind {
675
0
            core::ExportKind::Func => (wasm_encoder::ExportKind::Func, item.idx.into()),
676
0
            core::ExportKind::Table => (wasm_encoder::ExportKind::Table, item.idx.into()),
677
0
            core::ExportKind::Memory => (wasm_encoder::ExportKind::Memory, item.idx.into()),
678
0
            core::ExportKind::Global => (wasm_encoder::ExportKind::Global, item.idx.into()),
679
0
            core::ExportKind::Tag => (wasm_encoder::ExportKind::Tag, item.idx.into()),
680
        }
681
0
    }
682
}
683
684
impl From<core::ExportKind> for wasm_encoder::ExportKind {
685
0
    fn from(kind: core::ExportKind) -> Self {
686
0
        match kind {
687
0
            core::ExportKind::Func => Self::Func,
688
0
            core::ExportKind::Table => Self::Table,
689
0
            core::ExportKind::Memory => Self::Memory,
690
0
            core::ExportKind::Global => Self::Global,
691
0
            core::ExportKind::Tag => Self::Tag,
692
        }
693
0
    }
694
}
695
696
impl From<Index<'_>> for u32 {
697
0
    fn from(i: Index<'_>) -> Self {
698
0
        match i {
699
0
            Index::Num(i, _) => i,
700
0
            Index::Id(_) => unreachable!("unresolved index in encoding: {:?}", i),
701
        }
702
0
    }
703
}
704
705
impl<T> From<&ItemRef<'_, T>> for u32 {
706
0
    fn from(i: &ItemRef<'_, T>) -> Self {
707
0
        assert!(i.export_names.is_empty());
708
0
        i.idx.into()
709
0
    }
Unexecuted instantiation: <u32 as core::convert::From<&wast::component::item_ref::ItemRef<wast::kw::component>>>::from
Unexecuted instantiation: <u32 as core::convert::From<&wast::component::item_ref::ItemRef<wast::kw::module>>>::from
710
}
711
712
impl<T> From<&CoreTypeUse<'_, T>> for u32 {
713
0
    fn from(u: &CoreTypeUse<'_, T>) -> Self {
714
0
        match u {
715
0
            CoreTypeUse::Inline(_) => unreachable!("should be expanded already"),
716
0
            CoreTypeUse::Ref(r) => r.idx.into(),
717
0
        }
718
0
    }
719
}
720
721
impl<T> From<&ComponentTypeUse<'_, T>> for u32 {
722
0
    fn from(u: &ComponentTypeUse<'_, T>) -> Self {
723
0
        match u {
724
0
            ComponentTypeUse::Inline(_) => unreachable!("should be expanded already"),
725
0
            ComponentTypeUse::Ref(r) => r.idx.into(),
726
0
        }
727
0
    }
Unexecuted instantiation: <u32 as core::convert::From<&wast::component::types::ComponentTypeUse<wast::component::types::ComponentType>>>::from
Unexecuted instantiation: <u32 as core::convert::From<&wast::component::types::ComponentTypeUse<wast::component::types::ComponentFunctionType>>>::from
Unexecuted instantiation: <u32 as core::convert::From<&wast::component::types::ComponentTypeUse<wast::component::types::InstanceType>>>::from
728
}
729
730
impl From<&ComponentValType<'_>> for wasm_encoder::ComponentValType {
731
0
    fn from(r: &ComponentValType) -> Self {
732
0
        match r {
733
0
            ComponentValType::Inline(ComponentDefinedType::Primitive(p)) => {
734
0
                Self::Primitive((*p).into())
735
            }
736
0
            ComponentValType::Ref(i) => Self::Type(u32::from(*i)),
737
0
            ComponentValType::Inline(_) => unreachable!("should be expanded by now"),
738
        }
739
0
    }
740
}
741
742
impl From<PrimitiveValType> for wasm_encoder::PrimitiveValType {
743
0
    fn from(p: PrimitiveValType) -> Self {
744
0
        match p {
745
0
            PrimitiveValType::Bool => Self::Bool,
746
0
            PrimitiveValType::S8 => Self::S8,
747
0
            PrimitiveValType::U8 => Self::U8,
748
0
            PrimitiveValType::S16 => Self::S16,
749
0
            PrimitiveValType::U16 => Self::U16,
750
0
            PrimitiveValType::S32 => Self::S32,
751
0
            PrimitiveValType::U32 => Self::U32,
752
0
            PrimitiveValType::S64 => Self::S64,
753
0
            PrimitiveValType::U64 => Self::U64,
754
0
            PrimitiveValType::Float32 => Self::Float32,
755
0
            PrimitiveValType::Float64 => Self::Float64,
756
0
            PrimitiveValType::Char => Self::Char,
757
0
            PrimitiveValType::String => Self::String,
758
        }
759
0
    }
760
}
761
762
impl From<&Refinement<'_>> for u32 {
763
0
    fn from(r: &Refinement) -> Self {
764
0
        match r {
765
0
            Refinement::Index(..) => unreachable!("should be resolved by now"),
766
0
            Refinement::Resolved(i) => *i,
767
0
        }
768
0
    }
769
}
770
771
impl From<&ItemSigKind<'_>> for wasm_encoder::ComponentTypeRef {
772
0
    fn from(k: &ItemSigKind) -> Self {
773
0
        match k {
774
0
            ItemSigKind::Component(c) => Self::Component(c.into()),
775
0
            ItemSigKind::CoreModule(m) => Self::Module(m.into()),
776
0
            ItemSigKind::Instance(i) => Self::Instance(i.into()),
777
0
            ItemSigKind::Value(v) => Self::Value((&v.0).into()),
778
0
            ItemSigKind::Func(f) => Self::Func(f.into()),
779
0
            ItemSigKind::Type(TypeBounds::Eq(t)) => {
780
0
                Self::Type(wasm_encoder::TypeBounds::Eq, (*t).into())
781
            }
782
        }
783
0
    }
784
}
785
786
impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
787
0
    fn from(ty: &ComponentType) -> Self {
788
0
        let mut encoded = wasm_encoder::ComponentType::new();
789
790
0
        for decl in &ty.decls {
791
0
            match decl {
792
0
                ComponentTypeDecl::CoreType(t) => {
793
0
                    encode_core_type(encoded.core_type(), &t.def);
794
0
                }
795
0
                ComponentTypeDecl::Type(t) => {
796
0
                    encode_type(encoded.ty(), &t.def);
797
0
                }
798
0
                ComponentTypeDecl::Alias(a) => {
799
0
                    encoded.alias((&a.target).into());
800
0
                }
801
0
                ComponentTypeDecl::Import(i) => {
802
0
                    encoded.import(i.name, i.url.unwrap_or(""), (&i.item.kind).into());
803
0
                }
804
0
                ComponentTypeDecl::Export(e) => {
805
0
                    encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into());
806
0
                }
807
            }
808
        }
809
810
0
        encoded
811
0
    }
812
}
813
814
impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
815
0
    fn from(ty: &InstanceType) -> Self {
816
0
        let mut encoded = wasm_encoder::InstanceType::new();
817
818
0
        for decl in &ty.decls {
819
0
            match decl {
820
0
                InstanceTypeDecl::CoreType(t) => {
821
0
                    encode_core_type(encoded.core_type(), &t.def);
822
0
                }
823
0
                InstanceTypeDecl::Type(t) => {
824
0
                    encode_type(encoded.ty(), &t.def);
825
0
                }
826
0
                InstanceTypeDecl::Alias(a) => {
827
0
                    encoded.alias((&a.target).into());
828
0
                }
829
0
                InstanceTypeDecl::Export(e) => {
830
0
                    encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into());
831
0
                }
832
            }
833
        }
834
835
0
        encoded
836
0
    }
837
}
838
839
impl From<&ModuleType<'_>> for wasm_encoder::ModuleType {
840
0
    fn from(ty: &ModuleType) -> Self {
841
0
        let mut encoded = wasm_encoder::ModuleType::new();
842
843
0
        for decl in &ty.decls {
844
0
            match decl {
845
0
                ModuleTypeDecl::Type(t) => match &t.def {
846
0
                    core::TypeDef::Func(f) => encoded.ty().function(
847
0
                        f.params.iter().map(|(_, _, ty)| (*ty).into()),
848
0
                        f.results.iter().copied().map(Into::into),
849
0
                    ),
850
                    core::TypeDef::Struct(_) | core::TypeDef::Array(_) => {
851
0
                        todo!("encoding of GC proposal types not yet implemented")
852
                    }
853
                },
854
0
                ModuleTypeDecl::Alias(a) => match &a.target {
855
                    AliasTarget::Outer {
856
0
                        outer,
857
0
                        index,
858
0
                        kind: ComponentOuterAliasKind::CoreType,
859
0
                    } => {
860
0
                        encoded.alias_outer_core_type(u32::from(*outer), u32::from(*index));
861
0
                    }
862
0
                    _ => unreachable!("only outer type aliases are supported"),
863
                },
864
0
                ModuleTypeDecl::Import(i) => {
865
0
                    encoded.import(i.module, i.field, (&i.item.kind).into());
866
0
                }
867
0
                ModuleTypeDecl::Export(name, item) => {
868
0
                    encoded.export(name, (&item.kind).into());
869
0
                }
870
            }
871
        }
872
873
0
        encoded
874
0
    }
875
}
876
877
impl From<&InstantiationArgKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
878
0
    fn from(kind: &InstantiationArgKind) -> Self {
879
0
        match kind {
880
0
            InstantiationArgKind::Item(i) => i.into(),
881
0
            InstantiationArgKind::BundleOfExports(..) => unreachable!("should be expanded already"),
882
        }
883
0
    }
884
}
885
886
impl From<&ComponentExportKind<'_>> for (wasm_encoder::ComponentExportKind, u32) {
887
0
    fn from(kind: &ComponentExportKind) -> Self {
888
0
        match kind {
889
0
            ComponentExportKind::CoreModule(m) => {
890
0
                (wasm_encoder::ComponentExportKind::Module, m.idx.into())
891
            }
892
0
            ComponentExportKind::Func(f) => (wasm_encoder::ComponentExportKind::Func, f.idx.into()),
893
0
            ComponentExportKind::Value(v) => {
894
0
                (wasm_encoder::ComponentExportKind::Value, v.idx.into())
895
            }
896
0
            ComponentExportKind::Type(t) => (wasm_encoder::ComponentExportKind::Type, t.idx.into()),
897
0
            ComponentExportKind::Component(c) => {
898
0
                (wasm_encoder::ComponentExportKind::Component, c.idx.into())
899
            }
900
0
            ComponentExportKind::Instance(i) => {
901
0
                (wasm_encoder::ComponentExportKind::Instance, i.idx.into())
902
            }
903
        }
904
0
    }
905
}
906
907
impl From<ComponentOuterAliasKind> for wasm_encoder::ComponentOuterAliasKind {
908
0
    fn from(kind: ComponentOuterAliasKind) -> Self {
909
0
        match kind {
910
0
            ComponentOuterAliasKind::CoreModule => Self::CoreModule,
911
0
            ComponentOuterAliasKind::CoreType => Self::CoreType,
912
0
            ComponentOuterAliasKind::Type => Self::Type,
913
0
            ComponentOuterAliasKind::Component => Self::Component,
914
        }
915
0
    }
916
}
917
918
impl From<ComponentExportAliasKind> for wasm_encoder::ComponentExportKind {
919
0
    fn from(kind: ComponentExportAliasKind) -> Self {
920
0
        match kind {
921
0
            ComponentExportAliasKind::CoreModule => Self::Module,
922
0
            ComponentExportAliasKind::Func => Self::Func,
923
0
            ComponentExportAliasKind::Value => Self::Value,
924
0
            ComponentExportAliasKind::Type => Self::Type,
925
0
            ComponentExportAliasKind::Component => Self::Component,
926
0
            ComponentExportAliasKind::Instance => Self::Instance,
927
        }
928
0
    }
929
}
930
931
impl From<&CanonOpt<'_>> for wasm_encoder::CanonicalOption {
932
0
    fn from(opt: &CanonOpt) -> Self {
933
0
        match opt {
934
0
            CanonOpt::StringUtf8 => Self::UTF8,
935
0
            CanonOpt::StringUtf16 => Self::UTF16,
936
0
            CanonOpt::StringLatin1Utf16 => Self::CompactUTF16,
937
0
            CanonOpt::Memory(m) => Self::Memory(m.idx.into()),
938
0
            CanonOpt::Realloc(f) => Self::Realloc(f.idx.into()),
939
0
            CanonOpt::PostReturn(f) => Self::PostReturn(f.idx.into()),
940
        }
941
0
    }
942
}
943
944
impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> {
945
0
    fn from(target: &AliasTarget<'a>) -> Self {
946
0
        match target {
947
            AliasTarget::Export {
948
0
                instance,
949
0
                name,
950
0
                kind,
951
0
            } => wasm_encoder::Alias::InstanceExport {
952
0
                instance: (*instance).into(),
953
0
                kind: (*kind).into(),
954
0
                name,
955
0
            },
956
            AliasTarget::CoreExport {
957
0
                instance,
958
0
                name,
959
0
                kind,
960
0
            } => wasm_encoder::Alias::CoreInstanceExport {
961
0
                instance: (*instance).into(),
962
0
                kind: (*kind).into(),
963
0
                name,
964
0
            },
965
0
            AliasTarget::Outer { outer, index, kind } => wasm_encoder::Alias::Outer {
966
0
                count: (*outer).into(),
967
0
                kind: (*kind).into(),
968
0
                index: (*index).into(),
969
0
            },
970
        }
971
0
    }
972
}