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