porffor 0.20.2 → 0.20.4

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/compiler/opt.js CHANGED
@@ -4,14 +4,6 @@ import { read_signedLEB128, read_ieee754_binary64 } from './encoding.js';
4
4
  import { log } from './log.js';
5
5
  import Prefs from './prefs.js';
6
6
 
7
- const performWasmOp = (op, a, b) => {
8
- switch (op) {
9
- case Opcodes.add: return a + b;
10
- case Opcodes.sub: return a - b;
11
- case Opcodes.mul: return a * b;
12
- }
13
- };
14
-
15
7
  export default (funcs, globals, pages, tags, exceptions) => {
16
8
  const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
17
9
  if (optLevel === 0) return;
@@ -114,21 +106,12 @@ export default (funcs, globals, pages, tags, exceptions) => {
114
106
  while (runs > 0) {
115
107
  runs--;
116
108
 
117
- let getCount = {}, setCount = {};
118
- for (const x in f.locals) {
119
- getCount[f.locals[x].idx] = 0;
120
- setCount[f.locals[x].idx] = 0;
121
- }
122
-
123
109
  // main pass
124
110
  for (let i = 0; i < wasm.length; i++) {
125
111
  let inst = wasm[i];
126
112
  inst = [ ...inst ];
127
113
  wasm[i] = inst;
128
114
 
129
- if (inst[0] === Opcodes.local_get) getCount[inst[1]]++;
130
- if (inst[0] === Opcodes.local_set || inst[0] === Opcodes.local_tee) setCount[inst[1]]++;
131
-
132
115
  // if (inst[0] === Opcodes.throw) {
133
116
  // tagUse[inst[1]]++;
134
117
 
@@ -267,7 +250,6 @@ export default (funcs, globals, pages, tags, exceptions) => {
267
250
  lastInst[0] = Opcodes.local_tee; // replace last inst opcode (set -> tee)
268
251
  wasm.splice(i, 1); // remove this inst (get)
269
252
 
270
- getCount[inst[1]]--;
271
253
  i--;
272
254
  // if (Prefs.optLog) log('opt', `consolidated set, get -> tee`);
273
255
  continue;
@@ -280,8 +262,6 @@ export default (funcs, globals, pages, tags, exceptions) => {
280
262
  // -->
281
263
  //
282
264
 
283
- getCount[lastInst[1]]--;
284
-
285
265
  wasm.splice(i - 1, 2); // remove this inst and last
286
266
  i -= 2;
287
267
  continue;
@@ -294,8 +274,6 @@ export default (funcs, globals, pages, tags, exceptions) => {
294
274
  // -->
295
275
  // local.set 0
296
276
 
297
- getCount[lastInst[1]]--;
298
-
299
277
  lastInst[0] = Opcodes.local_set; // change last op
300
278
 
301
279
  wasm.splice(i, 1); // remove this inst
@@ -427,78 +405,6 @@ export default (funcs, globals, pages, tags, exceptions) => {
427
405
  continue;
428
406
  }
429
407
  }
430
-
431
- if (optLevel < 2) continue;
432
-
433
- if (Prefs.optLog) log('opt', `get counts: ${Object.keys(f.locals).map(x => `${x} (${f.locals[x].idx}): ${getCount[f.locals[x].idx]}`).join(', ')}`);
434
-
435
- // remove unneeded var: remove pass
436
- // locals only got once. we don't need to worry about sets/else as these are only candidates and we will check for matching set + get insts in wasm
437
- let unneededCandidates = Object.keys(getCount).filter(x => getCount[x] === 0 || (getCount[x] === 1 && setCount[x] === 0)).map(x => parseInt(x));
438
- if (Prefs.optLog) log('opt', `found unneeded locals candidates: ${unneededCandidates.join(', ')} (${unneededCandidates.length}/${Object.keys(getCount).length})`);
439
-
440
- // note: disabled for now due to instability
441
- if (unneededCandidates.length > 0 && false) for (let i = 0; i < wasm.length; i++) {
442
- if (i < 1) continue;
443
-
444
- const inst = wasm[i];
445
- const lastInst = wasm[i - 1];
446
-
447
- if (lastInst[1] === inst[1] && lastInst[0] === Opcodes.local_set && inst[0] === Opcodes.local_get && unneededCandidates.includes(inst[1])) {
448
- // local.set N
449
- // local.get N
450
- // -->
451
- // <nothing>
452
-
453
- wasm.splice(i - 1, 2); // remove insts
454
- i -= 2;
455
- delete f.locals[Object.keys(f.locals)[inst[1]]]; // remove from locals
456
- if (Prefs.optLog) log('opt', `removed redundant local (get set ${inst[1]})`);
457
- }
458
-
459
- if (inst[0] === Opcodes.local_tee && unneededCandidates.includes(inst[1])) {
460
- // local.tee N
461
- // -->
462
- // <nothing>
463
-
464
- wasm.splice(i, 1); // remove inst
465
- i--;
466
-
467
- const localName = Object.keys(f.locals)[inst[1]];
468
- const removedIdx = f.locals[localName].idx;
469
- delete f.locals[localName]; // remove from locals
470
-
471
- // fix locals index for locals after
472
- for (const x in f.locals) {
473
- const local = f.locals[x];
474
- if (local.idx > removedIdx) local.idx--;
475
- }
476
-
477
- for (const inst of wasm) {
478
- if ((inst[0] === Opcodes.local_get || inst[0] === Opcodes.local_set || inst[0] === Opcodes.local_tee) && inst[1] > removedIdx) inst[1]--;
479
- }
480
-
481
- unneededCandidates.splice(unneededCandidates.indexOf(inst[1]), 1);
482
- unneededCandidates = unneededCandidates.map(x => x > removedIdx ? (x - 1) : x);
483
-
484
- if (Prefs.optLog) log('opt', `removed redundant local ${localName} (tee ${inst[1]})`);
485
- }
486
- }
487
-
488
- const useCount = {};
489
- for (const x in f.locals) useCount[f.locals[x].idx] = 0;
490
-
491
- const localIdxs = Object.values(f.locals).map(x => x.idx);
492
- // remove unused locals (cleanup)
493
- for (const x in useCount) {
494
- if (useCount[x] === 0) {
495
- const name = Object.keys(f.locals)[localIdxs.indexOf(parseInt(x))];
496
- if (Prefs.optLog) log('opt', `removed internal local ${x} (${name})`);
497
- delete f.locals[name];
498
- }
499
- }
500
-
501
- if (Prefs.optLog) log('opt', `final use counts: ${Object.keys(f.locals).map(x => `${x} (${f.locals[x].idx}): ${useCount[f.locals[x].idx]}`).join(', ')}`);
502
408
  }
503
409
  }
504
410
 
@@ -1,4 +1,5 @@
1
1
  import { Opcodes } from './wasmSpec.js';
2
+ import { read_unsignedLEB128 } from './encoding.js';
2
3
  import { TYPES } from './types.js';
3
4
 
4
5
  import process from 'node:process';
@@ -68,10 +69,11 @@ const compile = async (file, _funcs) => {
68
69
  const y = wasm[i];
69
70
  const n = wasm[i + 1];
70
71
  if (y[0] === Opcodes.call) {
71
- const f = funcs.find(x => x.index === y[1]);
72
+ const idx = read_unsignedLEB128(y.slice(1));
73
+ const f = funcs.find(x => x.index === idx);
72
74
  if (!f) continue;
73
75
 
74
- y[1] = f.name;
76
+ y.splice(1, 10, f.name);
75
77
  }
76
78
 
77
79
  if (y[0] === Opcodes.global_get || y[0] === Opcodes.global_set) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.20.2+fe061341a",
4
+ "version": "0.20.4+74ad00ced",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.20.2+fe061341a';
3
+ globalThis.version = '0.20.4+74ad00ced';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {