porffor 0.34.12 → 0.34.14
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 -5
- package/compiler/2c.js +1 -0
- package/compiler/codegen.js +2 -0
- package/compiler/index.js +40 -9
- package/compiler/opt.js +3 -0
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/README.md
CHANGED
@@ -67,12 +67,10 @@ Expect nothing to work! Only very limited JS is currently supported. See files i
|
|
67
67
|
- `-O2` to enable advanced opt (inlining). unstable!
|
68
68
|
- `-O3` to enable advanceder opt (precompute const math). unstable!
|
69
69
|
|
70
|
-
##
|
71
|
-
-
|
72
|
-
- No object prototypes yet
|
73
|
-
- No async/promise/await
|
70
|
+
## Current limitations
|
71
|
+
- Limited async support
|
74
72
|
- No variables between scopes (except args and globals)
|
75
|
-
- No `eval()` etc (since it is AOT)
|
73
|
+
- No `eval()`/`Function()` etc (since it is AOT)
|
76
74
|
|
77
75
|
## Sub-engines
|
78
76
|
|
@@ -154,6 +152,8 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
|
|
154
152
|
- Rest parameters (`(...foo) => { ... }`)
|
155
153
|
- `this`
|
156
154
|
- Constructors (`new Foo`)
|
155
|
+
- Classes (`class A {}`)
|
156
|
+
- Await (`await promise`)
|
157
157
|
|
158
158
|
### Built-ins
|
159
159
|
|
@@ -176,6 +176,7 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
|
|
176
176
|
- `parseInt`
|
177
177
|
- Spec-compliant `Date`
|
178
178
|
- WIP typed arrays (`Uint8Array`, `Int32Array`, etc)
|
179
|
+
- Synchronous `Promise`
|
179
180
|
|
180
181
|
### Custom
|
181
182
|
|
package/compiler/2c.js
CHANGED
@@ -727,6 +727,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
727
727
|
line(`printf("Uncaught ${exceptions[id].constructor}: ${exceptions[id].message}\\n")`);
|
728
728
|
line(`exit(1)`);
|
729
729
|
|
730
|
+
includes.set('stdio.h', true);
|
730
731
|
includes.set('stdlib.h', true);
|
731
732
|
|
732
733
|
break;
|
package/compiler/codegen.js
CHANGED
package/compiler/index.js
CHANGED
@@ -27,10 +27,36 @@ const logFuncs = (funcs, globals, exceptions) => {
|
|
27
27
|
const fs = (typeof process?.version !== 'undefined' ? (await import('node:fs')) : undefined);
|
28
28
|
const execSync = (typeof process?.version !== 'undefined' ? (await import('node:child_process')).execSync : undefined);
|
29
29
|
|
30
|
+
let progressLines = 0, progressInterval;
|
31
|
+
let spinner = ['-', '\\', '|', '/'], spin = 0;
|
32
|
+
const progressStart = msg => {
|
33
|
+
const log = (extra, after) => {
|
34
|
+
const pre = extra ? `${extra}` : spinner[spin++ % 4];
|
35
|
+
process.stdout.write(`\r\u001b[90m${' '.repeat(10 - pre.length)}${pre} ${msg}${after ?? ''}\u001b[0m`);
|
36
|
+
};
|
37
|
+
log();
|
38
|
+
|
39
|
+
globalThis.progress = log;
|
40
|
+
progressInterval = setInterval(log, 100);
|
41
|
+
};
|
42
|
+
const progressDone = (msg, start) => {
|
43
|
+
clearInterval(progressInterval);
|
44
|
+
|
45
|
+
const timeStr = (performance.now() - start).toFixed(2);
|
46
|
+
console.log(`\r${' '.repeat(50)}\r\u001b[90m${' '.repeat(8 - timeStr.length)}${timeStr}ms\u001b[0m \u001b[92m${msg}\u001b[0m`);
|
47
|
+
progressLines++;
|
48
|
+
};
|
49
|
+
const progressClear = () => {
|
50
|
+
process.stdout.write(`\u001b[${progressLines}F\u001b[0J`);
|
51
|
+
progressLines = 0;
|
52
|
+
};
|
53
|
+
|
30
54
|
export default (code, flags) => {
|
31
55
|
let target = Prefs.target ?? 'wasm';
|
32
56
|
if (Prefs.native) target = 'native';
|
33
57
|
|
58
|
+
const logProgress = Prefs.profileCompiler || (target === 'native' && !Prefs.native && globalThis.file);
|
59
|
+
|
34
60
|
let outFile = Prefs.o;
|
35
61
|
|
36
62
|
globalThis.valtype = Prefs.valtype ?? 'f64';
|
@@ -46,18 +72,19 @@ export default (code, flags) => {
|
|
46
72
|
|
47
73
|
if (Prefs.pgo) pgo.setup();
|
48
74
|
|
49
|
-
if (
|
50
|
-
|
75
|
+
if (logProgress) progressStart('parsing...');
|
51
76
|
const t0 = performance.now();
|
52
77
|
const program = parse(code, flags);
|
53
|
-
if (
|
78
|
+
if (logProgress) progressDone('parsed', t0);
|
54
79
|
|
80
|
+
if (logProgress) progressStart('generating wasm...');
|
55
81
|
const t1 = performance.now();
|
56
82
|
const { funcs, globals, tags, exceptions, pages, data } = codegen(program);
|
57
|
-
if (
|
83
|
+
if (logProgress) progressDone('generated wasm', t1);
|
58
84
|
|
59
85
|
if (Prefs.funcs) logFuncs(funcs, globals, exceptions);
|
60
86
|
|
87
|
+
if (logProgress) progressStart('optimizing...');
|
61
88
|
const t2 = performance.now();
|
62
89
|
opt(funcs, globals, pages, tags, exceptions);
|
63
90
|
|
@@ -103,7 +130,7 @@ export default (code, flags) => {
|
|
103
130
|
}
|
104
131
|
}
|
105
132
|
|
106
|
-
if (
|
133
|
+
if (logProgress) progressDone('optimized', t2);
|
107
134
|
|
108
135
|
if (Prefs.builtinTree) {
|
109
136
|
let data = funcs.filter(x => x.includes);
|
@@ -131,12 +158,13 @@ export default (code, flags) => {
|
|
131
158
|
console.log(`built-in tree: ${url}`);
|
132
159
|
}
|
133
160
|
|
161
|
+
if (logProgress) progressStart('assembling...');
|
134
162
|
const t3 = performance.now();
|
135
163
|
const out = { funcs, globals, tags, exceptions, pages, data, times: [ t0, t1, t2, t3 ] };
|
136
164
|
if (globalThis.precompile) return out;
|
137
165
|
|
138
166
|
const wasm = out.wasm = assemble(funcs, globals, tags, pages, data, flags);
|
139
|
-
if (
|
167
|
+
if (logProgress) progressDone('assembled', t3);
|
140
168
|
|
141
169
|
if (Prefs.optFuncs) logFuncs(funcs, globals, exceptions);
|
142
170
|
|
@@ -179,10 +207,12 @@ export default (code, flags) => {
|
|
179
207
|
const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO ];
|
180
208
|
if (!Prefs.compiler) args.push('-flto=thin', '-march=native', '-s', '-ffast-math', '-fno-exceptions', '-fno-ident', '-fno-asynchronous-unwind-tables', '-ffunction-sections', '-fdata-sections', '-Wl,--gc-sections');
|
181
209
|
|
210
|
+
if (logProgress) progressStart('compiling Wasm to C...');
|
182
211
|
const t4 = performance.now();
|
183
212
|
const c = toc(out);
|
184
|
-
if (
|
213
|
+
if (logProgress) progressDone('compiled Wasm to C', t4);
|
185
214
|
|
215
|
+
if (logProgress) progressStart(`compiling C to native (using ${compiler})...`);
|
186
216
|
const t5 = performance.now();
|
187
217
|
|
188
218
|
fs.writeFileSync(tmpfile, c);
|
@@ -192,7 +222,7 @@ export default (code, flags) => {
|
|
192
222
|
|
193
223
|
fs.unlinkSync(tmpfile);
|
194
224
|
|
195
|
-
if (
|
225
|
+
if (logProgress) progressStart(`compiled C to native (using ${compiler})`, t5);
|
196
226
|
|
197
227
|
if (process.version) {
|
198
228
|
if (Prefs.native) {
|
@@ -215,8 +245,9 @@ export default (code, flags) => {
|
|
215
245
|
} catch {}
|
216
246
|
}
|
217
247
|
|
218
|
-
if (
|
248
|
+
if (logProgress) {
|
219
249
|
const total = performance.now();
|
250
|
+
progressClear();
|
220
251
|
console.log(`\u001b[90m[${total.toFixed(2)}ms]\u001b[0m \u001b[92mcompiled ${globalThis.file} -> ${outFile}\u001b[0m`);
|
221
252
|
}
|
222
253
|
|
package/compiler/opt.js
CHANGED
@@ -131,9 +131,12 @@ export default (funcs, globals, pages, tags, exceptions) => {
|
|
131
131
|
// const exceptionUse = exceptions.reduce((acc, _, i) => { acc[i] = 0; return acc; }, {});
|
132
132
|
|
133
133
|
// wasm transform pass
|
134
|
+
let fi = 0;
|
134
135
|
for (const f of funcs) {
|
135
136
|
const wasm = f.wasm;
|
136
137
|
|
138
|
+
globalThis.progress?.(`${fi++}/${funcs.length}`);
|
139
|
+
|
137
140
|
const lastType = f.locals['#last_type']?.idx;
|
138
141
|
|
139
142
|
let runs = (+Prefs.optWasmRuns) || 2; // todo: how many by default?
|
package/package.json
CHANGED