porffor 0.37.7 → 0.37.9
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 +1 -2
- package/compiler/assemble.js +1 -2
- package/compiler/builtins_precompiled.js +827 -827
- package/compiler/codegen.js +7 -3
- package/compiler/index.js +9 -2
- package/compiler/opt.js +1 -82
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -2964,6 +2964,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
2964
2964
|
|
2965
2965
|
const typed = typedInput && pattern.typeAnnotation;
|
2966
2966
|
let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(pattern).type != null));
|
2967
|
+
addVarMetadata(scope, name, global, { kind });
|
2967
2968
|
|
2968
2969
|
if (typed) {
|
2969
2970
|
addVarMetadata(scope, name, global, extractTypeAnnotation(pattern));
|
@@ -3563,6 +3564,9 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3563
3564
|
];
|
3564
3565
|
}
|
3565
3566
|
|
3567
|
+
// check not const
|
3568
|
+
if (local.metadata?.kind === 'const') return internalThrow(scope, 'TypeError', `Cannot assign to constant variable ${name}`, true);
|
3569
|
+
|
3566
3570
|
if (op === '=') {
|
3567
3571
|
return setLocalWithType(scope, name, isGlobal, decl.right, true);
|
3568
3572
|
}
|
@@ -6274,9 +6278,9 @@ export default program => {
|
|
6274
6278
|
// run callbacks
|
6275
6279
|
const wasm = f.wasm;
|
6276
6280
|
for (let j = 0; j < wasm.length; j++) {
|
6277
|
-
const
|
6278
|
-
if (
|
6279
|
-
wasm.splice(j
|
6281
|
+
const o = wasm[j];
|
6282
|
+
if (o[0] === null && typeof o[1] === 'function') {
|
6283
|
+
wasm.splice(j--, 1, ...o[1]());
|
6280
6284
|
}
|
6281
6285
|
}
|
6282
6286
|
|
package/compiler/index.js
CHANGED
@@ -53,6 +53,8 @@ const progressClear = () => {
|
|
53
53
|
};
|
54
54
|
|
55
55
|
export default (code, flags) => {
|
56
|
+
const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
|
57
|
+
|
56
58
|
let target = Prefs.target ?? 'wasm';
|
57
59
|
if (Prefs.native) target = 'native';
|
58
60
|
|
@@ -67,8 +69,13 @@ export default (code, flags) => {
|
|
67
69
|
|
68
70
|
// change some prefs by default for c/native
|
69
71
|
if (target !== 'wasm') {
|
70
|
-
Prefs.pgo = Prefs.pgo === false ? false : true;
|
71
|
-
Prefs.passiveData = false;
|
72
|
+
Prefs.pgo = Prefs.pgo === false ? false : true; // enable pgo
|
73
|
+
Prefs.passiveData = false; // disable using passive Wasm data as unsupported by 2c for now
|
74
|
+
}
|
75
|
+
|
76
|
+
// change some prefs by default for -O2
|
77
|
+
if (optLevel >= 2) {
|
78
|
+
Prefs.cyclone = Prefs.cyclone === false ? false : true; // enable cyclone
|
72
79
|
}
|
73
80
|
|
74
81
|
if (Prefs.pgo) pgo.setup();
|
package/compiler/opt.js
CHANGED
@@ -9,88 +9,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
|
|
9
9
|
if (optLevel === 0) return;
|
10
10
|
|
11
11
|
const tailCall = Prefs.tailCall;
|
12
|
-
if (tailCall) log.warning('opt', 'tail call proposal is not widely implemented! (you used
|
13
|
-
|
14
|
-
if (optLevel >= 2 && !Prefs.optNoInline) {
|
15
|
-
// inline pass (very WIP)
|
16
|
-
// get candidates for inlining
|
17
|
-
// todo: pick smart in future (if func is used <N times? or?)
|
18
|
-
const callsSelf = f => f.wasm.some(x => x[0] === Opcodes.call && x[1] === f.index);
|
19
|
-
const suitableReturns = wasm => wasm.reduce((acc, x) => acc + (x[0] === Opcodes.return), 0) <= 1;
|
20
|
-
const candidates = funcs.filter(x => x.name !== 'main' && Object.keys(x.locals).length === x.params.length && (x.returns.length === 0 || suitableReturns(x.wasm)) && !callsSelf(x) && !x.throws).reverse();
|
21
|
-
if (Prefs.optLog) {
|
22
|
-
log('opt', `found inline candidates: ${candidates.map(x => x.name).join(', ')} (${candidates.length}/${funcs.length - 1})`);
|
23
|
-
|
24
|
-
let reasons = {};
|
25
|
-
for (const f of funcs) {
|
26
|
-
if (f.name === 'main') continue;
|
27
|
-
reasons[f.name] = [];
|
28
|
-
|
29
|
-
if (f.name === 'main') reasons[f.name].push('main');
|
30
|
-
if (Object.keys(f.locals).length !== f.params.length) reasons[f.name].push('cannot inline funcs with locals yet');
|
31
|
-
if (f.returns.length !== 0 && !suitableReturns(f.wasm)) reasons[f.name].push('cannot inline funcs with multiple returns yet');
|
32
|
-
if (callsSelf(f)) reasons[f.name].push('cannot inline func calling itself');
|
33
|
-
if (f.throws) reasons[f.name].push('will not inline funcs throwing yet');
|
34
|
-
}
|
35
|
-
|
36
|
-
if (Object.values(reasons).some(x => x.length > 0)) console.log(` reasons not:\n${Object.keys(reasons).filter(x => reasons[x].length > 0).map(x => ` ${x}: ${reasons[x].join(', ')}`).join('\n')}\n`)
|
37
|
-
}
|
38
|
-
|
39
|
-
for (const c of candidates) {
|
40
|
-
const cWasm = c.wasm;
|
41
|
-
|
42
|
-
for (const t of funcs) {
|
43
|
-
const tWasm = t.wasm;
|
44
|
-
if (t.name === c.name) continue; // skip self
|
45
|
-
|
46
|
-
for (let i = 0; i < tWasm.length; i++) {
|
47
|
-
const inst = tWasm[i];
|
48
|
-
if (inst[0] === Opcodes.call && inst[1] === c.index) {
|
49
|
-
if (Prefs.optLog) log('opt', `inlining call for ${c.name} (in ${t.name})`);
|
50
|
-
tWasm.splice(i, 1); // remove this call
|
51
|
-
|
52
|
-
// add params as locals and set in reverse order
|
53
|
-
const paramIdx = {};
|
54
|
-
let localIdx = Math.max(-1, ...Object.values(t.locals).map(x => x.idx)) + 1;
|
55
|
-
for (let j = c.params.length - 1; j >= 0; j--) {
|
56
|
-
const name = `__porf_inline_${c.name}_param_${j}`;
|
57
|
-
|
58
|
-
if (t.locals[name] === undefined) {
|
59
|
-
t.locals[name] = { idx: localIdx++, type: c.params[j] };
|
60
|
-
}
|
61
|
-
|
62
|
-
const idx = t.locals[name].idx;
|
63
|
-
paramIdx[j] = idx;
|
64
|
-
|
65
|
-
tWasm.splice(i, 0, [ Opcodes.local_set, idx ]);
|
66
|
-
i++;
|
67
|
-
}
|
68
|
-
|
69
|
-
let iWasm = cWasm.slice().map(x => x.slice()); // deep clone arr (depth 2)
|
70
|
-
// remove final return
|
71
|
-
if (iWasm.length !== 0 && iWasm[iWasm.length - 1][0] === Opcodes.return) iWasm = iWasm.slice(0, -1);
|
72
|
-
|
73
|
-
// adjust local operands to go to correct param index
|
74
|
-
for (const inst of iWasm) {
|
75
|
-
if ((inst[0] === Opcodes.local_get || inst[0] === Opcodes.local_set) && inst[1] < c.params.length) {
|
76
|
-
if (Prefs.optLog) log('opt', `replacing local operand in inlined wasm (${inst[1]} -> ${paramIdx[inst[1]]})`);
|
77
|
-
inst[1] = paramIdx[inst[1]];
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
tWasm.splice(i, 0, ...iWasm);
|
82
|
-
i += iWasm.length;
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
|
-
if (t.index > c.index) t.index--; // adjust index if after removed func
|
87
|
-
}
|
88
|
-
|
89
|
-
funcs.splice(funcs.indexOf(c), 1); // remove func from funcs
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
if (Prefs.optInlineOnly) return;
|
12
|
+
if (tailCall) log.warning('opt', 'tail call proposal is not widely implemented! (you used --tail-call)');
|
94
13
|
|
95
14
|
// todo: this breaks exceptions after due to indexes not being adjusted
|
96
15
|
// const tagUse = tags.reduce((acc, x) => { acc[x.idx] = 0; return acc; }, {});
|
package/package.json
CHANGED