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 events = 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::Event(i) => events.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, Event, &events);
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::Event(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::Event => 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 // Try to switch element expressions to indices if we can which uses a
648 // more MVP-compatible encoding.
649 //
650 // FIXME(WebAssembly/wabt#1447) ideally we wouldn't do this so we could
651 // be faithful to the original format.
652 let mut to_encode = self.payload.clone();
653 if let ElemPayload::Exprs {
654 ty:
655 RefType {
656 nullable: true,
657 heap: HeapType::Func,
658 },
659 exprs,
660 } = &to_encode
661 {
662 if let Some(indices) = extract_indices(exprs) {
663 to_encode = ElemPayload::Indices(indices);
664 }
665 }
666
667 match (&self.kind, &to_encode) {
668 (
669 ElemKind::Active {
670 table:
671 ItemRef::Item {
672 idx: Index::Num(0, _),
673 ..
674 },
675 offset,
676 },
677 ElemPayload::Indices(_),
678 ) => {
679 e.push(0x00);
680 offset.encode(e);
681 }
682 (ElemKind::Passive, ElemPayload::Indices(_)) => {
683 e.push(0x01); // flags
684 e.push(0x00); // extern_kind
685 }
686 (ElemKind::Active { table, offset }, ElemPayload::Indices(_)) => {
687 e.push(0x02); // flags
688 table.encode(e);
689 offset.encode(e);
690 e.push(0x00); // extern_kind
691 }
692 (
693 ElemKind::Active {
694 table:
695 ItemRef::Item {
696 idx: Index::Num(0, _),
697 ..
698 },
699 offset,
700 },
701 ElemPayload::Exprs {
702 ty:
703 RefType {
704 nullable: true,
705 heap: HeapType::Func,
706 },
707 ..
708 },
709 ) => {
710 e.push(0x04);
711 offset.encode(e);
712 }
713 (ElemKind::Passive, ElemPayload::Exprs { ty, .. }) => {
714 e.push(0x05);
715 ty.encode(e);
716 }
717 (ElemKind::Active { table, offset }, ElemPayload::Exprs { ty, .. }) => {
718 e.push(0x06);
719 table.encode(e);
720 offset.encode(e);
721 ty.encode(e);
722 }
723 (ElemKind::Declared, ElemPayload::Indices(_)) => {
724 e.push(0x03); // flags
725 e.push(0x00); // extern_kind
726 }
727 (ElemKind::Declared, ElemPayload::Exprs { ty, .. }) => {
728 e.push(0x07); // flags
729 ty.encode(e);
730 }
731 }
732
733 to_encode.encode(e);
734
735 fn extract_indices<'a>(
736 indices: &[Option<ItemRef<'a, kw::func>>],
737 ) -> Option<Vec<ItemRef<'a, kw::func>>> {
738 indices.iter().cloned().collect()
739 }
740 }
741 }
742
743 impl Encode for ElemPayload<'_> {
encode(&self, e: &mut Vec<u8>)744 fn encode(&self, e: &mut Vec<u8>) {
745 match self {
746 ElemPayload::Indices(v) => v.encode(e),
747 ElemPayload::Exprs { exprs, ty } => {
748 exprs.len().encode(e);
749 for idx in exprs {
750 match idx {
751 Some(idx) => {
752 Instruction::RefFunc(IndexOrRef(idx.clone())).encode(e);
753 }
754 None => {
755 Instruction::RefNull(ty.heap).encode(e);
756 }
757 }
758 Instruction::End(None).encode(e);
759 }
760 }
761 }
762 }
763 }
764
765 impl Encode for Data<'_> {
encode(&self, e: &mut Vec<u8>)766 fn encode(&self, e: &mut Vec<u8>) {
767 match &self.kind {
768 DataKind::Passive => e.push(0x01),
769 DataKind::Active { memory, offset } => {
770 if let ItemRef::Item {
771 idx: Index::Num(0, _),
772 ..
773 } = memory
774 {
775 e.push(0x00);
776 } else {
777 e.push(0x02);
778 memory.encode(e);
779 }
780 offset.encode(e);
781 }
782 }
783 self.data.iter().map(|l| l.len()).sum::<usize>().encode(e);
784 for val in self.data.iter() {
785 val.push_onto(e);
786 }
787 }
788 }
789
790 impl Encode for Func<'_> {
encode(&self, e: &mut Vec<u8>)791 fn encode(&self, e: &mut Vec<u8>) {
792 assert!(self.exports.names.is_empty());
793 let mut tmp = Vec::new();
794 let (expr, locals) = match &self.kind {
795 FuncKind::Inline { expression, locals } => (expression, locals),
796 _ => panic!("should only have inline functions in emission"),
797 };
798
799 locals.encode(&mut tmp);
800 expr.encode(&mut tmp);
801
802 tmp.len().encode(e);
803 e.extend_from_slice(&tmp);
804 }
805 }
806
807 impl Encode for Vec<Local<'_>> {
encode(&self, e: &mut Vec<u8>)808 fn encode(&self, e: &mut Vec<u8>) {
809 let mut locals_compressed = Vec::<(u32, ValType)>::new();
810 for local in self {
811 if let Some((cnt, prev)) = locals_compressed.last_mut() {
812 if *prev == local.ty {
813 *cnt += 1;
814 continue;
815 }
816 }
817 locals_compressed.push((1, local.ty));
818 }
819 locals_compressed.encode(e);
820 }
821 }
822
823 impl Encode for Expression<'_> {
encode(&self, e: &mut Vec<u8>)824 fn encode(&self, e: &mut Vec<u8>) {
825 for instr in self.instrs.iter() {
826 instr.encode(e);
827 }
828 e.push(0x0b);
829 }
830 }
831
832 impl Encode for BlockType<'_> {
encode(&self, e: &mut Vec<u8>)833 fn encode(&self, e: &mut Vec<u8>) {
834 // block types using an index are encoded as an sleb, not a uleb
835 if let Some(ItemRef::Item {
836 idx: Index::Num(n, _),
837 ..
838 }) = &self.ty.index
839 {
840 return i64::from(*n).encode(e);
841 }
842 let ty = self
843 .ty
844 .inline
845 .as_ref()
846 .expect("function type not filled in");
847 if ty.params.is_empty() && ty.results.is_empty() {
848 return e.push(0x40);
849 }
850 if ty.params.is_empty() && ty.results.len() == 1 {
851 return ty.results[0].encode(e);
852 }
853 panic!("multi-value block types should have an index");
854 }
855 }
856
857 impl Encode for FuncBindType<'_> {
encode(&self, e: &mut Vec<u8>)858 fn encode(&self, e: &mut Vec<u8>) {
859 self.ty.encode(e);
860 }
861 }
862
863 impl Encode for LetType<'_> {
encode(&self, e: &mut Vec<u8>)864 fn encode(&self, e: &mut Vec<u8>) {
865 self.block.encode(e);
866 self.locals.encode(e);
867 }
868 }
869
870 impl Encode for LaneArg {
encode(&self, e: &mut Vec<u8>)871 fn encode(&self, e: &mut Vec<u8>) {
872 self.lane.encode(e);
873 }
874 }
875
876 impl Encode for MemArg<'_> {
encode(&self, e: &mut Vec<u8>)877 fn encode(&self, e: &mut Vec<u8>) {
878 match &self.memory {
879 ItemRef::Item {
880 idx: Index::Num(0, _),
881 ..
882 } => {
883 self.align.trailing_zeros().encode(e);
884 self.offset.encode(e);
885 }
886 n => {
887 (self.align.trailing_zeros() | (1 << 6)).encode(e);
888 self.offset.encode(e);
889 n.encode(e);
890 }
891 }
892 }
893 }
894
895 impl Encode for LoadOrStoreLane<'_> {
encode(&self, e: &mut Vec<u8>)896 fn encode(&self, e: &mut Vec<u8>) {
897 self.memarg.encode(e);
898 self.lane.encode(e);
899 }
900 }
901
902 impl Encode for CallIndirect<'_> {
encode(&self, e: &mut Vec<u8>)903 fn encode(&self, e: &mut Vec<u8>) {
904 self.ty.encode(e);
905 self.table.encode(e);
906 }
907 }
908
909 impl Encode for TableInit<'_> {
encode(&self, e: &mut Vec<u8>)910 fn encode(&self, e: &mut Vec<u8>) {
911 self.elem.encode(e);
912 self.table.encode(e);
913 }
914 }
915
916 impl Encode for TableCopy<'_> {
encode(&self, e: &mut Vec<u8>)917 fn encode(&self, e: &mut Vec<u8>) {
918 self.dst.encode(e);
919 self.src.encode(e);
920 }
921 }
922
923 impl Encode for TableArg<'_> {
encode(&self, e: &mut Vec<u8>)924 fn encode(&self, e: &mut Vec<u8>) {
925 self.dst.encode(e);
926 }
927 }
928
929 impl Encode for MemoryArg<'_> {
encode(&self, e: &mut Vec<u8>)930 fn encode(&self, e: &mut Vec<u8>) {
931 self.mem.encode(e);
932 }
933 }
934
935 impl Encode for MemoryInit<'_> {
encode(&self, e: &mut Vec<u8>)936 fn encode(&self, e: &mut Vec<u8>) {
937 self.data.encode(e);
938 self.mem.encode(e);
939 }
940 }
941
942 impl Encode for MemoryCopy<'_> {
encode(&self, e: &mut Vec<u8>)943 fn encode(&self, e: &mut Vec<u8>) {
944 self.dst.encode(e);
945 self.src.encode(e);
946 }
947 }
948
949 impl Encode for BrTableIndices<'_> {
encode(&self, e: &mut Vec<u8>)950 fn encode(&self, e: &mut Vec<u8>) {
951 self.labels.encode(e);
952 self.default.encode(e);
953 }
954 }
955
956 impl Encode for Float32 {
encode(&self, e: &mut Vec<u8>)957 fn encode(&self, e: &mut Vec<u8>) {
958 e.extend_from_slice(&self.bits.to_le_bytes());
959 }
960 }
961
962 impl Encode for Float64 {
encode(&self, e: &mut Vec<u8>)963 fn encode(&self, e: &mut Vec<u8>) {
964 e.extend_from_slice(&self.bits.to_le_bytes());
965 }
966 }
967
968 struct Names<'a> {
969 module: Option<&'a str>,
970 funcs: Vec<(u32, &'a str)>,
971 locals: Vec<(u32, Vec<(u32, &'a str)>)>,
972 }
973
find_names<'a>( module_id: &Option<Id<'a>>, module_name: &Option<NameAnnotation<'a>>, fields: &[ModuleField<'a>], ) -> Names<'a>974 fn find_names<'a>(
975 module_id: &Option<Id<'a>>,
976 module_name: &Option<NameAnnotation<'a>>,
977 fields: &[ModuleField<'a>],
978 ) -> Names<'a> {
979 fn get_name<'a>(id: &Option<Id<'a>>, name: &Option<NameAnnotation<'a>>) -> Option<&'a str> {
980 name.as_ref().map(|n| n.name).or(id.and_then(|id| {
981 if id.is_gensym() {
982 None
983 } else {
984 Some(id.name())
985 }
986 }))
987 }
988
989 let mut funcs = Vec::new();
990 let mut locals = Vec::new();
991 let mut idx = 0;
992 for field in fields {
993 match field {
994 ModuleField::Import(i) => {
995 match i.item.kind {
996 ItemKind::Func(_) => {}
997 _ => continue,
998 }
999
1000 if let Some(name) = get_name(&i.item.id, &i.item.name) {
1001 funcs.push((idx, name));
1002 }
1003
1004 idx += 1;
1005 }
1006 ModuleField::Func(f) => {
1007 if let Some(name) = get_name(&f.id, &f.name) {
1008 funcs.push((idx, name));
1009 }
1010 let mut local_names = Vec::new();
1011 let mut local_idx = 0;
1012
1013 // Consult the inline type listed for local names of parameters.
1014 // This is specifically preserved during the name resolution
1015 // pass, but only for functions, so here we can look at the
1016 // original source's names.
1017 if let Some(ty) = &f.ty.inline {
1018 for (id, name, _) in ty.params.iter() {
1019 if let Some(name) = get_name(id, name) {
1020 local_names.push((local_idx, name));
1021 }
1022 local_idx += 1;
1023 }
1024 }
1025 if let FuncKind::Inline { locals, .. } = &f.kind {
1026 for local in locals {
1027 if let Some(name) = get_name(&local.id, &local.name) {
1028 local_names.push((local_idx, name));
1029 }
1030 local_idx += 1;
1031 }
1032 }
1033 if local_names.len() > 0 {
1034 locals.push((idx, local_names));
1035 }
1036 idx += 1;
1037 }
1038 ModuleField::Alias(Alias {
1039 id,
1040 name,
1041 kind: ExportKind::Func,
1042 ..
1043 }) => {
1044 if let Some(name) = get_name(id, name) {
1045 funcs.push((idx, name));
1046 }
1047 idx += 1;
1048 }
1049 _ => {}
1050 }
1051 }
1052
1053 Names {
1054 module: get_name(module_id, module_name),
1055 funcs,
1056 locals,
1057 }
1058 }
1059
1060 impl Names<'_> {
is_empty(&self) -> bool1061 fn is_empty(&self) -> bool {
1062 self.module.is_none() && self.funcs.is_empty() && self.locals.is_empty()
1063 }
1064 }
1065
1066 impl Encode for Names<'_> {
encode(&self, dst: &mut Vec<u8>)1067 fn encode(&self, dst: &mut Vec<u8>) {
1068 let mut tmp = Vec::new();
1069
1070 let mut subsec = |id: u8, data: &mut Vec<u8>| {
1071 dst.push(id);
1072 data.encode(dst);
1073 data.truncate(0);
1074 };
1075
1076 if let Some(id) = self.module {
1077 id.encode(&mut tmp);
1078 subsec(0, &mut tmp);
1079 }
1080 if self.funcs.len() > 0 {
1081 self.funcs.encode(&mut tmp);
1082 subsec(1, &mut tmp);
1083 }
1084 if self.locals.len() > 0 {
1085 self.locals.encode(&mut tmp);
1086 subsec(2, &mut tmp);
1087 }
1088 }
1089 }
1090
1091 impl Encode for Id<'_> {
encode(&self, dst: &mut Vec<u8>)1092 fn encode(&self, dst: &mut Vec<u8>) {
1093 assert!(!self.is_gensym());
1094 self.name().encode(dst);
1095 }
1096 }
1097
1098 impl Encode for V128Const {
encode(&self, dst: &mut Vec<u8>)1099 fn encode(&self, dst: &mut Vec<u8>) {
1100 dst.extend_from_slice(&self.to_le_bytes());
1101 }
1102 }
1103
1104 impl Encode for I8x16Shuffle {
encode(&self, dst: &mut Vec<u8>)1105 fn encode(&self, dst: &mut Vec<u8>) {
1106 dst.extend_from_slice(&self.lanes);
1107 }
1108 }
1109
1110 impl<'a> Encode for SelectTypes<'a> {
encode(&self, dst: &mut Vec<u8>)1111 fn encode(&self, dst: &mut Vec<u8>) {
1112 match &self.tys {
1113 Some(list) => {
1114 dst.push(0x1c);
1115 list.encode(dst);
1116 }
1117 None => dst.push(0x1b),
1118 }
1119 }
1120 }
1121
1122 impl Encode for Custom<'_> {
encode(&self, e: &mut Vec<u8>)1123 fn encode(&self, e: &mut Vec<u8>) {
1124 for list in self.data.iter() {
1125 e.extend_from_slice(list);
1126 }
1127 }
1128 }
1129
1130 impl Encode for Event<'_> {
encode(&self, e: &mut Vec<u8>)1131 fn encode(&self, e: &mut Vec<u8>) {
1132 self.ty.encode(e);
1133 match &self.kind {
1134 EventKind::Inline() => {}
1135 _ => panic!("EventKind should be inline during encoding"),
1136 }
1137 }
1138 }
1139
1140 impl Encode for EventType<'_> {
encode(&self, e: &mut Vec<u8>)1141 fn encode(&self, e: &mut Vec<u8>) {
1142 match self {
1143 EventType::Exception(ty) => {
1144 e.push(0x00);
1145 ty.encode(e);
1146 }
1147 }
1148 }
1149 }
1150
1151 impl Encode for StructAccess<'_> {
encode(&self, e: &mut Vec<u8>)1152 fn encode(&self, e: &mut Vec<u8>) {
1153 self.r#struct.encode(e);
1154 self.field.encode(e);
1155 }
1156 }
1157
1158 impl Encode for NestedModule<'_> {
encode(&self, e: &mut Vec<u8>)1159 fn encode(&self, e: &mut Vec<u8>) {
1160 let fields = match &self.kind {
1161 NestedModuleKind::Inline { fields, .. } => fields,
1162 _ => panic!("should only have inline modules in emission"),
1163 };
1164
1165 encode_fields(&self.id, &self.name, fields).encode(e);
1166 }
1167 }
1168
1169 impl Encode for Instance<'_> {
encode(&self, e: &mut Vec<u8>)1170 fn encode(&self, e: &mut Vec<u8>) {
1171 assert!(self.exports.names.is_empty());
1172 let (module, args) = match &self.kind {
1173 InstanceKind::Inline { module, args } => (module, args),
1174 _ => panic!("should only have inline instances in emission"),
1175 };
1176 e.push(0x00);
1177 module.encode(e);
1178 args.encode(e);
1179 }
1180 }
1181
1182 impl Encode for InstanceArg<'_> {
encode(&self, e: &mut Vec<u8>)1183 fn encode(&self, e: &mut Vec<u8>) {
1184 self.name.encode(e);
1185 if let ItemRef::Item { kind, .. } = &self.index {
1186 kind.encode(e);
1187 }
1188 self.index.encode(e);
1189 }
1190 }
1191
1192 impl Encode for Alias<'_> {
encode(&self, e: &mut Vec<u8>)1193 fn encode(&self, e: &mut Vec<u8>) {
1194 match &self.source {
1195 AliasSource::InstanceExport { instance, export } => {
1196 e.push(0x00);
1197 instance.encode(e);
1198 self.kind.encode(e);
1199 export.encode(e);
1200 }
1201 AliasSource::Outer { module, index } => {
1202 e.push(0x01);
1203 module.encode(e);
1204 self.kind.encode(e);
1205 index.encode(e);
1206 }
1207 }
1208 }
1209 }
1210