porffor 0.2.0-15592d6 → 0.2.0-181627c

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.
@@ -1,3 +1,5 @@
1
+ import { Opcodes } from './wasmSpec.js';
2
+
1
3
  import fs from 'node:fs';
2
4
  import { join } from 'node:path';
3
5
 
@@ -20,11 +22,6 @@ const compile = async (file, [ _funcs, _globals ]) => {
20
22
  }
21
23
  process.argv = argv.concat(args);
22
24
 
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
25
  // const porfParse = (await import(`./parse.js?_=${Date.now()}`)).default;
29
26
  // const porfCodegen = (await import(`./codeGen.js?_=${Date.now()}`)).default;
30
27
 
@@ -34,17 +31,29 @@ const compile = async (file, [ _funcs, _globals ]) => {
34
31
 
35
32
  let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
36
33
 
37
- funcs = funcs.filter(x => x.export);
38
- for (const x of funcs) {
34
+ const exports = funcs.filter(x => x.export);
35
+ for (const x of exports) {
39
36
  if (x.data) x.data = x.data.map(x => data[x]);
40
37
  if (x.exceptions) x.exceptions = x.exceptions.map(x => {
41
38
  const obj = exceptions[x];
42
39
  if (obj) obj.exceptId = x;
43
40
  return obj;
44
41
  }).filter(x => x);
42
+
43
+ for (const y of x.wasm) {
44
+ if (y[0] === Opcodes.call) {
45
+ const f = funcs.find(x => x.index === y[1]);
46
+ if (!f) continue;
47
+
48
+ if (!f.internal) throw 'todo';
49
+
50
+ x.used ??= [];
51
+ x.used.push(f.name);
52
+ }
53
+ }
45
54
  }
46
55
 
47
- _funcs.push(...funcs);
56
+ _funcs.push(...exports);
48
57
  _globals.push(...Object.values(globals));
49
58
  };
50
59
 
@@ -59,7 +68,7 @@ const precompile = async () => {
59
68
 
60
69
  // todo: globals, exceptions, pages per func
61
70
 
62
- return `// autogenerated by precompile.js
71
+ return `// autogenerated by compiler/precompile.js
63
72
 
64
73
  export const BuiltinFuncs = function() {
65
74
  ${funcs.map(x => ` this.${x.name} = {
@@ -72,6 +81,7 @@ ${funcs.map(x => ` this.${x.name} = {
72
81
  ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
73
82
  ${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)},` : ''}
74
83
  ${x.exceptions && x.exceptions.length > 0 ? ` exceptions: ${JSON.stringify(x.exceptions)},` : ''}
84
+ ${x.used && x.used.length > 0 ? ` used: ${JSON.stringify(x.used)},` : ''}
75
85
  };`.replaceAll('\n\n', '\n')).join('\n')}
76
86
  }`;
77
87
  };
@@ -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] = {
@@ -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
@@ -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,
@@ -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-15592d6",
4
+ "version": "0.2.0-181627c",
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);