porffor 0.37.30 → 0.37.32

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.
@@ -1733,7 +1733,7 @@ const aliasPrimObjsBC = bc => {
1733
1733
  const createThisArg = (scope, decl) => {
1734
1734
  const name = mapName(decl.callee?.name);
1735
1735
  if (decl._new) {
1736
- // if precompiling or builtin func, just make empty object
1736
+ // if precompiling or builtin func, just make it null as unused
1737
1737
  if (globalThis.precompile || Object.hasOwn(builtinFuncs, name)) return [
1738
1738
  ...number(NULL),
1739
1739
  ...number(TYPES.object, Valtype.i32)
@@ -1793,11 +1793,12 @@ const createThisArg = (scope, decl) => {
1793
1793
  ];
1794
1794
  }
1795
1795
 
1796
- // do not generate globalThis now,
1796
+ // undefined do not generate globalThis now,
1797
1797
  // do it dynamically in generateThis in the func later
1798
+ // (or not for strict mode)
1798
1799
  return [
1799
- ...number(NULL),
1800
- ...number(TYPES.object, Valtype.i32)
1800
+ ...number(UNDEFINED),
1801
+ ...number(TYPES.undefined, Valtype.i32)
1801
1802
  ];
1802
1803
  }
1803
1804
  };
@@ -2597,27 +2598,22 @@ const generateThis = (scope, decl) => {
2597
2598
  ];
2598
2599
  }
2599
2600
 
