porffor 0.19.9 → 0.19.10

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.
@@ -11,7 +11,7 @@ globalThis.precompile = true;
11
11
 
12
12
  const argv = process.argv.slice();
13
13
 
14
- const compile = async (file, [ _funcs, _globals ]) => {
14
+ const compile = async (file, _funcs) => {
15
15
  let source = fs.readFileSync(file, 'utf8');
16
16
  let first = source.slice(0, source.indexOf('\n'));
17
17
 
@@ -32,6 +32,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
32
32
 
33
33
  const allocated = new Set();
34
34
 
35
+ const main = funcs.find(x => x.name === 'main');
35
36
  const exports = funcs.filter(x => x.export && x.name !== 'main');
36
37
  for (const x of exports) {
37
38
  if (x.data) {
@@ -54,41 +55,65 @@ const compile = async (file, [ _funcs, _globals ]) => {
54
55
  return acc;
55
56
  }, {});
56
57
 
57
- for (let i = 0; i < x.wasm.length; i++) {
58
- const y = x.wasm[i];
59
- const n = x.wasm[i + 1];
60
- if (y[0] === Opcodes.call) {
61
- const f = funcs.find(x => x.index === y[1]);
62
- if (!f) continue;
63
-
64
- y[1] = f.name;
65
- }
66
-
67
- if (y[0] === Opcodes.const && (n[0] === Opcodes.local_set || n[0] === Opcodes.local_tee)) {
68
- const l = locals[n[1]];
69
- if (!l) continue;
70
- if (![TYPES.string, TYPES.array, TYPES.bytestring].includes(l.metadata?.type)) continue;
71
- if (!x.pages) continue;
72
-
73
- const pageName = [...x.pages.keys()].find(z => z.endsWith(l.name));
74
- if (!pageName || allocated.has(pageName)) continue;
75
- allocated.add(pageName);
76
-
77
- y.splice(0, 10, 'alloc', pageName, x.pages.get(pageName).type, valtypeBinary);
58
+ const rewriteWasm = (x, wasm, rewriteLocals = false) => {
59
+ for (let i = 0; i < wasm.length; i++) {
60
+ const y = wasm[i];
61
+ const n = wasm[i + 1];
62
+ if (y[0] === Opcodes.call) {
63
+ const f = funcs.find(x => x.index === y[1]);
64
+ if (!f) continue;
65
+
66
+ y[1] = f.name;
67
+ }
68
+
69
+ if (y[0] === Opcodes.global_get || y[0] === Opcodes.global_set) {
70
+ const global = Object.values(globals).findIndex(x => x.idx === y[1]);
71
+ const name = Object.keys(globals)[global];
72
+ const type = globals[name].type;
73
+ y.splice(0, 10, 'global', y[0], name, type);
74
+
75
+ if (!x.globalInits) {
76
+ x.globalInits = { ...main.globalInits };
77
+ for (const z in x.globalInits) {
78
+ rewriteWasm(main, x.globalInits[z], true);
79
+ }
80
+ }
81
+ }
82
+
83
+ if (rewriteLocals && (y[0] === Opcodes.local_get || y[0] === Opcodes.local_set || y[0] === Opcodes.local_tee)) {
84
+ const local = Object.values(x.locals).findIndex(x => x.idx === y[1]);
85
+ const name = Object.keys(x.locals)[local];
86
+ const type = x.locals[name].type;
87
+ y.splice(1, 10, 'local', name, type);
88
+ }
89
+
90
+ if (y[0] === Opcodes.const && (n[0] === Opcodes.local_set || n[0] === Opcodes.local_tee)) {
91
+ const l = locals[n[1]];
92
+ if (!l) continue;
93
+ if (![TYPES.string, TYPES.array, TYPES.bytestring].includes(l.metadata?.type)) continue;
94
+ if (!x.pages) continue;
95
+
96
+ const pageName = [...x.pages.keys()].find(z => z.endsWith(l.name));
97
+ if (!pageName || allocated.has(pageName)) continue;
98
+ allocated.add(pageName);
99
+
100
+ y.splice(0, 10, 'alloc', pageName, x.pages.get(pageName).type, valtypeBinary);
101
+ }
102
+
103
+ if (y[0] === Opcodes.i32_const && n[0] === Opcodes.throw) {
104
+ const id = y[1];
105
+ y.splice(0, 10, 'throw', exceptions[id].constructor, exceptions[id].message);
106
+
107
+ // remove throw inst
108
+ wasm.splice(i + 1, 1);
109
+ }
78
110
  }
111
+ };
79
112
 
80
- if (y[0] === Opcodes.i32_const && n[0] === Opcodes.throw) {
81
- const id = y[1];
82
- y.splice(0, 10, 'throw', exceptions[id].constructor, exceptions[id].message);
83
-
84
- // remove throw inst
85
- x.wasm.splice(i + 1, 1);
86
- }
87
- }
113
+ rewriteWasm(x, x.wasm);
88
114
  }
89
115
 
90
116
  _funcs.push(...exports);
91
- _globals.push(...Object.values(globals));
92
117
  };
93
118
 
94
119
  const precompile = async () => {
@@ -96,14 +121,14 @@ const precompile = async () => {
96
121
 
97
122
  const dir = join(__dirname, 'builtins');
98
123
 
99
- let funcs = [], globals = [];
124
+ let funcs = [];
100
125
  for (const file of fs.readdirSync(dir)) {
101
126
  if (file.endsWith('.d.ts')) continue;
102
127
 
103
128
  console.log(`${' '.repeat(12)}${file}`);
104
129
 
105
130
  const t = performance.now();
106
- await compile(join(dir, file), [ funcs, globals ]);
131
+ await compile(join(dir, file), funcs);
107
132
 
108
133
  console.log(`\u001b[A${' '.repeat(100)}\r\u001b[90m${`[${(performance.now() - t).toFixed(2)}ms]`.padEnd(12, ' ')}\u001b[0m\u001b[92m${file}\u001b[0m`);
109
134
  }
@@ -113,13 +138,23 @@ import { number } from './embedding.js';
113
138
 
114
139
  export const BuiltinFuncs = function() {
115
140
  ${funcs.map(x => {
116
- const wasm = JSON.stringify(x.wasm.filter(x => x.length && x[0] != null)).replace(/\["alloc","(.*?)","(.*?)",(.*?)\]/g, (_, reason, type, valtype) => `...number(allocPage(scope, '${reason}', '${type}') * pageSize, ${valtype})`).replace(/\[16,"(.*?)"]/g, (_, name) => `[16, builtin('${name}')]`).replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(scope, '${constructor}', \`${message}\`)`);
141
+ const rewriteWasm = wasm => {
142
+ const str = JSON.stringify(wasm.filter(x => x.length && x[0] != null))
143
+ .replace(/\["alloc","(.*?)","(.*?)",(.*?)\]/g, (_, reason, type, valtype) => `...number(allocPage(scope, '${reason}', '${type}') * pageSize, ${valtype})`)
144
+ .replace(/\["global",(.*?),"(.*?)",(.*?)\]/g, (_, opcode, name, valtype) => `...glbl(${opcode}, '${name}', ${valtype})`)
145
+ .replace(/\"local","(.*?)",(.*?)\]/g, (_, name, valtype) => `loc('${name}', ${valtype})]`)
146
+ .replace(/\[16,"(.*?)"]/g, (_, name) => `[16, builtin('${name}')]`)
147
+ .replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(scope, '${constructor}', \`${message}\`)`);
148
+
149
+ return `(scope, {${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}`.slice(0, -1)}}) => ` + str;
150
+ };
151
+
117
152
  return ` this.${x.name} = {
118
- wasm: (scope, {${`${wasm.includes('allocPage(') ? 'allocPage,' : ''}${wasm.includes('builtin(') ? 'builtin,' : ''}${wasm.includes('internalThrow(') ? 'internalThrow,' : ''}`.slice(0, -1)}}) => ${wasm},
153
+ wasm: ${rewriteWasm(x.wasm)},
119
154
  params: ${JSON.stringify(x.params)}, typedParams: 1,
120
155
  returns: ${JSON.stringify(x.returns)}, ${x.returnType != null ? `returnType: ${JSON.stringify(x.returnType)}` : 'typedReturns: 1'},
121
156
  locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length).map(x => x.type))}, localNames: ${JSON.stringify(Object.keys(x.locals))},
122
- ${x.data && x.data.length > 0 ? ` data: [${x.data.map(x => `[${x.offset ?? 'null'},[${x.bytes.join(',')}]]`).join(',')}],` : ''}
157
+ ${x.globalInits ? ` globalInits: {${Object.keys(x.globalInits).map(y => `${y}: ${rewriteWasm(x.globalInits[y])}`).join(',')}},\n` : ''}${x.data && x.data.length > 0 ? ` data: [${x.data.map(x => `[${x.offset ?? 'null'},[${x.bytes.join(',')}]]`).join(',')}],` : ''}
123
158
  ${x.table ? ` table: 1,` : ''}${x.constr ? ` constr: 1,` : ''}${x.hasRestArgument ? ` hasRestArgument: 1,` : ''}
124
159
  };`.replaceAll('\n\n', '\n').replaceAll('\n\n', '\n').replaceAll('\n\n', '\n');
125
160
  }).join('\n')}
package/compiler/wrap.js CHANGED
@@ -114,9 +114,10 @@ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
114
114
  }
115
115
 
116
116
  case TYPES.symbol: {
117
- const descStore = pages.get('bytestring: __Porffor_symbol_descStore/ptr').ind * pageSize;
118
- if (!descStore) return Symbol();
117
+ const page = pages.get('bytestring: __Porffor_symbol_descStore/ptr');
118
+ if (!page) return Symbol();
119
119
 
120
+ const descStore = page.ind * pageSize;
120
121
  const offset = descStore + 4 + ((value - 1) * 9);
121
122
 
122
123
  const v = read(Float64Array, memory, offset, 1)[0];
@@ -233,12 +234,15 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
233
234
 
234
235
  const printDecomp = (middleIndex, func, funcs, globals, exceptions) => {
235
236
  console.log(`\x1B[35m\x1B[1mporffor backtrace\u001b[0m`);
236
- console.log('\x1B[4m' + func.name + '\x1B[0m');
237
+
238
+ const strParams = func.params.map(v => invValtype[v]);
239
+ const strReturns = func.returns.map(v => invValtype[v]);
240
+ console.log(`\x1B[1m${func.name}\x1B[0m \x1B[90m(${strParams.join(', ')}) -> (${strReturns.join(', ')})\x1B[0m`);
237
241
 
238
242
  const surrounding = Prefs.backtraceSurrounding ?? 5;
239
243
  let min = middleIndex - surrounding;
240
244
  let max = middleIndex + surrounding + 1;
241
- if (Prefs.backtraceEntireFunc || middleIndex == -1) {
245
+ if (Prefs.backtraceFunc || middleIndex == -1) {
242
246
  min = 0;
243
247
  max = func.wasm.length;
244
248
  }
@@ -378,7 +382,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
378
382
  if (!process.argv.includes('-i')) throw e;
379
383
  if (!(e instanceof WebAssembly.CompileError)) throw e;
380
384
 
381
- const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
385
+ const funcInd = parseInt(e.message.match(/function #([0-9]+)/)?.[1]);
382
386
  const blobOffset = parseInt(e.message.split('@')?.[1]);
383
387
 
384
388
  backtrace(funcInd, blobOffset);
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.19.9+a07f4dac1",
4
+ "version": "0.19.10+d1a9d685a",
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.19.9+a07f4dac1';
3
+ globalThis.version = '0.19.10+d1a9d685a';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {