@markw65/monkeyc-optimizer 1.0.16 → 1.0.17
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 +15 -0
- package/build/api.cjs +364 -323
- package/build/optimizer.cjs +380 -160
- package/build/sdk-util.cjs +1 -1
- package/build/src/api.d.ts +1 -1
- package/build/src/inliner.d.ts +11 -2
- package/build/src/optimizer.d.ts +2 -2
- package/build/src/pragma-checker.d.ts +2 -0
- package/build/src/variable-renamer.d.ts +1 -0
- package/build/util.cjs +1 -1
- package/package.json +1 -1
package/build/optimizer.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
0 && (module.exports = {copyRecursiveAsNeeded,
|
|
1
|
+
0 && (module.exports = {buildOptimizedProject,copyRecursiveAsNeeded,defaultConfig,generateApiMirTests,generateOptimizedProject,getProjectAnalysis,get_jungle,isErrorWithLocation,launchSimulator,manifestProducts,mctree,simulateProgram});
|
|
2
2
|
/******/ (() => { // webpackBootstrap
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
@@ -10791,11 +10791,67 @@ function simulateProgram(prg, device, test) {
|
|
|
10791
10791
|
return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => (0,external_util_cjs_namespaceObject.spawnByLine)(external_path_.resolve(sdk, "bin", "monkeydo"), args, (line) => console.log(line)).then(() => { }));
|
|
10792
10792
|
}
|
|
10793
10793
|
|
|
10794
|
+
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
10795
|
+
|
|
10796
|
+
function renameVariable(state, locals, declName) {
|
|
10797
|
+
const map = locals.map;
|
|
10798
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, declName))
|
|
10799
|
+
return null;
|
|
10800
|
+
let suffix = 0;
|
|
10801
|
+
let node_name = declName;
|
|
10802
|
+
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
10803
|
+
if (match) {
|
|
10804
|
+
node_name = match[1];
|
|
10805
|
+
suffix = parseInt(match[2], 10) + 1;
|
|
10806
|
+
}
|
|
10807
|
+
if (!locals.inners) {
|
|
10808
|
+
// find all the names declared in this scope, to avoid
|
|
10809
|
+
// more conflicts
|
|
10810
|
+
locals.inners = {};
|
|
10811
|
+
const inners = locals.inners;
|
|
10812
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
|
|
10813
|
+
if (node.type === "VariableDeclarator") {
|
|
10814
|
+
inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
|
|
10815
|
+
}
|
|
10816
|
+
});
|
|
10817
|
+
}
|
|
10818
|
+
let name;
|
|
10819
|
+
while (true) {
|
|
10820
|
+
name = `pmcr_${node_name}_${suffix}`;
|
|
10821
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) && !(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
|
|
10822
|
+
// we also need to ensure that we don't hide the name of
|
|
10823
|
+
// an outer module, class, function, enum or variable,
|
|
10824
|
+
// since someone might want to access it from this scope.
|
|
10825
|
+
let ok = false;
|
|
10826
|
+
let i;
|
|
10827
|
+
for (i = state.stack.length; i--;) {
|
|
10828
|
+
const elm = state.stack[i];
|
|
10829
|
+
if (ok) {
|
|
10830
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
|
|
10831
|
+
break;
|
|
10832
|
+
}
|
|
10833
|
+
}
|
|
10834
|
+
else if (elm.node && elm.node.type === "FunctionDeclaration") {
|
|
10835
|
+
ok = true;
|
|
10836
|
+
}
|
|
10837
|
+
}
|
|
10838
|
+
if (i < 0) {
|
|
10839
|
+
break;
|
|
10840
|
+
}
|
|
10841
|
+
}
|
|
10842
|
+
suffix++;
|
|
10843
|
+
}
|
|
10844
|
+
map[declName] = name;
|
|
10845
|
+
map[name] = true;
|
|
10846
|
+
return name;
|
|
10847
|
+
}
|
|
10848
|
+
|
|
10794
10849
|
;// CONCATENATED MODULE: ./src/inliner.ts
|
|
10795
10850
|
|
|
10796
|
-
|
|
10851
|
+
|
|
10852
|
+
function getArgSafety(state, func, args, requireAll) {
|
|
10797
10853
|
// determine whether decl might be changed by a function call
|
|
10798
|
-
// during the evaluation of FunctionStateNode.
|
|
10854
|
+
// or assignment during the evaluation of FunctionStateNode.
|
|
10799
10855
|
const getSafety = (decl) => {
|
|
10800
10856
|
// enums are constant, they cant change
|
|
10801
10857
|
if (decl.type === "EnumStringMember")
|
|
@@ -10825,18 +10881,24 @@ function canInline(state, func, args) {
|
|
|
10825
10881
|
case "Identifier":
|
|
10826
10882
|
case "MemberExpression": {
|
|
10827
10883
|
const [, results] = state.lookup(arg);
|
|
10828
|
-
if (!results || results.length !== 1)
|
|
10829
|
-
|
|
10884
|
+
if (!results || results.length !== 1) {
|
|
10885
|
+
safeArgs.push(null);
|
|
10886
|
+
return !requireAll;
|
|
10887
|
+
}
|
|
10830
10888
|
const safety = getSafety(results[0]);
|
|
10831
|
-
if (safety === null)
|
|
10832
|
-
return false;
|
|
10833
|
-
if (!safety)
|
|
10834
|
-
allSafe = false;
|
|
10835
10889
|
safeArgs.push(safety);
|
|
10890
|
+
if (!safety) {
|
|
10891
|
+
allSafe = false;
|
|
10892
|
+
if (safety === null) {
|
|
10893
|
+
return !requireAll;
|
|
10894
|
+
}
|
|
10895
|
+
}
|
|
10836
10896
|
return true;
|
|
10837
10897
|
}
|
|
10838
10898
|
}
|
|
10839
|
-
|
|
10899
|
+
allSafe = false;
|
|
10900
|
+
safeArgs.push(null);
|
|
10901
|
+
return !requireAll;
|
|
10840
10902
|
})) {
|
|
10841
10903
|
return false;
|
|
10842
10904
|
}
|
|
@@ -10865,17 +10927,26 @@ function canInline(state, func, args) {
|
|
|
10865
10927
|
switch (node.type) {
|
|
10866
10928
|
case "CallExpression":
|
|
10867
10929
|
case "NewExpression":
|
|
10930
|
+
case "AssignmentExpression":
|
|
10931
|
+
case "UpdateExpression":
|
|
10868
10932
|
callSeen = true;
|
|
10869
10933
|
break;
|
|
10870
10934
|
case "Identifier":
|
|
10871
10935
|
if (callSeen &&
|
|
10872
10936
|
(0,external_api_cjs_namespaceObject.hasProperty)(params, node.name) &&
|
|
10873
10937
|
!safeArgs[params[node.name]]) {
|
|
10874
|
-
|
|
10938
|
+
safeArgs[params[node.name]] = null;
|
|
10875
10939
|
}
|
|
10876
10940
|
}
|
|
10877
10941
|
});
|
|
10878
|
-
return
|
|
10942
|
+
return safeArgs;
|
|
10943
|
+
}
|
|
10944
|
+
function canInline(state, func, args) {
|
|
10945
|
+
const safeArgs = getArgSafety(state, func, args, true);
|
|
10946
|
+
if (safeArgs === true || safeArgs === false) {
|
|
10947
|
+
return safeArgs;
|
|
10948
|
+
}
|
|
10949
|
+
return safeArgs.every((arg) => arg !== null);
|
|
10879
10950
|
}
|
|
10880
10951
|
function inliningLooksUseful(func, node) {
|
|
10881
10952
|
while (true) {
|
|
@@ -10900,68 +10971,114 @@ function inliningLooksUseful(func, node) {
|
|
|
10900
10971
|
}
|
|
10901
10972
|
return false;
|
|
10902
10973
|
}
|
|
10974
|
+
var InlineStatus;
|
|
10975
|
+
(function (InlineStatus) {
|
|
10976
|
+
InlineStatus[InlineStatus["Never"] = 0] = "Never";
|
|
10977
|
+
InlineStatus[InlineStatus["AsExpression"] = 1] = "AsExpression";
|
|
10978
|
+
InlineStatus[InlineStatus["AsStatement"] = 2] = "AsStatement";
|
|
10979
|
+
})(InlineStatus || (InlineStatus = {}));
|
|
10903
10980
|
function shouldInline(state, func, args) {
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
func.node.
|
|
10909
|
-
|
|
10981
|
+
let autoInline = false;
|
|
10982
|
+
let inlineAsExpression = false;
|
|
10983
|
+
if (func.node.body &&
|
|
10984
|
+
func.node.body.body.length === 1 &&
|
|
10985
|
+
func.node.body.body[0].type === "ReturnStatement" &&
|
|
10986
|
+
func.node.body.body[0].argument &&
|
|
10987
|
+
func.node.params.length === args.length) {
|
|
10988
|
+
inlineAsExpression = true;
|
|
10989
|
+
autoInline = inliningLooksUseful(func.node, func.node.body.body[0].argument);
|
|
10990
|
+
}
|
|
10991
|
+
if (autoInline === 1) {
|
|
10992
|
+
return InlineStatus.AsExpression;
|
|
10910
10993
|
}
|
|
10911
|
-
const autoInline = inliningLooksUseful(func.node, func.node.body.body[0].argument);
|
|
10912
10994
|
const excludeAnnotations = (func.node.loc?.source &&
|
|
10913
|
-
state.fnMap[func.node.loc?.source]
|
|
10995
|
+
state.fnMap[func.node.loc?.source]?.excludeAnnotations) ||
|
|
10914
10996
|
{};
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
(attr.argument.name
|
|
10920
|
-
(attr.argument.name.
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10997
|
+
const inlineRequested = func.node.attrs &&
|
|
10998
|
+
func.node.attrs.attrs &&
|
|
10999
|
+
func.node.attrs.attrs.some((attr) => attr.type === "UnaryExpression" &&
|
|
11000
|
+
(attr.argument.name === "inline" ||
|
|
11001
|
+
(attr.argument.name.startsWith("inline_") &&
|
|
11002
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name.substring(7)))));
|
|
11003
|
+
if (autoInline || inlineRequested) {
|
|
11004
|
+
return inlineAsExpression && canInline(state, func, args)
|
|
11005
|
+
? InlineStatus.AsExpression
|
|
11006
|
+
: InlineStatus.AsStatement;
|
|
11007
|
+
}
|
|
11008
|
+
return InlineStatus.Never;
|
|
11009
|
+
}
|
|
11010
|
+
function processInlineBody(state, func, call, root, insertedVariableDecls, params) {
|
|
11011
|
+
if (!params) {
|
|
11012
|
+
const safeArgs = getArgSafety(state, func, call.arguments, false);
|
|
11013
|
+
params = Object.fromEntries(func.node.params.map((param, i) => {
|
|
11014
|
+
const argnum = safeArgs === true || (safeArgs !== false && safeArgs[i] !== null)
|
|
11015
|
+
? i
|
|
11016
|
+
: -1;
|
|
11017
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(param);
|
|
11018
|
+
return [name, argnum];
|
|
11019
|
+
}));
|
|
11020
|
+
}
|
|
11021
|
+
const pre = state.pre;
|
|
11022
|
+
const post = state.post;
|
|
10927
11023
|
try {
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
11024
|
+
state.pre = (node) => {
|
|
11025
|
+
node.start = call.start;
|
|
11026
|
+
node.end = call.end;
|
|
11027
|
+
node.loc = call.loc;
|
|
11028
|
+
if (node === insertedVariableDecls)
|
|
11029
|
+
return false;
|
|
11030
|
+
const result = pre(node, state);
|
|
11031
|
+
if (!insertedVariableDecls && node.type === "BlockStatement") {
|
|
11032
|
+
const locals = state.localsStack[state.localsStack.length - 1];
|
|
11033
|
+
const { map } = locals;
|
|
11034
|
+
if (!map)
|
|
11035
|
+
throw new Error("No local variable map!");
|
|
11036
|
+
const declarations = func.node.params
|
|
11037
|
+
.map((param, i) => {
|
|
11038
|
+
const paramName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(param);
|
|
11039
|
+
if (params[paramName] >= 0)
|
|
11040
|
+
return null;
|
|
11041
|
+
const name = renameVariable(state, locals, paramName) || paramName;
|
|
11042
|
+
return {
|
|
11043
|
+
type: "VariableDeclarator",
|
|
11044
|
+
id: { type: "Identifier", name },
|
|
11045
|
+
kind: "var",
|
|
11046
|
+
init: call.arguments[i],
|
|
11047
|
+
};
|
|
11048
|
+
})
|
|
11049
|
+
.filter((n) => n != null);
|
|
11050
|
+
insertedVariableDecls = {
|
|
11051
|
+
type: "VariableDeclaration",
|
|
11052
|
+
declarations,
|
|
11053
|
+
kind: "var",
|
|
11054
|
+
};
|
|
11055
|
+
node.body.unshift(insertedVariableDecls);
|
|
10944
11056
|
}
|
|
10945
|
-
return
|
|
10946
|
-
}
|
|
11057
|
+
return result;
|
|
11058
|
+
};
|
|
11059
|
+
state.post = (node) => {
|
|
11060
|
+
let replacement = null;
|
|
10947
11061
|
switch (node.type) {
|
|
10948
11062
|
case "Identifier": {
|
|
11063
|
+
if (state.inType)
|
|
11064
|
+
break;
|
|
10949
11065
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name)) {
|
|
10950
|
-
|
|
11066
|
+
const ix = params[node.name];
|
|
11067
|
+
if (ix >= 0) {
|
|
11068
|
+
replacement = call.arguments[ix];
|
|
11069
|
+
}
|
|
11070
|
+
break;
|
|
10951
11071
|
}
|
|
10952
|
-
|
|
10953
|
-
if (!
|
|
11072
|
+
replacement = fixNodeScope(state, node, func.stack);
|
|
11073
|
+
if (!replacement) {
|
|
10954
11074
|
throw new Error(`Inliner: Couldn't fix the scope of '${node.name}`);
|
|
10955
11075
|
}
|
|
10956
|
-
|
|
11076
|
+
break;
|
|
10957
11077
|
}
|
|
10958
11078
|
}
|
|
10959
|
-
return
|
|
10960
|
-
}
|
|
10961
|
-
|
|
10962
|
-
result.start = call.start;
|
|
10963
|
-
result.end = call.end;
|
|
10964
|
-
return result;
|
|
11079
|
+
return post(replacement || node, state) || replacement;
|
|
11080
|
+
};
|
|
11081
|
+
return state.traverse(root) || null;
|
|
10965
11082
|
}
|
|
10966
11083
|
catch (ex) {
|
|
10967
11084
|
if (ex instanceof Error) {
|
|
@@ -10971,6 +11088,75 @@ function inlineFunction(state, func, call) {
|
|
|
10971
11088
|
}
|
|
10972
11089
|
throw ex;
|
|
10973
11090
|
}
|
|
11091
|
+
finally {
|
|
11092
|
+
state.pre = pre;
|
|
11093
|
+
state.post = post;
|
|
11094
|
+
}
|
|
11095
|
+
}
|
|
11096
|
+
function unused(expression, top) {
|
|
11097
|
+
switch (expression.type) {
|
|
11098
|
+
case "Literal":
|
|
11099
|
+
return [];
|
|
11100
|
+
case "Identifier":
|
|
11101
|
+
return [];
|
|
11102
|
+
case "BinaryExpression":
|
|
11103
|
+
if (expression.operator === "as") {
|
|
11104
|
+
return unused(expression.left);
|
|
11105
|
+
}
|
|
11106
|
+
// fall through
|
|
11107
|
+
case "LogicalExpression":
|
|
11108
|
+
return unused(expression.left).concat(unused(expression.right));
|
|
11109
|
+
case "UnaryExpression":
|
|
11110
|
+
return unused(expression.argument);
|
|
11111
|
+
case "MemberExpression":
|
|
11112
|
+
return unused(expression.object).concat(unused(expression.property));
|
|
11113
|
+
}
|
|
11114
|
+
return top
|
|
11115
|
+
? null
|
|
11116
|
+
: [
|
|
11117
|
+
{
|
|
11118
|
+
type: "ExpressionStatement",
|
|
11119
|
+
expression,
|
|
11120
|
+
},
|
|
11121
|
+
];
|
|
11122
|
+
}
|
|
11123
|
+
function inlineWithArgs(state, func, call) {
|
|
11124
|
+
if (!func.node || !func.node.body) {
|
|
11125
|
+
return null;
|
|
11126
|
+
}
|
|
11127
|
+
let retStmtCount = 0;
|
|
11128
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(func.node.body, (node) => {
|
|
11129
|
+
node.type === "ReturnStatement" && retStmtCount++;
|
|
11130
|
+
});
|
|
11131
|
+
if (retStmtCount > 1 ||
|
|
11132
|
+
(retStmtCount === 1 &&
|
|
11133
|
+
func.node.body.body.slice(-1)[0].type !== "ReturnStatement")) {
|
|
11134
|
+
return null;
|
|
11135
|
+
}
|
|
11136
|
+
const body = JSON.parse(JSON.stringify(func.node.body));
|
|
11137
|
+
processInlineBody(state, func, call, body, func.node.params.length ? false : true);
|
|
11138
|
+
if (retStmtCount) {
|
|
11139
|
+
const last = body.body[body.body.length - 1];
|
|
11140
|
+
if (last.type != "ReturnStatement") {
|
|
11141
|
+
throw new Error("ReturnStatement got lost!");
|
|
11142
|
+
}
|
|
11143
|
+
if (last.argument) {
|
|
11144
|
+
const side_exprs = unused(last.argument);
|
|
11145
|
+
body.body.splice(body.body.length - 1, 1, ...side_exprs);
|
|
11146
|
+
}
|
|
11147
|
+
else {
|
|
11148
|
+
--body.body.length;
|
|
11149
|
+
}
|
|
11150
|
+
}
|
|
11151
|
+
return body;
|
|
11152
|
+
}
|
|
11153
|
+
function inlineFunction(state, func, call, inlineStatus) {
|
|
11154
|
+
if (inlineStatus == InlineStatus.AsStatement) {
|
|
11155
|
+
return inlineWithArgs(state, func, call);
|
|
11156
|
+
}
|
|
11157
|
+
const retArg = JSON.parse(JSON.stringify(func.node.body.body[0].argument));
|
|
11158
|
+
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11159
|
+
return processInlineBody(state, func, call, retArg, true, params) || retArg;
|
|
10974
11160
|
}
|
|
10975
11161
|
function applyTypeIfNeeded(node) {
|
|
10976
11162
|
if ("enumType" in node && node.enumType) {
|
|
@@ -10984,6 +11170,16 @@ function applyTypeIfNeeded(node) {
|
|
|
10984
11170
|
return node;
|
|
10985
11171
|
}
|
|
10986
11172
|
function fixNodeScope(state, lookupNode, nodeStack) {
|
|
11173
|
+
if (lookupNode.type === "Identifier") {
|
|
11174
|
+
for (let i = state.stack.length; --i > nodeStack.length;) {
|
|
11175
|
+
const si = state.stack[i];
|
|
11176
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(si.decls, lookupNode.name)) {
|
|
11177
|
+
// its a local from the inlined function.
|
|
11178
|
+
// Nothing to do.
|
|
11179
|
+
return lookupNode;
|
|
11180
|
+
}
|
|
11181
|
+
}
|
|
11182
|
+
}
|
|
10987
11183
|
const [, original] = state.lookup(lookupNode, null, nodeStack);
|
|
10988
11184
|
if (!original) {
|
|
10989
11185
|
return null;
|
|
@@ -11067,6 +11263,7 @@ function fixNodeScope(state, lookupNode, nodeStack) {
|
|
|
11067
11263
|
|
|
11068
11264
|
|
|
11069
11265
|
|
|
11266
|
+
|
|
11070
11267
|
function processImports(allImports, lookup) {
|
|
11071
11268
|
allImports.forEach(({ node, stack }) => {
|
|
11072
11269
|
const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
|
|
@@ -11080,10 +11277,13 @@ function processImports(allImports, lookup) {
|
|
|
11080
11277
|
module.forEach((m) => {
|
|
11081
11278
|
if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
|
|
11082
11279
|
(0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
|
|
11280
|
+
if (!parent.type_decls)
|
|
11281
|
+
parent.type_decls = {};
|
|
11282
|
+
const tdecls = parent.type_decls;
|
|
11283
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(tdecls, name))
|
|
11284
|
+
tdecls[name] = [];
|
|
11285
|
+
(0,external_util_cjs_namespaceObject.pushUnique)(tdecls[name], m);
|
|
11083
11286
|
if (node.type == "ImportModule" && m.type_decls) {
|
|
11084
|
-
if (!parent.type_decls)
|
|
11085
|
-
parent.type_decls = {};
|
|
11086
|
-
const tdecls = parent.type_decls;
|
|
11087
11287
|
Object.entries(m.type_decls).forEach(([name, decls]) => {
|
|
11088
11288
|
if (!(0,external_api_cjs_namespaceObject.hasProperty)(tdecls, name))
|
|
11089
11289
|
tdecls[name] = [];
|
|
@@ -11624,57 +11824,8 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11624
11824
|
const { map } = locals;
|
|
11625
11825
|
if (map) {
|
|
11626
11826
|
const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
// Recent monkeyc compilers complain, so rename it
|
|
11630
|
-
let suffix = 0;
|
|
11631
|
-
let node_name = declName;
|
|
11632
|
-
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
11633
|
-
if (match) {
|
|
11634
|
-
node_name = match[1];
|
|
11635
|
-
suffix = parseInt(match[2], 10) + 1;
|
|
11636
|
-
}
|
|
11637
|
-
if (!locals.inners) {
|
|
11638
|
-
// find all the names declared in this scope, to avoid
|
|
11639
|
-
// more conflicts
|
|
11640
|
-
locals.inners = {};
|
|
11641
|
-
const inners = locals.inners;
|
|
11642
|
-
(0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
|
|
11643
|
-
if (node.type === "VariableDeclarator") {
|
|
11644
|
-
inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
|
|
11645
|
-
}
|
|
11646
|
-
});
|
|
11647
|
-
}
|
|
11648
|
-
let name;
|
|
11649
|
-
while (true) {
|
|
11650
|
-
name = `pmcr_${node_name}_${suffix}`;
|
|
11651
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) &&
|
|
11652
|
-
!(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
|
|
11653
|
-
// we also need to ensure that we don't hide the name of
|
|
11654
|
-
// an outer module, class, function, enum or variable,
|
|
11655
|
-
// since someone might want to access it from this scope.
|
|
11656
|
-
let ok = false;
|
|
11657
|
-
let i;
|
|
11658
|
-
for (i = state.stack.length; i--;) {
|
|
11659
|
-
const elm = state.stack[i];
|
|
11660
|
-
if (ok) {
|
|
11661
|
-
if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
|
|
11662
|
-
break;
|
|
11663
|
-
}
|
|
11664
|
-
}
|
|
11665
|
-
else if (elm.node &&
|
|
11666
|
-
elm.node.type === "FunctionDeclaration") {
|
|
11667
|
-
ok = true;
|
|
11668
|
-
}
|
|
11669
|
-
}
|
|
11670
|
-
if (i < 0) {
|
|
11671
|
-
break;
|
|
11672
|
-
}
|
|
11673
|
-
}
|
|
11674
|
-
suffix++;
|
|
11675
|
-
}
|
|
11676
|
-
map[declName] = name;
|
|
11677
|
-
map[name] = true;
|
|
11827
|
+
const name = renameVariable(state, locals, declName);
|
|
11828
|
+
if (name) {
|
|
11678
11829
|
if (node.id.type === "Identifier") {
|
|
11679
11830
|
node.id.name = name;
|
|
11680
11831
|
}
|
|
@@ -11698,7 +11849,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11698
11849
|
state.exposed[node.argument.name] = true;
|
|
11699
11850
|
// In any case, we can't replace *this* use of the
|
|
11700
11851
|
// symbol with its value...
|
|
11701
|
-
return
|
|
11852
|
+
return [];
|
|
11702
11853
|
}
|
|
11703
11854
|
break;
|
|
11704
11855
|
case "Identifier": {
|
|
@@ -11716,7 +11867,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11716
11867
|
state.exposed[node.name] = true;
|
|
11717
11868
|
}
|
|
11718
11869
|
}
|
|
11719
|
-
return
|
|
11870
|
+
return [];
|
|
11720
11871
|
}
|
|
11721
11872
|
case "MemberExpression":
|
|
11722
11873
|
if (node.property.type === "Identifier" && !node.computed) {
|
|
@@ -11798,48 +11949,29 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11798
11949
|
}
|
|
11799
11950
|
break;
|
|
11800
11951
|
case "CallExpression": {
|
|
11801
|
-
const
|
|
11802
|
-
if (
|
|
11803
|
-
|
|
11804
|
-
("name" in node.callee && node.callee.name) ||
|
|
11805
|
-
("property" in node.callee &&
|
|
11806
|
-
node.callee.property &&
|
|
11807
|
-
"name" in node.callee.property &&
|
|
11808
|
-
node.callee.property.name);
|
|
11809
|
-
if (n) {
|
|
11810
|
-
state.exposed[n] = true;
|
|
11811
|
-
}
|
|
11812
|
-
else {
|
|
11813
|
-
// There are unnamed CallExpressions, such as new [size]
|
|
11814
|
-
// So there's nothing to do here.
|
|
11815
|
-
}
|
|
11816
|
-
return null;
|
|
11952
|
+
const ret = optimizeCall(state, node, false);
|
|
11953
|
+
if (ret) {
|
|
11954
|
+
replace(node, ret);
|
|
11817
11955
|
}
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
if (ret) {
|
|
11825
|
-
|
|
11826
|
-
return null;
|
|
11827
|
-
}
|
|
11828
|
-
}
|
|
11829
|
-
if (shouldInline(state, callees[0], node.arguments)) {
|
|
11830
|
-
const ret = inlineFunction(state, callees[0], node);
|
|
11831
|
-
if (ret) {
|
|
11832
|
-
replace(node, ret);
|
|
11833
|
-
return null;
|
|
11956
|
+
break;
|
|
11957
|
+
}
|
|
11958
|
+
case "ExpressionStatement":
|
|
11959
|
+
if (node.expression.type === "CallExpression") {
|
|
11960
|
+
const ret = optimizeCall(state, node.expression, true);
|
|
11961
|
+
if (ret) {
|
|
11962
|
+
if (ret.type === "BlockStatement") {
|
|
11963
|
+
return ret;
|
|
11834
11964
|
}
|
|
11965
|
+
node.expression = ret;
|
|
11835
11966
|
}
|
|
11836
11967
|
}
|
|
11837
|
-
|
|
11838
|
-
|
|
11968
|
+
else {
|
|
11969
|
+
const ret = unused(node.expression, true);
|
|
11970
|
+
if (ret) {
|
|
11971
|
+
return ret;
|
|
11972
|
+
}
|
|
11839
11973
|
}
|
|
11840
|
-
callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && state.calledFunctions[name].push(c.node));
|
|
11841
11974
|
break;
|
|
11842
|
-
}
|
|
11843
11975
|
}
|
|
11844
11976
|
return null;
|
|
11845
11977
|
};
|
|
@@ -11922,6 +12054,98 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11922
12054
|
});
|
|
11923
12055
|
});
|
|
11924
12056
|
}
|
|
12057
|
+
function optimizeCall(state, node, asStatement) {
|
|
12058
|
+
const [name, callees] = state.lookup(node.callee);
|
|
12059
|
+
if (!callees || !callees.length) {
|
|
12060
|
+
const n = name ||
|
|
12061
|
+
("name" in node.callee && node.callee.name) ||
|
|
12062
|
+
("property" in node.callee &&
|
|
12063
|
+
node.callee.property &&
|
|
12064
|
+
"name" in node.callee.property &&
|
|
12065
|
+
node.callee.property.name);
|
|
12066
|
+
if (n) {
|
|
12067
|
+
state.exposed[n] = true;
|
|
12068
|
+
}
|
|
12069
|
+
else {
|
|
12070
|
+
// There are unnamed CallExpressions, such as new [size]
|
|
12071
|
+
// So there's nothing to do here.
|
|
12072
|
+
}
|
|
12073
|
+
return null;
|
|
12074
|
+
}
|
|
12075
|
+
if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
|
|
12076
|
+
const callee = callees[0].node;
|
|
12077
|
+
if (callee.optimizable &&
|
|
12078
|
+
!callee.hasOverride &&
|
|
12079
|
+
node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
|
|
12080
|
+
const ret = evaluateFunction(callee, node.arguments);
|
|
12081
|
+
if (ret) {
|
|
12082
|
+
return ret;
|
|
12083
|
+
}
|
|
12084
|
+
}
|
|
12085
|
+
const inlineStatus = shouldInline(state, callees[0], node.arguments);
|
|
12086
|
+
if (inlineStatus === InlineStatus.AsExpression ||
|
|
12087
|
+
(asStatement && inlineStatus === InlineStatus.AsStatement)) {
|
|
12088
|
+
const ret = inlineFunction(state, callees[0], node, inlineStatus);
|
|
12089
|
+
if (ret) {
|
|
12090
|
+
return ret;
|
|
12091
|
+
}
|
|
12092
|
+
}
|
|
12093
|
+
}
|
|
12094
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
|
|
12095
|
+
state.calledFunctions[name] = [];
|
|
12096
|
+
}
|
|
12097
|
+
callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && state.calledFunctions[name].push(c.node));
|
|
12098
|
+
return null;
|
|
12099
|
+
}
|
|
12100
|
+
|
|
12101
|
+
;// CONCATENATED MODULE: ./src/pragma-checker.ts
|
|
12102
|
+
|
|
12103
|
+
function pragmaChecker(ast) {
|
|
12104
|
+
const comments = ast.comments;
|
|
12105
|
+
if (!comments)
|
|
12106
|
+
return;
|
|
12107
|
+
let index = -1;
|
|
12108
|
+
let comment;
|
|
12109
|
+
const next = () => {
|
|
12110
|
+
while (++index < comments.length) {
|
|
12111
|
+
comment = comments[index];
|
|
12112
|
+
if (comment.value.match(/^\s*@match\s+/)) {
|
|
12113
|
+
break;
|
|
12114
|
+
}
|
|
12115
|
+
}
|
|
12116
|
+
};
|
|
12117
|
+
next();
|
|
12118
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(ast, (node) => {
|
|
12119
|
+
if (index >= comments.length)
|
|
12120
|
+
return false;
|
|
12121
|
+
if (node.start && node.start >= (comment.end || Infinity)) {
|
|
12122
|
+
let match = comment.value.match(/^\s*@match\s+([/%&#@"])(.+(?<!\\)(?:\\{2})*)\1\s+$/) || comment.value.match(/^\s*@match\s+(\S+)\s+$/);
|
|
12123
|
+
if (!match) {
|
|
12124
|
+
throw new Error(`Build pragma '${comment.value}' is invalid. In ${comment.loc.source}:${comment.loc.start.line}`);
|
|
12125
|
+
}
|
|
12126
|
+
const haystack = (0,external_api_cjs_namespaceObject.formatAst)(node).replace(/[\r\n]/g, " ");
|
|
12127
|
+
let found = false;
|
|
12128
|
+
let needle = match[1];
|
|
12129
|
+
if (match.length == 2) {
|
|
12130
|
+
found = haystack.includes(needle);
|
|
12131
|
+
}
|
|
12132
|
+
else {
|
|
12133
|
+
if (needle == '"') {
|
|
12134
|
+
found = haystack.includes((needle = match[2]));
|
|
12135
|
+
}
|
|
12136
|
+
else {
|
|
12137
|
+
const re = new RegExp((needle = match[2]));
|
|
12138
|
+
found = re.test(haystack);
|
|
12139
|
+
}
|
|
12140
|
+
}
|
|
12141
|
+
if (!found) {
|
|
12142
|
+
throw new Error(`Didn't find '${needle}' in ${comment.loc.source}:${comment.loc.start.line}`);
|
|
12143
|
+
}
|
|
12144
|
+
next();
|
|
12145
|
+
}
|
|
12146
|
+
return null;
|
|
12147
|
+
});
|
|
12148
|
+
}
|
|
11925
12149
|
|
|
11926
12150
|
;// CONCATENATED MODULE: ./src/optimizer.ts
|
|
11927
12151
|
|
|
@@ -11937,6 +12161,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11937
12161
|
|
|
11938
12162
|
|
|
11939
12163
|
|
|
12164
|
+
|
|
11940
12165
|
function relative_path_no_dotdot(relative) {
|
|
11941
12166
|
return relative.replace(/^(\.\.[\\\/])+/, (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`);
|
|
11942
12167
|
}
|
|
@@ -12346,7 +12571,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12346
12571
|
// the oldest optimized file, we don't need to regenerate
|
|
12347
12572
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12348
12573
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12349
|
-
if (source_time < opt_time &&
|
|
12574
|
+
if (source_time < opt_time && 1654384985724 < opt_time) {
|
|
12350
12575
|
return hasTests;
|
|
12351
12576
|
}
|
|
12352
12577
|
}
|
|
@@ -12358,15 +12583,10 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12358
12583
|
const dir = external_path_.dirname(name);
|
|
12359
12584
|
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
12360
12585
|
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
12586
|
+
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12361
12587
|
if (config.checkBuildPragmas) {
|
|
12362
|
-
|
|
12363
|
-
for (const [line, needle, haystack] of matches) {
|
|
12364
|
-
if (!haystack.includes(needle)) {
|
|
12365
|
-
throw new Error(`Checking build pragmas in ${name} failed at \n\n${line}\n\n - Didn't find '${needle}'`);
|
|
12366
|
-
}
|
|
12367
|
-
}
|
|
12588
|
+
pragmaChecker(info.ast);
|
|
12368
12589
|
}
|
|
12369
|
-
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12370
12590
|
return info.hasTests;
|
|
12371
12591
|
})).then((results) => {
|
|
12372
12592
|
const hasTests = results.some((v) => v);
|