porffor 0.14.0-cdebd5442 → 0.14.0-db4b90996

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/wrap.js CHANGED
@@ -41,9 +41,22 @@ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
41
41
  case TYPES.array: {
42
42
  const length = (new Int32Array(memory.buffer, value, 1))[0];
43
43
 
44
- // have to slice because of memory alignment (?)
45
- const buf = memory.buffer.slice(value + 4, value + 4 + 8 * length);
46
- return Array.from(new Float64Array(buf, 0, length));
44
+ const out = [];
45
+ for (let i = 0; i < length; i++) {
46
+ const offset = value + 4 + (i * 9);
47
+
48
+ // have to slice because of memory alignment (?)
49
+ const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
50
+ const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
51
+
52
+ // console.log(`reading value at index ${i}...`)
53
+ // console.log(' memory:', Array.from(new Uint8Array(memory.buffer, offset, 9)).map(x => x.toString(16).padStart(2, '0')).join(' '));
54
+ // console.log(' read:', { value: v, type: t }, '\n');
55
+
56
+ out.push(porfToJSValue({ memory, funcs, pages }, v, t));
57
+ }
58
+
59
+ return out;
47
60
  }
48
61
 
49
62
  case TYPES.date: {
@@ -103,40 +116,12 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
103
116
  times.push(performance.now() - t1);
104
117
  if (Prefs.profileCompiler) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
105
118
 
106
- const t2 = performance.now();
107
-
108
- let instance;
109
- try {
110
- let wasmEngine = WebAssembly;
111
- if (Prefs.asur) {
112
- log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
113
- wasmEngine = await import('../asur/index.js');
114
- }
115
-
116
- 0, { instance } = await wasmEngine.instantiate(wasm, {
117
- '': {
118
- p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
119
- c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
120
- t: () => performance.now(),
121
- u: () => performance.timeOrigin,
122
- y: () => {},
123
- z: () => {},
124
- ...customImports
125
- }
126
- });
127
- } catch (e) {
128
- // only backtrace for runner, not test262/etc
129
- if (!process.argv[1].includes('/runner')) throw e;
130
-
131
- const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
132
- const blobOffset = parseInt(e.message.split('@')?.[1]);
133
-
134
- if (!funcInd) throw e;
119
+ const backtrace = (funcInd, blobOffset) => {
120
+ if (funcInd == null || blobOffset == null) return false;
135
121
 
136
122
  // convert blob offset -> function wasm offset.
137
123
  // this is not good code and is somewhat duplicated
138
124
  // I just want it to work for debugging, I don't care about perf/yes
139
-
140
125
  const func = funcs.find(x => x.index === funcInd);
141
126
  const locals = Object.values(func.locals).sort((a, b) => a.idx - b.idx).slice(func.params.length).sort((a, b) => a.idx - b.idx);
142
127
 
@@ -154,7 +139,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
154
139
 
155
140
  if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
156
141
 
157
- const toFind = encodeVector(localDecl).concat(func.wasm.flat().filter(x => x != null && x <= 0xff).slice(0, 40));
142
+ const toFind = encodeVector(localDecl).concat(func.wasm.flat().filter(x => x != null && x <= 0xff).slice(0, 60));
158
143
 
159
144
  let i = 0;
160
145
  for (; i < wasm.length; i++) {
@@ -169,7 +154,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
169
154
  if (!mismatch) break;
170
155
  }
171
156
 
172
- if (i === wasm.length) throw e;
157
+ if (i === wasm.length) return false;
173
158
 
174
159
  const offset = (blobOffset - i) + encodeVector(localDecl).length;
175
160
 
@@ -180,7 +165,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
180
165
  if (cumLen === offset) break;
181
166
  }
182
167
 
183
- if (cumLen !== offset) throw e;
168
+ if (cumLen !== offset) return false;
184
169
 
185
170
  i -= 1;
186
171
 
@@ -205,6 +190,38 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
205
190
  console.log(decomp.join('\n'));
206
191
  console.log('\x1B[90m...\x1B[0m\n');
207
192
 
193
+ return true;
194
+ };
195
+
196
+ const t2 = performance.now();
197
+
198
+ let instance;
199
+ try {
200
+ let wasmEngine = WebAssembly;
201
+ if (Prefs.asur) {
202
+ log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
203
+ wasmEngine = await import('../asur/index.js');
204
+ }
205
+
206
+ 0, { instance } = await wasmEngine.instantiate(wasm, {
207
+ '': {
208
+ p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
209
+ c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
210
+ t: () => performance.now(),
211
+ u: () => performance.timeOrigin,
212
+ y: () => {},
213
+ z: () => {},
214
+ ...customImports
215
+ }
216
+ });
217
+ } catch (e) {
218
+ // only backtrace for runner, not test262/etc
219
+ if (!process.argv[1].includes('/runner')) throw e;
220
+
221
+ const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
222
+ const blobOffset = parseInt(e.message.split('@')?.[1]);
223
+
224
+ backtrace(funcInd, blobOffset);
208
225
  throw e;
209
226
  }
210
227
 
@@ -212,6 +229,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
212
229
  if (Prefs.profileCompiler) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
213
230
 
214
231
  const exports = {};
232
+ const rawValues = process.argv.includes('-i');
215
233
 
216
234
  const exceptTag = instance.exports['0'], memory = instance.exports['$'];
217
235
  for (const x in instance.exports) {
@@ -232,7 +250,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
232
250
  const ret = exp.apply(this, arguments);
233
251
  if (ret == null) return undefined;
234
252
 
235
- if (Prefs.rawValue) return { value: ret[0], type: ret[1] };
253
+ if (rawValues) return { value: ret[0], type: ret[1], js: porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]) };
236
254
 
