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/README.md +69 -44
- package/asur/README.md +2 -0
- package/asur/index.js +978 -0
- package/compiler/2c.js +11 -11
- package/compiler/builtins/base64.ts +153 -0
- package/compiler/builtins/porffor.d.ts +23 -0
- package/compiler/builtins.js +65 -192
- package/compiler/codeGen.js +206 -110
- package/compiler/generated_builtins.js +15 -0
- package/compiler/index.js +9 -20
- package/compiler/log.js +4 -1
- package/compiler/opt.js +39 -26
- package/compiler/parse.js +4 -2
- package/compiler/precompile.js +129 -0
- package/compiler/prefs.js +26 -0
- package/compiler/prototype.js +11 -10
- package/compiler/sections.js +7 -6
- package/compiler/wasmSpec.js +14 -7
- package/compiler/wrap.js +12 -4
- package/package.json +1 -1
- package/porf +2 -0
- package/rhemyn/compile.js +2 -1
- package/runner/index.js +12 -2
- package/runner/profiler.js +83 -0
- package/compiler/builtins/base64.js +0 -92
- package/filesize.cmd +0 -2
- package/runner/profile.js +0 -46
- package/runner/results.json +0 -1
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
|
+
};
|