porffor 0.2.0-cb647c8 → 0.2.0-dcc06c8

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
@@ -2,6 +2,7 @@ import { Opcodes, Valtype } from "./wasmSpec.js";
2
2
  import { number } from "./embedding.js";
3
3
  import { read_signedLEB128, read_ieee754_binary64 } from "./encoding.js";
4
4
  import { log } from "./log.js";
5
+ import Prefs from './prefs.js';
5
6
 
6
7
  const performWasmOp = (op, a, b) => {
7
8
  switch (op) {
@@ -11,21 +12,21 @@ const performWasmOp = (op, a, b) => {
11
12
  }
12
13
  };
13
14
 
14
- export default (funcs, globals, pages, tags) => {
15
+ export default (funcs, globals, pages, tags, exceptions) => {
15
16
  const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
16
17
  if (optLevel === 0) return;
17
18
 
18
- const tailCall = process.argv.includes('-tail-call');
19
+ const tailCall = Prefs.tailCall;
19
20
  if (tailCall) log.warning('opt', 'tail call proposal is not widely implemented! (you used -tail-call)');
20
21
 
21
- if (optLevel >= 2 && !process.argv.includes('-opt-no-inline')) {
22
+ if (optLevel >= 2 && !Prefs.optNoInline) {
22
23
  // inline pass (very WIP)
23
24
  // get candidates for inlining
24
25
  // todo: pick smart in future (if func is used <N times? or?)
25
26
  const callsSelf = f => f.wasm.some(x => x[0] === Opcodes.call && x[1] === f.index);
26
27
  const suitableReturns = wasm => wasm.reduce((acc, x) => acc + (x[0] === Opcodes.return), 0) <= 1;
27
28
  const candidates = funcs.filter(x => x.name !== 'main' && Object.keys(x.locals).length === x.params.length && (x.returns.length === 0 || suitableReturns(x.wasm)) && !callsSelf(x) && !x.throws).reverse();
28
- if (optLog) {
29
+ if (Prefs.optLog) {
29
30
  log('opt', `found inline candidates: ${candidates.map(x => x.name).join(', ')} (${candidates.length}/${funcs.length - 1})`);
30
31
 
31
32
  let reasons = {};
@@ -53,7 +54,7 @@ export default (funcs, globals, pages, tags) => {
53
54
  for (let i = 0; i < tWasm.length; i++) {
54
55
  const inst = tWasm[i];
55
56
  if (inst[0] === Opcodes.call && inst[1] === c.index) {
56
- if (optLog) log('opt', `inlining call for ${c.name} (in ${t.name})`);
57
+ if (Prefs.optLog) log('opt', `inlining call for ${c.name} (in ${t.name})`);
57
58
  tWasm.splice(i, 1); // remove this call
58
59
 
59
60
  // add params as locals and set in reverse order
@@ -80,7 +81,7 @@ export default (funcs, globals, pages, tags) => {
80
81
  // adjust local operands to go to correct param index
81
82
  for (const inst of iWasm) {
82
83
  if ((inst[0] === Opcodes.local_get || inst[0] === Opcodes.local_set) && inst[1] < c.params.length) {
83
- if (optLog) log('opt', `replacing local operand in inlined wasm (${inst[1]} -> ${paramIdx[inst[1]]})`);
84
+ if (Prefs.optLog) log('opt', `replacing local operand in inlined wasm (${inst[1]} -> ${paramIdx[inst[1]]})`);
84
85
  inst[1] = paramIdx[inst[1]];
85
86
  }
86
87
  }
@@ -97,9 +98,10 @@ export default (funcs, globals, pages, tags) => {
97
98
  }
98
99
  }
99
100
 
100
- if (process.argv.includes('-opt-inline-only')) return;
101
+ if (Prefs.optInlineOnly) return;
101
102
 
102
103
  const tagUse = tags.reduce((acc, x) => { acc[x.idx] = 0; return acc; }, {});
104
+ const exceptionUse = exceptions.reduce((acc, _, i) => { acc[i] = 0; return acc; }, {});
103
105
 
104
106
  // wasm transform pass
105
107
  for (const f of funcs) {
@@ -129,7 +131,12 @@ export default (funcs, globals, pages, tags) => {
129
131
  if (inst[0] === Opcodes.local_get) getCount[inst[1]]++;
130
132
  if (inst[0] === Opcodes.local_set || inst[0] === Opcodes.local_tee) setCount[inst[1]]++;
131
133
 
132
- if (inst[0] === Opcodes.throw) tagUse[inst[1]]++;
134
+ if (inst[0] === Opcodes.throw) {
135
+ tagUse[inst[1]]++;
136
+
137
+ const exceptId = read_signedLEB128(wasm[i - 1].slice(1));
138
+ exceptionUse[exceptId]++;
139
+ }
133
140
 
134
141
  if (inst[0] === Opcodes.block) {
135
142
  // remove unneeded blocks (no brs inside)
@@ -160,7 +167,7 @@ export default (funcs, globals, pages, tags) => {
160
167
 
161
168
  wasm.splice(j - 1, 1); // remove end of this block
162
169
 
163
- if (optLog) log('opt', `removed unneeded block in for loop`);
170
+ if (Prefs.optLog) log('opt', `removed unneeded block in for loop`);
164
171
  }
165
172
  }
166
173
 
@@ -209,7 +216,7 @@ export default (funcs, globals, pages, tags) => {
209
216
  i -= 4;
210
217
  inst = wasm[i];
211
218
 
212
- if (optLog) log('opt', `removed unneeded typeswitch check`);
219
+ if (Prefs.optLog) log('opt', `removed unneeded typeswitch check`);
213
220
  }
214
221
  }
215
222
 
@@ -232,7 +239,7 @@ export default (funcs, globals, pages, tags) => {
232
239
  wasm.splice(j - 1, 2, [ Opcodes.drop ]); // remove typeswitch start
233
240
  wasm.splice(i - 1, 1); // remove this inst
234
241
 
235
- if (optLog) log('opt', 'removed unneeded entire typeswitch');
242
+ if (Prefs.optLog) log('opt', 'removed unneeded entire typeswitch');
236
243
 
237
244
  if (i > 0) i--;
238
245
  continue;
@@ -261,7 +268,7 @@ export default (funcs, globals, pages, tags) => {
261
268
 
262
269
  getCount[inst[1]]--;
263
270
  i--;
264
- // if (optLog) log('opt', `consolidated set, get -> tee`);
271
+ // if (Prefs.optLog) log('opt', `consolidated set, get -> tee`);
265
272
  continue;
266
273
  }
267
274
 
@@ -329,7 +336,7 @@ export default (funcs, globals, pages, tags) => {
329
336
 
330
337
  wasm.splice(i - 1, 2); // remove this inst and last
331
338
  i -= 2;
332
- // if (optLog) log('opt', `removed redundant i32 -> i64 -> i32 conversion ops`);
339
+ // if (Prefs.optLog) log('opt', `removed redundant i32 -> i64 -> i32 conversion ops`);
333
340
  continue;
334
341
  }
335
342
 
@@ -342,7 +349,7 @@ export default (funcs, globals, pages, tags) => {
342
349
 
343
350
  wasm.splice(i - 1, 2); // remove this inst and last
344
351
  i -= 2;
345
- // if (optLog) log('opt', `removed redundant i32 -> f64 -> i32 conversion ops`);
352
+ // if (Prefs.optLog) log('opt', `removed redundant i32 -> f64 -> i32 conversion ops`);
346
353
  continue;
347
354
  }
348
355
 
@@ -357,7 +364,7 @@ export default (funcs, globals, pages, tags) => {
357
364
 
358
365
  wasm.splice(i, 1); // remove this inst
359
366
  i--;
360
- if (optLog) log('opt', `converted const -> i32 convert into i32 const`);
367
+ if (Prefs.optLog) log('opt', `converted const -> i32 convert into i32 const`);
361
368
  continue;
362
369
  }
363
370
 
@@ -372,7 +379,7 @@ export default (funcs, globals, pages, tags) => {
372
379
 
373
380
  wasm.splice(i, 1); // remove this inst
374
381
  i--;
375
- if (optLog) log('opt', `converted i32 const -> convert into const`);
382
+ if (Prefs.optLog) log('opt', `converted i32 const -> convert into const`);
376
383
  continue;
377
384
  }
378
385
 
@@ -387,7 +394,7 @@ export default (funcs, globals, pages, tags) => {
387
394
 
388
395
  wasm.splice(i, 1); // remove this inst (return)
389
396
  i--;
390
- if (optLog) log('opt', `tail called return, call`);
397
+ if (Prefs.optLog) log('opt', `tail called return, call`);
391
398
  continue;
392
399
  }
393
400
 
@@ -400,7 +407,7 @@ export default (funcs, globals, pages, tags) => {
400
407
 
401
408
  wasm.splice(i, 1); // remove this inst (return)
402
409
  i--;
403
- // if (optLog) log('opt', `removed redundant return at end`);
410
+ // if (Prefs.optLog) log('opt', `removed redundant return at end`);
404
411
  continue;
405
412
  }
406
413
 
@@ -430,7 +437,7 @@ export default (funcs, globals, pages, tags) => {
430
437
  // <nothing>
431
438
 
432
439
  wasm.splice(i - 2, 3); // remove this, last, 2nd last insts
433
- if (optLog) log('opt', `removed redundant inline param local handling`);
440
+ if (Prefs.optLog) log('opt', `removed redundant inline param local handling`);
434
441
  i -= 3;
435
442
  continue;
436
443
  }
@@ -438,12 +445,12 @@ export default (funcs, globals, pages, tags) => {
438
445
 
439
446
  if (optLevel < 2) continue;
440
447
 
441
- if (optLog) log('opt', `get counts: ${Object.keys(f.locals).map(x => `${x} (${f.locals[x].idx}): ${getCount[f.locals[x].idx]}`).join(', ')}`);
448
+ if (Prefs.optLog) log('opt', `get counts: ${Object.keys(f.locals).map(x => `${x} (${f.locals[x].idx}): ${getCount[f.locals[x].idx]}`).join(', ')}`);
442
449
 
443
450
  // remove unneeded var: remove pass
444
451
  // 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
445
452
  let unneededCandidates = Object.keys(getCount).filter(x => getCount[x] === 0 || (getCount[x] === 1 && setCount[x] === 0)).map(x => parseInt(x));
446
- if (optLog) log('opt', `found unneeded locals candidates: ${unneededCandidates.join(', ')} (${unneededCandidates.length}/${Object.keys(getCount).length})`);
453
+ if (Prefs.optLog) log('opt', `found unneeded locals candidates: ${unneededCandidates.join(', ')} (${unneededCandidates.length}/${Object.keys(getCount).length})`);
447
454
 
448
455
  // note: disabled for now due to instability
449
456
  if (unneededCandidates.length > 0 && false) for (let i = 0; i < wasm.length; i++) {
@@ -461,7 +468,7 @@ export default (funcs, globals, pages, tags) => {
461
468
  wasm.splice(i - 1, 2); // remove insts
462
469
  i -= 2;
463
470
  delete f.locals[Object.keys(f.locals)[inst[1]]]; // remove from locals
464
- if (optLog) log('opt', `removed redundant local (get set ${inst[1]})`);
471
+ if (Prefs.optLog) log('opt', `removed redundant local (get set ${inst[1]})`);
465
472
  }
466
473
 
467
474
  if (inst[0] === Opcodes.local_tee && unneededCandidates.includes(inst[1])) {
@@ -489,7 +496,7 @@ export default (funcs, globals, pages, tags) => {
489
496
  unneededCandidates.splice(unneededCandidates.indexOf(inst[1]), 1);
490
497
  unneededCandidates = unneededCandidates.map(x => x > removedIdx ? (x - 1) : x);
491
498
 
492
- if (optLog) log('opt', `removed redundant local ${localName} (tee ${inst[1]})`);
499
+ if (Prefs.optLog) log('opt', `removed redundant local ${localName} (tee ${inst[1]})`);
493
500
  }
494
501
  }
495
502
 
@@ -525,7 +532,7 @@ export default (funcs, globals, pages, tags) => {
525
532
  let b = lastInst[1];
526
533
 
527
534
  const val = performWasmOp(inst[0], a, b);
528
- if (optLog) log('opt', `inlined math op (${a} ${inst[0].toString(16)} ${b} -> ${val})`);
535
+ if (Prefs.optLog) log('opt', `inlined math op (${a} ${inst[0].toString(16)} ${b} -> ${val})`);
529
536
 
530
537
  wasm.splice(i - 2, 3, ...number(val)); // remove consts, math op and add new const
531
538
  i -= 2;
@@ -537,12 +544,12 @@ export default (funcs, globals, pages, tags) => {
537
544
  for (const x in useCount) {
538
545
  if (useCount[x] === 0) {
539
546
  const name = Object.keys(f.locals)[localIdxs.indexOf(parseInt(x))];
540
- if (optLog) log('opt', `removed internal local ${x} (${name})`);
547
+ if (Prefs.optLog) log('opt', `removed internal local ${x} (${name})`);
541
548
  delete f.locals[name];
542
549
  }
543
550
  }
544
551
 
545
- if (optLog) log('opt', `final use counts: ${Object.keys(f.locals).map(x => `${x} (${f.locals[x].idx}): ${useCount[f.locals[x].idx]}`).join(', ')}`);
552
+ 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(', ')}`);
546
553
  }
547
554
  }
548
555
 
@@ -553,5 +560,11 @@ export default (funcs, globals, pages, tags) => {
553
560
  }
554
561
  }
555
562
 
563
+ for (const x of Object.keys(exceptionUse).sort((a, b) => b - a)) {
564
+ if (exceptionUse[x] === 0) {
565
+ exceptions.splice(+x, 1);
566
+ }
567
+ }
568
+
556
569
  // return funcs;
557
570
  };
package/compiler/parse.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { log } from "./log.js";
2
+ import Prefs from './prefs.js';
3
+
2
4
  // import { parse } from 'acorn';
3
5
 
4
6
  // deno compat
@@ -8,8 +10,8 @@ if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
8
10
  }
9
11
 
10
12
  // should we try to support types (while parsing)
11
- const types = process.argv.includes('-parse-types');
12
- globalThis.typedInput = types && process.argv.includes('-opt-types');
13
+ const types = Prefs.parseTypes;
14
+ globalThis.typedInput = types && Prefs.optTypes;
13
15
 
14
16
  // todo: review which to use by default
15
17
  // supported parsers:
@@ -0,0 +1,79 @@
1
+ import fs from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
6
+
7
+ // import porfParse from './parse.js';
8
+ // import porfCodegen from './codeGen.js';
9
+
10
+ const argv = process.argv.slice();
11
+
12
+ const compile = async (file, [ _funcs, _globals ]) => {
13
+ const source = fs.readFileSync(file, 'utf8');
14
+ const first = source.slice(0, source.indexOf('\n'));
15
+
16
+ let args = ['-bytestring'];
17
+ if (file.endsWith('.ts')) args.push('-parse-types', '-opt-types');
18
+ if (first.startsWith('// @porf')) {
19
+ args = args.concat(first.slice('// @porf '.length).split(' '));
20
+ }
21
+ process.argv = argv.concat(args);
22
+
23
+ // globalThis.optLog = process.argv.includes('-opt-log');
24
+ // globalThis.codeLog = process.argv.includes('-code-log');
25
+ // globalThis.allocLog = process.argv.includes('-alloc-log');
26
+ // globalThis.regexLog = process.argv.includes('-regex-log');
27
+
28
+ // const porfParse = (await import(`./parse.js?_=${Date.now()}`)).default;
29
+ // const porfCodegen = (await import(`./codeGen.js?_=${Date.now()}`)).default;
30
+
31
+ // let { funcs, globals, data } = porfCodegen(porfParse(source, ['module']));
32
+
33
+ const porfCompile = (await import(`./index.js?_=${Date.now()}`)).default;
34
+
35
+ let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
36
+
37
+ funcs = funcs.filter(x => x.export);
38
+ for (const x of funcs) {
39
+ if (x.data) x.data = x.data.map(x => data[x]);
40
+ if (x.exceptions) x.exceptions = x.exceptions.map(x => {
41
+ const obj = exceptions[x];
42
+ if (obj) obj.exceptId = x;
43
+ return obj;
44
+ }).filter(x => x);
45
+ }
46
+
47
+ _funcs.push(...funcs);
48
+ _globals.push(...Object.values(globals));
49
+ };
50
+
51
+ const precompile = async () => {
52
+ const dir = join(__dirname, 'builtins');
53
+
54
+ let funcs = [], globals = [];
55
+ for (const file of fs.readdirSync(dir)) {
56
+ if (file.endsWith('.d.ts')) continue;
57
+ await compile(join(dir, file), [ funcs, globals ]);
58
+ }
59
+
60
+ // todo: globals, exceptions, pages per func
61
+
62
+ return `// autogenerated by precompile.js
63
+
64
+ export const BuiltinFuncs = function() {
65
+ ${funcs.map(x => ` this.${x.name} = {
66
+ wasm: ${JSON.stringify(x.wasm)},
67
+ params: ${JSON.stringify(x.params)},
68
+ typedParams: true,
69
+ returns: ${JSON.stringify(x.returns)},
70
+ typedReturns: true,
71
+ locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length * 2).map(x => x.type))},
72
+ ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
73
+ ${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)},` : ''}
74
+ ${x.exceptions && x.exceptions.length > 0 ? ` exceptions: ${JSON.stringify(x.exceptions)},` : ''}
75
+ };`.replaceAll('\n\n', '\n')).join('\n')}
76
+ }`;
77
+ };
78
+
79
+ console.log(await precompile());
@@ -0,0 +1,22 @@
1
+ const cache = {};
2
+ const obj = new Proxy({}, {
3
+ get(_, p) {
4
+ // intentionally misses with undefined values cached
5
+ if (cache[p]) return cache[p];
6
+
7
+ return cache[p] = (() => {
8
+ // fooBar -> foo-bar
9
+ const name = p[0] === '_' ? p : p.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);
10
+ if (process.argv.includes('-' + name)) return true;
11
+
12
+ const valArg = process.argv.find(x => x.startsWith(`-${name}=`));
13
+ if (valArg) return valArg.slice(name.length + 2);
14
+
15
+ return undefined;
16
+ })();
17
+ }
18
+ });
19
+
20
+ obj.uncache = () => cache = {};
21
+
22
+ export default obj;
@@ -2,6 +2,7 @@ import { Opcodes, Blocktype, Valtype, ValtypeSize, PageSize } from "./wasmSpec.j
2
2
  import { number } from "./embedding.js";
3
3
  import { unsignedLEB128 } from "./encoding.js";
4
4
  import { UNDEFINED } from "./builtins.js";
5
+ import Prefs from './prefs.js';
5
6
 
6
7
  // todo: do not duplicate this
7
8
  const TYPES = {
@@ -23,9 +24,10 @@ const TYPES = {
23
24
  // todo: turn these into built-ins once arrays and these become less hacky
24
25
 
25
26
  export const PrototypeFuncs = function() {
26
- const noUnlikelyChecks = process.argv.includes('-funsafe-no-unlikely-proto-checks');
27
- let zeroChecks = process.argv.find(x => x.startsWith('-funsafe-zero-proto-checks='));
28
- if (zeroChecks) zeroChecks = zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
27
+ const noUnlikelyChecks = Prefs.funsafeNoUnlikelyProtoChecks;
28
+
29
+ let zeroChecks;
30
+ if (Prefs.zeroChecks) zeroChecks = Prefs.zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
29
31
  else zeroChecks = {};
30
32
 
31
33
  this[TYPES._array] = {
@@ -342,8 +344,8 @@ export const PrototypeFuncs = function() {
342
344
  ...number(0, Valtype.i32), // base 0 for store later
343
345
 
344
346
  ...wIndex,
345
-
346
347
  Opcodes.i32_to,
348
+
347
349
  ...number(ValtypeSize.i16, Valtype.i32),
348
350
  [ Opcodes.i32_mul ],
349
351
 
@@ -489,10 +491,10 @@ export const PrototypeFuncs = function() {
489
491
  this[TYPES.string].isWellFormed.local2 = Valtype.i32;
490
492
  this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
491
493
 
492
- if (process.argv.includes('-bytestring')) {
494
+ if (Prefs.bytestring) {
493
495
  this[TYPES._bytestring] = {
494
496
  at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
495
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
497
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
496
498
 
497
499
  return [
498
500
  // setup new/out array
@@ -548,7 +550,7 @@ export const PrototypeFuncs = function() {
548
550
 
549
551
  // todo: out of bounds properly
550
552
  charAt: (pointer, length, wIndex, _1, _2, arrayShell) => {
551
- const [ newOut, newPointer ] = arrayShell(1, 'i16');
553
+ const [ newOut, newPointer ] = arrayShell(1, 'i8');
552
554
 
553
555
  return [
554
556
  // setup new/out array
@@ -558,7 +560,6 @@ export const PrototypeFuncs = function() {
558
560
  ...number(0, Valtype.i32), // base 0 for store later
559
561
 
560
562
  ...wIndex,
561
-
562
563
  Opcodes.i32_to,
563
564
 
564
565
  ...pointer,
@@ -3,6 +3,7 @@ import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128 }
3
3
  import { number } from './embedding.js';
4
4
  import { importedFuncs } from './builtins.js';
5
5
  import { log } from "./log.js";
6
+ import Prefs from './prefs.js';
6
7
 
7
8
  const createSection = (type, data) => [
8
9
  type,
@@ -26,12 +27,12 @@ export default (funcs, globals, tags, pages, data, flags) => {
26
27
 
27
28
  const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
28
29
 
29
- const compileHints = process.argv.includes('-compile-hints');
30
+ const compileHints = Prefs.compileHints;
30
31
  if (compileHints) log.warning('sections', 'compile hints is V8 only w/ experimental arg! (you used -compile-hints)');
31
32
 
32
33
  const getType = (params, returns) => {
33
34
  const hash = `${params.join(',')}_${returns.join(',')}`;
34
- if (optLog) log('sections', `getType(${JSON.stringify(params)}, ${JSON.stringify(returns)}) -> ${hash} | cache: ${typeCache[hash]}`);
35
+ if (Prefs.optLog) log('sections', `getType(${JSON.stringify(params)}, ${JSON.stringify(returns)}) -> ${hash} | cache: ${typeCache[hash]}`);
35
36
  if (optLevel >= 1 && typeCache[hash] !== undefined) return typeCache[hash];
36
37
 
37
38
  const type = [ FuncType, ...encodeVector(params), ...encodeVector(returns) ];
@@ -79,7 +80,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
79
80
  }
80
81
  globalThis.importFuncs = importFuncs;
81
82
 
82
- if (optLog) log('sections', `treeshake: using ${importFuncs.length}/${importedFuncs.length} imports`);
83
+ if (Prefs.optLog) log('sections', `treeshake: using ${importFuncs.length}/${importedFuncs.length} imports`);
83
84
 
84
85
  const importSection = importFuncs.length === 0 ? [] : createSection(
85
86
  Section.import,
@@ -95,7 +96,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
95
96
  // https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
96
97
  const chSection = !compileHints ? [] : customSection(
97
98
  'compilationHints',
98
- // for now just do everything as optimise eager
99
+ // for now just do everything as optimize eager
99
100
  encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
100
101
  );
101
102
 
@@ -106,7 +107,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
106
107
 
107
108
  const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, x.index ]);
108
109
 
109
- if (process.argv.includes('-always-memory') && pages.size === 0) pages.set('-always-memory', 0);
110
+ if (Prefs.alwaysMemory && pages.size === 0) pages.set('-always-memory', 0);
110
111
  if (optLevel === 0) pages.set('O0 precaution', 0);
111
112
 
112
113
  const usesMemory = pages.size > 0;
@@ -169,7 +170,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
169
170
  unsignedLEB128(data.length)
170
171
  );
171
172
 
172
- if (process.argv.includes('-sections')) console.log({
173
+ if (Prefs.sections) console.log({
173
174
  typeSection: typeSection.map(x => x.toString(16)),
174
175
  importSection: importSection.map(x => x.toString(16)),
175
176
  funcSection: funcSection.map(x => x.toString(16)),
package/demo.js CHANGED
@@ -1,3 +1,3 @@
1
- foo();
1
+ // foo();
2
2
 
3
- // console.log('Hello, World!');
3
+ console.log('Hello, World!');
package/hello ADDED
Binary file
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.2.0-cb647c8",
4
+ "version": "0.2.0-dcc06c8",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "dependencies": {
package/rhemyn/compile.js CHANGED
@@ -2,6 +2,7 @@ import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from '../compiler/
2
2
  import { number } from '../compiler/embedding.js';
3
3
  import { signedLEB128, unsignedLEB128 } from '../compiler/encoding.js';
4
4
  import parse from './parse.js';
5
+ import Prefs from '../compiler/prefs.js';
5
6
 
6
7
  // local indexes
7
8
  const BasePointer = 0; // base string pointer
@@ -80,7 +81,7 @@ const generate = (node, negated = false, get = true, func = 'test') => {
80
81
  })[func], Valtype.i32)
81
82
  ];
82
83
 
83
- if (globalThis.regexLog) {
84
+ if (Prefs.regexLog) {
84
85
  const underline = x => `\u001b[4m\u001b[1m${x}\u001b[0m`;
85
86
  console.log(`\n${underline('ast')}`);
86
87
  console.log(node);