Projekt

Obecné

Profil

Stáhnout (51.1 KB) Statistiky
| Větev: | Revize:
1
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
2

    
3
import { CompileError } from "@webassemblyjs/helper-api-error";
4
import * as ieee754 from "@webassemblyjs/ieee754";
5
import * as utf8 from "@webassemblyjs/utf8";
6
import * as t from "@webassemblyjs/ast";
7
import { decodeInt32, decodeUInt32, MAX_NUMBER_OF_BYTE_U32, decodeInt64, decodeUInt64, MAX_NUMBER_OF_BYTE_U64 } from "@webassemblyjs/leb128";
8
import constants from "@webassemblyjs/helper-wasm-bytecode";
9

    
10
function toHex(n) {
11
  return "0x" + Number(n).toString(16);
12
}
13

    
14
function byteArrayEq(l, r) {
15
  if (l.length !== r.length) {
16
    return false;
17
  }
18

    
19
  for (var i = 0; i < l.length; i++) {
20
    if (l[i] !== r[i]) {
21
      return false;
22
    }
23
  }
24

    
25
  return true;
26
}
27

    
28
export function decode(ab, opts) {
29
  var buf = new Uint8Array(ab);
30
  var getUniqueName = t.getUniqueNameGenerator();
31
  var offset = 0;
32

    
33
  function getPosition() {
34
    return {
35
      line: -1,
36
      column: offset
37
    };
38
  }
39

    
40
  function dump(b, msg) {
41
    if (opts.dump === false) return;
42
    var pad = "\t\t\t\t\t\t\t\t\t\t";
43
    var str = "";
44

    
45
    if (b.length < 5) {
46
      str = b.map(toHex).join(" ");
47
    } else {
48
      str = "...";
49
    }
50

    
51
    console.log(toHex(offset) + ":\t", str, pad, ";", msg);
52
  }
53

    
54
  function dumpSep(msg) {
55
    if (opts.dump === false) return;
56
    console.log(";", msg);
57
  }
58
  /**
59
   * TODO(sven): we can atually use a same structure
60
   * we are adding incrementally new features
61
   */
62

    
63

    
64
  var state = {
65
    elementsInFuncSection: [],
66
    elementsInExportSection: [],
67
    elementsInCodeSection: [],
68

    
69
    /**
70
     * Decode memory from:
71
     * - Memory section
72
     */
73
    memoriesInModule: [],
74

    
75
    /**
76
     * Decoded types from:
77
     * - Type section
78
     */
79
    typesInModule: [],
80

    
81
    /**
82
     * Decoded functions from:
83
     * - Function section
84
     * - Import section
85
     */
86
    functionsInModule: [],
87

    
88
    /**
89
     * Decoded tables from:
90
     * - Table section
91
     */
92
    tablesInModule: [],
93

    
94
    /**
95
     * Decoded globals from:
96
     * - Global section
97
     */
98
    globalsInModule: []
99
  };
100

    
101
  function isEOF() {
102
    return offset >= buf.length;
103
  }
104

    
105
  function eatBytes(n) {
106
    offset = offset + n;
107
  }
108

    
109
  function readBytesAtOffset(_offset, numberOfBytes) {
110
    var arr = [];
111

    
112
    for (var i = 0; i < numberOfBytes; i++) {
113
      arr.push(buf[_offset + i]);
114
    }
115

    
116
    return arr;
117
  }
118

    
119
  function readBytes(numberOfBytes) {
120
    return readBytesAtOffset(offset, numberOfBytes);
121
  }
122

    
123
  function readF64() {
124
    var bytes = readBytes(ieee754.NUMBER_OF_BYTE_F64);
125
    var value = ieee754.decodeF64(bytes);
126

    
127
    if (Math.sign(value) * value === Infinity) {
128
      return {
129
        value: Math.sign(value),
130
        inf: true,
131
        nextIndex: ieee754.NUMBER_OF_BYTE_F64
132
      };
133
    }
134

    
135
    if (isNaN(value)) {
136
      var sign = bytes[bytes.length - 1] >> 7 ? -1 : 1;
137
      var mantissa = 0;
138

    
139
      for (var i = 0; i < bytes.length - 2; ++i) {
140
        mantissa += bytes[i] * Math.pow(256, i);
141
      }
142

    
143
      mantissa += bytes[bytes.length - 2] % 16 * Math.pow(256, bytes.length - 2);
144
      return {
145
        value: sign * mantissa,
146
        nan: true,
147
        nextIndex: ieee754.NUMBER_OF_BYTE_F64
148
      };
149
    }
150

    
151
    return {
152
      value: value,
153
      nextIndex: ieee754.NUMBER_OF_BYTE_F64
154
    };
155
  }
156

    
157
  function readF32() {
158
    var bytes = readBytes(ieee754.NUMBER_OF_BYTE_F32);
159
    var value = ieee754.decodeF32(bytes);
160

    
161
    if (Math.sign(value) * value === Infinity) {
162
      return {
163
        value: Math.sign(value),
164
        inf: true,
165
        nextIndex: ieee754.NUMBER_OF_BYTE_F32
166
      };
167
    }
168

    
169
    if (isNaN(value)) {
170
      var sign = bytes[bytes.length - 1] >> 7 ? -1 : 1;
171
      var mantissa = 0;
172

    
173
      for (var i = 0; i < bytes.length - 2; ++i) {
174
        mantissa += bytes[i] * Math.pow(256, i);
175
      }
176

    
177
      mantissa += bytes[bytes.length - 2] % 128 * Math.pow(256, bytes.length - 2);
178
      return {
179
        value: sign * mantissa,
180
        nan: true,
181
        nextIndex: ieee754.NUMBER_OF_BYTE_F32
182
      };
183
    }
184

    
185
    return {
186
      value: value,
187
      nextIndex: ieee754.NUMBER_OF_BYTE_F32
188
    };
189
  }
190

    
191
  function readUTF8String() {
192
    var lenu32 = readU32(); // Don't eat any bytes. Instead, peek ahead of the current offset using
193
    // readBytesAtOffset below. This keeps readUTF8String neutral with respect
194
    // to the current offset, just like the other readX functions.
195

    
196
    var strlen = lenu32.value;
197
    dump([strlen], "string length");
198
    var bytes = readBytesAtOffset(offset + lenu32.nextIndex, strlen);
199
    var value = utf8.decode(bytes);
200
    return {
201
      value: value,
202
      nextIndex: strlen + lenu32.nextIndex
203
    };
204
  }
205
  /**
206
   * Decode an unsigned 32bits integer
207
   *
208
   * The length will be handled by the leb librairy, we pass the max number of
209
   * byte.
210
   */
211

    
212

    
213
  function readU32() {
214
    var bytes = readBytes(MAX_NUMBER_OF_BYTE_U32);
215
    var buffer = Buffer.from(bytes);
216
    return decodeUInt32(buffer);
217
  }
218

    
219
  function readVaruint32() {
220
    // where 32 bits = max 4 bytes
221
    var bytes = readBytes(4);
222
    var buffer = Buffer.from(bytes);
223
    return decodeUInt32(buffer);
224
  }
225

    
226
  function readVaruint7() {
227
    // where 7 bits = max 1 bytes
228
    var bytes = readBytes(1);
229
    var buffer = Buffer.from(bytes);
230
    return decodeUInt32(buffer);
231
  }
232
  /**
233
   * Decode a signed 32bits interger
234
   */
235

    
236

    
237
  function read32() {
238
    var bytes = readBytes(MAX_NUMBER_OF_BYTE_U32);
239
    var buffer = Buffer.from(bytes);
240
    return decodeInt32(buffer);
241
  }
242
  /**
243
   * Decode a signed 64bits integer
244
   */
245

    
246

    
247
  function read64() {
248
    var bytes = readBytes(MAX_NUMBER_OF_BYTE_U64);
249
    var buffer = Buffer.from(bytes);
250
    return decodeInt64(buffer);
251
  }
252

    
253
  function readU64() {
254
    var bytes = readBytes(MAX_NUMBER_OF_BYTE_U64);
255
    var buffer = Buffer.from(bytes);
256
    return decodeUInt64(buffer);
257
  }
258

    
259
  function readByte() {
260
    return readBytes(1)[0];
261
  }
262

    
263
  function parseModuleHeader() {
264
    if (isEOF() === true || offset + 4 > buf.length) {
265
      throw new Error("unexpected end");
266
    }
267

    
268
    var header = readBytes(4);
269

    
270
    if (byteArrayEq(constants.magicModuleHeader, header) === false) {
271
      throw new CompileError("magic header not detected");
272
    }
273

    
274
    dump(header, "wasm magic header");
275
    eatBytes(4);
276
  }
277

    
278
  function parseVersion() {
279
    if (isEOF() === true || offset + 4 > buf.length) {
280
      throw new Error("unexpected end");
281
    }
282

    
283
    var version = readBytes(4);
284

    
285
    if (byteArrayEq(constants.moduleVersion, version) === false) {
286
      throw new CompileError("unknown binary version");
287
    }
288

    
289
    dump(version, "wasm version");
290
    eatBytes(4);
291
  }
292

    
293
  function parseVec(cast) {
294
    var u32 = readU32();
295
    var length = u32.value;
296
    eatBytes(u32.nextIndex);
297
    dump([length], "number");
298

    
299
    if (length === 0) {
300
      return [];
301
    }
302

    
303
    var elements = [];
304

    
305
    for (var i = 0; i < length; i++) {
306
      var byte = readByte();
307
      eatBytes(1);
308
      var value = cast(byte);
309
      dump([byte], value);
310

    
311
      if (typeof value === "undefined") {
312
        throw new CompileError("Internal failure: parseVec could not cast the value");
313
      }
314

    
315
      elements.push(value);
316
    }
317

    
318
    return elements;
319
  } // Type section
320
  // https://webassembly.github.io/spec/binary/modules.html#binary-typesec
321

    
322

    
323
  function parseTypeSection(numberOfTypes) {
324
    var typeInstructionNodes = [];
325
    dump([numberOfTypes], "num types");
326

    
327
    for (var i = 0; i < numberOfTypes; i++) {
328
      var _startLoc = getPosition();
329

    
330
      dumpSep("type " + i);
331
      var type = readByte();
332
      eatBytes(1);
333

    
334
      if (type == constants.types.func) {
335
        dump([type], "func");
336
        var paramValtypes = parseVec(function (b) {
337
          return constants.valtypes[b];
338
        });
339
        var params = paramValtypes.map(function (v) {
340
          return t.funcParam(
341
          /*valtype*/
342
          v);
343
        });
344
        var result = parseVec(function (b) {
345
          return constants.valtypes[b];
346
        });
347
        typeInstructionNodes.push(function () {
348
          var endLoc = getPosition();
349
          return t.withLoc(t.typeInstruction(undefined, t.signature(params, result)), endLoc, _startLoc);
350
        }());
351
        state.typesInModule.push({
352
          params: params,
353
          result: result
354
        });
355
      } else {
356
        throw new Error("Unsupported type: " + toHex(type));
357
      }
358
    }
359

    
360
    return typeInstructionNodes;
361
  } // Import section
362
  // https://webassembly.github.io/spec/binary/modules.html#binary-importsec
363

    
364

    
365
  function parseImportSection(numberOfImports) {
366
    var imports = [];
367

    
368
    for (var i = 0; i < numberOfImports; i++) {
369
      dumpSep("import header " + i);
370

    
371
      var _startLoc2 = getPosition();
372
      /**
373
       * Module name
374
       */
375

    
376

    
377
      var moduleName = readUTF8String();
378
      eatBytes(moduleName.nextIndex);
379
      dump([], "module name (".concat(moduleName.value, ")"));
380
      /**
381
       * Name
382
       */
383

    
384
      var name = readUTF8String();
385
      eatBytes(name.nextIndex);
386
      dump([], "name (".concat(name.value, ")"));
387
      /**
388
       * Import descr
389
       */
390

    
391
      var descrTypeByte = readByte();
392
      eatBytes(1);
393
      var descrType = constants.importTypes[descrTypeByte];
394
      dump([descrTypeByte], "import kind");
395

    
396
      if (typeof descrType === "undefined") {
397
        throw new CompileError("Unknown import description type: " + toHex(descrTypeByte));
398
      }
399

    
400
      var importDescr = void 0;
401

    
402
      if (descrType === "func") {
403
        var indexU32 = readU32();
404
        var typeindex = indexU32.value;
405
        eatBytes(indexU32.nextIndex);
406
        dump([typeindex], "type index");
407
        var signature = state.typesInModule[typeindex];
408

    
409
        if (typeof signature === "undefined") {
410
          throw new CompileError("function signature not found (".concat(typeindex, ")"));
411
        }
412

    
413
        var id = getUniqueName("func");
414
        importDescr = t.funcImportDescr(id, t.signature(signature.params, signature.result));
415
        state.functionsInModule.push({
416
          id: t.identifier(name.value),
417
          signature: signature,
418
          isExternal: true
419
        });
420
      } else if (descrType === "global") {
421
        importDescr = parseGlobalType();
422
        var globalNode = t.global(importDescr, []);
423
        state.globalsInModule.push(globalNode);
424
      } else if (descrType === "table") {
425
        importDescr = parseTableType(i);
426
      } else if (descrType === "mem") {
427
        var memoryNode = parseMemoryType(0);
428
        state.memoriesInModule.push(memoryNode);
429
        importDescr = memoryNode;
430
      } else {
431
        throw new CompileError("Unsupported import of type: " + descrType);
432
      }
433

    
434
      imports.push(function () {
435
        var endLoc = getPosition();
436
        return t.withLoc(t.moduleImport(moduleName.value, name.value, importDescr), endLoc, _startLoc2);
437
      }());
438
    }
439

    
440
    return imports;
441
  } // Function section
442
  // https://webassembly.github.io/spec/binary/modules.html#function-section
443

    
444

    
445
  function parseFuncSection(numberOfFunctions) {
446
    dump([numberOfFunctions], "num funcs");
447

    
448
    for (var i = 0; i < numberOfFunctions; i++) {
449
      var indexU32 = readU32();
450
      var typeindex = indexU32.value;
451
      eatBytes(indexU32.nextIndex);
452
      dump([typeindex], "type index");
453
      var signature = state.typesInModule[typeindex];
454

    
455
      if (typeof signature === "undefined") {
456
        throw new CompileError("function signature not found (".concat(typeindex, ")"));
457
      } // preserve anonymous, a name might be resolved later
458

    
459

    
460
      var id = t.withRaw(t.identifier(getUniqueName("func")), "");
461
      state.functionsInModule.push({
462
        id: id,
463
        signature: signature,
464
        isExternal: false
465
      });
466
    }
467
  } // Export section
468
  // https://webassembly.github.io/spec/binary/modules.html#export-section
469

    
470

    
471
  function parseExportSection(numberOfExport) {
472
    dump([numberOfExport], "num exports"); // Parse vector of exports
473

    
474
    for (var i = 0; i < numberOfExport; i++) {
475
      var _startLoc3 = getPosition();
476
      /**
477
       * Name
478
       */
479

    
480

    
481
      var name = readUTF8String();
482
      eatBytes(name.nextIndex);
483
      dump([], "export name (".concat(name.value, ")"));
484
      /**
485
       * exportdescr
486
       */
487

    
488
      var typeIndex = readByte();
489
      eatBytes(1);
490
      dump([typeIndex], "export kind");
491
      var indexu32 = readU32();
492
      var index = indexu32.value;
493
      eatBytes(indexu32.nextIndex);
494
      dump([index], "export index");
495
      var id = void 0,
496
          signature = void 0;
497

    
498
      if (constants.exportTypes[typeIndex] === "Func") {
499
        var func = state.functionsInModule[index];
500

    
501
        if (typeof func === "undefined") {
502
          throw new CompileError("unknown function (".concat(index, ")"));
503
        }
504

    
505
        id = t.numberLiteralFromRaw(index, String(index));
506
        signature = func.signature;
507
      } else if (constants.exportTypes[typeIndex] === "Table") {
508
        var table = state.tablesInModule[index];
509

    
510
        if (typeof table === "undefined") {
511
          throw new CompileError("unknown table ".concat(index));
512
        }
513

    
514
        id = t.numberLiteralFromRaw(index, String(index));
515
        signature = null;
516
      } else if (constants.exportTypes[typeIndex] === "Mem") {
517
        var memNode = state.memoriesInModule[index];
518

    
519
        if (typeof memNode === "undefined") {
520
          throw new CompileError("unknown memory ".concat(index));
521
        }
522

    
523
        id = t.numberLiteralFromRaw(index, String(index));
524
        signature = null;
525
      } else if (constants.exportTypes[typeIndex] === "Global") {
526
        var global = state.globalsInModule[index];
527

    
528
        if (typeof global === "undefined") {
529
          throw new CompileError("unknown global ".concat(index));
530
        }
531

    
532
        id = t.numberLiteralFromRaw(index, String(index));
533
        signature = null;
534
      } else {
535
        console.warn("Unsupported export type: " + toHex(typeIndex));
536
        return;
537
      }
538

    
539
      var endLoc = getPosition();
540
      state.elementsInExportSection.push({
541
        name: name.value,
542
        type: constants.exportTypes[typeIndex],
543
        signature: signature,
544
        id: id,
545
        index: index,
546
        endLoc: endLoc,
547
        startLoc: _startLoc3
548
      });
549
    }
550
  } // Code section
551
  // https://webassembly.github.io/spec/binary/modules.html#code-section
552

    
553

    
554
  function parseCodeSection(numberOfFuncs) {
555
    dump([numberOfFuncs], "number functions"); // Parse vector of function
556

    
557
    for (var i = 0; i < numberOfFuncs; i++) {
558
      var _startLoc4 = getPosition();
559

    
560
      dumpSep("function body " + i); // the u32 size of the function code in bytes
561
      // Ignore it for now
562

    
563
      var bodySizeU32 = readU32();
564
      eatBytes(bodySizeU32.nextIndex);
565
      dump([bodySizeU32.value], "function body size");
566
      var code = [];
567
      /**
568
       * Parse locals
569
       */
570

    
571
      var funcLocalNumU32 = readU32();
572
      var funcLocalNum = funcLocalNumU32.value;
573
      eatBytes(funcLocalNumU32.nextIndex);
574
      dump([funcLocalNum], "num locals");
575
      var locals = [];
576

    
577
      for (var _i = 0; _i < funcLocalNum; _i++) {
578
        var _startLoc5 = getPosition();
579

    
580
        var localCountU32 = readU32();
581
        var localCount = localCountU32.value;
582
        eatBytes(localCountU32.nextIndex);
583
        dump([localCount], "num local");
584
        var valtypeByte = readByte();
585
        eatBytes(1);
586
        var type = constants.valtypes[valtypeByte];
587
        var args = [];
588

    
589
        for (var _i2 = 0; _i2 < localCount; _i2++) {
590
          args.push(t.valtypeLiteral(type));
591
        }
592

    
593
        var localNode = function () {
594
          var endLoc = getPosition();
595
          return t.withLoc(t.instruction("local", args), endLoc, _startLoc5);
596
        }();
597

    
598
        locals.push(localNode);
599
        dump([valtypeByte], type);
600

    
601
        if (typeof type === "undefined") {
602
          throw new CompileError("Unexpected valtype: " + toHex(valtypeByte));
603
        }
604
      }
605

    
606
      code.push.apply(code, locals); // Decode instructions until the end
607

    
608
      parseInstructionBlock(code);
609
      var endLoc = getPosition();
610
      state.elementsInCodeSection.push({
611
        code: code,
612
        locals: locals,
613
        endLoc: endLoc,
614
        startLoc: _startLoc4,
615
        bodySize: bodySizeU32.value
616
      });
617
    }
618
  }
619

    
620
  function parseInstructionBlock(code) {
621
    while (true) {
622
      var _startLoc6 = getPosition();
623

    
624
      var instructionAlreadyCreated = false;
625
      var instructionByte = readByte();
626
      eatBytes(1);
627

    
628
      if (instructionByte === 0xfe) {
629
        throw new CompileError("Atomic instructions are not implemented");
630
      }
631

    
632
      var instruction = constants.symbolsByByte[instructionByte];
633

    
634
      if (typeof instruction === "undefined") {
635
        throw new CompileError("Unexpected instruction: " + toHex(instructionByte));
636
      }
637

    
638
      if (typeof instruction.object === "string") {
639
        dump([instructionByte], "".concat(instruction.object, ".").concat(instruction.name));
640
      } else {
641
        dump([instructionByte], instruction.name);
642
      }
643
      /**
644
       * End of the function
645
       */
646

    
647

    
648
      if (instruction.name === "end") {
649
        var node = function () {
650
          var endLoc = getPosition();
651
          return t.withLoc(t.instruction(instruction.name), endLoc, _startLoc6);
652
        }();
653

    
654
        code.push(node);
655
        break;
656
      }
657

    
658
      var args = [];
659

    
660
      if (instruction.name === "loop") {
661
        var _startLoc7 = getPosition();
662

    
663
        var blocktypeByte = readByte();
664
        eatBytes(1);
665
        var blocktype = constants.blockTypes[blocktypeByte];
666
        dump([blocktypeByte], "blocktype");
667

    
668
        if (typeof blocktype === "undefined") {
669
          throw new CompileError("Unexpected blocktype: " + toHex(blocktypeByte));
670
        }
671

    
672
        var instr = [];
673
        parseInstructionBlock(instr); // preserve anonymous
674

    
675
        var label = t.withRaw(t.identifier(getUniqueName("loop")), "");
676

    
677
        var loopNode = function () {
678
          var endLoc = getPosition();
679
          return t.withLoc(t.loopInstruction(label, blocktype, instr), endLoc, _startLoc7);
680
        }();
681

    
682
        code.push(loopNode);
683
        instructionAlreadyCreated = true;
684
      } else if (instruction.name === "if") {
685
        var _startLoc8 = getPosition();
686

    
687
        var _blocktypeByte = readByte();
688

    
689
        eatBytes(1);
690
        var _blocktype = constants.blockTypes[_blocktypeByte];
691
        dump([_blocktypeByte], "blocktype");
692

    
693
        if (typeof _blocktype === "undefined") {
694
          throw new CompileError("Unexpected blocktype: " + toHex(_blocktypeByte));
695
        }
696

    
697
        var testIndex = t.withRaw(t.identifier(getUniqueName("if")), "");
698
        var ifBody = [];
699
        parseInstructionBlock(ifBody); // Defaults to no alternate
700

    
701
        var elseIndex = 0;
702

    
703
        for (elseIndex = 0; elseIndex < ifBody.length; ++elseIndex) {
704
          var _instr = ifBody[elseIndex];
705

    
706
          if (_instr.type === "Instr" && _instr.id === "else") {
707
            break;
708
          }
709
        }
710

    
711
        var consequentInstr = ifBody.slice(0, elseIndex);
712
        var alternate = ifBody.slice(elseIndex + 1); // wast sugar
713

    
714
        var testInstrs = [];
715

    
716
        var ifNode = function () {
717
          var endLoc = getPosition();
718
          return t.withLoc(t.ifInstruction(testIndex, testInstrs, _blocktype, consequentInstr, alternate), endLoc, _startLoc8);
719
        }();
720

    
721
        code.push(ifNode);
722
        instructionAlreadyCreated = true;
723
      } else if (instruction.name === "block") {
724
        var _startLoc9 = getPosition();
725

    
726
        var _blocktypeByte2 = readByte();
727

    
728
        eatBytes(1);
729
        var _blocktype2 = constants.blockTypes[_blocktypeByte2];
730
        dump([_blocktypeByte2], "blocktype");
731

    
732
        if (typeof _blocktype2 === "undefined") {
733
          throw new CompileError("Unexpected blocktype: " + toHex(_blocktypeByte2));
734
        }
735

    
736
        var _instr2 = [];
737
        parseInstructionBlock(_instr2); // preserve anonymous
738

    
739
        var _label = t.withRaw(t.identifier(getUniqueName("block")), "");
740

    
741
        var blockNode = function () {
742
          var endLoc = getPosition();
743
          return t.withLoc(t.blockInstruction(_label, _instr2, _blocktype2), endLoc, _startLoc9);
744
        }();
745

    
746
        code.push(blockNode);
747
        instructionAlreadyCreated = true;
748
      } else if (instruction.name === "call") {
749
        var indexu32 = readU32();
750
        var index = indexu32.value;
751
        eatBytes(indexu32.nextIndex);
752
        dump([index], "index");
753

    
754
        var callNode = function () {
755
          var endLoc = getPosition();
756
          return t.withLoc(t.callInstruction(t.indexLiteral(index)), endLoc, _startLoc6);
757
        }();
758

    
759
        code.push(callNode);
760
        instructionAlreadyCreated = true;
761
      } else if (instruction.name === "call_indirect") {
762
        var _startLoc10 = getPosition();
763

    
764
        var indexU32 = readU32();
765
        var typeindex = indexU32.value;
766
        eatBytes(indexU32.nextIndex);
767
        dump([typeindex], "type index");
768
        var signature = state.typesInModule[typeindex];
769

    
770
        if (typeof signature === "undefined") {
771
          throw new CompileError("call_indirect signature not found (".concat(typeindex, ")"));
772
        }
773

    
774
        var _callNode = t.callIndirectInstruction(t.signature(signature.params, signature.result), []);
775

    
776
        var flagU32 = readU32();
777
        var flag = flagU32.value; // 0x00 - reserved byte
778

    
779
        eatBytes(flagU32.nextIndex);
780

    
781
        if (flag !== 0) {
782
          throw new CompileError("zero flag expected");
783
        }
784

    
785
        code.push(function () {
786
          var endLoc = getPosition();
787
          return t.withLoc(_callNode, endLoc, _startLoc10);
788
        }());
789
        instructionAlreadyCreated = true;
790
      } else if (instruction.name === "br_table") {
791
        var indicesu32 = readU32();
792
        var indices = indicesu32.value;
793
        eatBytes(indicesu32.nextIndex);
794
        dump([indices], "num indices");
795

    
796
        for (var i = 0; i <= indices; i++) {
797
          var _indexu = readU32();
798

    
799
          var _index = _indexu.value;
800
          eatBytes(_indexu.nextIndex);
801
          dump([_index], "index");
802
          args.push(t.numberLiteralFromRaw(_indexu.value.toString(), "u32"));
803
        }
804
      } else if (instructionByte >= 0x28 && instructionByte <= 0x40) {
805
        /**
806
         * Memory instructions
807
         */
808
        if (instruction.name === "grow_memory" || instruction.name === "current_memory") {
809
          var _indexU = readU32();
810

    
811
          var _index2 = _indexU.value;
812
          eatBytes(_indexU.nextIndex);
813

    
814
          if (_index2 !== 0) {
815
            throw new Error("zero flag expected");
816
          }
817

    
818
          dump([_index2], "index");
819
        } else {
820
          var aligun32 = readU32();
821
          var align = aligun32.value;
822
          eatBytes(aligun32.nextIndex);
823
          dump([align], "align");
824
          var offsetu32 = readU32();
825
          var _offset2 = offsetu32.value;
826
          eatBytes(offsetu32.nextIndex);
827
          dump([_offset2], "offset");
828
        }
829
      } else if (instructionByte >= 0x41 && instructionByte <= 0x44) {
830
        /**
831
         * Numeric instructions
832
         */
833
        if (instruction.object === "i32") {
834
          var value32 = read32();
835
          var value = value32.value;
836
          eatBytes(value32.nextIndex);
837
          dump([value], "i32 value");
838
          args.push(t.numberLiteralFromRaw(value));
839
        }
840

    
841
        if (instruction.object === "u32") {
842
          var valueu32 = readU32();
843
          var _value = valueu32.value;
844
          eatBytes(valueu32.nextIndex);
845
          dump([_value], "u32 value");
846
          args.push(t.numberLiteralFromRaw(_value));
847
        }
848

    
849
        if (instruction.object === "i64") {
850
          var value64 = read64();
851
          var _value2 = value64.value;
852
          eatBytes(value64.nextIndex);
853
          dump([Number(_value2.toString())], "i64 value");
854
          var high = _value2.high,
855
              low = _value2.low;
856
          var _node = {
857
            type: "LongNumberLiteral",
858
            value: {
859
              high: high,
860
              low: low
861
            }
862
          };
863
          args.push(_node);
864
        }
865

    
866
        if (instruction.object === "u64") {
867
          var valueu64 = readU64();
868
          var _value3 = valueu64.value;
869
          eatBytes(valueu64.nextIndex);
870
          dump([Number(_value3.toString())], "u64 value");
871
          var _high = _value3.high,
872
              _low = _value3.low;
873
          var _node2 = {
874
            type: "LongNumberLiteral",
875
            value: {
876
              high: _high,
877
              low: _low
878
            }
879
          };
880
          args.push(_node2);
881
        }
882

    
883
        if (instruction.object === "f32") {
884
          var valuef32 = readF32();
885
          var _value4 = valuef32.value;
886
          eatBytes(valuef32.nextIndex);
887
          dump([_value4], "f32 value");
888
          args.push( // $FlowIgnore
889
          t.floatLiteral(_value4, valuef32.nan, valuef32.inf, String(_value4)));
890
        }
891

    
892
        if (instruction.object === "f64") {
893
          var valuef64 = readF64();
894
          var _value5 = valuef64.value;
895
          eatBytes(valuef64.nextIndex);
896
          dump([_value5], "f64 value");
897
          args.push( // $FlowIgnore
898
          t.floatLiteral(_value5, valuef64.nan, valuef64.inf, String(_value5)));
899
        }
900
      } else {
901
        for (var _i3 = 0; _i3 < instruction.numberOfArgs; _i3++) {
902
          var u32 = readU32();
903
          eatBytes(u32.nextIndex);
904
          dump([u32.value], "argument " + _i3);
905
          args.push(t.numberLiteralFromRaw(u32.value));
906
        }
907
      }
908

    
909
      if (instructionAlreadyCreated === false) {
910
        if (typeof instruction.object === "string") {
911
          var _node3 = function () {
912
            var endLoc = getPosition();
913
            return t.withLoc(t.objectInstruction(instruction.name, instruction.object, args), endLoc, _startLoc6);
914
          }();
915

    
916
          code.push(_node3);
917
        } else {
918
          var _node4 = function () {
919
            var endLoc = getPosition();
920
            return t.withLoc(t.instruction(instruction.name, args), endLoc, _startLoc6);
921
          }();
922

    
923
          code.push(_node4);
924
        }
925
      }
926
    }
927
  } // https://webassembly.github.io/spec/core/binary/types.html#limits
928

    
929

    
930
  function parseLimits() {
931
    var limitType = readByte();
932
    eatBytes(1);
933
    dump([limitType], "limit type");
934
    var min, max;
935

    
936
    if (limitType === 0x01 || limitType === 0x03 // shared limits
937
    ) {
938
        var u32min = readU32();
939
        min = parseInt(u32min.value);
940
        eatBytes(u32min.nextIndex);
941
        dump([min], "min");
942
        var u32max = readU32();
943
        max = parseInt(u32max.value);
944
        eatBytes(u32max.nextIndex);
945
        dump([max], "max");
946
      }
947

    
948
    if (limitType === 0x00) {
949
      var _u32min = readU32();
950

    
951
      min = parseInt(_u32min.value);
952
      eatBytes(_u32min.nextIndex);
953
      dump([min], "min");
954
    }
955

    
956
    return t.limit(min, max);
957
  } // https://webassembly.github.io/spec/core/binary/types.html#binary-tabletype
958

    
959

    
960
  function parseTableType(index) {
961
    var name = t.withRaw(t.identifier(getUniqueName("table")), String(index));
962
    var elementTypeByte = readByte();
963
    eatBytes(1);
964
    dump([elementTypeByte], "element type");
965
    var elementType = constants.tableTypes[elementTypeByte];
966

    
967
    if (typeof elementType === "undefined") {
968
      throw new CompileError("Unknown element type in table: " + toHex(elementType));
969
    }
970

    
971
    var limits = parseLimits();
972
    return t.table(elementType, limits, name);
973
  } // https://webassembly.github.io/spec/binary/types.html#global-types
974

    
975

    
976
  function parseGlobalType() {
977
    var valtypeByte = readByte();
978
    eatBytes(1);
979
    var type = constants.valtypes[valtypeByte];
980
    dump([valtypeByte], type);
981

    
982
    if (typeof type === "undefined") {
983
      throw new CompileError("Unknown valtype: " + toHex(valtypeByte));
984
    }
985

    
986
    var globalTypeByte = readByte();
987
    eatBytes(1);
988
    var globalType = constants.globalTypes[globalTypeByte];
989
    dump([globalTypeByte], "global type (".concat(globalType, ")"));
990

    
991
    if (typeof globalType === "undefined") {
992
      throw new CompileError("Invalid mutability: " + toHex(globalTypeByte));
993
    }
994

    
995
    return t.globalType(type, globalType);
996
  } // function parseNameModule() {
997
  //   const lenu32 = readVaruint32();
998
  //   eatBytes(lenu32.nextIndex);
999
  //   console.log("len", lenu32);
1000
  //   const strlen = lenu32.value;
1001
  //   dump([strlen], "string length");
1002
  //   const bytes = readBytes(strlen);
1003
  //   eatBytes(strlen);
1004
  //   const value = utf8.decode(bytes);
1005
  //   return [t.moduleNameMetadata(value)];
1006
  // }
1007
  // this section contains an array of function names and indices
1008

    
1009

    
1010
  function parseNameSectionFunctions() {
1011
    var functionNames = [];
1012
    var numberOfFunctionsu32 = readU32();
1013
    var numbeOfFunctions = numberOfFunctionsu32.value;
1014
    eatBytes(numberOfFunctionsu32.nextIndex);
1015

    
1016
    for (var i = 0; i < numbeOfFunctions; i++) {
1017
      var indexu32 = readU32();
1018
      var index = indexu32.value;
1019
      eatBytes(indexu32.nextIndex);
1020
      var name = readUTF8String();
1021
      eatBytes(name.nextIndex);
1022
      functionNames.push(t.functionNameMetadata(name.value, index));
1023
    }
1024

    
1025
    return functionNames;
1026
  }
1027

    
1028
  function parseNameSectionLocals() {
1029
    var localNames = [];
1030
    var numbeOfFunctionsu32 = readU32();
1031
    var numbeOfFunctions = numbeOfFunctionsu32.value;
1032
    eatBytes(numbeOfFunctionsu32.nextIndex);
1033

    
1034
    for (var i = 0; i < numbeOfFunctions; i++) {
1035
      var functionIndexu32 = readU32();
1036
      var functionIndex = functionIndexu32.value;
1037
      eatBytes(functionIndexu32.nextIndex);
1038
      var numLocalsu32 = readU32();
1039
      var numLocals = numLocalsu32.value;
1040
      eatBytes(numLocalsu32.nextIndex);
1041

    
1042
      for (var _i4 = 0; _i4 < numLocals; _i4++) {
1043
        var localIndexu32 = readU32();
1044
        var localIndex = localIndexu32.value;
1045
        eatBytes(localIndexu32.nextIndex);
1046
        var name = readUTF8String();
1047
        eatBytes(name.nextIndex);
1048
        localNames.push(t.localNameMetadata(name.value, localIndex, functionIndex));
1049
      }
1050
    }
1051

    
1052
    return localNames;
1053
  } // this is a custom section used for name resolution
1054
  // https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section
1055

    
1056

    
1057
  function parseNameSection(remainingBytes) {
1058
    var nameMetadata = [];
1059
    var initialOffset = offset;
1060

    
1061
    while (offset - initialOffset < remainingBytes) {
1062
      // name_type
1063
      var sectionTypeByte = readVaruint7();
1064
      eatBytes(sectionTypeByte.nextIndex); // name_payload_len
1065

    
1066
      var subSectionSizeInBytesu32 = readVaruint32();
1067
      eatBytes(subSectionSizeInBytesu32.nextIndex);
1068

    
1069
      switch (sectionTypeByte.value) {
1070
        // case 0: {
1071
        // TODO(sven): re-enable that
1072
        // Current status: it seems that when we decode the module's name
1073
        // no name_payload_len is used.
1074
        //
1075
        // See https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section
1076
        //
1077
        // nameMetadata.push(...parseNameModule());
1078
        // break;
1079
        // }
1080
        case 1:
1081
          {
1082
            nameMetadata.push.apply(nameMetadata, _toConsumableArray(parseNameSectionFunctions()));
1083
            break;
1084
          }
1085

    
1086
        case 2:
1087
          {
1088
            nameMetadata.push.apply(nameMetadata, _toConsumableArray(parseNameSectionLocals()));
1089
            break;
1090
          }
1091

    
1092
        default:
1093
          {
1094
            // skip unknown subsection
1095
            eatBytes(subSectionSizeInBytesu32.value);
1096
          }
1097
      }
1098
    }
1099

    
1100
    return nameMetadata;
1101
  } // this is a custom section used for information about the producers
1102
  // https://github.com/WebAssembly/tool-conventions/blob/master/ProducersSection.md
1103

    
1104

    
1105
  function parseProducersSection() {
1106
    var metadata = t.producersSectionMetadata([]); // field_count
1107

    
1108
    var sectionTypeByte = readVaruint32();
1109
    eatBytes(sectionTypeByte.nextIndex);
1110
    dump([sectionTypeByte.value], "num of producers");
1111
    var fields = {
1112
      language: [],
1113
      "processed-by": [],
1114
      sdk: []
1115
    }; // fields
1116

    
1117
    for (var fieldI = 0; fieldI < sectionTypeByte.value; fieldI++) {
1118
      // field_name
1119
      var fieldName = readUTF8String();
1120
      eatBytes(fieldName.nextIndex); // field_value_count
1121

    
1122
      var valueCount = readVaruint32();
1123
      eatBytes(valueCount.nextIndex); // field_values
1124

    
1125
      for (var producerI = 0; producerI < valueCount.value; producerI++) {
1126
        var producerName = readUTF8String();
1127
        eatBytes(producerName.nextIndex);
1128
        var producerVersion = readUTF8String();
1129
        eatBytes(producerVersion.nextIndex);
1130
        fields[fieldName.value].push(t.producerMetadataVersionedName(producerName.value, producerVersion.value));
1131
      }
1132

    
1133
      metadata.producers.push(fields[fieldName.value]);
1134
    }
1135

    
1136
    return metadata;
1137
  }
1138

    
1139
  function parseGlobalSection(numberOfGlobals) {
1140
    var globals = [];
1141
    dump([numberOfGlobals], "num globals");
1142

    
1143
    for (var i = 0; i < numberOfGlobals; i++) {
1144
      var _startLoc11 = getPosition();
1145

    
1146
      var globalType = parseGlobalType();
1147
      /**
1148
       * Global expressions
1149
       */
1150

    
1151
      var init = [];
1152
      parseInstructionBlock(init);
1153

    
1154
      var node = function () {
1155
        var endLoc = getPosition();
1156
        return t.withLoc(t.global(globalType, init), endLoc, _startLoc11);
1157
      }();
1158

    
1159
      globals.push(node);
1160
      state.globalsInModule.push(node);
1161
    }
1162

    
1163
    return globals;
1164
  }
1165

    
1166
  function parseElemSection(numberOfElements) {
1167
    var elems = [];
1168
    dump([numberOfElements], "num elements");
1169

    
1170
    for (var i = 0; i < numberOfElements; i++) {
1171
      var _startLoc12 = getPosition();
1172

    
1173
      var tableindexu32 = readU32();
1174
      var tableindex = tableindexu32.value;
1175
      eatBytes(tableindexu32.nextIndex);
1176
      dump([tableindex], "table index");
1177
      /**
1178
       * Parse instructions
1179
       */
1180

    
1181
      var instr = [];
1182
      parseInstructionBlock(instr);
1183
      /**
1184
       * Parse ( vector function index ) *
1185
       */
1186

    
1187
      var indicesu32 = readU32();
1188
      var indices = indicesu32.value;
1189
      eatBytes(indicesu32.nextIndex);
1190
      dump([indices], "num indices");
1191
      var indexValues = [];
1192

    
1193
      for (var _i5 = 0; _i5 < indices; _i5++) {
1194
        var indexu32 = readU32();
1195
        var index = indexu32.value;
1196
        eatBytes(indexu32.nextIndex);
1197
        dump([index], "index");
1198
        indexValues.push(t.indexLiteral(index));
1199
      }
1200

    
1201
      var elemNode = function () {
1202
        var endLoc = getPosition();
1203
        return t.withLoc(t.elem(t.indexLiteral(tableindex), instr, indexValues), endLoc, _startLoc12);
1204
      }();
1205

    
1206
      elems.push(elemNode);
1207
    }
1208

    
1209
    return elems;
1210
  } // https://webassembly.github.io/spec/core/binary/types.html#memory-types
1211

    
1212

    
1213
  function parseMemoryType(i) {
1214
    var limits = parseLimits();
1215
    return t.memory(limits, t.indexLiteral(i));
1216
  } // https://webassembly.github.io/spec/binary/modules.html#table-section
1217

    
1218

    
1219
  function parseTableSection(numberOfElements) {
1220
    var tables = [];
1221
    dump([numberOfElements], "num elements");
1222

    
1223
    for (var i = 0; i < numberOfElements; i++) {
1224
      var tablesNode = parseTableType(i);
1225
      state.tablesInModule.push(tablesNode);
1226
      tables.push(tablesNode);
1227
    }
1228

    
1229
    return tables;
1230
  } // https://webassembly.github.io/spec/binary/modules.html#memory-section
1231

    
1232

    
1233
  function parseMemorySection(numberOfElements) {
1234
    var memories = [];
1235
    dump([numberOfElements], "num elements");
1236

    
1237
    for (var i = 0; i < numberOfElements; i++) {
1238
      var memoryNode = parseMemoryType(i);
1239
      state.memoriesInModule.push(memoryNode);
1240
      memories.push(memoryNode);
1241
    }
1242

    
1243
    return memories;
1244
  } // https://webassembly.github.io/spec/binary/modules.html#binary-startsec
1245

    
1246

    
1247
  function parseStartSection() {
1248
    var startLoc = getPosition();
1249
    var u32 = readU32();
1250
    var startFuncIndex = u32.value;
1251
    eatBytes(u32.nextIndex);
1252
    dump([startFuncIndex], "index");
1253
    return function () {
1254
      var endLoc = getPosition();
1255
      return t.withLoc(t.start(t.indexLiteral(startFuncIndex)), endLoc, startLoc);
1256
    }();
1257
  } // https://webassembly.github.io/spec/binary/modules.html#data-section
1258

    
1259

    
1260
  function parseDataSection(numberOfElements) {
1261
    var dataEntries = [];
1262
    dump([numberOfElements], "num elements");
1263

    
1264
    for (var i = 0; i < numberOfElements; i++) {
1265
      var memoryIndexu32 = readU32();
1266
      var memoryIndex = memoryIndexu32.value;
1267
      eatBytes(memoryIndexu32.nextIndex);
1268
      dump([memoryIndex], "memory index");
1269
      var instrs = [];
1270
      parseInstructionBlock(instrs);
1271
      var hasExtraInstrs = instrs.filter(function (i) {
1272
        return i.id !== "end";
1273
      }).length !== 1;
1274

    
1275
      if (hasExtraInstrs) {
1276
        throw new CompileError("data section offset must be a single instruction");
1277
      }
1278

    
1279
      var bytes = parseVec(function (b) {
1280
        return b;
1281
      });
1282
      dump([], "init");
1283
      dataEntries.push(t.data(t.memIndexLiteral(memoryIndex), instrs[0], t.byteArray(bytes)));
1284
    }
1285

    
1286
    return dataEntries;
1287
  } // https://webassembly.github.io/spec/binary/modules.html#binary-section
1288

    
1289

    
1290
  function parseSection(sectionIndex) {
1291
    var sectionId = readByte();
1292
    eatBytes(1);
1293

    
1294
    if (sectionId >= sectionIndex || sectionIndex === constants.sections.custom) {
1295
      sectionIndex = sectionId + 1;
1296
    } else {
1297
      if (sectionId !== constants.sections.custom) throw new CompileError("Unexpected section: " + toHex(sectionId));
1298
    }
1299

    
1300
    var nextSectionIndex = sectionIndex;
1301
    var startOffset = offset;
1302
    var startLoc = getPosition();
1303
    var u32 = readU32();
1304
    var sectionSizeInBytes = u32.value;
1305
    eatBytes(u32.nextIndex);
1306

    
1307
    var sectionSizeInBytesNode = function () {
1308
      var endLoc = getPosition();
1309
      return t.withLoc(t.numberLiteralFromRaw(sectionSizeInBytes), endLoc, startLoc);
1310
    }();
1311

    
1312
    switch (sectionId) {
1313
      case constants.sections.type:
1314
        {
1315
          dumpSep("section Type");
1316
          dump([sectionId], "section code");
1317
          dump([sectionSizeInBytes], "section size");
1318

    
1319
          var _startLoc13 = getPosition();
1320

    
1321
          var _u = readU32();
1322

    
1323
          var numberOfTypes = _u.value;
1324
          eatBytes(_u.nextIndex);
1325

    
1326
          var _metadata = t.sectionMetadata("type", startOffset, sectionSizeInBytesNode, function () {
1327
            var endLoc = getPosition();
1328
            return t.withLoc(t.numberLiteralFromRaw(numberOfTypes), endLoc, _startLoc13);
1329
          }());
1330

    
1331
          var _nodes = parseTypeSection(numberOfTypes);
1332

    
1333
          return {
1334
            nodes: _nodes,
1335
            metadata: _metadata,
1336
            nextSectionIndex: nextSectionIndex
1337
          };
1338
        }
1339

    
1340
      case constants.sections.table:
1341
        {
1342
          dumpSep("section Table");
1343
          dump([sectionId], "section code");
1344
          dump([sectionSizeInBytes], "section size");
1345

    
1346
          var _startLoc14 = getPosition();
1347

    
1348
          var _u2 = readU32();
1349

    
1350
          var numberOfTable = _u2.value;
1351
          eatBytes(_u2.nextIndex);
1352
          dump([numberOfTable], "num tables");
1353

    
1354
          var _metadata2 = t.sectionMetadata("table", startOffset, sectionSizeInBytesNode, function () {
1355
            var endLoc = getPosition();
1356
            return t.withLoc(t.numberLiteralFromRaw(numberOfTable), endLoc, _startLoc14);
1357
          }());
1358

    
1359
          var _nodes2 = parseTableSection(numberOfTable);
1360

    
1361
          return {
1362
            nodes: _nodes2,
1363
            metadata: _metadata2,
1364
            nextSectionIndex: nextSectionIndex
1365
          };
1366
        }
1367

    
1368
      case constants.sections.import:
1369
        {
1370
          dumpSep("section Import");
1371
          dump([sectionId], "section code");
1372
          dump([sectionSizeInBytes], "section size");
1373

    
1374
          var _startLoc15 = getPosition();
1375

    
1376
          var numberOfImportsu32 = readU32();
1377
          var numberOfImports = numberOfImportsu32.value;
1378
          eatBytes(numberOfImportsu32.nextIndex);
1379
          dump([numberOfImports], "number of imports");
1380

    
1381
          var _metadata3 = t.sectionMetadata("import", startOffset, sectionSizeInBytesNode, function () {
1382
            var endLoc = getPosition();
1383
            return t.withLoc(t.numberLiteralFromRaw(numberOfImports), endLoc, _startLoc15);
1384
          }());
1385

    
1386
          var _nodes3 = parseImportSection(numberOfImports);
1387

    
1388
          return {
1389
            nodes: _nodes3,
1390
            metadata: _metadata3,
1391
            nextSectionIndex: nextSectionIndex
1392
          };
1393
        }
1394

    
1395
      case constants.sections.func:
1396
        {
1397
          dumpSep("section Function");
1398
          dump([sectionId], "section code");
1399
          dump([sectionSizeInBytes], "section size");
1400

    
1401
          var _startLoc16 = getPosition();
1402

    
1403
          var numberOfFunctionsu32 = readU32();
1404
          var numberOfFunctions = numberOfFunctionsu32.value;
1405
          eatBytes(numberOfFunctionsu32.nextIndex);
1406

    
1407
          var _metadata4 = t.sectionMetadata("func", startOffset, sectionSizeInBytesNode, function () {
1408
            var endLoc = getPosition();
1409
            return t.withLoc(t.numberLiteralFromRaw(numberOfFunctions), endLoc, _startLoc16);
1410
          }());
1411

    
1412
          parseFuncSection(numberOfFunctions);
1413
          var _nodes4 = [];
1414
          return {
1415
            nodes: _nodes4,
1416
            metadata: _metadata4,
1417
            nextSectionIndex: nextSectionIndex
1418
          };
1419
        }
1420

    
1421
      case constants.sections.export:
1422
        {
1423
          dumpSep("section Export");
1424
          dump([sectionId], "section code");
1425
          dump([sectionSizeInBytes], "section size");
1426

    
1427
          var _startLoc17 = getPosition();
1428

    
1429
          var _u3 = readU32();
1430

    
1431
          var numberOfExport = _u3.value;
1432
          eatBytes(_u3.nextIndex);
1433

    
1434
          var _metadata5 = t.sectionMetadata("export", startOffset, sectionSizeInBytesNode, function () {
1435
            var endLoc = getPosition();
1436
            return t.withLoc(t.numberLiteralFromRaw(numberOfExport), endLoc, _startLoc17);
1437
          }());
1438

    
1439
          parseExportSection(numberOfExport);
1440
          var _nodes5 = [];
1441
          return {
1442
            nodes: _nodes5,
1443
            metadata: _metadata5,
1444
            nextSectionIndex: nextSectionIndex
1445
          };
1446
        }
1447

    
1448
      case constants.sections.code:
1449
        {
1450
          dumpSep("section Code");
1451
          dump([sectionId], "section code");
1452
          dump([sectionSizeInBytes], "section size");
1453

    
1454
          var _startLoc18 = getPosition();
1455

    
1456
          var _u4 = readU32();
1457

    
1458
          var numberOfFuncs = _u4.value;
1459
          eatBytes(_u4.nextIndex);
1460

    
1461
          var _metadata6 = t.sectionMetadata("code", startOffset, sectionSizeInBytesNode, function () {
1462
            var endLoc = getPosition();
1463
            return t.withLoc(t.numberLiteralFromRaw(numberOfFuncs), endLoc, _startLoc18);
1464
          }());
1465

    
1466
          if (opts.ignoreCodeSection === true) {
1467
            var remainingBytes = sectionSizeInBytes - _u4.nextIndex;
1468
            eatBytes(remainingBytes); // eat the entire section
1469
          } else {
1470
            parseCodeSection(numberOfFuncs);
1471
          }
1472

    
1473
          var _nodes6 = [];
1474
          return {
1475
            nodes: _nodes6,
1476
            metadata: _metadata6,
1477
            nextSectionIndex: nextSectionIndex
1478
          };
1479
        }
1480

    
1481
      case constants.sections.start:
1482
        {
1483
          dumpSep("section Start");
1484
          dump([sectionId], "section code");
1485
          dump([sectionSizeInBytes], "section size");
1486

    
1487
          var _metadata7 = t.sectionMetadata("start", startOffset, sectionSizeInBytesNode);
1488

    
1489
          var _nodes7 = [parseStartSection()];
1490
          return {
1491
            nodes: _nodes7,
1492
            metadata: _metadata7,
1493
            nextSectionIndex: nextSectionIndex
1494
          };
1495
        }
1496

    
1497
      case constants.sections.element:
1498
        {
1499
          dumpSep("section Element");
1500
          dump([sectionId], "section code");
1501
          dump([sectionSizeInBytes], "section size");
1502

    
1503
          var _startLoc19 = getPosition();
1504

    
1505
          var numberOfElementsu32 = readU32();
1506
          var numberOfElements = numberOfElementsu32.value;
1507
          eatBytes(numberOfElementsu32.nextIndex);
1508

    
1509
          var _metadata8 = t.sectionMetadata("element", startOffset, sectionSizeInBytesNode, function () {
1510
            var endLoc = getPosition();
1511
            return t.withLoc(t.numberLiteralFromRaw(numberOfElements), endLoc, _startLoc19);
1512
          }());
1513

    
1514
          var _nodes8 = parseElemSection(numberOfElements);
1515

    
1516
          return {
1517
            nodes: _nodes8,
1518
            metadata: _metadata8,
1519
            nextSectionIndex: nextSectionIndex
1520
          };
1521
        }
1522

    
1523
      case constants.sections.global:
1524
        {
1525
          dumpSep("section Global");
1526
          dump([sectionId], "section code");
1527
          dump([sectionSizeInBytes], "section size");
1528

    
1529
          var _startLoc20 = getPosition();
1530

    
1531
          var numberOfGlobalsu32 = readU32();
1532
          var numberOfGlobals = numberOfGlobalsu32.value;
1533
          eatBytes(numberOfGlobalsu32.nextIndex);
1534

    
1535
          var _metadata9 = t.sectionMetadata("global", startOffset, sectionSizeInBytesNode, function () {
1536
            var endLoc = getPosition();
1537
            return t.withLoc(t.numberLiteralFromRaw(numberOfGlobals), endLoc, _startLoc20);
1538
          }());
1539

    
1540
          var _nodes9 = parseGlobalSection(numberOfGlobals);
1541

    
1542
          return {
1543
            nodes: _nodes9,
1544
            metadata: _metadata9,
1545
            nextSectionIndex: nextSectionIndex
1546
          };
1547
        }
1548

    
1549
      case constants.sections.memory:
1550
        {
1551
          dumpSep("section Memory");
1552
          dump([sectionId], "section code");
1553
          dump([sectionSizeInBytes], "section size");
1554

    
1555
          var _startLoc21 = getPosition();
1556

    
1557
          var _numberOfElementsu = readU32();
1558

    
1559
          var _numberOfElements = _numberOfElementsu.value;
1560
          eatBytes(_numberOfElementsu.nextIndex);
1561

    
1562
          var _metadata10 = t.sectionMetadata("memory", startOffset, sectionSizeInBytesNode, function () {
1563
            var endLoc = getPosition();
1564
            return t.withLoc(t.numberLiteralFromRaw(_numberOfElements), endLoc, _startLoc21);
1565
          }());
1566

    
1567
          var _nodes10 = parseMemorySection(_numberOfElements);
1568

    
1569
          return {
1570
            nodes: _nodes10,
1571
            metadata: _metadata10,
1572
            nextSectionIndex: nextSectionIndex
1573
          };
1574
        }
1575

    
1576
      case constants.sections.data:
1577
        {
1578
          dumpSep("section Data");
1579
          dump([sectionId], "section code");
1580
          dump([sectionSizeInBytes], "section size");
1581

    
1582
          var _metadata11 = t.sectionMetadata("data", startOffset, sectionSizeInBytesNode);
1583

    
1584
          var _startLoc22 = getPosition();
1585

    
1586
          var _numberOfElementsu2 = readU32();
1587

    
1588
          var _numberOfElements2 = _numberOfElementsu2.value;
1589
          eatBytes(_numberOfElementsu2.nextIndex);
1590

    
1591
          _metadata11.vectorOfSize = function () {
1592
            var endLoc = getPosition();
1593
            return t.withLoc(t.numberLiteralFromRaw(_numberOfElements2), endLoc, _startLoc22);
1594
          }();
1595

    
1596
          if (opts.ignoreDataSection === true) {
1597
            var _remainingBytes = sectionSizeInBytes - _numberOfElementsu2.nextIndex;
1598

    
1599
            eatBytes(_remainingBytes); // eat the entire section
1600

    
1601
            dumpSep("ignore data (" + sectionSizeInBytes + " bytes)");
1602
            return {
1603
              nodes: [],
1604
              metadata: _metadata11,
1605
              nextSectionIndex: nextSectionIndex
1606
            };
1607
          } else {
1608
            var _nodes11 = parseDataSection(_numberOfElements2);
1609

    
1610
            return {
1611
              nodes: _nodes11,
1612
              metadata: _metadata11,
1613
              nextSectionIndex: nextSectionIndex
1614
            };
1615
          }
1616
        }
1617

    
1618
      case constants.sections.custom:
1619
        {
1620
          dumpSep("section Custom");
1621
          dump([sectionId], "section code");
1622
          dump([sectionSizeInBytes], "section size");
1623
          var _metadata12 = [t.sectionMetadata("custom", startOffset, sectionSizeInBytesNode)];
1624
          var sectionName = readUTF8String();
1625
          eatBytes(sectionName.nextIndex);
1626
          dump([], "section name (".concat(sectionName.value, ")"));
1627

    
1628
          var _remainingBytes2 = sectionSizeInBytes - sectionName.nextIndex;
1629

    
1630
          if (sectionName.value === "name") {
1631
            var initialOffset = offset;
1632

    
1633
            try {
1634
              _metadata12.push.apply(_metadata12, _toConsumableArray(parseNameSection(_remainingBytes2)));
1635
            } catch (e) {
1636
              console.warn("Failed to decode custom \"name\" section @".concat(offset, "; ignoring (").concat(e.message, ")."));
1637
              eatBytes(offset - (initialOffset + _remainingBytes2));
1638
            }
1639
          } else if (sectionName.value === "producers") {
1640
            var _initialOffset = offset;
1641

    
1642
            try {
1643
              _metadata12.push(parseProducersSection());
1644
            } catch (e) {
1645
              console.warn("Failed to decode custom \"producers\" section @".concat(offset, "; ignoring (").concat(e.message, ")."));
1646
              eatBytes(offset - (_initialOffset + _remainingBytes2));
1647
            }
1648
          } else {
1649
            // We don't parse the custom section
1650
            eatBytes(_remainingBytes2);
1651
            dumpSep("ignore custom " + JSON.stringify(sectionName.value) + " section (" + _remainingBytes2 + " bytes)");
1652
          }
1653

    
1654
          return {
1655
            nodes: [],
1656
            metadata: _metadata12,
1657
            nextSectionIndex: nextSectionIndex
1658
          };
1659
        }
1660
    }
1661

    
1662
    throw new CompileError("Unexpected section: " + toHex(sectionId));
1663
  }
1664

    
1665
  parseModuleHeader();
1666
  parseVersion();
1667
  var moduleFields = [];
1668
  var sectionIndex = 0;
1669
  var moduleMetadata = {
1670
    sections: [],
1671
    functionNames: [],
1672
    localNames: [],
1673
    producers: []
1674
  };
1675
  /**
1676
   * All the generate declaration are going to be stored in our state
1677
   */
1678

    
1679
  while (offset < buf.length) {
1680
    var _parseSection = parseSection(sectionIndex),
1681
        _nodes12 = _parseSection.nodes,
1682
        _metadata13 = _parseSection.metadata,
1683
        nextSectionIndex = _parseSection.nextSectionIndex;
1684

    
1685
    moduleFields.push.apply(moduleFields, _toConsumableArray(_nodes12));
1686
    var metadataArray = Array.isArray(_metadata13) ? _metadata13 : [_metadata13];
1687
    metadataArray.forEach(function (metadataItem) {
1688
      if (metadataItem.type === "FunctionNameMetadata") {
1689
        moduleMetadata.functionNames.push(metadataItem);
1690
      } else if (metadataItem.type === "LocalNameMetadata") {
1691
        moduleMetadata.localNames.push(metadataItem);
1692
      } else if (metadataItem.type === "ProducersSectionMetadata") {
1693
        moduleMetadata.producers.push(metadataItem);
1694
      } else {
1695
        moduleMetadata.sections.push(metadataItem);
1696
      }
1697
    }); // Ignore custom section
1698

    
1699
    if (nextSectionIndex) {
1700
      sectionIndex = nextSectionIndex;
1701
    }
1702
  }
1703
  /**
1704
   * Transform the state into AST nodes
1705
   */
1706

    
1707

    
1708
  var funcIndex = 0;
1709
  state.functionsInModule.forEach(function (func) {
1710
    var params = func.signature.params;
1711
    var result = func.signature.result;
1712
    var body = []; // External functions doesn't provide any code, can skip it here
1713

    
1714
    if (func.isExternal === true) {
1715
      return;
1716
    }
1717

    
1718
    var decodedElementInCodeSection = state.elementsInCodeSection[funcIndex];
1719

    
1720
    if (opts.ignoreCodeSection === false) {
1721
      if (typeof decodedElementInCodeSection === "undefined") {
1722
        throw new CompileError("func " + toHex(funcIndex) + " code not found");
1723
      }
1724

    
1725
      body = decodedElementInCodeSection.code;
1726
    }
1727

    
1728
    funcIndex++;
1729
    var funcNode = t.func(func.id, t.signature(params, result), body);
1730

    
1731
    if (func.isExternal === true) {
1732
      funcNode.isExternal = func.isExternal;
1733
    } // Add function position in the binary if possible
1734

    
1735

    
1736
    if (opts.ignoreCodeSection === false) {
1737
      var _startLoc23 = decodedElementInCodeSection.startLoc,
1738
          endLoc = decodedElementInCodeSection.endLoc,
1739
          bodySize = decodedElementInCodeSection.bodySize;
1740
      funcNode = t.withLoc(funcNode, endLoc, _startLoc23);
1741
      funcNode.metadata = {
1742
        bodySize: bodySize
1743
      };
1744
    }
1745

    
1746
    moduleFields.push(funcNode);
1747
  });
1748
  state.elementsInExportSection.forEach(function (moduleExport) {
1749
    /**
1750
     * If the export has no id, we won't be able to call it from the outside
1751
     * so we can omit it
1752
     */
1753
    if (moduleExport.id != null) {
1754
      moduleFields.push(t.withLoc(t.moduleExport(moduleExport.name, t.moduleExportDescr(moduleExport.type, moduleExport.id)), moduleExport.endLoc, moduleExport.startLoc));
1755
    }
1756
  });
1757
  dumpSep("end of program");
1758
  var module = t.module(null, moduleFields, t.moduleMetadata(moduleMetadata.sections, moduleMetadata.functionNames, moduleMetadata.localNames, moduleMetadata.producers));
1759
  return t.program([module]);
1760
}
(1-1/2)