porffor 0.2.0-e04e26f → 0.2.0-e62542f
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 +254 -0
- package/README.md +63 -44
- package/asur/index.js +1 -1
- package/compiler/assemble.js +1 -1
- package/compiler/builtins/annexb_string.js +2 -2
- package/compiler/builtins/annexb_string.ts +5 -6
- package/compiler/builtins/array.ts +10 -10
- package/compiler/builtins/base64.ts +4 -79
- package/compiler/builtins/crypto.ts +1 -1
- package/compiler/builtins/date.ts +1292 -349
- package/compiler/builtins/escape.ts +2 -2
- package/compiler/builtins/int.ts +3 -3
- package/compiler/builtins/number.ts +1 -1
- package/compiler/builtins/porffor.d.ts +21 -4
- package/compiler/builtins/string.ts +22 -22
- package/compiler/builtins/tostring.ts +4 -4
- package/compiler/builtins.js +6 -30
- package/compiler/codegen.js +138 -68
- package/compiler/decompile.js +0 -1
- package/compiler/generated_builtins.js +499 -154
- package/compiler/parse.js +4 -2
- package/compiler/precompile.js +7 -2
- package/compiler/prefs.js +6 -5
- package/compiler/prototype.js +14 -14
- package/compiler/types.js +1 -1
- package/compiler/wrap.js +3 -3
- package/package.json +1 -1
- package/rhemyn/compile.js +42 -25
- package/rhemyn/parse.js +4 -5
- package/runner/index.js +45 -4
- package/runner/repl.js +2 -2
- package/runner/sizes.js +1 -1
package/compiler/parse.js
CHANGED
@@ -9,8 +9,10 @@ if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
|
9
9
|
globalThis.process = { argv: ['', '', ...Deno.args], stdout: { write: str => Deno.writeAllSync(Deno.stdout, textEncoder.encode(str)) } };
|
10
10
|
}
|
11
11
|
|
12
|
+
const file = process.argv.slice(2).find(x => x[0] !== '-');
|
13
|
+
|
12
14
|
// should we try to support types (while parsing)
|
13
|
-
const types = Prefs.parseTypes;
|
15
|
+
const types = Prefs.parseTypes || file?.endsWith('.ts');
|
14
16
|
globalThis.typedInput = types && Prefs.optTypes;
|
15
17
|
|
16
18
|
// todo: review which to use by default
|
@@ -23,7 +25,7 @@ globalThis.typedInput = types && Prefs.optTypes;
|
|
23
25
|
globalThis.parser = '';
|
24
26
|
let parse;
|
25
27
|
const loadParser = async (fallbackParser = 'acorn', forceParser) => {
|
26
|
-
parser = forceParser ?? process.argv.find(x => x.startsWith('
|
28
|
+
parser = forceParser ?? process.argv.find(x => x.startsWith('--parser='))?.split('=')?.[1] ?? fallbackParser;
|
27
29
|
0, { parse } = (await import((globalThis.document || globalThis.Deno ? 'https://esm.sh/' : '') + parser));
|
28
30
|
};
|
29
31
|
globalThis._porf_loadParser = loadParser;
|
package/compiler/precompile.js
CHANGED
@@ -21,7 +21,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
21
21
|
first = source.slice(0, source.indexOf('\n'));
|
22
22
|
}
|
23
23
|
|
24
|
-
let args = ['
|
24
|
+
let args = ['--bytestring', '--todo-time=compile', '--no-aot-pointer-opt', '--no-treeshake-wasm-imports', '--scoped-page-names', '--parse-types', '--opt-types'];
|
25
25
|
if (first.startsWith('// @porf')) {
|
26
26
|
args = args.concat(first.slice('// @porf '.length).split(' '));
|
27
27
|
}
|
@@ -70,7 +70,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
70
70
|
if (y[0] === Opcodes.const && (n[0] === Opcodes.local_set || n[0] === Opcodes.local_tee)) {
|
71
71
|
const l = locals[n[1]];
|
72
72
|
if (!l) continue;
|
73
|
-
if (![TYPES.string, TYPES.
|
73
|
+
if (![TYPES.string, TYPES.array, TYPES.bytestring].includes(l.metadata?.type)) continue;
|
74
74
|
if (!x.pages) continue;
|
75
75
|
|
76
76
|
const pageName = [...x.pages.keys()].find(z => z.endsWith(l.name));
|
@@ -93,9 +93,14 @@ const precompile = async () => {
|
|
93
93
|
let funcs = [], globals = [];
|
94
94
|
for (const file of fs.readdirSync(dir)) {
|
95
95
|
if (file.endsWith('.d.ts')) continue;
|
96
|
+
console.log(file);
|
97
|
+
|
96
98
|
await compile(join(dir, file), [ funcs, globals ]);
|
97
99
|
}
|
98
100
|
|
101
|
+
// const a = funcs.find(x => x.name === '__ecma262_ToUTCDTSF');
|
102
|
+
// console.log(Object.values(a.locals).slice(a.params.length));
|
103
|
+
|
99
104
|
// ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
|
100
105
|
// ${x.used && x.used.length > 0 ? ` used: ${JSON.stringify(x.used)},` : ''}
|
101
106
|
|
package/compiler/prefs.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
const onByDefault = [ 'bytestring', 'aotPointerOpt' ];
|
1
|
+
const onByDefault = [ 'bytestring', 'aotPointerOpt', 'treeshakeWasmImports', 'alwaysMemory' ];
|
2
2
|
|
3
3
|
let cache = {};
|
4
4
|
const obj = new Proxy({}, {
|
@@ -9,11 +9,12 @@ const obj = new Proxy({}, {
|
|
9
9
|
return cache[p] = (() => {
|
10
10
|
// fooBar -> foo-bar
|
11
11
|
const name = p[0] === '_' ? p : p.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);
|
12
|
-
|
13
|
-
if (process.argv.includes(
|
12
|
+
const prefix = name.length === 1 ? '-' : '--';
|
13
|
+
if (process.argv.includes(prefix + name)) return true;
|
14
|
+
if (process.argv.includes(prefix + 'no-' + name)) return false;
|
14
15
|
|
15
|
-
const valArg = process.argv.find(x => x.startsWith(
|
16
|
-
if (valArg) return valArg.slice(name.length +
|
16
|
+
const valArg = process.argv.find(x => x.startsWith(`${prefix}${name}=`));
|
17
|
+
if (valArg) return valArg.slice(name.length + 1 + prefix.length);
|
17
18
|
|
18
19
|
if (onByDefault.includes(p)) return true;
|
19
20
|
return undefined;
|
package/compiler/prototype.js
CHANGED
@@ -14,7 +14,7 @@ export const PrototypeFuncs = function() {
|
|
14
14
|
if (Prefs.zeroChecks) zeroChecks = Prefs.zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
|
15
15
|
else zeroChecks = {};
|
16
16
|
|
17
|
-
this[TYPES.
|
17
|
+
this[TYPES.array] = {
|
18
18
|
// lX = local accessor of X ({ get, set }), iX = local index of X, wX = wasm ops of X
|
19
19
|
at: (pointer, length, wIndex, iTmp) => [
|
20
20
|
...wIndex,
|
@@ -253,10 +253,10 @@ export const PrototypeFuncs = function() {
|
|
253
253
|
]
|
254
254
|
};
|
255
255
|
|
256
|
-
this[TYPES.
|
257
|
-
this[TYPES.
|
258
|
-
this[TYPES.
|
259
|
-
this[TYPES.
|
256
|
+
this[TYPES.array].at.local = Valtype.i32;
|
257
|
+
this[TYPES.array].push.noArgRetLength = true;
|
258
|
+
this[TYPES.array].fill.local = valtypeBinary;
|
259
|
+
this[TYPES.array].fill.returnType = TYPES.array;
|
260
260
|
|
261
261
|
this[TYPES.string] = {
|
262
262
|
at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
|
@@ -476,7 +476,7 @@ export const PrototypeFuncs = function() {
|
|
476
476
|
this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
|
477
477
|
|
478
478
|
if (Prefs.bytestring) {
|
479
|
-
this[TYPES.
|
479
|
+
this[TYPES.bytestring] = {
|
480
480
|
at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
|
481
481
|
const [ newOut, newPointer ] = arrayShell(1, 'i8');
|
482
482
|
|
@@ -606,14 +606,14 @@ export const PrototypeFuncs = function() {
|
|
606
606
|
}
|
607
607
|
};
|
608
608
|
|
609
|
-
this[TYPES.
|
610
|
-
this[TYPES.
|
611
|
-
this[TYPES.
|
612
|
-
this[TYPES.
|
613
|
-
this[TYPES.
|
609
|
+
this[TYPES.bytestring].at.local = Valtype.i32;
|
610
|
+
this[TYPES.bytestring].at.returnType = TYPES.bytestring;
|
611
|
+
this[TYPES.bytestring].charAt.returnType = TYPES.bytestring;
|
612
|
+
this[TYPES.bytestring].charCodeAt.local = Valtype.i32;
|
613
|
+
this[TYPES.bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
|
614
614
|
|
615
|
-
this[TYPES.
|
616
|
-
this[TYPES.
|
617
|
-
this[TYPES.
|
615
|
+
this[TYPES.bytestring].isWellFormed.local = Valtype.i32;
|
616
|
+
this[TYPES.bytestring].isWellFormed.local2 = Valtype.i32;
|
617
|
+
this[TYPES.bytestring].isWellFormed.returnType = TYPES.boolean;
|
618
618
|
}
|
619
619
|
};
|
package/compiler/types.js
CHANGED
@@ -24,7 +24,7 @@ export const INTERNAL_TYPE_BASE = 0x10;
|
|
24
24
|
let internalTypeIndex = INTERNAL_TYPE_BASE;
|
25
25
|
const registerInternalType = name => {
|
26
26
|
const n = internalTypeIndex++;
|
27
|
-
TYPES[
|
27
|
+
TYPES[name.toLowerCase()] = n;
|
28
28
|
TYPE_NAMES[n] = name;
|
29
29
|
};
|
30
30
|
|
package/compiler/wrap.js
CHANGED
@@ -178,7 +178,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
178
178
|
return {[func.name]() {}}[func.name];
|
179
179
|
}
|
180
180
|
|
181
|
-
case TYPES.
|
181
|
+
case TYPES.array: {
|
182
182
|
const pointer = ret;
|
183
183
|
const length = (new Int32Array(memory.buffer, pointer, 1))[0];
|
184
184
|
|
@@ -188,14 +188,14 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
188
188
|
return Array.from(new Float64Array(buf));
|
189
189
|
}
|
190
190
|
|
191
|
-
case TYPES.
|
191
|
+
case TYPES.bytestring: {
|
192
192
|
const pointer = ret;
|
193
193
|
const length = (new Int32Array(memory.buffer, pointer, 1))[0];
|
194
194
|
|
195
195
|
return Array.from(new Uint8Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
|
196
196
|
}
|
197
197
|
|
198
|
-
case TYPES.
|
198
|
+
case TYPES.date: {
|
199
199
|
const pointer = ret;
|
200
200
|
const value = (new Float64Array(memory.buffer, pointer, 1))[0];
|
201
201
|
|
package/package.json
CHANGED
package/rhemyn/compile.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype,
|
1
|
+
import { Blocktype, Opcodes, Valtype, ValtypeSize } from '../compiler/wasmSpec.js';
|
2
2
|
import { number } from '../compiler/embedding.js';
|
3
|
-
import { signedLEB128, unsignedLEB128 } from '../compiler/encoding.js';
|
4
3
|
import parse from './parse.js';
|
5
4
|
import Prefs from '../compiler/prefs.js';
|
5
|
+
import { TYPES } from '../compiler/types.js';
|
6
6
|
|
7
7
|
// local indexes
|
8
8
|
const BasePointer = 0; // base string pointer
|
@@ -14,7 +14,7 @@ const Length = 5;
|
|
14
14
|
const Tmp = 6;
|
15
15
|
|
16
16
|
let exprLastGet = false;
|
17
|
-
const generate = (node, negated = false, get = true, func = 'test') => {
|
17
|
+
const generate = (node, negated = false, get = true, stringSize = 2, func = 'test') => {
|
18
18
|
let out = [];
|
19
19
|
switch (node.type) {
|
20
20
|
case 'Expression':
|
@@ -42,7 +42,7 @@ const generate = (node, negated = false, get = true, func = 'test') => {
|
|
42
42
|
// generate checks
|
43
43
|
...node.body.flatMap((x, i) => {
|
44
44
|
exprLastGet = x.type !== 'Group' && i === (node.body.length - 1);
|
45
|
-
return generate(x, negated);
|
45
|
+
return generate(x, negated, true, stringSize, func);
|
46
46
|
}),
|
47
47
|
|
48
48
|
// reached end without branching out, successful match
|
@@ -56,9 +56,9 @@ const generate = (node, negated = false, get = true, func = 'test') => {
|
|
56
56
|
|
57
57
|
[ Opcodes.end ],
|
58
58
|
|
59
|
-
// increment iter pointer by
|
59
|
+
// increment iter pointer by string size
|
60
60
|
[ Opcodes.local_get, IterPointer ],
|
61
|
-
...number(
|
61
|
+
...number(stringSize, Valtype.i32),
|
62
62
|
[ Opcodes.i32_add ],
|
63
63
|
[ Opcodes.local_set, IterPointer ],
|
64
64
|
|
@@ -91,34 +91,34 @@ const generate = (node, negated = false, get = true, func = 'test') => {
|
|
91
91
|
break;
|
92
92
|
|
93
93
|
case 'Character':
|
94
|
-
out = generateChar(node, node.negated ^ negated, get);
|
94
|
+
out = generateChar(node, node.negated ^ negated, get, stringSize);
|
95
95
|
break;
|
96
96
|
|
97
97
|
case 'Set':
|
98
|
-
out = generateSet(node, node.negated, get);
|
98
|
+
out = generateSet(node, node.negated, get, stringSize);
|
99
99
|
break;
|
100
100
|
|
101
101
|
case 'Group':
|
102
|
-
out = generateGroup(node, negated, get);
|
102
|
+
out = generateGroup(node, negated, get, stringSize);
|
103
103
|
break;
|
104
104
|
|
105
105
|
case 'Range':
|
106
|
-
out = generateRange(node, negated, get);
|
106
|
+
out = generateRange(node, negated, get, stringSize);
|
107
107
|
break;
|
108
108
|
}
|
109
109
|
|
110
110
|
return out;
|
111
111
|
};
|
112
112
|
|
113
|
-
const getNextChar = () => [
|
113
|
+
const getNextChar = (stringSize) => [
|
114
114
|
// get char from pointer
|
115
115
|
[ Opcodes.local_get, Pointer ],
|
116
|
-
[ Opcodes.i32_load16_u
|
116
|
+
[ stringSize == 2 ? Opcodes.i32_load16_u : Opcodes.i32_load8_u, 0, 0 ],
|
117
117
|
|
118
118
|
...(exprLastGet ? [] : [
|
119
|
-
// pointer +=
|
119
|
+
// pointer += string size
|
120
120
|
[ Opcodes.local_get, Pointer ],
|
121
|
-
...number(
|
121
|
+
...number(stringSize, Valtype.i32),
|
122
122
|
[ Opcodes.i32_add ],
|
123
123
|
[ Opcodes.local_set, Pointer ]
|
124
124
|
])
|
@@ -134,21 +134,21 @@ const checkFailure = () => [
|
|
134
134
|
[ Opcodes.br_if, 0 ]
|
135
135
|
];
|
136
136
|
|
137
|
-
const generateChar = (node, negated, get) => {
|
137
|
+
const generateChar = (node, negated, get, stringSize) => {
|
138
138
|
return [
|
139
|
-
...(get ? getNextChar() : []),
|
139
|
+
...(get ? getNextChar(stringSize) : []),
|
140
140
|
...number(node.char.charCodeAt(0), Valtype.i32),
|
141
141
|
negated ? [ Opcodes.i32_eq ] : [ Opcodes.i32_ne ],
|
142
142
|
...(get ? checkFailure(): [])
|
143
143
|
];
|
144
144
|
};
|
145
145
|
|
146
|
-
const generateSet = (node, negated, get) => {
|
146
|
+
const generateSet = (node, negated, get, stringSize) => {
|
147
147
|
// for a single char we do not need a tmp, it is like just
|
148
148
|
const singleChar = node.body.length === 1 && node.body[0].type === 'Character';
|
149
149
|
|
150
150
|
let out = [
|
151
|
-
...(get ? getNextChar() : []),
|
151
|
+
...(get ? getNextChar(stringSize) : []),
|
152
152
|
...(singleChar ? [] : [ [ Opcodes.local_set, Tmp ] ]),
|
153
153
|
];
|
154
154
|
|
@@ -156,7 +156,7 @@ const generateSet = (node, negated, get) => {
|
|
156
156
|
out = [
|
157
157
|
...out,
|
158
158
|
...(singleChar ? [] : [ [ Opcodes.local_get, Tmp ] ]),
|
159
|
-
...generate(x, negated, false)
|
159
|
+
...generate(x, negated, false, stringSize)
|
160
160
|
];
|
161
161
|
}
|
162
162
|
|
@@ -168,9 +168,9 @@ const generateSet = (node, negated, get) => {
|
|
168
168
|
];
|
169
169
|
};
|
170
170
|
|
171
|
-
const generateRange = (node, negated, get) => {
|
171
|
+
const generateRange = (node, negated, get, stringSize) => {
|
172
172
|
return [
|
173
|
-
...(get ? getNextChar() : []),
|
173
|
+
...(get ? getNextChar(stringSize) : []),
|
174
174
|
...(get ? [ [ Opcodes.local_tee, Tmp ] ] : []),
|
175
175
|
|
176
176
|
...number(node.from.charCodeAt(0), Valtype.i32),
|
@@ -192,8 +192,25 @@ const generateGroup = (node, negated, get) => {
|
|
192
192
|
return [];
|
193
193
|
};
|
194
194
|
|
195
|
-
|
196
|
-
|
195
|
+
const wrapFunc = (regex, func, name, index) => {
|
196
|
+
const parsed = parse(regex);
|
197
|
+
|
198
|
+
return outputFunc([
|
199
|
+
[ Opcodes.local_get, 1 ],
|
200
|
+
...number(TYPES.string, Valtype.i32),
|
201
|
+
[ Opcodes.i32_eq ],
|
202
|
+
[ Opcodes.if, Valtype.i32 ],
|
203
|
+
// string
|
204
|
+
...generate(parsed, false, true, 2, func),
|
205
|
+
[ Opcodes.else ],
|
206
|
+
// bytestring
|
207
|
+
...generate(parsed, false, true, 1, func),
|
208
|
+
[ Opcodes.end ]
|
209
|
+
], name, index);
|
210
|
+
};
|
211
|
+
|
212
|
+
export const test = (regex, index = 0, name = 'regex_test_' + regex) => wrapFunc(regex, 'test', name, index);
|
213
|
+
export const search = (regex, index = 0, name = 'regex_search_' + regex) => wrapFunc(regex, 'search', name, index);
|
197
214
|
|
198
215
|
const outputFunc = (wasm, name, index) => ({
|
199
216
|
name,
|
@@ -201,9 +218,9 @@ const outputFunc = (wasm, name, index) => ({
|
|
201
218
|
wasm,
|
202
219
|
|
203
220
|
export: true,
|
204
|
-
params: [ Valtype.i32 ],
|
221
|
+
params: [ Valtype.i32, Valtype.i32 ],
|
205
222
|
returns: [ Valtype.i32 ],
|
206
|
-
returnType:
|
223
|
+
returnType: TYPES.boolean,
|
207
224
|
locals: {
|
208
225
|
basePointer: { idx: 0, type: Valtype.i32 },
|
209
226
|
iterPointer: { idx: 1, type: Valtype.i32 },
|
package/rhemyn/parse.js
CHANGED
@@ -11,7 +11,7 @@ const Quantifiers = {
|
|
11
11
|
const QuantifierKeys = Object.keys(Quantifiers);
|
12
12
|
|
13
13
|
const getArg = (name, def) => {
|
14
|
-
const arg = (typeof process !== 'undefined' ? process.argv : Deno.args).find(x => x.startsWith(
|
14
|
+
const arg = (typeof process !== 'undefined' ? process.argv : Deno.args).find(x => x.startsWith(`--${name}=`));
|
15
15
|
if (arg) return arg.split('=')[0];
|
16
16
|
|
17
17
|
return def;
|
@@ -20,8 +20,7 @@ const getArg = (name, def) => {
|
|
20
20
|
// full is spec-compliant but slower. not needed most of the time. (evil)
|
21
21
|
const DotChars = () => ({
|
22
22
|
full: [ '\n', '\r', '\u2028', '\u2029' ],
|
23
|
-
|
24
|
-
fast: [ '\n' ]
|
23
|
+
fast: [ '\n', '\r' ]
|
25
24
|
})[getArg('regex-dot', 'fast')];
|
26
25
|
|
27
26
|
const WordChars = () => ({
|
@@ -31,8 +30,8 @@ const WordChars = () => ({
|
|
31
30
|
|
32
31
|
const WhitespaceChars = () => ({
|
33
32
|
full: [ ' ', '\t', '\n', '\r', '\u2028', '\u2029' ],
|
34
|
-
|
35
|
-
})[getArg('regex-ws', '
|
33
|
+
fast: [ ' ', '\t', '\n', '\r' ]
|
34
|
+
})[getArg('regex-ws', 'fast')];
|
36
35
|
|
37
36
|
const _Metachars = () => ({
|
38
37
|
unescaped: {
|
package/runner/index.js
CHANGED
@@ -5,7 +5,7 @@ import fs from 'node:fs';
|
|
5
5
|
|
6
6
|
const start = performance.now();
|
7
7
|
|
8
|
-
if (process.argv.includes('
|
8
|
+
if (process.argv.includes('--compile-hints')) {
|
9
9
|
const v8 = await import('node:v8');
|
10
10
|
v8.setFlagsFromString(`--experimental-wasm-compilation-hints`);
|
11
11
|
|
@@ -17,6 +17,47 @@ if (process.argv.includes('-compile-hints')) {
|
|
17
17
|
// --experimental-wasm-return-call (on by default)
|
18
18
|
}
|
19
19
|
|
20
|
+
if (process.argv.includes('--help')) {
|
21
|
+
// description + version
|
22
|
+
console.log(`\x1B[1m\x1B[35mPorffor\x1B[0m is a JavaScript engine/runtime/compiler. \x1B[90m(${(await import('./version.js')).default})\x1B[0m`);
|
23
|
+
|
24
|
+
// basic usage
|
25
|
+
console.log(`Usage: \x1B[1mporf [command] path/to/script.js [...prefs] [...args]\x1B[0m`);
|
26
|
+
|
27
|
+
// commands
|
28
|
+
console.log(`\n\u001b[4mCommands\x1B[0m`);
|
29
|
+
for (const [ cmd, [ color, desc ] ] of Object.entries({
|
30
|
+
run: [ 34, 'Run a JS file' ],
|
31
|
+
wasm: [ 34, 'Compile a JS file to a Wasm binary\n' ],
|
32
|
+
c: [ 31, 'Compile a JS file to C source code' ],
|
33
|
+
native: [ 31, 'Compile a JS file to a native binary\n' ],
|
34
|
+
profile: [ 33, 'Profile a JS file' ],
|
35
|
+
debug: [ 33, 'Debug a JS file' ],
|
36
|
+
'debug-wasm': [ 33, 'Debug the compiled Wasm of a JS file' ]
|
37
|
+
})) {
|
38
|
+
console.log(` \x1B[1m\x1B[${color}m${cmd}\x1B[0m${' '.repeat(20 - cmd.length - (desc.startsWith('🧪') ? 3 : 0))}${desc}`);
|
39
|
+
}
|
40
|
+
|
41
|
+
// console.log();
|
42
|
+
|
43
|
+
// // options
|
44
|
+
// console.log(`\n\u001b[4mCommands\x1B[0m`);
|
45
|
+
// for (const [ cmd, [ color, desc ] ] of Object.entries({
|
46
|
+
// run: [ 34, 'Run a JS file' ],
|
47
|
+
// wasm: [ 34, 'Compile a JS file to a Wasm binary\n' ],
|
48
|
+
// c: [ 31, 'Compile a JS file to C source code' ],
|
49
|
+
// native: [ 31, 'Compile a JS file to a native binary\n' ],
|
50
|
+
// profile: [ 33, 'Profile a JS file' ],
|
51
|
+
// debug: [ 33, 'Debug a JS file' ],
|
52
|
+
// 'debug-wasm': [ 33, 'Debug the compiled Wasm of a JS file' ]
|
53
|
+
// })) {
|
54
|
+
// console.log(` \x1B[1m\x1B[${color}m${cmd}\x1B[0m${' '.repeat(20 - cmd.length - (desc.startsWith('🧪') ? 3 : 0))}${desc}`);
|
55
|
+
// }
|
56
|
+
|
57
|
+
console.log();
|
58
|
+
process.exit(0);
|
59
|
+
}
|
60
|
+
|
20
61
|
let file = process.argv.slice(2).find(x => x[0] !== '-');
|
21
62
|
if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
|
22
63
|
if (file === 'profile') {
|
@@ -26,11 +67,11 @@ if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(fi
|
|
26
67
|
}
|
27
68
|
|
28
69
|
if (['wasm', 'native', 'c'].includes(file)) {
|
29
|
-
process.argv.push(
|
70
|
+
process.argv.push(`--target=${file}`);
|
30
71
|
}
|
31
72
|
|
32
73
|
if (file === 'debug-wasm') {
|
33
|
-
process.argv.push('
|
74
|
+
process.argv.push('--asur', '--wasm-debug');
|
34
75
|
}
|
35
76
|
|
36
77
|
if (file === 'debug') {
|
@@ -77,7 +118,7 @@ try {
|
|
77
118
|
if (process.argv.includes('-b')) {
|
78
119
|
const { wasm, exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
79
120
|
|
80
|
-
if (!process.argv.includes('
|
121
|
+
if (!process.argv.includes('--no-run')) exports.main();
|
81
122
|
|
82
123
|
console.log(`\n\nwasm size: ${wasm.byteLength} bytes`);
|
83
124
|
} else {
|
package/runner/repl.js
CHANGED
@@ -21,7 +21,7 @@ try {
|
|
21
21
|
|
22
22
|
globalThis.valtype = 'f64';
|
23
23
|
|
24
|
-
const valtypeOpt = process.argv.find(x => x.startsWith('
|
24
|
+
const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
|
25
25
|
if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
|
26
26
|
|
27
27
|
let host = globalThis?.navigator?.userAgent;
|
@@ -116,7 +116,7 @@ replServer.defineCommand('asm', {
|
|
116
116
|
this.clearBufferedCommand();
|
117
117
|
|
118
118
|
try {
|
119
|
-
process.argv.push('
|
119
|
+
process.argv.push('--opt-funcs');
|
120
120
|
await run('', null, null, () => {}, false);
|
121
121
|
process.argv.pop();
|
122
122
|
} catch { }
|
package/runner/sizes.js
CHANGED
@@ -18,7 +18,7 @@ const perform = async (file, args) => {
|
|
18
18
|
console.log(label, ' '.repeat(40 - label.length), `${size}b`);
|
19
19
|
};
|
20
20
|
|
21
|
-
const argsValtypes = [ '
|
21
|
+
const argsValtypes = [ '--valtype=i32', '--valtype=i64', '--valtype=f64' ];
|
22
22
|
const argsOptlevels = [ '-O0', '-O1', '-O2', '-O3' ];
|
23
23
|
|
24
24
|
for (const file of [ 'bench/prime_basic.js', 'bench/fib_iter.js', 'test/math_1.js', 'test/math_3.js', 'test/while_1.js', 'test/for_2.js', 'test/unary_3.js', 'test/updateexp_1.js', 'test/eq_3.js', 'test/empty.js' ]) {
|