porffor 0.17.0-9c7bd8098 → 0.17.0-a23029b3a
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/README.md +6 -4
- package/compiler/2c.js +28 -11
- package/compiler/assemble.js +19 -4
- package/compiler/builtins/array.ts +79 -9
- package/compiler/builtins/base64.ts +28 -24
- package/compiler/builtins/date.ts +104 -106
- package/compiler/builtins/error.js +2 -5
- package/compiler/builtins/math.ts +6 -2
- package/compiler/builtins/set.ts +11 -14
- package/compiler/builtins/string_f64.ts +4 -6
- package/compiler/builtins/symbol.ts +2 -1
- package/compiler/builtins/typedarray.js +94 -0
- package/compiler/builtins/z_ecma262.ts +1 -0
- package/compiler/builtins.js +25 -0
- package/compiler/codegen.js +858 -160
- package/compiler/generated_builtins.js +2769 -666
- package/compiler/pgo.js +9 -1
- package/compiler/precompile.js +4 -2
- package/compiler/prototype.js +0 -69
- package/compiler/types.js +31 -5
- package/compiler/wasmSpec.js +2 -0
- package/compiler/wrap.js +69 -12
- package/package.json +1 -1
- package/rhemyn/README.md +7 -4
- package/rhemyn/compile.js +170 -76
- package/runner/debug.js +1 -1
- package/runner/index.js +5 -3
- package/runner/profile.js +1 -1
- package/runner/repl.js +16 -11
package/compiler/pgo.js
CHANGED
@@ -91,7 +91,9 @@ export const run = obj => {
|
|
91
91
|
},
|
92
92
|
w: (ind, outPtr) => { // readArgv
|
93
93
|
const pgoInd = process.argv.indexOf('--pgo');
|
94
|
-
|
94
|
+
let args = process.argv.slice(pgoInd);
|
95
|
+
args = args.slice(args.findIndex(x => !x.startsWith('-')) + 1);
|
96
|
+
|
95
97
|
const str = args[ind - 1];
|
96
98
|
if (pgoInd === -1 || !str) {
|
97
99
|
if (Prefs.pgoLog) console.log('\nPGO warning: script was expecting arguments, please specify args to use for PGO after --pgo arg');
|
@@ -100,6 +102,9 @@ export const run = obj => {
|
|
100
102
|
|
101
103
|
writeByteStr(exports.$, outPtr, str);
|
102
104
|
return str.length;
|
105
|
+
},
|
106
|
+
q: (pathPtr, outPtr) => {
|
107
|
+
return -1;
|
103
108
|
}
|
104
109
|
}, () => {});
|
105
110
|
|
@@ -179,6 +184,9 @@ export const run = obj => {
|
|
179
184
|
|
180
185
|
log = '';
|
181
186
|
for (const x of funcs) {
|
187
|
+
// skip pgo opt for main()
|
188
|
+
if (x.name === 'main') continue;
|
189
|
+
|
182
190
|
const wasmFunc = wasmFuncs.find(y => y.name === x.name);
|
183
191
|
|
184
192
|
let targets = [];
|
package/compiler/precompile.js
CHANGED
@@ -6,6 +6,8 @@ import { join } from 'node:path';
|
|
6
6
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
8
8
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
9
|
+
globalThis.precompileCompilerPath = __dirname;
|
10
|
+
globalThis.precompile = true;
|
9
11
|
|
10
12
|
const argv = process.argv.slice();
|
11
13
|
|
@@ -14,7 +16,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
14
16
|
let first = source.slice(0, source.indexOf('\n'));
|
15
17
|
|
16
18
|
if (first.startsWith('export default')) {
|
17
|
-
source = (await import(file)).default();
|
19
|
+
source = await (await import(file)).default();
|
18
20
|
first = source.slice(0, source.indexOf('\n'));
|
19
21
|
}
|
20
22
|
|
@@ -117,7 +119,7 @@ ${funcs.map(x => {
|
|
117
119
|
locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length).map(x => x.type))},
|
118
120
|
localNames: ${JSON.stringify(Object.keys(x.locals))},
|
119
121
|
${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)},` : ''}
|
120
|
-
${x.table ? ` table: true` : ''}
|
122
|
+
${x.table ? ` table: true,` : ''}${x.constr ? ` constr: true,` : ''}
|
121
123
|
};`.replaceAll('\n\n', '\n').replaceAll('\n\n', '\n').replaceAll('\n\n', '\n');
|
122
124
|
}).join('\n')}
|
123
125
|
};`;
|
package/compiler/prototype.js
CHANGED
@@ -208,72 +208,6 @@ export const PrototypeFuncs = function() {
|
|
208
208
|
// ...number(1, Valtype.i32),
|
209
209
|
// [ Opcodes.i32_sub ]
|
210
210
|
// ]),
|
211
|
-
],
|
212
|
-
|
213
|
-
fill: (pointer, length, wElement, wType, iTmp, iTmp2) => [
|
214
|
-
...wElement,
|
215
|
-
[ Opcodes.local_set, iTmp ],
|
216
|
-
|
217
|
-
// use cached length i32 as pointer
|
218
|
-
...length.getCachedI32(),
|
219
|
-
|
220
|
-
// length - 1 for indexes
|
221
|
-
...number(1, Valtype.i32),
|
222
|
-
[ Opcodes.i32_sub ],
|
223
|
-
|
224
|
-
// * sizeof value
|
225
|
-
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
226
|
-
[ Opcodes.i32_mul ],
|
227
|
-
|
228
|
-
...length.setCachedI32(),
|
229
|
-
|
230
|
-
...(noUnlikelyChecks ? [] : [
|
231
|
-
...length.getCachedI32(),
|
232
|
-
...number(0, Valtype.i32),
|
233
|
-
[ Opcodes.i32_lt_s ],
|
234
|
-
[ Opcodes.if, Blocktype.void ],
|
235
|
-
...pointer,
|
236
|
-
Opcodes.i32_from_u,
|
237
|
-
[ Opcodes.br, 1 ],
|
238
|
-
[ Opcodes.end ]
|
239
|
-
]),
|
240
|
-
|
241
|
-
[ Opcodes.loop, Blocktype.void ],
|
242
|
-
|
243
|
-
// calculate offset
|
244
|
-
...length.getCachedI32(),
|
245
|
-
...pointer,
|
246
|
-
[ Opcodes.i32_add ],
|
247
|
-
[ Opcodes.local_set, iTmp2 ],
|
248
|
-
|
249
|
-
// store value
|
250
|
-
[ Opcodes.local_get, iTmp2 ],
|
251
|
-
[ Opcodes.local_get, iTmp ],
|
252
|
-
[ Opcodes.store, 0, ValtypeSize.i32 ],
|
253
|
-
|
254
|
-
// store type
|
255
|
-
[ Opcodes.local_get, iTmp2 ],
|
256
|
-
...wType,
|
257
|
-
[ Opcodes.i32_store8, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
|
258
|
-
|
259
|
-
// pointer - sizeof value
|
260
|
-
...length.getCachedI32(),
|
261
|
-
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
262
|
-
[ Opcodes.i32_sub ],
|
263
|
-
|
264
|
-
...length.setCachedI32(),
|
265
|
-
|
266
|
-
// if pointer >= 0, loop
|
267
|
-
...length.getCachedI32(),
|
268
|
-
...number(0, Valtype.i32),
|
269
|
-
[ Opcodes.i32_ge_s ],
|
270
|
-
[ Opcodes.br_if, 0 ],
|
271
|
-
|
272
|
-
[ Opcodes.end ],
|
273
|
-
|
274
|
-
// return this array
|
275
|
-
...pointer,
|
276
|
-
Opcodes.i32_from_u,
|
277
211
|
]
|
278
212
|
};
|
279
213
|
|
@@ -282,9 +216,6 @@ export const PrototypeFuncs = function() {
|
|
282
216
|
this[TYPES.array].push.noArgRetLength = true;
|
283
217
|
this[TYPES.array].push.local = Valtype.i32;
|
284
218
|
this[TYPES.array].pop.local = Valtype.i32;
|
285
|
-
this[TYPES.array].fill.local = valtypeBinary;
|
286
|
-
this[TYPES.array].fill.local2 = Valtype.i32;
|
287
|
-
this[TYPES.array].fill.returnType = TYPES.array;
|
288
219
|
|
289
220
|
this[TYPES.string] = {
|
290
221
|
at: (pointer, length, wIndex, wType, iTmp, _, arrayShell) => {
|
package/compiler/types.js
CHANGED
@@ -20,10 +20,26 @@ export const TYPE_NAMES = {
|
|
20
20
|
[TYPES.bigint]: 'BigInt'
|
21
21
|
};
|
22
22
|
|
23
|
+
// flags
|
24
|
+
export const TYPE_FLAGS = {
|
25
|
+
// iterable: 0b10000000,
|
26
|
+
length: 0b01000000,
|
27
|
+
};
|
28
|
+
|
29
|
+
// TYPES.string |= TYPE_FLAGS.iterable;
|
30
|
+
TYPES.string |= TYPE_FLAGS.length;
|
31
|
+
|
32
|
+
export const typeHasFlag = (type, flag) => (type & flag) !== 0;
|
33
|
+
|
23
34
|
export const INTERNAL_TYPE_BASE = 0x10;
|
24
35
|
let internalTypeIndex = INTERNAL_TYPE_BASE;
|
25
|
-
const registerInternalType = name => {
|
26
|
-
|
36
|
+
const registerInternalType = (name, flags = []) => {
|
37
|
+
let n = internalTypeIndex++;
|
38
|
+
|
39
|
+
for (const x of flags) {
|
40
|
+
if (TYPE_FLAGS[x]) n |= TYPE_FLAGS[x];
|
41
|
+
}
|
42
|
+
|
27
43
|
TYPES[name.toLowerCase()] = n;
|
28
44
|
TYPE_NAMES[n] = name;
|
29
45
|
};
|
@@ -31,8 +47,18 @@ const registerInternalType = name => {
|
|
31
47
|
// note: when adding a new internal type, please also add a deserializer to wrap.js
|
32
48
|
// (it is okay to add a throw todo deserializer for wips)
|
33
49
|
|
34
|
-
registerInternalType('Array');
|
50
|
+
registerInternalType('Array', ['iterable', 'length']);
|
35
51
|
registerInternalType('RegExp');
|
36
|
-
registerInternalType('ByteString');
|
52
|
+
registerInternalType('ByteString', ['iterable', 'length']);
|
37
53
|
registerInternalType('Date');
|
38
|
-
registerInternalType('Set');
|
54
|
+
registerInternalType('Set', ['iterable']);
|
55
|
+
|
56
|
+
registerInternalType('Uint8Array', ['iterable', 'length']);
|
57
|
+
registerInternalType('Int8Array', ['iterable', 'length']);
|
58
|
+
registerInternalType('Uint8ClampedArray', ['iterable', 'length']);
|
59
|
+
registerInternalType('Uint16Array', ['iterable', 'length']);
|
60
|
+
registerInternalType('Int16Array', ['iterable', 'length']);
|
61
|
+
registerInternalType('Uint32Array', ['iterable', 'length']);
|
62
|
+
registerInternalType('Int32Array', ['iterable', 'length']);
|
63
|
+
registerInternalType('Float32Array', ['iterable', 'length']);
|
64
|
+
registerInternalType('Float64Array', ['iterable', 'length']);
|
package/compiler/wasmSpec.js
CHANGED
@@ -68,6 +68,7 @@ export const Opcodes = {
|
|
68
68
|
|
69
69
|
i32_load: 0x28,
|
70
70
|
i64_load: 0x29,
|
71
|
+
f32_load: 0x2a,
|
71
72
|
f64_load: 0x2b,
|
72
73
|
|
73
74
|
i32_load8_s: 0x2c,
|
@@ -82,6 +83,7 @@ export const Opcodes = {
|
|
82
83
|
|
83
84
|
i32_store: 0x36,
|
84
85
|
i64_store: 0x37,
|
86
|
+
f32_store: 0x38,
|
85
87
|
f64_store: 0x39,
|
86
88
|
|
87
89
|
i32_store8: 0x3a,
|
package/compiler/wrap.js
CHANGED
@@ -2,7 +2,7 @@ import { encodeVector, encodeLocal } from './encoding.js';
|
|
2
2
|
import { importedFuncs } from './builtins.js';
|
3
3
|
import compile from './index.js';
|
4
4
|
import decompile from './decompile.js';
|
5
|
-
import { TYPES } from './types.js';
|
5
|
+
import { TYPES, TYPE_NAMES } from './types.js';
|
6
6
|
import { log } from './log.js';
|
7
7
|
import Prefs from './prefs.js';
|
8
8
|
|
@@ -115,6 +115,19 @@ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
|
|
115
115
|
return Symbol(desc);
|
116
116
|
}
|
117
117
|
|
118
|
+
case TYPES.uint8array:
|
119
|
+
case TYPES.int8array:
|
120
|
+
case TYPES.uint8clampedarray:
|
121
|
+
case TYPES.uint16array:
|
122
|
+
case TYPES.int16array:
|
123
|
+
case TYPES.uint32array:
|
124
|
+
case TYPES.int32array:
|
125
|
+
case TYPES.float32array:
|
126
|
+
case TYPES.float64array: {
|
127
|
+
const length = (new Int32Array(memory.buffer, value, 1))[0];
|
128
|
+
return new globalThis[TYPE_NAMES[type]](memory.buffer, value + 4, length);
|
129
|
+
}
|
130
|
+
|
118
131
|
default: return value;
|
119
132
|
}
|
120
133
|
};
|
@@ -127,7 +140,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
127
140
|
|
128
141
|
globalThis.porfDebugInfo = { funcs, globals };
|
129
142
|
|
130
|
-
if (source.includes?.('export ')) flags.push('module');
|
143
|
+
// if (process.argv[1].includes('/runner') && source.includes?.('export ')) flags.push('module');
|
131
144
|
|
132
145
|
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
133
146
|
|
@@ -235,8 +248,10 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
235
248
|
y: () => {},
|
236
249
|
z: () => {},
|
237
250
|
w: (ind, outPtr) => { // readArgv
|
238
|
-
|
239
|
-
|
251
|
+
let args = process.argv.slice(2);
|
252
|
+
args = args.slice(args.findIndex(x => !x.startsWith('-')) + 1);
|
253
|
+
|
254
|
+
const str = args[ind - 1];
|
240
255
|
if (!str) return -1;
|
241
256
|
|
242
257
|
writeByteStr(memory, outPtr, str);
|
@@ -244,7 +259,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
244
259
|
},
|
245
260
|
q: (pathPtr, outPtr) => { // readFile
|
246
261
|
try {
|
247
|
-
const path = readByteStr(memory, pathPtr);
|
262
|
+
const path = pathPtr === 0 ? 0 : readByteStr(memory, pathPtr);
|
248
263
|
const contents = fs.readFileSync(path, 'utf8');
|
249
264
|
writeByteStr(memory, outPtr, contents);
|
250
265
|
return contents.length;
|
@@ -297,16 +312,58 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
297
312
|
return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
|
298
313
|
} catch (e) {
|
299
314
|
if (e.is && e.is(exceptTag)) {
|
300
|
-
const
|
301
|
-
|
315
|
+
const exceptionMode = Prefs.exceptionMode ?? 'lut';
|
316
|
+
if (exceptionMode === 'lut') {
|
317
|
+
const exceptId = e.getArg(exceptTag, 0);
|
318
|
+
const exception = exceptions[exceptId];
|
319
|
+
|
320
|
+
const constructorName = exception.constructor;
|
302
321
|
|
303
|
-
|
322
|
+
// no constructor, just throw message
|
323
|
+
if (!constructorName) throw exception.message;
|
324
|
+
|
325
|
+
const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
|
326
|
+
throw new constructor(exception.message);
|
327
|
+
}
|
328
|
+
|
329
|
+
if (exceptionMode === 'stack') {
|
330
|
+
const value = e.getArg(exceptTag, 0);
|
331
|
+
const type = e.getArg(exceptTag, 1);
|
332
|
+
|
333
|
+
throw porfToJSValue({ memory, funcs, pages }, value, type);
|
334
|
+
}
|
304
335
|
|
305
|
-
|
306
|
-
|
336
|
+
if (exceptionMode === 'stackest') {
|
337
|
+
const constructorIdx = e.getArg(exceptTag, 0);
|
338
|
+
const constructorName = constructorIdx == -1 ? null : funcs.find(x => ((x.originalIndex ?? x.index) - importedFuncs.length) === constructorIdx)?.name;
|
307
339
|
|
308
|
-
|
309
|
-
|
340
|
+
const value = e.getArg(exceptTag, 1);
|
341
|
+
const type = e.getArg(exceptTag, 2);
|
342
|
+
const message = porfToJSValue({ memory, funcs, pages }, value, type);
|
343
|
+
|
344
|
+
// no constructor, just throw message
|
345
|
+
if (!constructorName) throw message;
|
346
|
+
|
347
|
+
const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
|
348
|
+
throw new constructor(message);
|
349
|
+
}
|
350
|
+
|
351
|
+
if (exceptionMode === 'partial') {
|
352
|
+
const exceptId = e.getArg(exceptTag, 0);
|
353
|
+
const exception = exceptions[exceptId];
|
354
|
+
|
355
|
+
const constructorName = exception.constructor;
|
356
|
+
|
357
|
+
const value = e.getArg(exceptTag, 1);
|
358
|
+
const type = e.getArg(exceptTag, 2);
|
359
|
+
const message = porfToJSValue({ memory, funcs, pages }, value, type);
|
360
|
+
|
361
|
+
// no constructor, just throw message
|
362
|
+
if (!constructorName) throw message;
|
363
|
+
|
364
|
+
const constructor = globalThis[constructorName] ?? eval(`class ${constructorName} extends Error { constructor(message) { super(message); this.name = "${constructorName}"; } }; ${constructorName}`);
|
365
|
+
throw new constructor(message);
|
366
|
+
}
|
310
367
|
}
|
311
368
|
|
312
369
|
if (e instanceof WebAssembly.RuntimeError) {
|
package/package.json
CHANGED
package/rhemyn/README.md
CHANGED
@@ -24,13 +24,16 @@ Made for use with Porffor but could possibly be adapted, implementation/library
|
|
24
24
|
- 🟢 digit, not digit (eg `\d\D`)
|
25
25
|
- 🟢 word, not word (eg `\w\W`)
|
26
26
|
- 🟢 whitespace, not whitespace (eg `\s\S`)
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
27
|
+
- 🟡 quantifiers
|
28
|
+
- 🟡 star (eg `a*`)
|
29
|
+
- 🟡 plus (eg `a+`)
|
30
|
+
- 🟡 optional (eg `a?`)
|
31
31
|
- 🟠 lazy modifier (eg `a*?`)
|
32
32
|
- 🔴 n repetitions (eg `a{4}`)
|
33
33
|
- 🔴 n-m repetitions (eg `a{2,4}`)
|
34
|
+
- 🟠 groups
|
35
|
+
- 🟠 capturing groups (`(a)`)
|
36
|
+
- 🔴 non-capturing groups (`(?:a)`)
|
34
37
|
- 🔴 assertions
|
35
38
|
- 🔴 beginning (eg `^a`)
|
36
39
|
- 🔴 end (eg `a$`)
|