1 use crate::ast::*;
2 
encode(module: &Module<'_>) -> Vec<u8>3 pub fn encode(module: &Module<'_>) -> Vec<u8> {
4     match &module.kind {
5         ModuleKind::Text(fields) => encode_fields(&module.id, &module.name, fields),
6         ModuleKind::Binary(bytes) => bytes.iter().flat_map(|b| b.iter().cloned()).collect(),
7     }
8 }
9 
encode_fields( module_id: &Option<Id<'_>>, module_name: &Option<NameAnnotation<'_>>, fields: &[ModuleField<'_>], ) -> Vec<u8>10 fn encode_fields(
11     module_id: &Option<Id<'_>>,
12     module_name: &Option<NameAnnotation<'_>>,
13     fields: &[ModuleField<'_>],
14 ) -> Vec<u8> {
15     use crate::ast::CustomPlace::*;
16     use crate::ast::CustomPlaceAnchor::*;
17 
18     let mut types = Vec::new();
19     let mut imports = Vec::new();
20     let mut funcs = Vec::new();
21     let mut tables = Vec::new();
22     let mut memories = Vec::new();
23     let mut globals = Vec::new();
24     let mut exports = Vec::new();
25     let mut start = Vec::new();
26     let mut elem = Vec::new();
27     let mut data = Vec::new();
28     let mut tags = Vec::new();
29     let mut customs = Vec::new();
30     let mut instances = Vec::new();
31     let mut modules = Vec::new();
32     let mut aliases = Vec::new();
33     for field in fields {
34         match field {
35             ModuleField::Type(i) => types.push(i),
36             ModuleField::Import(i) => imports.push(i),
37             ModuleField::Func(i) => funcs.push(i),
38             ModuleField::Table(i) => tables.push(i),
39             ModuleField::Memory(i) => memories.push(i),
40             ModuleField::Global(i) => globals.push(i),
41             ModuleField::Export(i) => exports.push(i),
42             ModuleField::Start(i) => start.push(i),
43             ModuleField::Elem(i) => elem.push(i),
44             ModuleField::Data(i) => data.push(i),
45             ModuleField::Tag(i) => tags.push(i),
46             ModuleField::Custom(i) => customs.push(i),
47             ModuleField::Instance(i) => instances.push(i),
48             ModuleField::NestedModule(i) => modules.push(i),
49             ModuleField::Alias(a) => aliases.push(a),
50         }
51     }
52 
53     let mut e = Encoder {
54         wasm: Vec::new(),
55         tmp: Vec::new(),
56         customs: &customs,
57     };
58     e.wasm.extend(b"\0asm");
59     e.wasm.extend(b"\x01\0\0\0");
60 
61     e.custom_sections(BeforeFirst);
62 
63     let mut items = fields
64         .iter()
65         .filter(|i| match i {
66             ModuleField::Alias(_)
67             | ModuleField::Type(_)
68             | ModuleField::Import(_)
69             | ModuleField::NestedModule(_)
70             | ModuleField::Instance(_) => true,
71             _ => false,
72         })
73         .peekable();
74 
75     // A special path is used for now to handle non-module-linking modules to
76     // work around WebAssembly/annotations#11
77     if aliases.len() == 0 && modules.len() == 0 && instances.len() == 0 {
78         e.section_list(1, Type, &types);
79         e.section_list(2, Import, &imports);
80     } else {
81         while let Some(field) = items.next() {
82             macro_rules! list {
83                 ($code:expr, $name:ident) => {
84                     list!($code, $name, $name)
85                 };
86                 ($code:expr, $field:ident, $custom:ident) => {
87                     if let ModuleField::$field(f) = field {
88                         let mut list = vec![f];
89                         while let Some(ModuleField::$field(f)) = items.peek() {
90                             list.push(f);
91                             items.next();
92                         }
93                         e.section_list($code, $custom, &list);
94                     }
95                 };
96             }
97             list!(1, Type);
98             list!(2, Import);
99             list!(14, NestedModule, Module);
100             list!(15, Instance);
101             list!(16, Alias);
102         }
103     }
104 
105     let functys = funcs.iter().map(|f| &f.ty).collect::<Vec<_>>();
106     e.section_list(3, Func, &functys);
107     e.section_list(4, Table, &tables);
108     e.section_list(5, Memory, &memories);
109     e.section_list(13, Tag, &tags);
110     e.section_list(6, Global, &globals);
111     e.section_list(7, Export, &exports);
112     e.custom_sections(Before(Start));
113     if let Some(start) = start.get(0) {
114         e.section(8, start);
115     }
116     e.custom_sections(After(Start));
117     e.section_list(9, Elem, &elem);
118     if contains_bulk_memory(&funcs) {
119         e.section(12, &data.len());
120     }
121     e.section_list(10, Code, &funcs);
122     e.section_list(11, Data, &data);
123 
124     let names = find_names(module_id, module_name, fields);
125     if !names.is_empty() {
126         e.section(0, &("name", names));
127     }
128     e.custom_sections(AfterLast);
129 
130     return e.wasm;
131 
132     fn contains_bulk_memory(funcs: &[&crate::ast::Func<'_>]) -> bool {
133         funcs
134             .iter()
135             .filter_map(|f| match &f.kind {
136                 FuncKind::Inline { expression, .. } => Some(expression),
137                 _ => None,
138             })
139             .flat_map(|e| e.instrs.iter())
140             .any(|i| match i {
141                 Instruction::MemoryInit(_) | Instruction::DataDrop(_) => true,
142                 _ => false,
143             })
144     }
145 }
146 
147 struct Encoder<'a> {
148     wasm: Vec<u8>,
149     tmp: Vec<u8>,
150     customs: &'a [&'a Custom<'a>],
151 }
152 
153 impl Encoder<'_> {
section(&mut self, id: u8, section: &dyn Encode)154     fn section(&mut self, id: u8, section: &dyn Encode) {
155         self.tmp.truncate(0);
156         section.encode(&mut self.tmp);
157         self.wasm.push(id);
158         self.tmp.encode(&mut self.wasm);
159     }
160 
custom_sections(&mut self, place: CustomPlace)161     fn custom_sections(&mut self, place: CustomPlace) {
162         for entry in self.customs.iter() {
163             if entry.place == place {
164                 self.section(0, &(entry.name, entry));
165             }
166         }
167     }
168 
section_list(&mut self, id: u8, anchor: CustomPlaceAnchor, list: &[impl Encode])169     fn section_list(&mut self, id: u8, anchor: CustomPlaceAnchor, list: &[impl Encode]) {
170         self.custom_sections(CustomPlace::Before(anchor));
171         if !list.is_empty() {
172             self.section(id, &list)
173         }
174         self.custom_sections(CustomPlace::After(anchor));
175     }
176 }
177 
178 pub(crate) trait Encode {
encode(&self, e: &mut Vec<u8>)179     fn encode(&self, e: &mut Vec<u8>);
180 }
181 
182 impl<T: Encode + ?Sized> Encode for &'_ T {
encode(&self, e: &mut Vec<u8>)183     fn encode(&self, e: &mut Vec<u8>) {
184         T::encode(self, e)
185     }
186 }
187 
188 impl<T: Encode> Encode for [T] {
encode(&self, e: &mut Vec<u8>)189     fn encode(&self, e: &mut Vec<u8>) {
190         self.len().encode(e);
191         for item in self {
192             item.encode(e);
193         }
194     }
195 }
196 
197 impl<T: Encode> Encode for Vec<T> {
encode(&self, e: &mut Vec<u8>)198     fn encode(&self, e: &mut Vec<u8>) {
199         <[T]>::encode(self, e)
200     }
201 }
202 
203 impl Encode for str {
encode(&self, e: &mut Vec<u8>)204     fn encode(&self, e: &mut Vec<u8>) {
205         self.len().encode(e);
206         e.extend_from_slice(self.as_bytes());
207     }
208 }
209 
210 impl Encode for usize {
encode(&self, e: &mut Vec<u8>)211     fn encode(&self, e: &mut Vec<u8>) {
212         assert!(*self <= u32::max_value() as usize);
213         (*self as u32).encode(e)
214     }
215 }
216 
217 impl Encode for u8 {
encode(&self, e: &mut Vec<u8>)218     fn encode(&self, e: &mut Vec<u8>) {
219         e.push(*self);
220     }
221 }
222 
223 impl Encode for u32 {
encode(&self, e: &mut Vec<u8>)224     fn encode(&self, e: &mut Vec<u8>) {
225         leb128::write::unsigned(e, (*self).into()).unwrap();
226     }
227 }
228 
229 impl Encode for i32 {
encode(&self, e: &mut Vec<u8>)230     fn encode(&self, e: &mut Vec<u8>) {
231         leb128::write::signed(e, (*self).into()).unwrap();
232     }
233 }
234 
235 impl Encode for u64 {
encode(&self, e: &mut Vec<u8>)236     fn encode(&self, e: &mut Vec<u8>) {
237         leb128::write::unsigned(e, (*self).into()).unwrap();
238     }
239 }
240 
241 impl Encode for i64 {
encode(&self, e: &mut Vec<u8>)242     fn encode(&self, e: &mut Vec<u8>) {
243         leb128::write::signed(e, *self).unwrap();
244     }
245 }
246 
247 impl Encode for FunctionType<'_> {
encode(&self, e: &mut Vec<u8>)248     fn encode(&self, e: &mut Vec<u8>) {
249         self.params.len().encode(e);
250         for (_, _, ty) in self.params.iter() {
251             ty.encode(e);
252         }
253         self.results.encode(e);
254     }
255 }
256 
257 impl Encode for StructType<'_> {
encode(&self, e: &mut Vec<u8>)258     fn encode(&self, e: &mut Vec<u8>) {
259         self.fields.len().encode(e);
260         for field in self.fields.iter() {
261             field.ty.encode(e);
262             (field.mutable as i32).encode(e);
263         }
264     }
265 }
266 
267 impl Encode for ArrayType<'_> {
encode(&self, e: &mut Vec<u8>)268     fn encode(&self, e: &mut Vec<u8>) {
269         self.ty.encode(e);
270         (self.mutable as i32).encode(e);
271     }
272 }
273 
274 impl Encode for ModuleType<'_> {
encode(&self, e: &mut Vec<u8>)275     fn encode(&self, e: &mut Vec<u8>) {
276         self.imports.encode(e);
277         self.exports.encode(e);
278     }
279 }
280 
281 impl Encode for InstanceType<'_> {
encode(&self, e: &mut Vec<u8>)282     fn encode(&self, e: &mut Vec<u8>) {
283         self.exports.encode(e);
284     }
285 }
286 
287 impl Encode for ExportType<'_> {
encode(&self, e: &mut Vec<u8>)288     fn encode(&self, e: &mut Vec<u8>) {
289         self.name.encode(e);
290         self.item.encode(e);
291     }
292 }
293 
294 impl Encode for Type<'_> {
encode(&self, e: &mut Vec<u8>)295     fn encode(&self, e: &mut Vec<u8>) {
296         match &self.def {
297             TypeDef::Func(func) => {
298                 e.push(0x60);
299                 func.encode(e)
300             }
301             TypeDef::Struct(r#struct) => {
302                 e.push(0x5f);
303                 r#struct.encode(e)
304             }
305             TypeDef::Array(array) => {
306                 e.push(0x5e);
307                 array.encode(e)
308             }
309             TypeDef::Module(module) => {
310                 e.push(0x61);
311                 module.encode(e)
312             }
313             TypeDef::Instance(instance) => {
314                 e.push(0x62);
315                 instance.encode(e)
316             }
317         }
318     }
319 }
320 
321 impl Encode for Option<Id<'_>> {
encode(&self, _e: &mut Vec<u8>)322     fn encode(&self, _e: &mut Vec<u8>) {
323         // used for parameters in the tuple impl as well as instruction labels
324     }
325 }
326 
327 impl<T: Encode, U: Encode> Encode for (T, U) {
encode(&self, e: &mut Vec<u8>)328     fn encode(&self, e: &mut Vec<u8>) {
329         self.0.encode(e);
330         self.1.encode(e);
331     }
332 }
333 
334 impl<'a> Encode for ValType<'a> {
encode(&self, e: &mut Vec<u8>)335     fn encode(&self, e: &mut Vec<u8>) {
336         match self {
337             ValType::I32 => e.push(0x7f),
338             ValType::I64 => e.push(0x7e),
339             ValType::F32 => e.push(0x7d),
340             ValType::F64 => e.push(0x7c),
341             ValType::V128 => e.push(0x7b),
342             ValType::Rtt(Some(depth), index) => {
343                 e.push(0x69);
344                 depth.encode(e);
345                 index.encode(e);
346             }
347             ValType::Rtt(None, index) => {
348                 e.push(0x68);
349                 index.encode(e);
350             }
351             ValType::Ref(ty) => {
352                 ty.encode(e);
353             }
354         }
355     }
356 }
357 
358 impl<'a> Encode for HeapType<'a> {
encode(&self, e: &mut Vec<u8>)359     fn encode(&self, e: &mut Vec<u8>) {
360         match self {
361             HeapType::Func => e.push(0x70),
362             HeapType::Extern => e.push(0x6f),
363             HeapType::Any => e.push(0x6e),
364             HeapType::Eq => e.push(0x6d),
365             HeapType::Data => e.push(0x67),
366             HeapType::I31 => e.push(0x6a),
367             HeapType::Index(index) => {
368                 index.encode(e);
369             }
370         }
371     }
372 }
373 
374 impl<'a> Encode for RefType<'a> {
encode(&self, e: &mut Vec<u8>)375     fn encode(&self, e: &mut Vec<u8>) {
376         match self {
377             // The 'funcref' binary abbreviation
378             RefType {
379                 nullable: true,
380                 heap: HeapType::Func,
381             } => e.push(0x70),
382             // The 'externref' binary abbreviation
383             RefType {
384                 nullable: true,
385                 heap: HeapType::Extern,
386             } => e.push(0x6f),
387             // The 'eqref' binary abbreviation
388             RefType {
389                 nullable: true,
390                 heap: HeapType::Eq,
391             } => e.push(0x6d),
392             // The 'dataref' binary abbreviation
393             RefType {
394                 nullable: true,
395                 heap: HeapType::Data,
396             } => e.push(0x67),
397             // The 'i31ref' binary abbreviation
398             RefType {
399                 nullable: true,
400                 heap: HeapType::I31,
401             } => e.push(0x6a),
402 
403             // Generic 'ref opt <heaptype>' encoding
404             RefType {
405                 nullable: true,
406                 heap,
407             } => {
408                 e.push(0x6c);
409                 heap.encode(e);
410             }
411             // Generic 'ref <heaptype>' encoding
412             RefType {
413                 nullable: false,
414                 heap,
415             } => {
416                 e.push(0x6b);
417                 heap.encode(e);
418             }
419         }
420     }
421 }
422 
423 impl<'a> Encode for StorageType<'a> {
encode(&self, e: &mut Vec<u8>)424     fn encode(&self, e: &mut Vec<u8>) {
425         match self {
426             StorageType::I8 => e.push(0x7a),
427             StorageType::I16 => e.push(0x79),
428             StorageType::Val(ty) => {
429                 ty.encode(e);
430             }
431         }
432     }
433 }
434 
435 impl Encode for Import<'_> {
encode(&self, e: &mut Vec<u8>)436     fn encode(&self, e: &mut Vec<u8>) {
437         self.module.encode(e);
438         match self.field {
439             Some(s) => s.encode(e),
440             None => {
441                 e.push(0x00);
442                 e.push(0xff);
443             }
444         }
445         self.item.encode(e);
446     }
447 }
448 
449 impl Encode for ItemSig<'_> {
encode(&self, e: &mut Vec<u8>)450     fn encode(&self, e: &mut Vec<u8>) {
451         match &self.kind {
452             ItemKind::Func(f) => {
453                 e.push(0x00);
454                 f.encode(e);
455             }
456             ItemKind::Table(f) => {
457                 e.push(0x01);
458                 f.encode(e);
459             }
460             ItemKind::Memory(f) => {
461                 e.push(0x02);
462                 f.encode(e);
463             }
464             ItemKind::Global(f) => {
465                 e.push(0x03);
466                 f.encode(e);
467             }
468             ItemKind::Tag(f) => {
469                 e.push(0x04);
470                 f.encode(e);
471             }
472             ItemKind::Module(m) => {
473                 e.push(0x05);
474                 m.encode(e);
475             }
476             ItemKind::Instance(i) => {
477                 e.push(0x06);
478                 i.encode(e);
479             }
480         }
481     }
482 }
483 
484 impl<T> Encode for TypeUse<'_, T> {
encode(&self, e: &mut Vec<u8>)485     fn encode(&self, e: &mut Vec<u8>) {
486         self.index
487             .as_ref()
488             .expect("TypeUse should be filled in by this point")
489             .encode(e)
490     }
491 }
492 
493 impl Encode for Index<'_> {
encode(&self, e: &mut Vec<u8>)494     fn encode(&self, e: &mut Vec<u8>) {
495         match self {
496             Index::Num(n, _) => n.encode(e),
497             Index::Id(n) => panic!("unresolved index in emission: {:?}", n),
498         }
499     }
500 }
501 
502 impl<T> Encode for IndexOrRef<'_, T> {
encode(&self, e: &mut Vec<u8>)503     fn encode(&self, e: &mut Vec<u8>) {
504         self.0.encode(e);
505     }
506 }
507 
508 impl<T> Encode for ItemRef<'_, T> {
encode(&self, e: &mut Vec<u8>)509     fn encode(&self, e: &mut Vec<u8>) {
510         match self {
511             ItemRef::Outer { .. } => panic!("should be expanded previously"),
512             ItemRef::Item {
513                 idx,
514                 exports,
515                 #[cfg(wast_check_exhaustive)]
516                 visited,
517                 ..
518             } => {
519                 #[cfg(wast_check_exhaustive)]
520                 assert!(*visited);
521                 assert!(exports.is_empty());
522                 idx.encode(e);
523             }
524         }
525     }
526 }
527 
528 impl<'a> Encode for TableType<'a> {
encode(&self, e: &mut Vec<u8>)529     fn encode(&self, e: &mut Vec<u8>) {
530         self.elem.encode(e);
531         self.limits.encode(e);
532     }
533 }
534 
535 impl Encode for Limits {
encode(&self, e: &mut Vec<u8>)536     fn encode(&self, e: &mut Vec<u8>) {
537         match self.max {
538             Some(max) => {
539                 e.push(0x01);
540                 self.min.encode(e);
541                 max.encode(e);
542             }
543             None => {
544                 e.push(0x00);
545                 self.min.encode(e);
546             }
547         }
548     }
549 }
550 
551 impl Encode for MemoryType {
encode(&self, e: &mut Vec<u8>)552     fn encode(&self, e: &mut Vec<u8>) {
553         match self {
554             MemoryType::B32 { limits, shared } => {
555                 let flag_max = limits.max.is_some() as u8;
556                 let flag_shared = *shared as u8;
557                 let flags = flag_max | (flag_shared << 1);
558                 e.push(flags);
559                 limits.min.encode(e);
560                 if let Some(max) = limits.max {
561                     max.encode(e);
562                 }
563             }
564             MemoryType::B64 { limits, shared } => {
565                 let flag_max = limits.max.is_some() as u8;
566                 let flag_shared = *shared as u8;
567                 let flags = flag_max | (flag_shared << 1) | 0x04;
568                 e.push(flags);
569                 limits.min.encode(e);
570                 if let Some(max) = limits.max {
571                     max.encode(e);
572                 }
573             }
574         }
575     }
576 }
577 
578 impl<'a> Encode for GlobalType<'a> {
encode(&self, e: &mut Vec<u8>)579     fn encode(&self, e: &mut Vec<u8>) {
580         self.ty.encode(e);
581         if self.mutable {
582             e.push(0x01);
583         } else {
584             e.push(0x00);
585         }
586     }
587 }
588 
589 impl Encode for Table<'_> {
encode(&self, e: &mut Vec<u8>)590     fn encode(&self, e: &mut Vec<u8>) {
591         assert!(self.exports.names.is_empty());
592         match &self.kind {
593             TableKind::Normal(t) => t.encode(e),
594             _ => panic!("TableKind should be normal during encoding"),
595         }
596     }
597 }
598 
599 impl Encode for Memory<'_> {
encode(&self, e: &mut Vec<u8>)600     fn encode(&self, e: &mut Vec<u8>) {
601         assert!(self.exports.names.is_empty());
602         match &self.kind {
603             MemoryKind::Normal(t) => t.encode(e),
604             _ => panic!("MemoryKind should be normal during encoding"),
605         }
606     }
607 }
608 
609 impl Encode for Global<'_> {
encode(&self, e: &mut Vec<u8>)610     fn encode(&self, e: &mut Vec<u8>) {
611         assert!(self.exports.names.is_empty());
612         self.ty.encode(e);
613         match &self.kind {
614             GlobalKind::Inline(expr) => expr.encode(e),
615             _ => panic!("GlobalKind should be inline during encoding"),
616         }
617     }
618 }
619 
620 impl Encode for Export<'_> {
encode(&self, e: &mut Vec<u8>)621     fn encode(&self, e: &mut Vec<u8>) {
622         self.name.encode(e);
623         if let ItemRef::Item { kind, .. } = &self.index {
624             kind.encode(e);
625         }
626         self.index.encode(e);
627     }
628 }
629 
630 impl Encode for ExportKind {
encode(&self, e: &mut Vec<u8>)631     fn encode(&self, e: &mut Vec<u8>) {
632         match self {
633             ExportKind::Func => e.push(0x00),
634             ExportKind::Table => e.push(0x01),
635             ExportKind::Memory => e.push(0x02),
636             ExportKind::Global => e.push(0x03),
637             ExportKind::Tag => e.push(0x04),
638             ExportKind::Module => e.push(0x05),
639             ExportKind::Instance => e.push(0x06),
640             ExportKind::Type => e.push(0x07),
641         }
642     }
643 }
644 
645 impl Encode for Elem<'_> {
encode(&self, e: &mut Vec<u8>)646     fn encode(&self, e: &mut Vec<u8>) {
647         match (&self.kind, &self.payload) {
648             (
649                 ElemKind::Active {
650                     table:
651                         ItemRef::Item {
652                             idx: Index::Num(0, _),
653                             ..
654                         },
655                     offset,
656                 },
657                 ElemPayload::Indices(_),
658             ) => {
659                 e.push(0x00);
660                 offset.encode(e);
661             }
662             (ElemKind::Passive, ElemPayload::Indices(_)) => {
663                 e.push(0x01); // flags
664                 e.push(0x00); // extern_kind
665             }
666             (ElemKind::Active { table, offset }, ElemPayload::Indices(_)) => {
667                 e.push(0x02); // flags
668                 table.encode(e);
669                 offset.encode(e);
670                 e.push(0x00); // extern_kind
671             }
672             (
673                 ElemKind::Active {
674                     table:
675                         ItemRef::Item {
676                             idx: Index::Num(0, _),
677                             ..
678                         },
679                     offset,
680                 },
681                 ElemPayload::Exprs {
682                     ty:
683                         RefType {
684                             nullable: true,
685                             heap: HeapType::Func,
686                         },
687                     ..
688                 },
689             ) => {
690                 e.push(0x04);
691                 offset.encode(e);
692             }
693             (ElemKind::Passive, ElemPayload::Exprs { ty, .. }) => {
694                 e.push(0x05);
695                 ty.encode(e);
696             }
697             (ElemKind::Active { table, offset }, ElemPayload::Exprs { ty, .. }) => {
698                 e.push(0x06);
699                 table.encode(e);
700                 offset.encode(e);
701                 ty.encode(e);
702             }
703             (ElemKind::Declared, ElemPayload::Indices(_)) => {
704                 e.push(0x03); // flags
705                 e.push(0x00); // extern_kind
706             }
707             (ElemKind::Declared, ElemPayload::Exprs { ty, .. }) => {
708                 e.push(0x07); // flags
709                 ty.encode(e);
710             }
711         }
712 
713         self.payload.encode(e);
714     }
715 }
716 
717 impl Encode for ElemPayload<'_> {
encode(&self, e: &mut Vec<u8>)718     fn encode(&self, e: &mut Vec<u8>) {
719         match self {
720             ElemPayload::Indices(v) => v.encode(e),
721             ElemPayload::Exprs { exprs, ty: _ } => {
722                 exprs.len().encode(e);
723                 for expr in exprs {
724                     expr.encode(e);
725                 }
726             }
727         }
728     }
729 }
730 
731 impl Encode for Data<'_> {
encode(&self, e: &mut Vec<u8>)732     fn encode(&self, e: &mut Vec<u8>) {
733         match &self.kind {
734             DataKind::Passive => e.push(0x01),
735             DataKind::Active { memory, offset } => {
736                 if let ItemRef::Item {
737                     idx: Index::Num(0, _),
738                     ..
739                 } = memory
740                 {
741                     e.push(0x00);
742                 } else {
743                     e.push(0x02);
744                     memory.encode(e);
745                 }
746                 offset.encode(e);
747             }
748         }
749         self.data.iter().map(|l| l.len()).sum::<usize>().encode(e);
750         for val in self.data.iter() {
751             val.push_onto(e);
752         }
753     }
754 }
755 
756 impl Encode for Func<'_> {
encode(&self, e: &mut Vec<u8>)757     fn encode(&self, e: &mut Vec<u8>) {
758         assert!(self.exports.names.is_empty());
759         let mut tmp = Vec::new();
760         let (expr, locals) = match &self.kind {
761             FuncKind::Inline { expression, locals } => (expression, locals),
762             _ => panic!("should only have inline functions in emission"),
763         };
764 
765         locals.encode(&mut tmp);
766         expr.encode(&mut tmp);
767 
768         tmp.len().encode(e);
769         e.extend_from_slice(&tmp);
770     }
771 }
772 
773 impl Encode for Vec<Local<'_>> {
encode(&self, e: &mut Vec<u8>)774     fn encode(&self, e: &mut Vec<u8>) {
775         let mut locals_compressed = Vec::<(u32, ValType)>::new();
776         for local in self {
777             if let Some((cnt, prev)) = locals_compressed.last_mut() {
778                 if *prev == local.ty {
779                     *cnt += 1;
780                     continue;
781                 }
782             }
783             locals_compressed.push((1, local.ty));
784         }
785         locals_compressed.encode(e);
786     }
787 }
788 
789 impl Encode for Expression<'_> {
encode(&self, e: &mut Vec<u8>)790     fn encode(&self, e: &mut Vec<u8>) {
791         for instr in self.instrs.iter() {
792             instr.encode(e);
793         }
794         e.push(0x0b);
795     }
796 }
797 
798 impl Encode for BlockType<'_> {
encode(&self, e: &mut Vec<u8>)799     fn encode(&self, e: &mut Vec<u8>) {
800         // block types using an index are encoded as an sleb, not a uleb
801         if let Some(ItemRef::Item {
802             idx: Index::Num(n, _),
803             ..
804         }) = &self.ty.index
805         {
806             return i64::from(*n).encode(e);
807         }
808         let ty = self
809             .ty
810             .inline
811             .as_ref()
812             .expect("function type not filled in");
813         if ty.params.is_empty() && ty.results.is_empty() {
814             return e.push(0x40);
815         }
816         if ty.params.is_empty() && ty.results.len() == 1 {
817             return ty.results[0].encode(e);
818         }
819         panic!("multi-value block types should have an index");
820     }
821 }
822 
823 impl Encode for FuncBindType<'_> {
encode(&self, e: &mut Vec<u8>)824     fn encode(&self, e: &mut Vec<u8>) {
825         self.ty.encode(e);
826     }
827 }
828 
829 impl Encode for LetType<'_> {
encode(&self, e: &mut Vec<u8>)830     fn encode(&self, e: &mut Vec<u8>) {
831         self.block.encode(e);
832         self.locals.encode(e);
833     }
834 }
835 
836 impl Encode for LaneArg {
encode(&self, e: &mut Vec<u8>)837     fn encode(&self, e: &mut Vec<u8>) {
838         self.lane.encode(e);
839     }
840 }
841 
842 impl Encode for MemArg<'_> {
encode(&self, e: &mut Vec<u8>)843     fn encode(&self, e: &mut Vec<u8>) {
844         match &self.memory {
845             ItemRef::Item {
846                 idx: Index::Num(0, _),
847                 ..
848             } => {
849                 self.align.trailing_zeros().encode(e);
850                 self.offset.encode(e);
851             }
852             n => {
853                 (self.align.trailing_zeros() | (1 << 6)).encode(e);
854                 self.offset.encode(e);
855                 n.encode(e);
856             }
857         }
858     }
859 }
860 
861 impl Encode for LoadOrStoreLane<'_> {
encode(&self, e: &mut Vec<u8>)862     fn encode(&self, e: &mut Vec<u8>) {
863         self.memarg.encode(e);
864         self.lane.encode(e);
865     }
866 }
867 
868 impl Encode for CallIndirect<'_> {
encode(&self, e: &mut Vec<u8>)869     fn encode(&self, e: &mut Vec<u8>) {
870         self.ty.encode(e);
871         self.table.encode(e);
872     }
873 }
874 
875 impl Encode for TableInit<'_> {
encode(&self, e: &mut Vec<u8>)876     fn encode(&self, e: &mut Vec<u8>) {
877         self.elem.encode(e);
878         self.table.encode(e);
879     }
880 }
881 
882 impl Encode for TableCopy<'_> {
encode(&self, e: &mut Vec<u8>)883     fn encode(&self, e: &mut Vec<u8>) {
884         self.dst.encode(e);
885         self.src.encode(e);
886     }
887 }
888 
889 impl Encode for TableArg<'_> {
encode(&self, e: &mut Vec<u8>)890     fn encode(&self, e: &mut Vec<u8>) {
891         self.dst.encode(e);
892     }
893 }
894 
895 impl Encode for MemoryArg<'_> {
encode(&self, e: &mut Vec<u8>)896     fn encode(&self, e: &mut Vec<u8>) {
897         self.mem.encode(e);
898     }
899 }
900 
901 impl Encode for MemoryInit<'_> {
encode(&self, e: &mut Vec<u8>)902     fn encode(&self, e: &mut Vec<u8>) {
903         self.data.encode(e);
904         self.mem.encode(e);
905     }
906 }
907 
908 impl Encode for MemoryCopy<'_> {
encode(&self, e: &mut Vec<u8>)909     fn encode(&self, e: &mut Vec<u8>) {
910         self.dst.encode(e);
911         self.src.encode(e);
912     }
913 }
914 
915 impl Encode for BrTableIndices<'_> {
encode(&self, e: &mut Vec<u8>)916     fn encode(&self, e: &mut Vec<u8>) {
917         self.labels.encode(e);
918         self.default.encode(e);
919     }
920 }
921 
922 impl Encode for Float32 {
encode(&self, e: &mut Vec<u8>)923     fn encode(&self, e: &mut Vec<u8>) {
924         e.extend_from_slice(&self.bits.to_le_bytes());
925     }
926 }
927 
928 impl Encode for Float64 {
encode(&self, e: &mut Vec<u8>)929     fn encode(&self, e: &mut Vec<u8>) {
930         e.extend_from_slice(&self.bits.to_le_bytes());
931     }
932 }
933 
934 #[derive(Default)]
935 struct Names<'a> {
936     module: Option<&'a str>,
937     funcs: Vec<(u32, &'a str)>,
938     func_idx: u32,
939     locals: Vec<(u32, Vec<(u32, &'a str)>)>,
940     labels: Vec<(u32, Vec<(u32, &'a str)>)>,
941     globals: Vec<(u32, &'a str)>,
942     global_idx: u32,
943     memories: Vec<(u32, &'a str)>,
944     memory_idx: u32,
945     tables: Vec<(u32, &'a str)>,
946     table_idx: u32,
947     tags: Vec<(u32, &'a str)>,
948     tag_idx: u32,
949     modules: Vec<(u32, &'a str)>,
950     module_idx: u32,
951     instances: Vec<(u32, &'a str)>,
952     instance_idx: u32,
953     types: Vec<(u32, &'a str)>,
954     type_idx: u32,
955     data: Vec<(u32, &'a str)>,
956     data_idx: u32,
957     elems: Vec<(u32, &'a str)>,
958     elem_idx: u32,
959 }
960 
find_names<'a>( module_id: &Option<Id<'a>>, module_name: &Option<NameAnnotation<'a>>, fields: &[ModuleField<'a>], ) -> Names<'a>961 fn find_names<'a>(
962     module_id: &Option<Id<'a>>,
963     module_name: &Option<NameAnnotation<'a>>,
964     fields: &[ModuleField<'a>],
965 ) -> Names<'a> {
966     fn get_name<'a>(id: &Option<Id<'a>>, name: &Option<NameAnnotation<'a>>) -> Option<&'a str> {
967         name.as_ref().map(|n| n.name).or(id.and_then(|id| {
968             if id.is_gensym() {
969                 None
970             } else {
971                 Some(id.name())
972             }
973         }))
974     }
975 
976     enum Name {
977         Type,
978         Global,
979         Func,
980         Module,
981         Instance,
982         Memory,
983         Table,
984         Tag,
985         Elem,
986         Data,
987     }
988 
989     let mut ret = Names::default();
990     ret.module = get_name(module_id, module_name);
991     for field in fields {
992         // Extract the kind/id/name from whatever kind of field this is...
993         let (kind, id, name) = match field {
994             ModuleField::Import(i) => (
995                 match i.item.kind {
996                     ItemKind::Func(_) => Name::Func,
997                     ItemKind::Table(_) => Name::Table,
998                     ItemKind::Memory(_) => Name::Memory,
999                     ItemKind::Global(_) => Name::Global,
1000                     ItemKind::Tag(_) => Name::Tag,
1001                     ItemKind::Instance(_) => Name::Instance,
1002                     ItemKind::Module(_) => Name::Module,
1003                 },
1004                 &i.item.id,
1005                 &i.item.name,
1006             ),
1007             ModuleField::Global(g) => (Name::Global, &g.id, &g.name),
1008             ModuleField::Table(t) => (Name::Table, &t.id, &t.name),
1009             ModuleField::Memory(m) => (Name::Memory, &m.id, &m.name),
1010             ModuleField::Tag(t) => (Name::Tag, &t.id, &t.name),
1011             ModuleField::NestedModule(m) => (Name::Module, &m.id, &m.name),
1012             ModuleField::Instance(i) => (Name::Instance, &i.id, &i.name),
1013             ModuleField::Type(t) => (Name::Type, &t.id, &t.name),
1014             ModuleField::Elem(e) => (Name::Elem, &e.id, &e.name),
1015             ModuleField::Data(d) => (Name::Data, &d.id, &d.name),
1016             ModuleField::Func(f) => (Name::Func, &f.id, &f.name),
1017             ModuleField::Alias(a) => (
1018                 match a.kind {
1019                     ExportKind::Func => Name::Func,
1020                     ExportKind::Table => Name::Table,
1021                     ExportKind::Memory => Name::Memory,
1022                     ExportKind::Global => Name::Global,
1023                     ExportKind::Module => Name::Module,
1024                     ExportKind::Instance => Name::Instance,
1025                     ExportKind::Tag => Name::Tag,
1026                     ExportKind::Type => Name::Type,
1027                 },
1028                 &a.id,
1029                 &a.name,
1030             ),
1031             ModuleField::Export(_) | ModuleField::Start(_) | ModuleField::Custom(_) => continue,
1032         };
1033 
1034         // .. and using the kind we can figure out where to place this name
1035         let (list, idx) = match kind {
1036             Name::Func => (&mut ret.funcs, &mut ret.func_idx),
1037             Name::Table => (&mut ret.tables, &mut ret.table_idx),
1038             Name::Memory => (&mut ret.memories, &mut ret.memory_idx),
1039             Name::Global => (&mut ret.globals, &mut ret.global_idx),
1040             Name::Module => (&mut ret.modules, &mut ret.module_idx),
1041             Name::Instance => (&mut ret.instances, &mut ret.instance_idx),
1042             Name::Tag => (&mut ret.tags, &mut ret.tag_idx),
1043             Name::Type => (&mut ret.types, &mut ret.type_idx),
1044             Name::Elem => (&mut ret.elems, &mut ret.elem_idx),
1045             Name::Data => (&mut ret.data, &mut ret.data_idx),
1046         };
1047         if let Some(name) = get_name(id, name) {
1048             list.push((*idx, name));
1049         }
1050 
1051         // Handle module locals separately from above
1052         if let ModuleField::Func(f) = field {
1053             let mut local_names = Vec::new();
1054             let mut label_names = Vec::new();
1055             let mut local_idx = 0;
1056             let mut label_idx = 0;
1057 
1058             // Consult the inline type listed for local names of parameters.
1059             // This is specifically preserved during the name resolution
1060             // pass, but only for functions, so here we can look at the
1061             // original source's names.
1062             if let Some(ty) = &f.ty.inline {
1063                 for (id, name, _) in ty.params.iter() {
1064                     if let Some(name) = get_name(id, name) {
1065                         local_names.push((local_idx, name));
1066                     }
1067                     local_idx += 1;
1068                 }
1069             }
1070             if let FuncKind::Inline {
1071                 locals, expression, ..
1072             } = &f.kind
1073             {
1074                 for local in locals {
1075                     if let Some(name) = get_name(&local.id, &local.name) {
1076                         local_names.push((local_idx, name));
1077                     }
1078                     local_idx += 1;
1079                 }
1080 
1081                 for i in expression.instrs.iter() {
1082                     match i {
1083                         Instruction::If(block)
1084                         | Instruction::Block(block)
1085                         | Instruction::Loop(block)
1086                         | Instruction::Try(block)
1087                         | Instruction::Let(LetType { block, .. }) => {
1088                             if let Some(name) = get_name(&block.label, &block.label_name) {
1089                                 label_names.push((label_idx, name));
1090                             }
1091                             label_idx += 1;
1092                         }
1093                         _ => {}
1094                     }
1095                 }
1096             }
1097             if local_names.len() > 0 {
1098                 ret.locals.push((*idx, local_names));
1099             }
1100             if label_names.len() > 0 {
1101                 ret.labels.push((*idx, label_names));
1102             }
1103         }
1104 
1105         *idx += 1;
1106     }
1107 
1108     return ret;
1109 }
1110 
1111 impl Names<'_> {
is_empty(&self) -> bool1112     fn is_empty(&self) -> bool {
1113         self.module.is_none()
1114             && self.funcs.is_empty()
1115             && self.locals.is_empty()
1116             && self.labels.is_empty()
1117             && self.globals.is_empty()
1118             && self.memories.is_empty()
1119             && self.tables.is_empty()
1120             && self.types.is_empty()
1121             && self.data.is_empty()
1122             && self.elems.is_empty()
1123         // NB: specifically don't check tags/modules/instances since they're
1124         // not encoded for now.
1125     }
1126 }
1127 
1128 impl Encode for Names<'_> {
encode(&self, dst: &mut Vec<u8>)1129     fn encode(&self, dst: &mut Vec<u8>) {
1130         let mut tmp = Vec::new();
1131 
1132         let mut subsec = |id: u8, data: &mut Vec<u8>| {
1133             dst.push(id);
1134             data.encode(dst);
1135             data.truncate(0);
1136         };
1137 
1138         if let Some(id) = self.module {
1139             id.encode(&mut tmp);
1140             subsec(0, &mut tmp);
1141         }
1142         if self.funcs.len() > 0 {
1143             self.funcs.encode(&mut tmp);
1144             subsec(1, &mut tmp);
1145         }
1146         if self.locals.len() > 0 {
1147             self.locals.encode(&mut tmp);
1148             subsec(2, &mut tmp);
1149         }
1150         if self.labels.len() > 0 {
1151             self.labels.encode(&mut tmp);
1152             subsec(3, &mut tmp);
1153         }
1154         if self.types.len() > 0 {
1155             self.types.encode(&mut tmp);
1156             subsec(4, &mut tmp);
1157         }
1158         if self.tables.len() > 0 {
1159             self.tables.encode(&mut tmp);
1160             subsec(5, &mut tmp);
1161         }
1162         if self.memories.len() > 0 {
1163             self.memories.encode(&mut tmp);
1164             subsec(6, &mut tmp);
1165         }
1166         if self.globals.len() > 0 {
1167             self.globals.encode(&mut tmp);
1168             subsec(7, &mut tmp);
1169         }
1170         if self.elems.len() > 0 {
1171             self.elems.encode(&mut tmp);
1172             subsec(8, &mut tmp);
1173         }
1174         if self.data.len() > 0 {
1175             self.data.encode(&mut tmp);
1176             subsec(9, &mut tmp);
1177         }
1178     }
1179 }
1180 
1181 impl Encode for Id<'_> {
encode(&self, dst: &mut Vec<u8>)1182     fn encode(&self, dst: &mut Vec<u8>) {
1183         assert!(!self.is_gensym());
1184         self.name().encode(dst);
1185     }
1186 }
1187 
1188 impl Encode for V128Const {
encode(&self, dst: &mut Vec<u8>)1189     fn encode(&self, dst: &mut Vec<u8>) {
1190         dst.extend_from_slice(&self.to_le_bytes());
1191     }
1192 }
1193 
1194 impl Encode for I8x16Shuffle {
encode(&self, dst: &mut Vec<u8>)1195     fn encode(&self, dst: &mut Vec<u8>) {
1196         dst.extend_from_slice(&self.lanes);
1197     }
1198 }
1199 
1200 impl<'a> Encode for SelectTypes<'a> {
encode(&self, dst: &mut Vec<u8>)1201     fn encode(&self, dst: &mut Vec<u8>) {
1202         match &self.tys {
1203             Some(list) => {
1204                 dst.push(0x1c);
1205                 list.encode(dst);
1206             }
1207             None => dst.push(0x1b),
1208         }
1209     }
1210 }
1211 
1212 impl Encode for Custom<'_> {
encode(&self, e: &mut Vec<u8>)1213     fn encode(&self, e: &mut Vec<u8>) {
1214         for list in self.data.iter() {
1215             e.extend_from_slice(list);
1216         }
1217     }
1218 }
1219 
1220 impl Encode for Tag<'_> {
encode(&self, e: &mut Vec<u8>)1221     fn encode(&self, e: &mut Vec<u8>) {
1222         self.ty.encode(e);
1223         match &self.kind {
1224             TagKind::Inline() => {}
1225             _ => panic!("TagKind should be inline during encoding"),
1226         }
1227     }
1228 }
1229 
1230 impl Encode for TagType<'_> {
encode(&self, e: &mut Vec<u8>)1231     fn encode(&self, e: &mut Vec<u8>) {
1232         match self {
1233             TagType::Exception(ty) => {
1234                 e.push(0x00);
1235                 ty.encode(e);
1236             }
1237         }
1238     }
1239 }
1240 
1241 impl Encode for StructAccess<'_> {
encode(&self, e: &mut Vec<u8>)1242     fn encode(&self, e: &mut Vec<u8>) {
1243         self.r#struct.encode(e);
1244         self.field.encode(e);
1245     }
1246 }
1247 
1248 impl Encode for NestedModule<'_> {
encode(&self, e: &mut Vec<u8>)1249     fn encode(&self, e: &mut Vec<u8>) {
1250         let fields = match &self.kind {
1251             NestedModuleKind::Inline { fields, .. } => fields,
1252             _ => panic!("should only have inline modules in emission"),
1253         };
1254 
1255         encode_fields(&self.id, &self.name, fields).encode(e);
1256     }
1257 }
1258 
1259 impl Encode for Instance<'_> {
encode(&self, e: &mut Vec<u8>)1260     fn encode(&self, e: &mut Vec<u8>) {
1261         assert!(self.exports.names.is_empty());
1262         let (module, args) = match &self.kind {
1263             InstanceKind::Inline { module, args } => (module, args),
1264             _ => panic!("should only have inline instances in emission"),
1265         };
1266         e.push(0x00);
1267         module.encode(e);
1268         args.encode(e);
1269     }
1270 }
1271 
1272 impl Encode for InstanceArg<'_> {
encode(&self, e: &mut Vec<u8>)1273     fn encode(&self, e: &mut Vec<u8>) {
1274         self.name.encode(e);
1275         if let ItemRef::Item { kind, .. } = &self.index {
1276             kind.encode(e);
1277         }
1278         self.index.encode(e);
1279     }
1280 }
1281 
1282 impl Encode for Alias<'_> {
encode(&self, e: &mut Vec<u8>)1283     fn encode(&self, e: &mut Vec<u8>) {
1284         match &self.source {
1285             AliasSource::InstanceExport { instance, export } => {
1286                 e.push(0x00);
1287                 instance.encode(e);
1288                 self.kind.encode(e);
1289                 export.encode(e);
1290             }
1291             AliasSource::Outer { module, index } => {
1292                 e.push(0x01);
1293                 module.encode(e);
1294                 self.kind.encode(e);
1295                 index.encode(e);
1296             }
1297         }
1298     }
1299 }
1300