porffor 0.50.9 → 0.50.11
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/compiler/codegen.js +39 -9
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -48,14 +48,16 @@ const cacheAst = (decl, wasm) => {
|
|
48
48
|
};
|
49
49
|
|
50
50
|
let indirectFuncs = [];
|
51
|
+
let doNotMarkFuncRef = false;
|
51
52
|
const funcRef = func => {
|
52
|
-
func.
|
53
|
-
func.referenced = true;
|
53
|
+
if (!doNotMarkFuncRef) func.referenced = true;
|
54
54
|
|
55
55
|
if (globalThis.precompile) return [
|
56
56
|
[ Opcodes.const, 'funcref', func.name ]
|
57
57
|
];
|
58
58
|
|
59
|
+
func.generate?.();
|
60
|
+
|
59
61
|
const wrapperArgc = Prefs.indirectWrapperArgc ?? 10;
|
60
62
|
if (!func.wrapperFunc) {
|
61
63
|
const locals = {}, params = [];
|
@@ -1786,15 +1788,11 @@ const disposeLeftover = wasm => {
|
|
1786
1788
|
};
|
1787
1789
|
|
1788
1790
|
const generateExp = (scope, decl) => {
|
1789
|
-
|
1790
|
-
|
1791
|
-
if (expression.type === 'Literal' && typeof expression.value === 'string') {
|
1792
|
-
if (expression.value === 'use strict') {
|
1793
|
-
scope.strict = true;
|
1794
|
-
}
|
1791
|
+
if (decl.directive === 'use strict') {
|
1792
|
+
scope.strict = true;
|
1795
1793
|
}
|
1796
1794
|
|
1797
|
-
const out = generate(scope, expression, undefined, undefined, !scope.inEval);
|
1795
|
+
const out = generate(scope, decl.expression, undefined, undefined, !scope.inEval);
|
1798
1796
|
disposeLeftover(out);
|
1799
1797
|
|
1800
1798
|
return out;
|
@@ -3727,6 +3725,9 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3727
3725
|
const useCoctc = Prefs.coctc && !decl.left.computed && !decl.left.optional && !['prototype', 'size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'length', '__proto__'].includes(decl.left.property.name) && coctcOffset(decl.left.property.name) > 0;
|
3728
3726
|
if (useCoctc) valueUnused = false;
|
3729
3727
|
|
3728
|
+
// opt: do not mark prototype funcs as referenced to optimize this in them
|
3729
|
+
if (object?.property?.name === 'prototype' && isFuncType(decl.right.type)) decl.right._doNotMarkFuncRef = true;
|
3730
|
+
|
3730
3731
|
const out = [
|
3731
3732
|
...generate(scope, object),
|
3732
3733
|
[ Opcodes.local_set, objectTmp ],
|
@@ -5645,9 +5646,13 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
5645
5646
|
|
5646
5647
|
let chainCount = scope.chainMembers != null ? ++scope.chainMembers : 0;
|
5647
5648
|
|
5649
|
+
doNotMarkFuncRef = true;
|
5650
|
+
|
5648
5651
|
// generate now so type is gotten correctly later (it gets cached)
|
5649
5652
|
generate(scope, object);
|
5650
5653
|
|
5654
|
+
doNotMarkFuncRef = false;
|
5655
|
+
|
5651
5656
|
// hack: .length
|
5652
5657
|
if (decl.property.name === 'length') {
|
5653
5658
|
// todo: support optional
|
@@ -6385,6 +6390,8 @@ const funcByIndex = idx => {
|
|
6385
6390
|
const funcByName = name => funcByIndex(funcIndex[name]);
|
6386
6391
|
|
6387
6392
|
const generateFunc = (scope, decl, forceNoExpr = false) => {
|
6393
|
+
doNotMarkFuncRef = false;
|
6394
|
+
|
6388
6395
|
const name = decl.id ? decl.id.name : `#anonymous${uniqId()}`;
|
6389
6396
|
if (decl.type.startsWith('Class')) {
|
6390
6397
|
const out = generateClass(scope, {
|
@@ -6404,6 +6411,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
|
|
6404
6411
|
// TODO: share scope/locals between !!!
|
6405
6412
|
const arrow = decl.type === 'ArrowFunctionExpression' || decl.type === 'Program';
|
6406
6413
|
const func = {
|
6414
|
+
start: decl.start,
|
6407
6415
|
locals: {},
|
6408
6416
|
localInd: 0,
|
6409
6417
|
// value, type
|
@@ -6432,6 +6440,25 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
|
|
6432
6440
|
};
|
6433
6441
|
}
|
6434
6442
|
|
6443
|
+
// todo: enable for all block statement bodies, not just main
|
6444
|
+
if (name === '#main') {
|
6445
|
+
// hoist function declarations to the top of AST pre-codegen so
|
6446
|
+
// we can optimize function calls so calls before decl are not indirect
|
6447
|
+
// (without more post-codegen jank)
|
6448
|
+
// plus, more spec-compliant hoisting!
|
6449
|
+
|
6450
|
+
let b = body.body, j = 0;
|
6451
|
+
|
6452
|
+
// append after directive if it exists
|
6453
|
+
if (b[0]?.directive) j++;
|
6454
|
+
|
6455
|
+
for (let i = 0; i < b.length; i++) {
|
6456
|
+
if (b[i].type === 'FunctionDeclaration') {
|
6457
|
+
b.splice(j++, 0, b.splice(i, 1)[0]);
|
6458
|
+
}
|
6459
|
+
}
|
6460
|
+
}
|
6461
|
+
|
6435
6462
|
func.identFailEarly = true;
|
6436
6463
|
let localInd = args.length * 2;
|
6437
6464
|
for (let i = 0; i < args.length; i++) {
|
@@ -6701,7 +6728,10 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
|
|
6701
6728
|
// force generate all for precompile
|
6702
6729
|
if (globalThis.precompile) func.generate();
|
6703
6730
|
|
6731
|
+
if (decl._doNotMarkFuncRef) doNotMarkFuncRef = true;
|
6704
6732
|
const out = decl.type.endsWith('Expression') && !forceNoExpr ? funcRef(func) : [];
|
6733
|
+
doNotMarkFuncRef = false;
|
6734
|
+
|
6705
6735
|
astCache.set(decl, out);
|
6706
6736
|
return [ func, out ];
|
6707
6737
|
};
|
package/package.json
CHANGED