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/CONTRIBUTING.md +5 -1
- package/asur/index.js +1 -1
- package/compiler/assemble.js +14 -0
- package/compiler/builtins/array.ts +28 -4
- package/compiler/builtins/error.js +22 -0
- package/compiler/builtins/set.ts +5 -6
- package/compiler/builtins/symbol.ts +1 -1
- package/compiler/builtins.js +9 -4
- package/compiler/codegen.js +405 -144
- package/compiler/generated_builtins.js +223 -59
- package/compiler/precompile.js +4 -3
- package/compiler/prefs.js +1 -1
- package/compiler/prototype.js +180 -157
- package/compiler/wrap.js +66 -37
- package/package.json +1 -1
- package/runner/index.js +1 -1
- package/runner/repl.js +18 -2
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
|
-
|
45
|
-
|
46
|
-
|
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
|
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,
|
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)
|
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)
|
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 (
|
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
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\
|
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
|
-
|
90
|
-
|
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 });
|