porffor 0.2.0-ef043de → 0.2.0-f7ea197
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 +18 -24
- package/asur/index.js +1 -1
- package/compiler/assemble.js +1 -1
- package/compiler/codegen.js +14 -7
- package/compiler/parse.js +1 -1
- package/compiler/precompile.js +1 -1
- package/compiler/prefs.js +5 -4
- package/fib.js +5 -2
- package/package.json +1 -1
- package/rhemyn/compile.js +42 -25
- package/rhemyn/parse.js +4 -5
- package/runner/index.js +34 -6
- package/runner/repl.js +2 -2
- package/runner/sizes.js +1 -1
package/README.md
CHANGED
@@ -23,13 +23,13 @@ Expect nothing to work! Only very limited JS is currently supported. See files i
|
|
23
23
|
**`porf path/to/script.js`**
|
24
24
|
|
25
25
|
### Compiling to Wasm
|
26
|
-
**`porf
|
26
|
+
**`porf wasm path/to/script.js out.wasm`**. Currently it does not use an import standard like WASI, so it is mostly unusable on its own.
|
27
27
|
|
28
28
|
### Compiling to native binaries
|
29
29
|
> [!WARNING]
|
30
30
|
> Compiling to native binaries uses [2c](#2c), Porffor's own Wasm -> C compiler, which is experimental.
|
31
31
|
|
32
|
-
**`porf native path/to/script.js out(.exe)`**. You can specify the compiler with
|
32
|
+
**`porf native path/to/script.js out(.exe)`**. You can specify the compiler with `--compiler=clang/zig/gcc`, and which opt level to use with `--cO=O3` (`Ofast` by default). Output binaries are also stripped by default.
|
33
33
|
|
34
34
|
### Compiling to C
|
35
35
|
> [!WARNING]
|
@@ -57,31 +57,25 @@ Expect nothing to work! Only very limited JS is currently supported. See files i
|
|
57
57
|
|
58
58
|
|
59
59
|
### Options
|
60
|
-
-
|
61
|
-
- `-
|
62
|
-
|
63
|
-
-
|
64
|
-
- `-compiler=clang` to set compiler binary (path/name) to use to compile
|
65
|
-
- `-cO=O3` to set compiler opt argument
|
66
|
-
- `-parser=acorn|@babel/parser|meriyah|hermes-parser` (default: `acorn`) to set which parser to use
|
67
|
-
- `-parse-types` to enable parsing type annotations/typescript. if `-parser` is unset, changes default to `@babel/parser`. does not type check
|
68
|
-
- `-opt-types` to perform optimizations using type annotations as compiler hints. does not type check
|
69
|
-
- `-valtype=i32|i64|f64` (default: `f64`) to set valtype
|
60
|
+
- `--parser=acorn|@babel/parser|meriyah|hermes-parser` (default: `acorn`) to set which parser to use
|
61
|
+
- `--parse-types` to enable parsing type annotations/typescript. if `-parser` is unset, changes default to `@babel/parser`. does not type check
|
62
|
+
- `--opt-types` to perform optimizations using type annotations as compiler hints. does not type check
|
63
|
+
- `--valtype=i32|i64|f64` (default: `f64`) to set valtype
|
70
64
|
- `-O0` to disable opt
|
71
65
|
- `-O1` (default) to enable basic opt (simplify insts, treeshake wasm imports)
|
72
66
|
- `-O2` to enable advanced opt (inlining). unstable
|
73
67
|
- `-O3` to enable advanceder opt (precompute const math). unstable
|
74
|
-
-
|
75
|
-
-
|
76
|
-
-
|
77
|
-
-
|
78
|
-
-
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
-
|
84
|
-
-
|
68
|
+
- `--no-run` to not run wasm output, just compile
|
69
|
+
- `--opt-log` to log some opts
|
70
|
+
- `--code-log` to log some codegen (you probably want `-funcs`)
|
71
|
+
- `--regex-log` to log some regex
|
72
|
+
- `--funcs` to log funcs
|
73
|
+
- `--ast-log` to log AST
|
74
|
+
- `--opt-funcs` to log funcs after opt
|
75
|
+
- `--sections` to log sections as hex
|
76
|
+
- `--opt-no-inline` to not inline any funcs
|
77
|
+
- `--tail-call` to enable tail calls (experimental + not widely implemented)
|
78
|
+
- `--compile-hints` to enable V8 compilation hints (experimental + doesn't seem to do much?)
|
85
79
|
|
86
80
|
### Running in the repo
|
87
81
|
The repo comes with easy alias files for Unix and Windows, which you can use like so:
|
@@ -211,7 +205,7 @@ Mostly for reducing size. I do not really care about compiler perf/time as long
|
|
211
205
|
### Traditional opts
|
212
206
|
- Inlining functions (WIP, limited)
|
213
207
|
- Inline const math ops
|
214
|
-
- Tail calls (behind flag
|
208
|
+
- Tail calls (behind flag `--tail-call`)
|
215
209
|
|
216
210
|
### Wasm transforms
|
217
211
|
- `local.set`, `local.get` -> `local.tee`
|
package/asur/index.js
CHANGED
@@ -1244,7 +1244,7 @@ paused = _paused;`);
|
|
1244
1244
|
});
|
1245
1245
|
|
1246
1246
|
export const instantiate = async (binary, importImpls) => {
|
1247
|
-
const _vm = process?.argv?.includes('
|
1247
|
+
const _vm = process?.argv?.includes('--wasm-debug') ? await wasmDebugVm() : vm;
|
1248
1248
|
|
1249
1249
|
const parsed = parse(binary);
|
1250
1250
|
const exports = {};
|
package/compiler/assemble.js
CHANGED
@@ -154,7 +154,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
154
154
|
|
155
155
|
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, x.index ]);
|
156
156
|
|
157
|
-
if (Prefs.alwaysMemory && pages.size === 0) pages.set('
|
157
|
+
if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
|
158
158
|
if (optLevel === 0) pages.set('O0 precaution', 0);
|
159
159
|
|
160
160
|
const usesMemory = pages.size > 0;
|
package/compiler/codegen.js
CHANGED
@@ -1646,18 +1646,25 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1646
1646
|
// megahack for /regex/.func()
|
1647
1647
|
const funcName = decl.callee.property.name;
|
1648
1648
|
if (decl.callee.object.regex && Object.hasOwn(Rhemyn, funcName)) {
|
1649
|
-
const
|
1649
|
+
const regex = decl.callee.object.regex.pattern;
|
1650
|
+
const rhemynName = `regex_${funcName}_${regex}`;
|
1650
1651
|
|
1651
|
-
funcIndex[
|
1652
|
-
|
1652
|
+
if (!funcIndex[rhemynName]) {
|
1653
|
+
const func = Rhemyn[funcName](regex, currentFuncIndex++, rhemynName);
|
1653
1654
|
|
1655
|
+
funcIndex[func.name] = func.index;
|
1656
|
+
funcs.push(func);
|
1657
|
+
}
|
1658
|
+
|
1659
|
+
const idx = funcIndex[rhemynName];
|
1654
1660
|
return [
|
1655
1661
|
// make string arg
|
1656
1662
|
...generate(scope, decl.arguments[0]),
|
1663
|
+
Opcodes.i32_to_u,
|
1664
|
+
...getNodeType(scope, decl.arguments[0]),
|
1657
1665
|
|
1658
1666
|
// call regex func
|
1659
|
-
Opcodes.
|
1660
|
-
[ Opcodes.call, func.index ],
|
1667
|
+
[ Opcodes.call, idx ],
|
1661
1668
|
Opcodes.i32_from_u,
|
1662
1669
|
|
1663
1670
|
...number(TYPES.boolean, Valtype.i32),
|
@@ -3649,7 +3656,7 @@ export default program => {
|
|
3649
3656
|
|
3650
3657
|
globalThis.valtype = 'f64';
|
3651
3658
|
|
3652
|
-
const valtypeOpt = process.argv.find(x => x.startsWith('
|
3659
|
+
const valtypeOpt = process.argv.find(x => x.startsWith('--valtype='));
|
3653
3660
|
if (valtypeOpt) valtype = valtypeOpt.split('=')[1];
|
3654
3661
|
|
3655
3662
|
globalThis.valtypeBinary = Valtype[valtype];
|
@@ -3657,7 +3664,7 @@ export default program => {
|
|
3657
3664
|
const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
|
3658
3665
|
|
3659
3666
|
globalThis.pageSize = PageSize;
|
3660
|
-
const pageSizeOpt = process.argv.find(x => x.startsWith('
|
3667
|
+
const pageSizeOpt = process.argv.find(x => x.startsWith('--page-size='));
|
3661
3668
|
if (pageSizeOpt) pageSize = parseInt(pageSizeOpt.split('=')[1]) * 1024;
|
3662
3669
|
|
3663
3670
|
// set generic opcodes for current valtype
|
package/compiler/parse.js
CHANGED
@@ -23,7 +23,7 @@ globalThis.typedInput = types && Prefs.optTypes;
|
|
23
23
|
globalThis.parser = '';
|
24
24
|
let parse;
|
25
25
|
const loadParser = async (fallbackParser = 'acorn', forceParser) => {
|
26
|
-
parser = forceParser ?? process.argv.find(x => x.startsWith('
|
26
|
+
parser = forceParser ?? process.argv.find(x => x.startsWith('--parser='))?.split('=')?.[1] ?? fallbackParser;
|
27
27
|
0, { parse } = (await import((globalThis.document || globalThis.Deno ? 'https://esm.sh/' : '') + parser));
|
28
28
|
};
|
29
29
|
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
|
}
|
package/compiler/prefs.js
CHANGED
@@ -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/fib.js
CHANGED
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
|
|
@@ -22,11 +22,39 @@ if (process.argv.includes('--help')) {
|
|
22
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
23
|
|
24
24
|
// basic usage
|
25
|
-
console.log(
|
25
|
+
console.log(`Usage: \x1B[1mporf [command] path/to/script.js [...prefs] [...args]\x1B[0m`);
|
26
26
|
|
27
27
|
// commands
|
28
|
-
console.log(`\
|
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
|
+
}
|
29
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();
|
30
58
|
process.exit(0);
|
31
59
|
}
|
32
60
|
|
@@ -39,11 +67,11 @@ if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(fi
|
|
39
67
|
}
|
40
68
|
|
41
69
|
if (['wasm', 'native', 'c'].includes(file)) {
|
42
|
-
process.argv.push(
|
70
|
+
process.argv.push(`--target=${file}`);
|
43
71
|
}
|
44
72
|
|
45
73
|
if (file === 'debug-wasm') {
|
46
|
-
process.argv.push('
|
74
|
+
process.argv.push('--asur', '--wasm-debug');
|
47
75
|
}
|
48
76
|
|
49
77
|
if (file === 'debug') {
|
@@ -90,7 +118,7 @@ try {
|
|
90
118
|
if (process.argv.includes('-b')) {
|
91
119
|
const { wasm, exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
92
120
|
|
93
|
-
if (!process.argv.includes('
|
121
|
+
if (!process.argv.includes('--no-run')) exports.main();
|
94
122
|
|
95
123
|
console.log(`\n\nwasm size: ${wasm.byteLength} bytes`);
|
96
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' ]) {
|