2600
- // opt: do not check for pure constructors
2601
- if (scope._onlyConstr || scope._onlyThisMethod || decl._noGlobalThis) return [
2601
+ // opt: do not check for pure constructors or strict mode
2602
+ if ((!globalThis.precompile && scope.strict) || scope._onlyConstr || scope._onlyThisMethod || decl._noGlobalThis) return [
2602
2603
  [ Opcodes.local_get, scope.locals['#this'].idx ],
2603
2604
  ...setLastType(scope, [ [ Opcodes.local_get, scope.locals['#this#type'].idx ] ])
2604
2605
  ];
2605
2606
 
2606
2607
  return [
2607
2608
  // default this to globalThis
2608
- [ Opcodes.local_get, scope.locals['#this'].idx ],
2609
- Opcodes.i32_to_u,
2610
- [ Opcodes.i32_eqz ],
2609
+ [ Opcodes.local_get, scope.locals['#this#type'].idx ],
2610
+ ...number(TYPES.undefined, Valtype.i32),
2611
+ [ Opcodes.i32_eq ],
2611
2612
  [ Opcodes.if, Blocktype.void ],
2612
- [ Opcodes.local_get, scope.locals['#this#type'].idx ],
2613
- ...number(TYPES.object, Valtype.i32),
2614
- [ Opcodes.i32_eq ],
2615
- [ Opcodes.if, Blocktype.void ],
2616
- ...generate(scope, { type: 'Identifier', name: 'globalThis' }),
2617
- [ Opcodes.local_set, scope.locals['#this'].idx ],
2618
- ...getType(scope, 'globalThis'),
2619
- [ Opcodes.local_set, scope.locals['#this#type'].idx ],
2620
- [ Opcodes.end ],
2613
+ ...generate(scope, { type: 'Identifier', name: 'globalThis' }),
2614
+ [ Opcodes.local_set, scope.locals['#this'].idx ],
2615
+ ...getType(scope, 'globalThis'),
2616
+ [ Opcodes.local_set, scope.locals['#this#type'].idx ],
2621
2617
  [ Opcodes.end ],
2622
2618
 
2623
2619
  [ Opcodes.local_get, scope.locals['#this'].idx ],
@@ -4707,7 +4703,7 @@ const generateLabel = (scope, decl) => {
4707
4703
  const generateThrow = (scope, decl) => {
4708
4704
  scope.throws = true;
4709
4705
 
4710
- const exceptionMode = Prefs.exceptionMode ?? 'lut';
4706
+ const exceptionMode = Prefs.exceptionMode ?? 'stack';
4711
4707
  if (exceptionMode === 'lut') {
4712
4708
  let message = decl.argument.value, constructor = null;
4713
4709
 
package/compiler/index.js CHANGED
@@ -52,7 +52,9 @@ const progressClear = () => {
52
52
  progressLines = 0;
53
53
  };
54
54
 
55
- export default (code, flags) => {
55
+ export default (code, module = undefined) => {
56
+ if (module !== undefined) Prefs.module = module;
57
+
56
58
  const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
57
59
 
58
60
  let target = Prefs.target ?? 'wasm';
@@ -82,7 +84,7 @@ export default (code, flags) => {
82
84
 
83
85
  if (logProgress) progressStart('parsing...');
84
86
  const t0 = performance.now();
85
- const program = parse(code, flags);
87
+ const program = parse(code);
86
88
  if (logProgress) progressDone('parsed', t0);
87
89
 
88
90
  if (logProgress) progressStart('generating wasm...');
@@ -98,7 +100,7 @@ export default (code, flags) => {
98
100
 
99
101
  if (Prefs.pgo) {
100
102
  if (Prefs.pgoLog) {
101
- const oldSize = assemble(funcs, globals, tags, pages, data, flags, true).byteLength;
103
+ const oldSize = assemble(funcs, globals, tags, pages, data, true).byteLength;
102
104
  const t = performance.now();
103
105
 
104
106
  pgo.run({ funcs, globals, tags, exceptions, pages, data });
@@ -106,7 +108,7 @@ export default (code, flags) => {
106
108
 
107
109
  console.log(`PGO total time: ${(performance.now() - t).toFixed(2)}ms`);
108
110
 
109
- const newSize = assemble(funcs, globals, tags, pages, data, flags, true).byteLength;
111
+ const newSize = assemble(funcs, globals, tags, pages, data, true).byteLength;
110
112
  console.log(`PGO size diff: ${oldSize - newSize} bytes (${oldSize} -> ${newSize})\n`);
111
113
  } else {
112
114
  pgo.run({ funcs, globals, tags, exceptions, pages, data });
@@ -116,7 +118,7 @@ export default (code, flags) => {
116
118
 
117
119
  if (Prefs.cyclone) {
118
120
  if (Prefs.cycloneLog) {
119
- const oldSize = assemble(funcs, globals, tags, pages, data, flags, true).byteLength;
121
+ const oldSize = assemble(funcs, globals, tags, pages, data, true).byteLength;
120
122
  const t = performance.now();
121
123
 
122
124
  for (const x of funcs) {
@@ -129,7 +131,7 @@ export default (code, flags) => {
129
131
 
130
132
  console.log(`cyclone total time: ${(performance.now() - t).toFixed(2)}ms`);
131
133
 
132
- const newSize = assemble(funcs, globals, tags, pages, data, flags, true).byteLength;
134
+ const newSize = assemble(funcs, globals, tags, pages, data, true).byteLength;
133
135
  console.log(`cyclone size diff: ${oldSize - newSize} bytes (${oldSize} -> ${newSize})\n`);
134
136
  } else {
135
137
  for (const x of funcs) {
@@ -171,7 +173,7 @@ export default (code, flags) => {
171
173
  const out = { funcs, globals, tags, exceptions, pages, data, times: [ t0, t1, t2, t3 ] };
172
174
  if (globalThis.precompile) return out;
173
175
 
174
- const wasm = out.wasm = assemble(funcs, globals, tags, pages, data, flags);
176
+ const wasm = out.wasm = assemble(funcs, globals, tags, pages, data);
175
177
  if (logProgress) progressDone('assembled', t3);
176
178
 
177
179
  if (Prefs.optFuncs || Prefs.f) logFuncs(funcs, globals, exceptions);
package/compiler/parse.js CHANGED
@@ -25,7 +25,7 @@ await loadParser(types ? '@babel/parser' : undefined);
25
25
 
26
26
  if (types && !['@babel/parser', 'hermes-parser'].includes(parser)) log.warning('parse', `passed -parse-types with a parser (${parser}) which does not support`);
27
27
 
28
- export default (input, flags) => {
28
+ export default input => {
29
29
  try {
30
30
  const ast = parse(input, {
31
31
  // acorn
@@ -33,14 +33,14 @@ export default (input, flags) => {
33
33
 
34
34
  // meriyah
35
35
  next: true,
36
- module: flags.includes('module'),
36
+ module: Prefs.module,
37
37
  webcompat: true,
38
38
 
39
39
  // babel
40
- plugins: types || flags.includes('typed') ? ['estree', 'typescript'] : ['estree'],
40
+ plugins: types ? ['estree', 'typescript'] : ['estree'],
41
41
 
42
42
  // multiple
43
- sourceType: flags.includes('module') ? 'module' : 'script',
43
+ sourceType: Prefs.module ? 'module' : 'script',
44
44
  ranges: false,
45
45
  tokens: false,
46
46
  comments: false,
package/compiler/pgo.js CHANGED
@@ -81,12 +81,12 @@ export const run = obj => {
81
81
 
82
82
  let activeFunc = null, abort = false;
83
83
  try {
84
- obj.wasm = assemble(obj.funcs, obj.globals, obj.tags, obj.pages, obj.data, obj.flags, true);
84
+ obj.wasm = assemble(obj.funcs, obj.globals, obj.tags, obj.pages, obj.data, true);
85
85
 
86
86
  Prefs._profileCompiler = Prefs.profileCompiler;
87
87
  Prefs.profileCompiler = false;
88
88
 
89
- const { exports } = wrap(obj, [], {
89
+ const { exports } = wrap(obj, undefined, {
90
90
  y: n => {
91
91
  activeFunc = n;
92
92
  },
@@ -25,7 +25,7 @@ const compile = async (file, _funcs) => {
25
25
  first = source.slice(0, source.indexOf('\n'));
26
26
  }
27
27
 
28
- let args = ['--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--exception-mode=lut'];
28
+ let args = ['--module', '--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--scoped-page-names', '--funsafe-no-unlikely-proto-checks', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--exception-mode=lut'];
29
29
  if (first.startsWith('// @porf')) {
30
30
  args = first.slice('// @porf '.length).split(' ').concat(args);
31
31
  }
@@ -34,7 +34,7 @@ const compile = async (file, _funcs) => {
34
34
 
35
35
  const porfCompile = (await import(`./index.js?_=${Date.now()}`)).default;
36
36
 
37
- let { funcs, globals, data, exceptions, times } = porfCompile(source, ['module', 'typed']);
37
+ let { funcs, globals, data, exceptions, times } = porfCompile(source);
38
38
 
39
39
  timing.parse ??= 0;
40
40
  timing.parse += times[1] - times[0];
package/compiler/wrap.js CHANGED
@@ -325,16 +325,14 @@ ${flags & 0b0001 ? ` get func idx: ${get}
325
325
  }
326
326
  };
327
327
 
328
- export default (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
328
+ export default (source, module = undefined, customImports = {}, print = str => process.stdout.write(str)) => {
329
329
  const times = [];
330
330
 
331
331
  const t1 = performance.now();
332
- const { wasm, funcs, globals, tags, exceptions, pages, c } = typeof source === 'object' ? source : compile(source, flags);
332
+ const { wasm, funcs, globals, tags, exceptions, pages, c } = typeof source === 'object' ? source : compile(source, module);
333
333
 
334
334
  globalThis.porfDebugInfo = { funcs, globals };
335
335
 
336
- // if (process.argv[1].includes('/runner') && source.includes?.('export ')) flags.push('module');
337
-
338
336
  // fs.writeFileSync('out.wasm', Buffer.from(wasm));
339
337
 
340
338
  times.push(performance.now() - t1);
@@ -504,7 +502,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
504
502
  return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
505
503
  } catch (e) {
506
504
  if (e.is && e.is(exceptTag)) {
507
- const exceptionMode = Prefs.exceptionMode ?? 'lut';
505
+ const exceptionMode = Prefs.exceptionMode ?? 'stack';
508
506
  if (exceptionMode === 'lut') {
509
507
  const exceptId = e.getArg(exceptTag, 0);
510
508
  const exception = exceptions[exceptId];
@@ -541,7 +539,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
541
539
  };
542
540
  }
543
541
 
544
- if (flags.includes('decomp')) {
542
+ if (Prefs.decomp) {
545
543
  return { exports, wasm, times, decomps: funcs.map(x => decompile(x.wasm, x.name, x.index, x.locals, x.params, x.returns, funcs, globals, exceptions)), c };
546
544
  }
547
545
 
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.37.30+d663c99a2",
4
+ "version": "0.37.32+fde2c20c4",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/rhemyn/compile.js CHANGED
@@ -12,15 +12,17 @@ const Length = 4;
12
12
  const Tmp = 5;
13
13
  const QuantifierTmp = 6; // the temporary variable used for quanitifers
14
14
 
15
- const doesSucceedZero = (node) => {
15
+ const doesSucceedZero = node => {
16
16
  for (const n of node.body) {
17
- if (n.type === "Group") {
18
- if (!doesSucceedZero(node)) return false;
17
+ if (n.type === 'Group') {
18
+ if (!doesSucceedZero(n)) return false;
19
19
  }
20
+
20
21
  if (!n.quantifier || n.quantifier[0] > 0) {
21
22
  return false;
22
23
  }
23
24
  }
25
+
24
26
  return true;
25
27
  }
26
28
 
package/runner/debug.js CHANGED
@@ -43,7 +43,7 @@ let lastLine;
43
43
  let output = '';
44
44
 
45
45
  try {
46
- const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
46
+ const { exports } = compile(source, undefined, {
47
47
  y: n => {
48
48
  if (callStarts[callStarts.length - 1] === n - 1) {
49
49
  // end of call
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.37.30+d663c99a2';
3
+ globalThis.version = '0.37.32+fde2c20c4';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
@@ -158,7 +158,7 @@ const compile = (await import('../compiler/wrap.js')).default;
158
158
  let runStart;
159
159
  let ret;
160
160
  try {
161
- const out = compile(source, process.argv.includes('--module') ? [ 'module' ] : []);
161
+ const out = compile(source);
162
162
  runStart = performance.now();
163
163
  if (!process.argv.includes('--no-run')) ret = out.exports.main();
164
164
 
package/runner/profile.js CHANGED
@@ -20,7 +20,7 @@ let spin = 0;
20
20
  let last = 0;
21
21
 
22
22
  try {
23
- const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
23
+ const { exports } = compile(source, undefined, {
24
24
  y: n => {
25
25
  tmp[n] = performance.now();
26
26
  },
package/runner/repl.js CHANGED
@@ -89,7 +89,7 @@ const run = (source, _context, _filename, callback, run = true) => {
89
89
 
90
90
  let shouldPrint = !prev;
91
91
  try {
92
- const { exports, pages } = compile(toRun, process.argv.includes('--module') ? [ 'module' ] : [], {}, str => {
92
+ const { exports, pages } = compile(toRun, undefined, {}, str => {
93
93
  if (shouldPrint) process.stdout.write(str);
94
94
  if (str === '-4919') shouldPrint = true;
95
95
  });
package/runner/compare.js DELETED
@@ -1,34 +0,0 @@
1
- import { execSync } from 'node:child_process';
2
- import fs from 'node:fs';
3
-
4
- const [ commitsAgo, file ] = process.argv.slice(2);
5
- const source = fs.readFileSync(file, 'utf8');
6
-
7
- const compileNow = (await import('../compiler/index.js')).default;
8
- const wasmNow = compileNow(source).byteLength;
9
-
10
- execSync(`git checkout HEAD~${commitsAgo}`);
11
-
12
- let failed = false;
13
-
14
- fs.writeFileSync('tmp.js', source);
15
- try {
16
- execSync(`node runner/index.js tmp.js`);
17
- } catch {
18
- failed = true;
19
- } finally {
20
- fs.rmSync('tmp.js');
21
- execSync(`git checkout main`);
22
- }
23
-
24
- console.log();
25
-
26
- if (failed) {
27
- console.log(`!! failed to compile then`);
28
- process.exit();
29
- }
30
-
31
- const wasmThen = Buffer.byteLength(fs.readFileSync('out.wasm'));
32
-
33
- console.log(`now: ${wasmNow} bytes`);
34
- console.log(`${commitsAgo} commit${commitsAgo > 1 ? 's' : ''} ago: ${wasmThen} bytes`);
package/runner/sizes.js DELETED
@@ -1,38 +0,0 @@
1
- import compile from '../compiler/index.js';
2
- import fs from 'node:fs';
3
-
4
- // deno compat
5
- const textEncoder = new TextEncoder();
6
- if (typeof process === 'undefined') globalThis.process = { argv: ['', '', ...Deno.args], stdout: { write: str => Deno.writeAllSync(Deno.stdout, textEncoder.encode(str)) } };
7
-
8
- let csv = `file,porffor i32 -O0,porffor i32 -O1,porffor i32 -O2,porffor i32 -O3,porffor i64 -O0,porffor i64 -O1,porffor i64 -O2,porffor i64 -O3,porffor f64 -O0, porffor f64 -O1, porffor f64 -O2, porffor f64 -O3\n`;
9
- const perform = async (file, args) => {
10
- process.argv = process.argv.slice(0, 2).concat(args);
11
- const source = fs.readFileSync(file, 'utf8');
12
-
13
- const { wasm } = compile(source, []);
14
- const size = wasm.byteLength;
15
-
16
- const label = `${file} ${args.join(' ')}`;
17
- csv += `${size},`;
18
- console.log(label, ' '.repeat(40 - label.length), `${size}b`);
19
- };
20
-
21
- const argsValtypes = [ '--valtype=i32', '--valtype=f64' ];
22
- const argsOptlevels = [ '-O0', '-O1', '-O2', '-O3' ];
23
-
24
- for (const file of [ 'bench/prime_basic.js', 'bench/fib_iter.js', 'test/math_1.js', 'test/math_3.js', 'test/while_1.js', 'test/for_2.js', 'test/unary_3.js', 'test/updateexp_1.js', 'test/eq_3.js', 'test/empty.js' ]) {
25
- const niceFile = file.split('/')[1].slice(0, -3);
26
- csv += `${niceFile},`;
27
-
28
- for (const x of argsValtypes) {
29
- for (const y of argsOptlevels) {
30
- await perform(file, [ x, y ]);
31
- }
32
- }
33
-
34
- csv = csv.slice(0, -1) + '\n';
35
- }
36
-
37
- fs.writeFileSync('sizes.csv', csv);
38
- console.log(csv);