porffor 0.2.0-623cdf0 → 0.2.0-6aff0fa

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/asur/index.js ADDED
@@ -0,0 +1,978 @@
1
+ let offset = 0, input;
2
+
3
+ const read = () => input[offset++];
4
+
5
+ const signedLEB128 = () => {
6
+ let result = 0, shift = 0;
7
+
8
+ while (true) {
9
+ const byte = read();
10
+ result |= (byte & 0x7f) << shift;
11
+
12
+ shift += 7;
13
+
14
+ if ((0x80 & byte) == 0) { // final byte
15
+ if (shift < 32 && (byte & 0x40) != 0) {
16
+ return result | (-1 << shift);
17
+ }
18
+
19
+ return result;
20
+ }
21
+ }
22
+ };
23
+
24
+ const unsignedLEB128 = () => {
25
+ let result = 0, shift = 0;
26
+
27
+ while (true) {
28
+ const byte = read();
29
+ result |= (byte & 0x7f) << shift;
30
+
31
+ shift += 7;
32
+
33
+ if ((0x80 & byte) == 0) { // final byte
34
+ return result;
35
+ }
36
+ }
37
+ };
38
+
39
+ const ieee754 = () => new Float64Array(new Uint8Array([ read(), read(), read(), read(), read(), read(), read(), read() ]).buffer)[0];
40
+
41
+ const string = () => {
42
+ let out = '';
43
+
44
+ const len = unsignedLEB128();
45
+ for (let i = 0; i < len; i++) {
46
+ out += String.fromCharCode(read());
47
+ }
48
+
49
+ return out;
50
+ };
51
+
52
+ const parse = (binary) => {
53
+ offset = 0;
54
+ input = binary;
55
+
56
+ if (
57
+ read() != 0x00 ||
58
+ read() != 0x61 ||
59
+ read() != 0x73 ||
60
+ read() != 0x6d
61
+ ) throw new Error('invalid magic');
62
+
63
+ if (
64
+ read() != 0x01 ||
65
+ read() != 0x00 ||
66
+ read() != 0x00 ||
67
+ read() != 0x00
68
+ ) throw new Error('invalid version');
69
+
70
+ let types = [],
71
+ imports = [],
72
+ funcs = [],
73
+ exports = [],
74
+ globals = [],
75
+ codes = [];
76
+
77
+ const len = input.length;
78
+ while (offset < len) {
79
+ const section = read();
80
+ const bytes = unsignedLEB128();
81
+
82
+ if (section === 1) { // type
83
+ const typesLength = unsignedLEB128();
84
+ types = new Array(typesLength);
85
+
86
+ for (let i = 0; i < typesLength; i++) {
87
+ const type = read();
88
+
89
+ const paramsLength = unsignedLEB128();
90
+ const params = new Array(paramsLength);
91
+ for (let j = 0; j < paramsLength; j++) params[j] = read();
92
+
93
+ const returnsLength = unsignedLEB128();
94
+ const returns = new Array(returnsLength);
95
+ for (let j = 0; j < returnsLength; j++) returns[j] = read();
96
+
97
+ types[i] = { type, params, returns };
98
+ }
99
+
100
+ continue;
101
+ }
102
+
103
+ if (section === 2) { // import
104
+ const importsLength = unsignedLEB128();
105
+ imports = new Array(importsLength);
106
+
107
+ for (let i = 0; i < importsLength; i++) {
108
+ const module = string();
109
+ const name = string();
110
+
111
+ const type = read();
112
+
113
+ const typeIdx = unsignedLEB128();
114
+
115
+ imports[i] = { module, name, type, typeIdx };
116
+ }
117
+
118
+ continue;
119
+ }
120
+
121
+ if (section === 3) { // func
122
+ const funcsLength = unsignedLEB128();
123
+ funcs = new Array(funcsLength);
124
+
125
+ for (let i = 0; i < funcsLength; i++) {
126
+ funcs[i] = unsignedLEB128();
127
+ }
128
+
129
+ continue;
130
+ }
131
+
132
+ if (section === 5) { // memory
133
+
134
+ }
135
+
136
+ if (section === 6) { // global
137
+ const globalsLength = unsignedLEB128();
138
+ globals = new Array(globalsLength);
139
+
140
+ for (let i = 0; i < globalsLength; i++) {
141
+ const valtype = read();
142
+ const mutable = read() === 0x01;
143
+
144
+ let init = [];
145
+ while (true) {
146
+ const byte = read();
147
+ init.push(byte);
148
+
149
+ if (byte === 0x0b) break; // end
150
+ }
151
+
152
+ globals[i] = { valtype, mutable, init };
153
+ }
154
+
155
+ continue;
156
+ }
157
+
158
+ if (section === 7) { // export
159
+ const exportsLength = unsignedLEB128();
160
+ exports = new Array(exportsLength);
161
+
162
+ for (let i = 0; i < exportsLength; i++) {
163
+ const name = string();
164
+
165
+ const type = read();
166
+
167
+ const index = unsignedLEB128();
168
+
169
+ exports[i] = { name, type, index };
170
+ }
171
+
172
+ continue;
173
+ }
174
+
175
+ if (section === 10) { // code
176
+ const codesLength = unsignedLEB128();
177
+ codes = new Array(codesLength);
178
+
179
+ for (let i = 0; i < codesLength; i++) {
180
+ const size = unsignedLEB128();
181
+ const end = offset + size;
182
+
183
+ const locals = [];
184
+
185
+ const localsLength = unsignedLEB128();
186
+ for (let j = 0; j < localsLength; j++) {
187
+ const count = unsignedLEB128();
188
+ const type = read();
189
+
190
+ for (let k = 0; k < count; k++) locals.push(type);
191
+ }
192
+
193
+ const bytesLeft = end - offset;
194
+ const wasm = new Array(bytesLeft);
195
+ for (let j = 0; j < bytesLeft; j++) wasm[j] = read();
196
+
197
+ codes[i] = { locals, wasm };
198
+ }
199
+
200
+ continue;
201
+ }
202
+
203
+ if (section === 11) { // data
204
+
205
+ }
206
+ }
207
+
208
+ return { types, imports, funcs, globals, exports, codes };
209
+ };
210
+
211
+ const inv = (obj, keyMap = x => x) => Object.keys(obj).reduce((acc, x) => { acc[keyMap(obj[x])] = x; return acc; }, {});
212
+ const Opcodes = (await import('../compiler/wasmSpec.js')).Opcodes;
213
+ const invOpcodes = inv(Opcodes, x => {
214
+ if (typeof x === 'number') return x;
215
+ return (x[0] << 8) + x[1];
216
+ });
217
+
218
+ const vm = ({ types, imports, funcs, globals, exports, codes }, importImpls, startFunc) => {
219
+ const constCache = {};
220
+ const skipCache = {};
221
+
222
+ const run = (activeFunc, params = [], setup = true) => {
223
+ let locals = [];
224
+ if (setup) {
225
+ const activeCode = codes[activeFunc - imports.length];
226
+
227
+ input = activeCode.wasm; // active code
228
+ offset = 0; // PC
229
+
230
+ locals = new Array(activeCode.locals.length).fill(0);
231
+
232
+ for (let i = 0; i < params.length; i++) locals[i] = params[i];
233
+ }
234
+
235
+ if (!constCache[activeFunc]) constCache[activeFunc] = {};
236
+ if (!skipCache[activeFunc]) skipCache[activeFunc] = {};
237
+
238
+ let stack = [];
239
+
240
+ let depth = 0;
241
+
242
+ let skipStart = 0;
243
+ let skipUntilEnd = 0;
244
+ let skipUntilElse = 0;
245
+ let loopStarts = [];
246
+ let rets = [];
247
+
248
+ while (true) {
249
+ let opcode = read();
250
+
251
+ const skip = skipUntilEnd !== 0 || skipUntilElse !== 0;
252
+
253
+ if (opcode === 0xfc) { // multibyte op
254
+ opcode = (opcode << 8) + read();
255
+ }
256
+
257
+ // console.log((skip ? '\x1B[90m' : '') + ' '.repeat(depth * 2) + invOpcodes[opcode] + '\x1B[0m', stack, depth);
258
+
259
+ const blockStart = (loop) => {
260
+ const returns = read();
261
+ rets.push(returns !== 0x40);
262
+
263
+ loopStarts.push(loop ? offset : null);
264
+
265
+ depth++;
266
+ };
267
+
268
+ const skipEnd = until => {
269
+ if (skipCache[activeFunc][offset]) {
270
+ offset = skipCache[activeFunc][offset];
271
+ } else {
272
+ skipUntilEnd = until;
273
+ skipStart = offset;
274
+ }
275
+ };
276
+
277
+ const skipElse = until => {
278
+ skipUntilElse = until;
279
+
280
+ if (skipCache[activeFunc][offset]) {
281
+ offset = skipCache[activeFunc][offset];
282
+ } else {
283
+ skipStart = offset;
284
+ }
285
+ };
286
+
287
+ const br = n => {
288
+ const ind = depth - n - 1;
289
+
290
+ // depth -= n;
291
+ if (loopStarts[ind]) {
292
+ depth -= n;
293
+
294
+ if (n === 0) {
295
+
296
+ } else if (n === 1) {
297
+ loopStarts.pop();
298
+ rets.pop();
299
+ } else {
300
+ // loopStarts.splice(loopStarts.length - n - 1, n);
301
+ // rets.splice(rets.length - n - 1, n);
302
+ loopStarts = loopStarts.slice(0, depth);
303
+ rets = rets.slice(0, depth);
304
+ }
305
+
306
+ // // loopStarts.splice(loopStarts.length - n - 1, n);
307
+ // // rets.splice(rets.length - n - 1, n);
308
+ // loopStarts = loopStarts.slice(0, depth);
309
+ // rets = rets.slice(0, depth);
310
+
311
+ offset = loopStarts[ind];
312
+ } else skipEnd(depth);
313
+
314
+ // if (rets[ind]) stack
315
+ };
316
+
317
+ switch (opcode) {
318
+ case 0x00: { // unreachable
319
+ if (skip) break;
320
+ throw new Error('unreachable');
321
+ }
322
+
323
+ case 0x01: { // nop
324
+ break;
325
+ }
326
+
327
+ case 0x02: { // block
328
+ blockStart(false);
329
+ break;
330
+ }
331
+
332
+ case 0x03: { // loop
333
+ blockStart(true);
334
+ break;
335
+ }
336
+
337
+ case 0x04: { // if
338
+ blockStart(false);
339
+ if (skip) break;
340
+
341
+ const cond = stack.pop();
342
+ if (cond) {
343
+
344
+ } else skipElse(depth); // skip to else
345
+
346
+ break;
347
+ }
348
+
349
+ case 0x05: { // else
350
+ if (skipUntilElse === depth) { // were skipping to else, stop skip
351
+ skipUntilElse = 0;
352
+
353
+ if (!skipCache[activeFunc][skipStart]) {
354
+ // skipCache[activeFunc][skipStart] = offset - 1;
355
+ }
356
+ } else { // were running consequent, skip else
357
+ if (!skip) skipEnd(depth);
358
+ }
359
+
360
+ break;
361
+ }
362
+
363
+ case 0x0b: { // end
364
+ if (depth === 0) return stack;
365
+
366
+ // were skipping to here, stop skip
367
+ if (skipUntilElse === depth || skipUntilEnd === depth) {
368
+ skipUntilElse = 0;
369
+ skipUntilEnd = 0;
370
+
371
+ if (!skipCache[activeFunc][skipStart]) {
372
+ // skipCache[activeFunc][skipStart] = offset - 1;
373
+ }
374
+ }
375
+
376
+ depth--;
377
+
378
+ rets.pop();
379
+ loopStarts.pop();
380
+
381
+ break;
382
+ }
383
+
384
+ case 0x0c: { // br
385
+ if (skip) {
386
+ read();
387
+ break;
388
+ }
389
+
390
+ br(read());
391
+ break;
392
+ }
393
+
394
+ case 0x0d: { // br_if
395
+ if (skip) {
396
+ read();
397
+ break;
398
+ }
399
+
400
+ const n = read();
401
+
402
+ if (stack.pop()) br(n);
403
+
404
+ break;
405
+ }
406
+
407
+ case 0x0f: { // return
408
+ if (skip) break;
409
+
410
+ return stack;
411
+ }
412
+
413
+ case 0x10: { // call
414
+ if (skip) {
415
+ read();
416
+ break;
417
+ }
418
+
419
+ // const func = unsignedLEB128();
420
+ const func = read();
421
+
422
+ if (func < imports.length) {
423
+ const mod = imports[func].module;
424
+ const name = imports[func].name;
425
+
426
+ const type = types[imports[func].typeIdx];
427
+
428
+ const paramCount = type.params.length;
429
+
430
+ const params = new Array(paramCount);
431
+ for (let i = 0; i < paramCount; i++) params[i] = stack.pop();
432
+
433
+ const ret = importImpls[mod][name](...params);
434
+
435
+ if (type.returns.length > 0) stack.push(ret);
436
+
437
+ break;
438
+ }
439
+
440
+ const type = types[funcs[func - imports.length]];
441
+ const paramCount = type.params.length;
442
+
443
+ const params = new Array(paramCount);
444
+
445
+ if (paramCount === 0) {}
446
+ else if (paramCount === 1) params[0] = stack.pop();
447
+ else if (paramCount === 2) { params[1] = stack.pop(); params[0] = stack.pop(); }
448
+ else for (let i = paramCount - 1; i >= 0; i--) params[i] = stack.pop();
449
+
450
+ // for (let i = paramCount - 1; i >= 0; i--) params[i] = stack.pop();
451
+
452
+ const _input = input;
453
+ const _offset = offset;
454
+
455
+ const outStack = run(func, params);
456
+ stack.push(...outStack);
457
+ // while (outStack.length > 0) stack.push(outStack.pop());
458
+ // stack = stack.concat(outStack);
459
+
460
+ input = _input;
461
+ offset = _offset;
462
+
463
+ break;
464
+ }
465
+
466
+ case 0x1a: { // drop
467
+ if (skip) break;
468
+
469
+ stack.pop();
470
+ break;
471
+ }
472
+
473
+ case 0x20: { // local.get
474
+ if (skip) {
475
+ read();
476
+ break;
477
+ }
478
+
479
+ // stack.push(locals[unsignedLEB128()]);
480
+ // stack.push(locals[input[offset++]]);
481
+ stack.push(locals[read()]);
482
+ break;
483
+ }
484
+
485
+ case 0x21: { // local.set
486
+ if (skip) {
487
+ read();
488
+ break;
489
+ }
490
+
491
+ // locals[unsignedLEB128()] = stack.pop();
492
+ locals[read()] = stack.pop();
493
+ break;
494
+ }
495
+
496
+ case 0x22: { // local.tee
497
+ if (skip) {
498
+ read();
499
+ break;
500
+ }
501
+
502
+ // stack.push(locals[unsignedLEB128()] = stack.pop());
503
+ stack.push(locals[read()] = stack.pop());
504
+ break;
505
+ }
506
+
507
+ case 0x23: { // global.get
508
+ if (skip) {
509
+ read();
510
+ break;
511
+ }
512
+
513
+ const ind = read();
514
+ if (globals[ind].value == null) {
515
+ const _input = input;
516
+ const _offset = offset;
517
+
518
+ input = globals[ind].init;
519
+ offset = 0;
520
+
521
+ globals[ind].value = run(null, [], false)[0];
522
+
523
+ input = _input;
524
+ offset = _offset;
525
+ }
526
+
527
+ // stack.push(globals[unsignedLEB128()]);
528
+ stack.push(globals[ind].value);
529
+ break;
530
+ }
531
+
532
+ case 0x24: { // global.set
533
+ if (skip) {
534
+ read();
535
+ break;
536
+ }
537
+
538
+ // globals[unsignedLEB128()] = stack.pop();
539
+ globals[read()].value = stack.pop();
540
+ break;
541
+ }
542
+
543
+ case 0x41: { // i32.const
544
+ if (skip) {
545
+ signedLEB128();
546
+ break;
547
+ }
548
+
549
+ stack.push(signedLEB128());
550
+ break;
551
+ }
552
+ case 0x42: { // i64.const
553
+ if (skip) {
554
+ signedLEB128();
555
+ break;
556
+ }
557
+
558
+ stack.push(signedLEB128());
559
+ break;
560
+ }
561
+ case 0x44: { // f64.const
562
+ if (skip) {
563
+ offset += 8;
564
+ break;
565
+ }
566
+
567
+ if (constCache[activeFunc][offset] != null) {
568
+ stack.push(constCache[activeFunc][offset]);
569
+ offset += 8;
570
+ break;
571
+ }
572
+
573
+ const val = ieee754();
574
+ constCache[activeFunc][offset - 8] = val;
575
+ stack.push(val);
576
+ break;
577
+ }
578
+
579
+ case 0x45: { // i32_eqz
580
+ if (skip) break;
581
+
582
+ stack.push(stack.pop() === 0);
583
+ break;
584
+ }
585
+ case 0x46: { // i32_eq
586
+ if (skip) break;
587
+
588
+ stack.push(stack.pop() === stack.pop());
589
+ break;
590
+ }
591
+ case 0x47: { // i32_ne
592
+ if (skip) break;
593
+
594
+ stack.push(stack.pop() !== stack.pop());
595
+ break;
596
+ }
597
+ case 0x48: { // i32.lt_s
598
+ if (skip) break;
599
+
600
+ const b = stack.pop();
601
+ const a = stack.pop();
602
+ stack.push(a < b);
603
+ break;
604
+ }
605
+ case 0x4c: { // i32.le_s
606
+ if (skip) break;
607
+
608
+ const b = stack.pop();
609
+ const a = stack.pop();
610
+ stack.push(a <= b);
611
+ break;
612
+ }
613
+ case 0x4a: { // i32.gt_s
614
+ if (skip) break;
615
+
616
+ const b = stack.pop();
617
+ const a = stack.pop();
618
+ stack.push(a > b);
619
+ break;
620
+ }
621
+ case 0x4e: { // i32_ge_s
622
+ if (skip) break;
623
+
624
+ const b = stack.pop();
625
+ const a = stack.pop();
626
+ stack.push(a >= b);
627
+ break;
628
+ }
629
+
630
+ case 0x6a: { // i32_add
631
+ if (skip) break;
632
+
633
+ const b = stack.pop();
634
+ const a = stack.pop();
635
+ stack.push(a + b);
636
+ break;
637
+ }
638
+ case 0x6b: { // i32_sub
639
+ if (skip) break;
640
+
641
+ const b = stack.pop();
642
+ const a = stack.pop();
643
+ stack.push(a - b);
644
+ break;
645
+ }
646
+ case 0x6c: { // i32_mul
647
+ if (skip) break;
648
+
649
+ const b = stack.pop();
650
+ const a = stack.pop();
651
+ stack.push(a * b);
652
+ break;
653
+ }
654
+ case 0x6d: { // i32_div_s
655
+ if (skip) break;
656
+
657
+ const b = stack.pop();
658
+ const a = stack.pop();
659
+ stack.push(a / b);
660
+ break;
661
+ }
662
+ case 0x6f: { // i32_rem_s
663
+ if (skip) break;
664
+
665
+ const b = stack.pop();
666
+ const a = stack.pop();
667
+ stack.push(a % b);
668
+ break;
669
+ }
670
+
671
+ case 0x71: { // i32_and
672
+ if (skip) break;
673
+
674
+ const b = stack.pop();
675
+ const a = stack.pop();
676
+ stack.push(a & b);
677
+ break;
678
+ }
679
+ case 0x72: { // i32_or
680
+ if (skip) break;
681
+
682
+ const b = stack.pop();
683
+ const a = stack.pop();
684
+ stack.push(a | b);
685
+ break;
686
+ }
687
+ case 0x73: { // i32_xor
688
+ if (skip) break;
689
+
690
+ const b = stack.pop();
691
+ const a = stack.pop();
692
+ stack.push(a ^ b);
693
+ break;
694
+ }
695
+ case 0x74: { // i32_shl
696
+ if (skip) break;
697
+
698
+ const b = stack.pop();
699
+ const a = stack.pop();
700
+ stack.push(a << b);
701
+ break;
702
+ }
703
+ case 0x75: { // i32_shr_s
704
+ if (skip) break;
705
+
706
+ const b = stack.pop();
707
+ const a = stack.pop();
708
+ stack.push(a >> b);
709
+ break;
710
+ }
711
+ case 0x76: { // i32_shr_u
712
+ if (skip) break;
713
+
714
+ const b = stack.pop();
715
+ const a = stack.pop();
716
+ stack.push(a >>> b);
717
+ break;
718
+ }
719
+
720
+ // case 0x50: { // i64_eqz
721
+ // break;
722
+ // }
723
+ // case 0x51: { // i64_eq
724
+ // break;
725
+ // }
726
+ // case 0x52: { // i64_ne
727
+ // break;
728
+ // }
729
+
730
+ // case 0x53: { // i64_lt_s
731
+ // break;
732
+ // }
733
+ // case 0x57: { // i64_le_s
734
+ // break;
735
+ // }
736
+ // case 0x55: { // i64_gt_s
737
+ // break;
738
+ // }
739
+ // case 0x59: { // i64_ge_s
740
+ // break;
741
+ // }
742
+
743
+ // case 0x7c: { // i64_add
744
+ // break;
745
+ // }
746
+ // case 0x7d: { // i64_sub
747
+ // break;
748
+ // }
749
+ // case 0x7e: { // i64_mul
750
+ // break;
751
+ // }
752
+ // case 0x7f: { // i64_div_s
753
+ // break;
754
+ // }
755
+ // case 0x81: { // i64_rem_s
756
+ // break;
757
+ // }
758
+
759
+ // case 0x83: { // i64_and
760
+ // break;
761
+ // }
762
+ // case 0x84: { // i64_or
763
+ // break;
764
+ // }
765
+ // case 0x85: { // i64_xor
766
+ // break;
767
+ // }
768
+ // case 0x86: { // i64_shl
769
+ // break;
770
+ // }
771
+ // case 0x87: { // i64_shr_s
772
+ // break;
773
+ // }
774
+ // case 0x88: { // i64_shr_u
775
+ // break;
776
+ // }
777
+
778
+ case 0x61: { // f64_eq
779
+ if (skip) break;
780
+
781
+ stack.push(stack.pop() === stack.pop());
782
+ break;
783
+ }
784
+ case 0x62: { // f64_ne
785
+ if (skip) break;
786
+
787
+ stack.push(stack.pop() !== stack.pop());
788
+ break;
789
+ }
790
+
791
+ case 0x63: { // f64_lt
792
+ if (skip) break;
793
+
794
+ const b = stack.pop();
795
+ const a = stack.pop();
796
+ stack.push(a < b);
797
+ break;
798
+ }
799
+ case 0x65: { // f64_le
800
+ if (skip) break;
801
+
802
+ const b = stack.pop();
803
+ const a = stack.pop();
804
+ stack.push(a <= b);
805
+ break;
806
+ }
807
+ case 0x64: { // f64_gt
808
+ if (skip) break;
809
+
810
+ const b = stack.pop();
811
+ const a = stack.pop();
812
+ stack.push(a > b);
813
+ break;
814
+ }
815
+ case 0x66: { // f64_ge
816
+ if (skip) break;
817
+
818
+ const b = stack.pop();
819
+ const a = stack.pop();
820
+ stack.push(a >= b);
821
+ break;
822
+ }
823
+
824
+ case 0x99: { // f64_abs
825
+ if (skip) break;
826
+
827
+ stack.push(Math.abs(stack.pop()));
828
+ break;
829
+ }
830
+ case 0x9a: { // f64_neg
831
+ if (skip) break;
832
+
833
+ stack.push(stack.pop() * -1);
834
+ break;
835
+ }
836
+
837
+ case 0x9b: { // f64_ceil
838
+ if (skip) break;
839
+
840
+ stack.push(Math.ceil(stack.pop()));
841
+ break;
842
+ }
843
+ case 0x9c: { // f64_floor
844
+ if (skip) break;
845
+
846
+ stack.push(Math.floor(stack.pop()));
847
+ break;
848
+ }
849
+ case 0x9d: { // f64_trunc
850
+ if (skip) break;
851
+
852
+ stack.push(stack.pop() | 0);
853
+ break;
854
+ }
855
+ case 0x9e: { // f64_nearest
856
+ if (skip) break;
857
+
858
+ stack.push(Math.round(stack.pop()));
859
+ break;
860
+ }
861
+
862
+ case 0x9f: { // f64_sqrt
863
+ if (skip) break;
864
+
865
+ stack.push(Math.sqrt(stack.pop()));
866
+ break;
867
+ }
868
+ case 0xa0: { // f64_add
869
+ if (skip) break;
870
+
871
+ const b = stack.pop();
872
+ const a = stack.pop();
873
+ stack.push(a + b);
874
+ break;
875
+ }
876
+ case 0xa1: { // f64_sub
877
+ if (skip) break;
878
+
879
+ const b = stack.pop();
880
+ const a = stack.pop();
881
+ stack.push(a - b);
882
+ break;
883
+ }
884
+ case 0xa2: { // f64_mul
885
+ if (skip) break;
886
+
887
+ const b = stack.pop();
888
+ const a = stack.pop();
889
+ stack.push(a * b);
890
+ break;
891
+ }
892
+ case 0xa3: { // f64_div
893
+ if (skip) break;
894
+
895
+ const b = stack.pop();
896
+ const a = stack.pop();
897
+ stack.push(a / b);
898
+ break;
899
+ }
900
+ case 0xa4: { // f64_min
901
+ if (skip) break;
902
+
903
+ const b = stack.pop();
904
+ const a = stack.pop();
905
+ stack.push(a > b ? b : a);
906
+ break;
907
+ }
908
+ case 0xa5: { // f64_max
909
+ if (skip) break;
910
+
911
+ const b = stack.pop();
912
+ const a = stack.pop();
913
+ stack.push(a > b ? a : b);
914
+ break;
915
+ }
916
+
917
+ case 0xa7: { // i32_wrap_i64
918
+ break;
919
+ }
920
+ case 0xac: { // i64_extend_i32_s
921
+ break;
922
+ }
923
+ case 0xad: { // i64_extend_i32_u
924
+ break;
925
+ }
926
+
927
+ case 0xb6: { // f32_demote_f64
928
+ break;
929
+ }
930
+ case 0xbb: { // f64_promote_f32
931
+ break;
932
+ }
933
+
934
+ case 0xb7: { // f64_convert_i32_s
935
+ break;
936
+ }
937
+ case 0xb8: { // f64_convert_i32_u
938
+ break;
939
+ }
940
+ case 0xb9: { // f64_convert_i64_s
941
+ break;
942
+ }
943
+ case 0xba: { // f64_convert_i64_u
944
+ break;
945
+ }
946
+
947
+ case 0xfc02: { // i32_trunc_sat_f64_s
948
+ break;
949
+ }
950
+
951
+ case 0xfc03: { // i32_trunc_sat_f64_u
952
+ break;
953
+ }
954
+
955
+ default: {
956
+ console.log(activeFunc, offset, input.length, depth);
957
+ throw new Error(`unimplemented op: 0x${opcode?.toString(16)}`);
958
+ }
959
+ }
960
+ }
961
+ };
962
+
963
+ return (...args) => run(startFunc, args);
964
+ };
965
+
966
+ export const instantiate = async (binary, importImpls) => {
967
+ const parsed = parse(binary);
968
+ const exports = {};
969
+ for (const { name, type, index } of parsed.exports) {
970
+ if (type === 0x00) exports[name] = vm(parsed, importImpls, index);
971
+ }
972
+
973
+ return {
974
+ instance: {
975
+ exports
976
+ }
977
+ };
978
+ };