237
255
  return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
238
256
  } catch (e) {
@@ -249,6 +267,17 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
249
267
  throw new constructor(exception.message);
250
268
  }
251
269
 
270
+ if (e instanceof WebAssembly.RuntimeError) {
271
+ // only backtrace for runner, not test262/etc
272
+ if (!process.argv[1].includes('/runner')) throw e;
273
+
274
+ const match = e.stack.match(/wasm-function\[([0-9]+)\]:([0-9a-z]+)/) ?? [];
275
+ const funcInd = parseInt(match[1]);
276
+ const blobOffset = parseInt(match[2]);
277
+
278
+ backtrace(funcInd, blobOffset);
279
+ }
280
+
252
281
  throw e;
253
282
  }
254
283
  };
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.14.0-cdebd5442",
4
+ "version": "0.14.0-db4b90996",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {
package/runner/index.js CHANGED
@@ -25,7 +25,7 @@ if (process.argv.includes('--help')) {
25
25
  console.log(`Usage: \x1B[1mporf [command] path/to/script.js [...prefs] [...args]\x1B[0m`);
26
26
 
27
27
  // commands
28
- console.log(`\n\u001b[4mCommands\x1B[0m`);
28
+ console.log(`\n\x1B[1mCommands:\x1B[0m`);
29
29
  for (const [ cmd, [ color, desc ] ] of Object.entries({
30
30
  run: [ 34, 'Run a JS file' ],
31
31
  wasm: [ 34, 'Compile a JS file to a Wasm binary\n' ],
package/runner/repl.js CHANGED
@@ -1,6 +1,11 @@
1
+ import { TYPE_NAMES } from '../compiler/types.js';
1
2
  import compile from '../compiler/wrap.js';
2
3
  import version from './version.js';
3
4
 
5
+ import util from 'node:util';
6
+
7
+ process.argv.push('--no-opt-unused');
8
+
4
9
  let repl;
5
10
  try {
6
11
  // try importing node:repl
@@ -86,10 +91,21 @@ const run = async (source, _context, _filename, callback, run = true) => {
86
91
  lastPages = [...pages.keys()];
87
92
  }
88
93
 
89
- const ret = run ? exports.main() : undefined;
90
- callback(null, ret);
94
+ let ret = run ? exports.main() : undefined;
95
+ let value, type;
96
+ if (ret?.type != null) {
97
+ value = ret.value;
98
+ type = ret.type;
99
+ ret = ret.js;
100
+ }
101
+
102
+ console.log(util.inspect(ret, false, 2, true), (value != null ? `\x1B[34m\x1B[3m(value: ${value}, type: ${TYPE_NAMES[type]})\x1B[0m` : ''));
103
+
104
+ // callback(null, ret);
91
105
 
92
106
  prev = prev + ';\n' + source.trim();
107
+
108
+ callback();
93
109
  };
94
110
 
95
111
  const replServer = repl.start({ prompt: '> ', eval: run });