arkanalyzer 1.0.6 → 1.0.8
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/config/arkanalyzer.json +8 -0
- package/docs/IR2ts-stmt.md +81 -0
- package/docs/IR2ts.md +82 -0
- package/lib/Config.d.ts +29 -1
- package/lib/Config.d.ts.map +1 -1
- package/lib/Config.js +44 -11
- package/lib/Scene.d.ts +152 -9
- package/lib/Scene.d.ts.map +1 -1
- package/lib/Scene.js +233 -66
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts +2 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/AbstractAnalysis.js +14 -7
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +2 -4
- package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
- package/lib/callgraph/algorithm/RapidTypeAnalysis.js +2 -3
- package/lib/callgraph/common/Statistics.js +1 -1
- package/lib/callgraph/model/BaseGraph.js +2 -2
- package/lib/callgraph/model/CallGraph.d.ts +3 -2
- package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
- package/lib/callgraph/model/CallGraph.js +23 -14
- package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +2 -2
- package/lib/callgraph/model/builder/CallGraphBuilder.js +3 -3
- package/lib/callgraph/pointerAnalysis/Context.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Context.js +0 -1
- package/lib/callgraph/pointerAnalysis/Pag.d.ts +36 -9
- package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/Pag.js +130 -37
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +34 -5
- package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PagBuilder.js +479 -126
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +6 -0
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +107 -45
- package/lib/callgraph/pointerAnalysis/PtsDS.d.ts.map +1 -1
- package/lib/callgraph/pointerAnalysis/PtsDS.js +0 -2
- package/lib/core/base/Constant.d.ts +37 -5
- package/lib/core/base/Constant.d.ts.map +1 -1
- package/lib/core/base/Constant.js +58 -8
- package/lib/core/base/Expr.d.ts +98 -13
- package/lib/core/base/Expr.d.ts.map +1 -1
- package/lib/core/base/Expr.js +295 -127
- package/lib/core/base/Local.d.ts +70 -5
- package/lib/core/base/Local.d.ts.map +1 -1
- package/lib/core/base/Local.js +77 -4
- package/lib/core/base/Ref.d.ts +79 -5
- package/lib/core/base/Ref.d.ts.map +1 -1
- package/lib/core/base/Ref.js +143 -38
- package/lib/core/base/Stmt.d.ts +126 -12
- package/lib/core/base/Stmt.d.ts.map +1 -1
- package/lib/core/base/Stmt.js +135 -28
- package/lib/core/base/Type.d.ts +11 -2
- package/lib/core/base/Type.d.ts.map +1 -1
- package/lib/core/base/Type.js +47 -42
- package/lib/core/base/Value.d.ts +24 -2
- package/lib/core/base/Value.d.ts.map +1 -1
- package/lib/core/common/ArkError.d.ts +15 -0
- package/lib/core/common/ArkError.d.ts.map +1 -0
- package/lib/core/common/ArkError.js +28 -0
- package/lib/core/common/ArkIRTransformer.d.ts +12 -5
- package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
- package/lib/core/common/ArkIRTransformer.js +90 -45
- package/lib/core/common/BodyBuilder.d.ts +2 -0
- package/lib/core/common/BodyBuilder.d.ts.map +1 -1
- package/lib/core/common/BodyBuilder.js +5 -2
- package/lib/core/common/Builtin.js +1 -1
- package/lib/core/common/CfgBuilder.d.ts +12 -7
- package/lib/core/common/CfgBuilder.d.ts.map +1 -1
- package/lib/core/common/CfgBuilder.js +336 -140
- package/lib/core/common/Const.d.ts +15 -10
- package/lib/core/common/Const.d.ts.map +1 -1
- package/lib/core/common/Const.js +18 -11
- package/lib/core/common/DummyMainCreater.d.ts +5 -4
- package/lib/core/common/DummyMainCreater.d.ts.map +1 -1
- package/lib/core/common/DummyMainCreater.js +43 -28
- package/lib/core/common/EtsConst.d.ts +1 -0
- package/lib/core/common/EtsConst.d.ts.map +1 -1
- package/lib/core/common/EtsConst.js +2 -1
- package/lib/core/common/ExprUseReplacer.js +8 -8
- package/lib/core/common/IRUtils.d.ts +7 -0
- package/lib/core/common/IRUtils.d.ts.map +1 -1
- package/lib/core/common/IRUtils.js +34 -2
- package/lib/core/common/ModelUtils.d.ts +1 -0
- package/lib/core/common/ModelUtils.d.ts.map +1 -1
- package/lib/core/common/ModelUtils.js +39 -36
- package/lib/core/common/RefUseReplacer.js +3 -3
- package/lib/core/common/StmtUseReplacer.js +4 -4
- package/lib/core/common/TSConst.d.ts +10 -3
- package/lib/core/common/TSConst.d.ts.map +1 -1
- package/lib/core/common/TSConst.js +11 -4
- package/lib/core/common/TypeInference.d.ts +8 -2
- package/lib/core/common/TypeInference.d.ts.map +1 -1
- package/lib/core/common/TypeInference.js +222 -90
- package/lib/core/common/ValueUtil.d.ts +0 -4
- package/lib/core/common/ValueUtil.d.ts.map +1 -1
- package/lib/core/common/ValueUtil.js +10 -27
- package/lib/core/common/VisibleValue.js +1 -1
- package/lib/core/dataflow/DataflowProblem.d.ts +1 -0
- package/lib/core/dataflow/DataflowProblem.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowProblem.js +4 -4
- package/lib/core/dataflow/DataflowSolver.d.ts +20 -16
- package/lib/core/dataflow/DataflowSolver.d.ts.map +1 -1
- package/lib/core/dataflow/DataflowSolver.js +67 -78
- package/lib/core/dataflow/TiantAnalysis.d.ts +1 -0
- package/lib/core/dataflow/TiantAnalysis.d.ts.map +1 -1
- package/lib/core/dataflow/TiantAnalysis.js +42 -28
- package/lib/core/dataflow/UndefinedVariable.d.ts +15 -1
- package/lib/core/dataflow/UndefinedVariable.d.ts.map +1 -1
- package/lib/core/dataflow/UndefinedVariable.js +122 -76
- package/lib/core/dataflow/Util.d.ts +5 -1
- package/lib/core/dataflow/Util.d.ts.map +1 -1
- package/lib/core/dataflow/Util.js +43 -22
- package/lib/core/graph/BasicBlock.d.ts +72 -0
- package/lib/core/graph/BasicBlock.d.ts.map +1 -1
- package/lib/core/graph/BasicBlock.js +165 -3
- package/lib/core/graph/Cfg.d.ts +30 -1
- package/lib/core/graph/Cfg.d.ts.map +1 -1
- package/lib/core/graph/Cfg.js +131 -11
- package/lib/core/graph/DominanceFinder.js +7 -7
- package/lib/core/graph/DominanceTree.js +4 -4
- package/lib/core/graph/builder/ViewTreeBuilder.d.ts.map +1 -1
- package/lib/core/graph/builder/ViewTreeBuilder.js +6 -5
- package/lib/core/model/ArkBaseModel.d.ts +59 -0
- package/lib/core/model/ArkBaseModel.d.ts.map +1 -0
- package/lib/core/model/ArkBaseModel.js +271 -0
- package/lib/core/model/ArkBody.d.ts +3 -9
- package/lib/core/model/ArkBody.d.ts.map +1 -1
- package/lib/core/model/ArkBody.js +3 -14
- package/lib/core/model/ArkClass.d.ts +107 -13
- package/lib/core/model/ArkClass.d.ts.map +1 -1
- package/lib/core/model/ArkClass.js +152 -54
- package/lib/core/model/ArkExport.d.ts +8 -7
- package/lib/core/model/ArkExport.d.ts.map +1 -1
- package/lib/core/model/ArkExport.js +16 -18
- package/lib/core/model/ArkField.d.ts +16 -13
- package/lib/core/model/ArkField.d.ts.map +1 -1
- package/lib/core/model/ArkField.js +18 -62
- package/lib/core/model/ArkFile.d.ts +42 -0
- package/lib/core/model/ArkFile.d.ts.map +1 -1
- package/lib/core/model/ArkFile.js +58 -0
- package/lib/core/model/ArkImport.d.ts +9 -7
- package/lib/core/model/ArkImport.d.ts.map +1 -1
- package/lib/core/model/ArkImport.js +11 -12
- package/lib/core/model/ArkMetadata.d.ts +20 -0
- package/lib/core/model/ArkMetadata.d.ts.map +1 -0
- package/lib/core/model/ArkMetadata.js +44 -0
- package/lib/core/model/ArkMethod.d.ts +195 -17
- package/lib/core/model/ArkMethod.d.ts.map +1 -1
- package/lib/core/model/ArkMethod.js +363 -46
- package/lib/core/model/ArkNamespace.d.ts +6 -8
- package/lib/core/model/ArkNamespace.d.ts.map +1 -1
- package/lib/core/model/ArkNamespace.js +16 -20
- package/lib/core/model/ArkSignature.d.ts +41 -0
- package/lib/core/model/ArkSignature.d.ts.map +1 -1
- package/lib/core/model/ArkSignature.js +76 -19
- package/lib/core/model/builder/ArkClassBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkClassBuilder.js +60 -49
- package/lib/core/model/builder/ArkExportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkExportBuilder.js +12 -6
- package/lib/core/model/builder/ArkFieldBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkFieldBuilder.js +13 -9
- package/lib/core/model/builder/ArkFileBuilder.js +1 -3
- package/lib/core/model/builder/ArkImportBuilder.d.ts +2 -1
- package/lib/core/model/builder/ArkImportBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkImportBuilder.js +16 -13
- package/lib/core/model/builder/ArkMethodBuilder.d.ts +3 -1
- package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkMethodBuilder.js +105 -45
- package/lib/core/model/builder/ArkNamespaceBuilder.d.ts.map +1 -1
- package/lib/core/model/builder/ArkNamespaceBuilder.js +4 -5
- package/lib/core/model/builder/builderUtils.d.ts +2 -1
- package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
- package/lib/core/model/builder/builderUtils.js +63 -43
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -3
- package/lib/save/ArkStream.js +1 -1
- package/lib/save/DotPrinter.d.ts.map +1 -1
- package/lib/save/DotPrinter.js +1 -15
- package/lib/save/GraphPrinter.d.ts.map +1 -1
- package/lib/save/GraphPrinter.js +4 -2
- package/lib/save/JsonPrinter.js +5 -5
- package/lib/save/ViewTreePrinter.d.ts +16 -0
- package/lib/save/ViewTreePrinter.d.ts.map +1 -0
- package/lib/save/ViewTreePrinter.js +130 -0
- package/lib/save/source/SourceBase.d.ts +2 -2
- package/lib/save/source/SourceBase.d.ts.map +1 -1
- package/lib/save/source/SourceBase.js +6 -13
- package/lib/save/source/SourceBody.d.ts.map +1 -1
- package/lib/save/source/SourceBody.js +27 -14
- package/lib/save/source/SourceClass.d.ts.map +1 -1
- package/lib/save/source/SourceClass.js +12 -8
- package/lib/save/source/SourceField.d.ts.map +1 -1
- package/lib/save/source/SourceField.js +6 -2
- package/lib/save/source/SourceMethod.d.ts.map +1 -1
- package/lib/save/source/SourceMethod.js +10 -3
- package/lib/save/source/SourceModule.d.ts.map +1 -1
- package/lib/save/source/SourceModule.js +16 -10
- package/lib/save/source/SourceNamespace.d.ts.map +1 -1
- package/lib/save/source/SourceNamespace.js +4 -0
- package/lib/save/source/SourceStmt.d.ts +1 -1
- package/lib/save/source/SourceStmt.d.ts.map +1 -1
- package/lib/save/source/SourceStmt.js +37 -25
- package/lib/save/source/SourceTransformer.d.ts +6 -0
- package/lib/save/source/SourceTransformer.d.ts.map +1 -1
- package/lib/save/source/SourceTransformer.js +82 -51
- package/lib/save/source/SourceUtils.d.ts.map +1 -1
- package/lib/save/source/SourceUtils.js +12 -11
- package/lib/transformer/StaticSingleAssignmentFormer.js +3 -3
- package/lib/utils/CfgStructualAnalysis.d.ts +1 -0
- package/lib/utils/CfgStructualAnalysis.d.ts.map +1 -1
- package/lib/utils/CfgStructualAnalysis.js +103 -72
- package/lib/utils/callGraphUtils.d.ts.map +1 -1
- package/lib/utils/callGraphUtils.js +7 -10
- package/lib/utils/crypto_utils.d.ts +6 -0
- package/lib/utils/crypto_utils.d.ts.map +1 -0
- package/lib/utils/crypto_utils.js +57 -0
- package/lib/utils/entryMethodUtils.d.ts.map +1 -1
- package/lib/utils/entryMethodUtils.js +27 -26
- package/lib/utils/getAllFiles.d.ts +1 -1
- package/lib/utils/getAllFiles.d.ts.map +1 -1
- package/lib/utils/getAllFiles.js +4 -5
- package/lib/utils/logger.js +2 -2
- package/package.json +3 -2
|
@@ -39,6 +39,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.CfgBuilder = void 0;
|
|
41
41
|
const ts = __importStar(require("ohos-typescript"));
|
|
42
|
+
const Local_1 = require("../base/Local");
|
|
42
43
|
const Stmt_1 = require("../base/Stmt");
|
|
43
44
|
const BasicBlock_1 = require("../graph/BasicBlock");
|
|
44
45
|
const Cfg_1 = require("../graph/Cfg");
|
|
@@ -180,7 +181,7 @@ class CfgBuilder {
|
|
|
180
181
|
walkAST(lastStatement, nextStatement, nodes) {
|
|
181
182
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
182
183
|
function judgeLastType(s) {
|
|
183
|
-
if (lastStatement.type
|
|
184
|
+
if (lastStatement.type === 'ifStatement') {
|
|
184
185
|
let lastIf = lastStatement;
|
|
185
186
|
if (lastIf.nextT == null) {
|
|
186
187
|
lastIf.nextT = s;
|
|
@@ -191,12 +192,12 @@ class CfgBuilder {
|
|
|
191
192
|
s.lasts.add(lastIf);
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
|
-
else if (lastStatement.type
|
|
195
|
+
else if (lastStatement.type === 'loopStatement') {
|
|
195
196
|
let lastLoop = lastStatement;
|
|
196
197
|
lastLoop.nextT = s;
|
|
197
198
|
s.lasts.add(lastLoop);
|
|
198
199
|
}
|
|
199
|
-
else if (lastStatement.type
|
|
200
|
+
else if (lastStatement.type === 'catchOrNot') {
|
|
200
201
|
let lastLoop = lastStatement;
|
|
201
202
|
lastLoop.nextT = s;
|
|
202
203
|
s.lasts.add(lastLoop);
|
|
@@ -209,7 +210,7 @@ class CfgBuilder {
|
|
|
209
210
|
this.scopeLevel++;
|
|
210
211
|
let scope = new Scope(this.scopes.length, new Set(), this.scopeLevel);
|
|
211
212
|
for (let i = this.scopes.length - 1; i >= 0; i--) {
|
|
212
|
-
if (this.scopes[i].level
|
|
213
|
+
if (this.scopes[i].level === this.scopeLevel - 1) {
|
|
213
214
|
scope.parent = this.scopes[i];
|
|
214
215
|
break;
|
|
215
216
|
}
|
|
@@ -222,6 +223,11 @@ class CfgBuilder {
|
|
|
222
223
|
judgeLastType(s);
|
|
223
224
|
lastStatement = s;
|
|
224
225
|
}
|
|
226
|
+
else if (!this.declaringMethod.isDefaultArkMethod() && ts.isFunctionDeclaration(c)) {
|
|
227
|
+
let s = new StatementBuilder('functionDeclarationStatement', c.getText(this.sourceFile), c, scope.id);
|
|
228
|
+
judgeLastType(s);
|
|
229
|
+
lastStatement = s;
|
|
230
|
+
}
|
|
225
231
|
else if (ts.isReturnStatement(c)) {
|
|
226
232
|
let s = new StatementBuilder('returnStatement', c.getText(this.sourceFile), c, scope.id);
|
|
227
233
|
judgeLastType(s);
|
|
@@ -367,7 +373,7 @@ class CfgBuilder {
|
|
|
367
373
|
this.walkAST(lastStatement, loopstm, [c.statement]);
|
|
368
374
|
}
|
|
369
375
|
let lastType = lastStatement.type;
|
|
370
|
-
if (lastType
|
|
376
|
+
if (lastType === 'ifStatement' || lastType === 'loopStatement') {
|
|
371
377
|
let lastCondition = lastStatement;
|
|
372
378
|
loopstm.nextT = lastCondition.nextT;
|
|
373
379
|
(_f = lastCondition.nextT) === null || _f === void 0 ? void 0 : _f.lasts.add(loopstm);
|
|
@@ -376,7 +382,7 @@ class CfgBuilder {
|
|
|
376
382
|
loopstm.nextT = lastStatement.next;
|
|
377
383
|
(_g = lastStatement.next) === null || _g === void 0 ? void 0 : _g.lasts.add(loopstm);
|
|
378
384
|
}
|
|
379
|
-
if (loopstm.nextT && loopstm.nextT
|
|
385
|
+
if (loopstm.nextT && loopstm.nextT !== loopstm) {
|
|
380
386
|
loopstm.nextT.isDoWhile = true;
|
|
381
387
|
loopstm.doStatement = loopstm.nextT;
|
|
382
388
|
}
|
|
@@ -424,7 +430,7 @@ class CfgBuilder {
|
|
|
424
430
|
(_h = casestm.next) === null || _h === void 0 ? void 0 : _h.lasts.add(lastCaseExit);
|
|
425
431
|
}
|
|
426
432
|
lastCaseExit = caseExit;
|
|
427
|
-
if (i
|
|
433
|
+
if (i === c.caseBlock.clauses.length - 1) {
|
|
428
434
|
caseExit.next = switchExit;
|
|
429
435
|
switchExit.lasts.add(caseExit);
|
|
430
436
|
}
|
|
@@ -488,13 +494,13 @@ class CfgBuilder {
|
|
|
488
494
|
}
|
|
489
495
|
}
|
|
490
496
|
this.scopeLevel--;
|
|
491
|
-
if (lastStatement.type
|
|
497
|
+
if (lastStatement.type !== 'breakStatement' && lastStatement.type !== 'continueStatement' && lastStatement.type !== 'returnStatement') {
|
|
492
498
|
lastStatement.next = nextStatement;
|
|
493
499
|
nextStatement.lasts.add(lastStatement);
|
|
494
500
|
}
|
|
495
501
|
}
|
|
496
502
|
addReturnInEmptyMethod() {
|
|
497
|
-
if (this.entry.next
|
|
503
|
+
if (this.entry.next === this.exit) {
|
|
498
504
|
const ret = new StatementBuilder('returnStatement', 'return;', null, this.entry.scopeID);
|
|
499
505
|
this.entry.next = ret;
|
|
500
506
|
ret.lasts.add(this.entry);
|
|
@@ -506,13 +512,13 @@ class CfgBuilder {
|
|
|
506
512
|
for (const exit of this.exits) {
|
|
507
513
|
for (const last of [...exit.lasts]) {
|
|
508
514
|
if (last instanceof ConditionStatementBuilder) {
|
|
509
|
-
if (last.nextT
|
|
515
|
+
if (last.nextT === exit) {
|
|
510
516
|
last.nextT = exit.next;
|
|
511
517
|
const lasts = exit.next.lasts;
|
|
512
518
|
lasts.delete(exit);
|
|
513
519
|
lasts.add(last);
|
|
514
520
|
}
|
|
515
|
-
else if (last.nextF
|
|
521
|
+
else if (last.nextF === exit) {
|
|
516
522
|
last.nextF = exit.next;
|
|
517
523
|
const lasts = exit.next.lasts;
|
|
518
524
|
lasts.delete(exit);
|
|
@@ -522,7 +528,7 @@ class CfgBuilder {
|
|
|
522
528
|
else if (last instanceof SwitchStatementBuilder) {
|
|
523
529
|
for (let i = 0; i < last.nexts.length; i++) {
|
|
524
530
|
const stmt = last.nexts[i];
|
|
525
|
-
if (stmt
|
|
531
|
+
if (stmt === exit) {
|
|
526
532
|
last.nexts[i] = exit.next;
|
|
527
533
|
const lasts = exit.next.lasts;
|
|
528
534
|
lasts.delete(exit);
|
|
@@ -559,7 +565,7 @@ class CfgBuilder {
|
|
|
559
565
|
const block = new Block(this.blocks.length, []);
|
|
560
566
|
this.blocks.push(block);
|
|
561
567
|
while (stmt && !handledStmts.has(stmt)) {
|
|
562
|
-
if (stmt.type
|
|
568
|
+
if (stmt.type === 'loopStatement' && block.stmts.length > 0 && !stmt.isDoWhile) {
|
|
563
569
|
stmtQueue.push(stmt);
|
|
564
570
|
break;
|
|
565
571
|
}
|
|
@@ -599,15 +605,15 @@ class CfgBuilder {
|
|
|
599
605
|
}
|
|
600
606
|
else {
|
|
601
607
|
if (stmt.next) {
|
|
602
|
-
if ((stmt.type
|
|
608
|
+
if ((stmt.type === 'continueStatement' || stmt.next.type === 'loopStatement') && stmt.next.block) {
|
|
603
609
|
break;
|
|
604
610
|
}
|
|
605
611
|
if (stmt.next.type.includes('exit')) {
|
|
606
612
|
break;
|
|
607
613
|
}
|
|
608
614
|
stmt.next.passTmies++;
|
|
609
|
-
if (stmt.next.passTmies
|
|
610
|
-
if (stmt.next.scopeID
|
|
615
|
+
if (stmt.next.passTmies === stmt.next.lasts.size || (stmt.next.type === 'loopStatement') || stmt.next.isDoWhile) {
|
|
616
|
+
if (stmt.next.scopeID !== stmt.scopeID && !(stmt.next instanceof ConditionStatementBuilder && stmt.next.doStatement)
|
|
611
617
|
&& !(ts.isCaseClause(stmt.astNode) || ts.isDefaultClause(stmt.astNode))) {
|
|
612
618
|
stmtQueue.push(stmt.next);
|
|
613
619
|
break;
|
|
@@ -623,15 +629,15 @@ class CfgBuilder {
|
|
|
623
629
|
var _a, _b, _c, _d, _e, _f;
|
|
624
630
|
for (let block of this.blocks) {
|
|
625
631
|
for (let originStatement of block.stmts) {
|
|
626
|
-
let lastStatement = (block.stmts.indexOf(originStatement)
|
|
632
|
+
let lastStatement = (block.stmts.indexOf(originStatement) === block.stmts.length - 1);
|
|
627
633
|
if (originStatement instanceof ConditionStatementBuilder) {
|
|
628
634
|
let nextT = (_a = originStatement.nextT) === null || _a === void 0 ? void 0 : _a.block;
|
|
629
|
-
if (nextT && (lastStatement || nextT
|
|
635
|
+
if (nextT && (lastStatement || nextT !== block) && !((_b = originStatement.nextT) === null || _b === void 0 ? void 0 : _b.type.includes(' exit'))) {
|
|
630
636
|
block.nexts.push(nextT);
|
|
631
637
|
nextT.lasts.push(block);
|
|
632
638
|
}
|
|
633
639
|
let nextF = (_c = originStatement.nextF) === null || _c === void 0 ? void 0 : _c.block;
|
|
634
|
-
if (nextF && (lastStatement || nextF
|
|
640
|
+
if (nextF && (lastStatement || nextF !== block) && !((_d = originStatement.nextF) === null || _d === void 0 ? void 0 : _d.type.includes(' exit'))) {
|
|
635
641
|
block.nexts.push(nextF);
|
|
636
642
|
nextF.lasts.push(block);
|
|
637
643
|
}
|
|
@@ -639,7 +645,7 @@ class CfgBuilder {
|
|
|
639
645
|
else if (originStatement instanceof SwitchStatementBuilder) {
|
|
640
646
|
for (const next of originStatement.nexts) {
|
|
641
647
|
const nextBlock = next.block;
|
|
642
|
-
if (nextBlock && (lastStatement || nextBlock
|
|
648
|
+
if (nextBlock && (lastStatement || nextBlock !== block)) {
|
|
643
649
|
block.nexts.push(nextBlock);
|
|
644
650
|
nextBlock.lasts.push(block);
|
|
645
651
|
}
|
|
@@ -647,7 +653,7 @@ class CfgBuilder {
|
|
|
647
653
|
}
|
|
648
654
|
else {
|
|
649
655
|
let next = (_e = originStatement.next) === null || _e === void 0 ? void 0 : _e.block;
|
|
650
|
-
if (next && (lastStatement || next
|
|
656
|
+
if (next && (lastStatement || next !== block) && !((_f = originStatement.next) === null || _f === void 0 ? void 0 : _f.type.includes(' exit'))) {
|
|
651
657
|
block.nexts.push(next);
|
|
652
658
|
next.lasts.push(block);
|
|
653
659
|
}
|
|
@@ -659,7 +665,7 @@ class CfgBuilder {
|
|
|
659
665
|
var _a, _b, _c, _d;
|
|
660
666
|
let notReturnStmts = [];
|
|
661
667
|
for (let stmt of [...this.exit.lasts]) {
|
|
662
|
-
if (stmt.type
|
|
668
|
+
if (stmt.type !== 'returnStatement') {
|
|
663
669
|
notReturnStmts.push(stmt);
|
|
664
670
|
}
|
|
665
671
|
}
|
|
@@ -668,7 +674,7 @@ class CfgBuilder {
|
|
|
668
674
|
}
|
|
669
675
|
const returnStatement = new StatementBuilder('returnStatement', 'return;', null, this.exit.scopeID);
|
|
670
676
|
let tryExit = false;
|
|
671
|
-
if (notReturnStmts.length
|
|
677
|
+
if (notReturnStmts.length === 1 && notReturnStmts[0].block) {
|
|
672
678
|
for (const stmt of notReturnStmts[0].block.stmts) {
|
|
673
679
|
if (stmt instanceof TryStatementBuilder) {
|
|
674
680
|
tryExit = true;
|
|
@@ -676,7 +682,7 @@ class CfgBuilder {
|
|
|
676
682
|
}
|
|
677
683
|
}
|
|
678
684
|
}
|
|
679
|
-
if (notReturnStmts.length
|
|
685
|
+
if (notReturnStmts.length === 1 && !(notReturnStmts[0] instanceof ConditionStatementBuilder) && !tryExit) {
|
|
680
686
|
const notReturnStmt = notReturnStmts[0];
|
|
681
687
|
notReturnStmt.next = returnStatement;
|
|
682
688
|
returnStatement.lasts = new Set([notReturnStmt]);
|
|
@@ -693,11 +699,11 @@ class CfgBuilder {
|
|
|
693
699
|
this.blocks.push(returnBlock);
|
|
694
700
|
for (const notReturnStmt of notReturnStmts) {
|
|
695
701
|
if (notReturnStmt instanceof ConditionStatementBuilder) {
|
|
696
|
-
if (this.exit
|
|
702
|
+
if (this.exit === notReturnStmt.nextT) {
|
|
697
703
|
notReturnStmt.nextT = returnStatement;
|
|
698
704
|
(_b = notReturnStmt.block) === null || _b === void 0 ? void 0 : _b.nexts.splice(0, 0, returnBlock);
|
|
699
705
|
}
|
|
700
|
-
else if (this.exit
|
|
706
|
+
else if (this.exit === notReturnStmt.nextF) {
|
|
701
707
|
notReturnStmt.nextF = returnStatement;
|
|
702
708
|
(_c = notReturnStmt.block) === null || _c === void 0 ? void 0 : _c.nexts.push(returnBlock);
|
|
703
709
|
}
|
|
@@ -736,7 +742,7 @@ class CfgBuilder {
|
|
|
736
742
|
stmt.index = this.statementArray.length;
|
|
737
743
|
if (!stmt.type.includes(' exit'))
|
|
738
744
|
this.statementArray.push(stmt);
|
|
739
|
-
if (stmt.type
|
|
745
|
+
if (stmt.type === 'ifStatement' || stmt.type === 'loopStatement' || stmt.type === 'catchOrNot') {
|
|
740
746
|
let cstm = stmt;
|
|
741
747
|
if (cstm.nextT == null || cstm.nextF == null) {
|
|
742
748
|
this.errorTest(cstm);
|
|
@@ -745,13 +751,13 @@ class CfgBuilder {
|
|
|
745
751
|
this.CfgBuilder2Array(cstm.nextF);
|
|
746
752
|
this.CfgBuilder2Array(cstm.nextT);
|
|
747
753
|
}
|
|
748
|
-
else if (stmt.type
|
|
754
|
+
else if (stmt.type === 'switchStatement') {
|
|
749
755
|
let sstm = stmt;
|
|
750
756
|
for (let ss of sstm.nexts) {
|
|
751
757
|
this.CfgBuilder2Array(ss);
|
|
752
758
|
}
|
|
753
759
|
}
|
|
754
|
-
else if (stmt.type
|
|
760
|
+
else if (stmt.type === 'tryStatement') {
|
|
755
761
|
let trystm = stmt;
|
|
756
762
|
if (trystm.tryFirst) {
|
|
757
763
|
this.CfgBuilder2Array(trystm.tryFirst);
|
|
@@ -772,12 +778,12 @@ class CfgBuilder {
|
|
|
772
778
|
}
|
|
773
779
|
}
|
|
774
780
|
getDotEdges(stmt) {
|
|
775
|
-
if (this.statementArray.length
|
|
781
|
+
if (this.statementArray.length === 0)
|
|
776
782
|
this.CfgBuilder2Array(this.entry);
|
|
777
783
|
if (stmt.walked)
|
|
778
784
|
return;
|
|
779
785
|
stmt.walked = true;
|
|
780
|
-
if (stmt.type
|
|
786
|
+
if (stmt.type === 'ifStatement' || stmt.type === 'loopStatement' || stmt.type === 'catchOrNot') {
|
|
781
787
|
let cstm = stmt;
|
|
782
788
|
if (cstm.nextT == null || cstm.nextF == null) {
|
|
783
789
|
this.errorTest(cstm);
|
|
@@ -790,7 +796,7 @@ class CfgBuilder {
|
|
|
790
796
|
this.getDotEdges(cstm.nextF);
|
|
791
797
|
this.getDotEdges(cstm.nextT);
|
|
792
798
|
}
|
|
793
|
-
else if (stmt.type
|
|
799
|
+
else if (stmt.type === 'switchStatement') {
|
|
794
800
|
let sstm = stmt;
|
|
795
801
|
for (let ss of sstm.nexts) {
|
|
796
802
|
let edge = [sstm.index, ss.index];
|
|
@@ -823,12 +829,12 @@ class CfgBuilder {
|
|
|
823
829
|
}
|
|
824
830
|
for (let bi = 0; bi < this.blocks.length; bi++) {
|
|
825
831
|
let block = this.blocks[bi];
|
|
826
|
-
if (bi
|
|
832
|
+
if (bi !== 0)
|
|
827
833
|
text += 'label' + block.id + ':\n';
|
|
828
834
|
let length = block.stmts.length;
|
|
829
835
|
for (let i = 0; i < length; i++) {
|
|
830
836
|
let stmt = block.stmts[i];
|
|
831
|
-
if (stmt.type
|
|
837
|
+
if (stmt.type === 'ifStatement' || stmt.type === 'loopStatement' || stmt.type === 'catchOrNot') {
|
|
832
838
|
let cstm = stmt;
|
|
833
839
|
if (cstm.nextT == null || cstm.nextF == null) {
|
|
834
840
|
this.errorTest(cstm);
|
|
@@ -839,13 +845,13 @@ class CfgBuilder {
|
|
|
839
845
|
return text;
|
|
840
846
|
}
|
|
841
847
|
stmt.code = 'if !(' + cstm.condition + ') goto label' + cstm.nextF.block.id;
|
|
842
|
-
if (i
|
|
848
|
+
if (i === length - 1 && bi + 1 < this.blocks.length && this.blocks[bi + 1].id !== cstm.nextT.block.id) {
|
|
843
849
|
let gotoStm = new StatementBuilder('gotoStatement', 'goto label' + cstm.nextT.block.id, null, block.stmts[0].scopeID);
|
|
844
850
|
block.stmts.push(gotoStm);
|
|
845
851
|
length++;
|
|
846
852
|
}
|
|
847
853
|
}
|
|
848
|
-
else if (stmt.type
|
|
854
|
+
else if (stmt.type === 'breakStatement' || stmt.type === 'continueStatement') {
|
|
849
855
|
if (!((_b = stmt.next) === null || _b === void 0 ? void 0 : _b.block)) {
|
|
850
856
|
this.errorTest(stmt);
|
|
851
857
|
return text;
|
|
@@ -853,13 +859,13 @@ class CfgBuilder {
|
|
|
853
859
|
stmt.code = 'goto label' + ((_c = stmt.next) === null || _c === void 0 ? void 0 : _c.block.id);
|
|
854
860
|
}
|
|
855
861
|
else {
|
|
856
|
-
if (i
|
|
862
|
+
if (i === length - 1 && ((_d = stmt.next) === null || _d === void 0 ? void 0 : _d.block) && (bi + 1 < this.blocks.length && this.blocks[bi + 1].id !== stmt.next.block.id || bi + 1 === this.blocks.length)) {
|
|
857
863
|
let gotoStm = new StatementBuilder('StatementBuilder', 'goto label' + ((_e = stmt.next) === null || _e === void 0 ? void 0 : _e.block.id), null, block.stmts[0].scopeID);
|
|
858
864
|
block.stmts.push(gotoStm);
|
|
859
865
|
length++;
|
|
860
866
|
}
|
|
861
867
|
}
|
|
862
|
-
if (stmt.addressCode3.length
|
|
868
|
+
if (stmt.addressCode3.length === 0) {
|
|
863
869
|
text += ' ' + stmt.code + '\n';
|
|
864
870
|
}
|
|
865
871
|
else {
|
|
@@ -931,7 +937,7 @@ class CfgBuilder {
|
|
|
931
937
|
this.CfgBuilder2Array(this.entry);
|
|
932
938
|
this.addStmtBuilderPosition();
|
|
933
939
|
this.buildBlocks();
|
|
934
|
-
this.blocks = this.blocks.filter((b) => b.stmts.length
|
|
940
|
+
this.blocks = this.blocks.filter((b) => b.stmts.length !== 0);
|
|
935
941
|
this.buildBlocksNextLast();
|
|
936
942
|
this.addReturnBlock();
|
|
937
943
|
}
|
|
@@ -976,7 +982,6 @@ class CfgBuilder {
|
|
|
976
982
|
expressionBodyStmts.push(returnStmt);
|
|
977
983
|
arkIRTransformer.mapStmtsToTsStmt(expressionBodyStmts, expressionBodyNode);
|
|
978
984
|
stmts.push(...expressionBodyStmts);
|
|
979
|
-
const stmtToOriginalStmt = arkIRTransformer.getStmtToOriginalStmt();
|
|
980
985
|
const cfg = new Cfg_1.Cfg();
|
|
981
986
|
const blockInCfg = new BasicBlock_1.BasicBlock();
|
|
982
987
|
blockInCfg.setId(0);
|
|
@@ -986,15 +991,8 @@ class CfgBuilder {
|
|
|
986
991
|
});
|
|
987
992
|
cfg.addBlock(blockInCfg);
|
|
988
993
|
cfg.setStartingStmt(stmts[0]);
|
|
989
|
-
const originalCfg = new Cfg_1.Cfg();
|
|
990
|
-
const blockInOriginalCfg = new BasicBlock_1.BasicBlock();
|
|
991
|
-
blockInOriginalCfg.setId(0);
|
|
992
|
-
originalCfg.addBlock(blockInOriginalCfg);
|
|
993
|
-
originalCfg.setStartingStmt(stmtToOriginalStmt.get(stmts[0]));
|
|
994
994
|
return {
|
|
995
995
|
cfg: cfg,
|
|
996
|
-
originalCfg: originalCfg,
|
|
997
|
-
stmtToOriginalStmt: stmtToOriginalStmt,
|
|
998
996
|
locals: arkIRTransformer.getLocals(),
|
|
999
997
|
aliasTypeMap: arkIRTransformer.getAliasTypeMap()
|
|
1000
998
|
};
|
|
@@ -1003,10 +1001,7 @@ class CfgBuilder {
|
|
|
1003
1001
|
const cfg = new Cfg_1.Cfg();
|
|
1004
1002
|
const blockBuilderToCfgBlock = new Map();
|
|
1005
1003
|
let isStartingStmtInCfgBlock = true;
|
|
1006
|
-
const stmtsInOriginalCfg = [];
|
|
1007
|
-
const stmtSetInOriginalCfg = new Set();
|
|
1008
1004
|
const arkIRTransformer = new ArkIRTransformer_1.ArkIRTransformer(this.sourceFile, this.declaringMethod);
|
|
1009
|
-
const stmtToOriginalStmt = arkIRTransformer.getStmtToOriginalStmt();
|
|
1010
1005
|
const blocksContainLoopCondition = new Set();
|
|
1011
1006
|
for (let i = 0; i < this.blocks.length; i++) {
|
|
1012
1007
|
// build block in Cfg
|
|
@@ -1015,10 +1010,10 @@ class CfgBuilder {
|
|
|
1015
1010
|
stmtsInBlock.push(...arkIRTransformer.prebuildStmts());
|
|
1016
1011
|
}
|
|
1017
1012
|
for (const statementBuilder of this.blocks[i].stmts) {
|
|
1018
|
-
if (statementBuilder.type
|
|
1013
|
+
if (statementBuilder.type === 'loopStatement') {
|
|
1019
1014
|
blocksContainLoopCondition.add(this.blocks[i]);
|
|
1020
1015
|
}
|
|
1021
|
-
if (statementBuilder.astNode && statementBuilder.code
|
|
1016
|
+
if (statementBuilder.astNode && statementBuilder.code !== '') {
|
|
1022
1017
|
stmtsInBlock.push(...arkIRTransformer.tsNodeToStmts(statementBuilder.astNode));
|
|
1023
1018
|
}
|
|
1024
1019
|
else if (statementBuilder.code.startsWith('return')) {
|
|
@@ -1036,19 +1031,33 @@ class CfgBuilder {
|
|
|
1036
1031
|
}
|
|
1037
1032
|
cfg.addBlock(blockInCfg);
|
|
1038
1033
|
blockBuilderToCfgBlock.set(this.blocks[i], blockInCfg);
|
|
1039
|
-
// collect stmts in OriginalCfg
|
|
1040
|
-
for (const stmt of stmtsInBlock) {
|
|
1041
|
-
const originalStmt = stmtToOriginalStmt.get(stmt);
|
|
1042
|
-
if (originalStmt) {
|
|
1043
|
-
if (!stmtSetInOriginalCfg.has(originalStmt)) {
|
|
1044
|
-
stmtSetInOriginalCfg.add(originalStmt);
|
|
1045
|
-
stmtsInOriginalCfg.push(originalStmt);
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
1034
|
}
|
|
1050
1035
|
let currBlockId = this.blocks.length;
|
|
1051
|
-
|
|
1036
|
+
this.linkBasicBlocks(blockBuilderToCfgBlock);
|
|
1037
|
+
this.rebuildBlocksInLoop(blockBuilderToCfgBlock, blocksContainLoopCondition, cfg);
|
|
1038
|
+
this.rebuildBlocksInConditionalOperator(cfg);
|
|
1039
|
+
for (const blockBuilder of this.blocks) {
|
|
1040
|
+
if (blockBuilder.id === -1) {
|
|
1041
|
+
blockBuilder.id = currBlockId++;
|
|
1042
|
+
const block = blockBuilderToCfgBlock.get(blockBuilder);
|
|
1043
|
+
block.setId(blockBuilder.id);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
for (const block of cfg.getBlocks()) {
|
|
1047
|
+
if (block.getId() === -1) {
|
|
1048
|
+
block.setId(currBlockId++);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
for (const stmt of cfg.getStmts()) {
|
|
1052
|
+
stmt.setCfg(cfg);
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
cfg: cfg,
|
|
1056
|
+
locals: arkIRTransformer.getLocals(),
|
|
1057
|
+
aliasTypeMap: arkIRTransformer.getAliasTypeMap(),
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
linkBasicBlocks(blockBuilderToCfgBlock) {
|
|
1052
1061
|
for (const [blockBuilder, cfgBlock] of blockBuilderToCfgBlock) {
|
|
1053
1062
|
for (const successorBlockBuilder of blockBuilder.nexts) {
|
|
1054
1063
|
if (!blockBuilderToCfgBlock.get(successorBlockBuilder)) {
|
|
@@ -1065,7 +1074,204 @@ class CfgBuilder {
|
|
|
1065
1074
|
cfgBlock.addPredecessorBlock(predecessorBlock);
|
|
1066
1075
|
}
|
|
1067
1076
|
}
|
|
1068
|
-
|
|
1077
|
+
}
|
|
1078
|
+
rebuildBlocksInConditionalOperator(cfg) {
|
|
1079
|
+
var _a;
|
|
1080
|
+
for (const basicBlock of cfg.getBlocks()) {
|
|
1081
|
+
const stmts = Array.from(basicBlock.getStmts());
|
|
1082
|
+
const stmtCnt = stmts.length;
|
|
1083
|
+
let endPos = -1;
|
|
1084
|
+
for (let i = stmtCnt - 1; i >= 0; i--) {
|
|
1085
|
+
const stmt = stmts[i];
|
|
1086
|
+
if (stmt instanceof ArkIRTransformer_1.DummyStmt && ((_a = stmt.toString()) === null || _a === void 0 ? void 0 : _a.startsWith(ArkIRTransformer_1.ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT))) {
|
|
1087
|
+
endPos = i;
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
if (endPos === -1) {
|
|
1092
|
+
continue;
|
|
1093
|
+
}
|
|
1094
|
+
const { topBlock, bottomBlocks, allBlocks, } = this.traverseAndRebuildConditionalOperator(stmts, 0, endPos);
|
|
1095
|
+
basicBlock.getStmts().splice(topBlock.getStmts().length);
|
|
1096
|
+
const succBlocksOfIfBlock = topBlock.getSuccessors();
|
|
1097
|
+
succBlocksOfIfBlock.forEach((block) => {
|
|
1098
|
+
block.setPredecessorBlock(0, basicBlock);
|
|
1099
|
+
});
|
|
1100
|
+
const conditionalOperatorBlockSet = new Set(allBlocks);
|
|
1101
|
+
this.adjustSuccessorOfConditionalOperator(basicBlock, succBlocksOfIfBlock, stmts, bottomBlocks, endPos, conditionalOperatorBlockSet);
|
|
1102
|
+
conditionalOperatorBlockSet.forEach((block) => {
|
|
1103
|
+
if (block !== topBlock) {
|
|
1104
|
+
cfg.addBlock(block);
|
|
1105
|
+
}
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
traverseAndRebuildConditionalOperator(stmts, beginPos, endPos) {
|
|
1110
|
+
const { ifTruePos, ifFalsePos, conditionalOperatorEndPos } = this.findConditionalOperator(stmts, beginPos, endPos);
|
|
1111
|
+
if (ifTruePos === -1) {
|
|
1112
|
+
const block = new BasicBlock_1.BasicBlock();
|
|
1113
|
+
block.getStmts().push(...stmts.slice(beginPos, endPos + 1));
|
|
1114
|
+
return { topBlock: block, bottomBlocks: [], allBlocks: [block] };
|
|
1115
|
+
}
|
|
1116
|
+
const allBlocks = [];
|
|
1117
|
+
const topBlock = new BasicBlock_1.BasicBlock();
|
|
1118
|
+
topBlock.getStmts().push(...stmts.slice(beginPos, ifTruePos));
|
|
1119
|
+
allBlocks.push(topBlock);
|
|
1120
|
+
const { topBlock: ifTrueTopBlock, bottomBlocks: ifTrueBottomBlocks, allBlocks: ifTrueAllBlocks, } = this.traverseAndRebuildConditionalOperator(stmts, ifTruePos + 1, ifFalsePos - 1);
|
|
1121
|
+
allBlocks.push(...ifTrueAllBlocks);
|
|
1122
|
+
const { topBlock: ifFalseTopBlock, bottomBlocks: ifFalseBottomBlocks, allBlocks: ifFalseAllBlocks, } = this.traverseAndRebuildConditionalOperator(stmts, ifFalsePos + 1, conditionalOperatorEndPos - 1);
|
|
1123
|
+
allBlocks.push(...ifFalseAllBlocks);
|
|
1124
|
+
topBlock.addSuccessorBlock(ifTrueTopBlock);
|
|
1125
|
+
topBlock.addSuccessorBlock(ifFalseTopBlock);
|
|
1126
|
+
ifTrueTopBlock.addPredecessorBlock(topBlock);
|
|
1127
|
+
ifFalseTopBlock.addPredecessorBlock(topBlock);
|
|
1128
|
+
let bottomBlocks = [];
|
|
1129
|
+
bottomBlocks.push(...(ifTrueBottomBlocks.length > 0 ? ifTrueBottomBlocks : [ifTrueTopBlock]));
|
|
1130
|
+
bottomBlocks.push(...(ifFalseBottomBlocks.length > 0 ? ifFalseBottomBlocks : [ifFalseTopBlock]));
|
|
1131
|
+
if (conditionalOperatorEndPos !== endPos) {
|
|
1132
|
+
const bottomBlock = new BasicBlock_1.BasicBlock();
|
|
1133
|
+
bottomBlock.getStmts().push(...stmts.slice(conditionalOperatorEndPos + 1, endPos + 1));
|
|
1134
|
+
bottomBlocks.forEach(block => {
|
|
1135
|
+
block.addSuccessorBlock(bottomBlock);
|
|
1136
|
+
bottomBlock.addPredecessorBlock(block);
|
|
1137
|
+
});
|
|
1138
|
+
bottomBlocks = [bottomBlock];
|
|
1139
|
+
allBlocks.push(bottomBlock);
|
|
1140
|
+
}
|
|
1141
|
+
return { topBlock: topBlock, bottomBlocks: bottomBlocks, allBlocks: allBlocks };
|
|
1142
|
+
}
|
|
1143
|
+
findConditionalOperator(stmts, beginPos, endPos) {
|
|
1144
|
+
let ifTruePos = -1;
|
|
1145
|
+
let ifFalsePos = -1;
|
|
1146
|
+
let conditionalOperatorEndPos = -1;
|
|
1147
|
+
let currConditionalOperatorNo = '';
|
|
1148
|
+
for (let i = beginPos; i <= endPos; i++) {
|
|
1149
|
+
const stmt = stmts[i];
|
|
1150
|
+
if (stmt instanceof ArkIRTransformer_1.DummyStmt) {
|
|
1151
|
+
if (stmt.toString()
|
|
1152
|
+
.startsWith(ArkIRTransformer_1.ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT) && ifTruePos === -1) {
|
|
1153
|
+
ifTruePos = i;
|
|
1154
|
+
currConditionalOperatorNo =
|
|
1155
|
+
stmt.toString().replace(ArkIRTransformer_1.ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT, '');
|
|
1156
|
+
}
|
|
1157
|
+
else if (stmt.toString() === ArkIRTransformer_1.ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorNo) {
|
|
1158
|
+
ifFalsePos = i;
|
|
1159
|
+
}
|
|
1160
|
+
else if (stmt.toString() === ArkIRTransformer_1.ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorNo) {
|
|
1161
|
+
conditionalOperatorEndPos = i;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return { ifTruePos: ifTruePos, ifFalsePos: ifFalsePos, conditionalOperatorEndPos: conditionalOperatorEndPos };
|
|
1166
|
+
}
|
|
1167
|
+
adjustSuccessorOfConditionalOperator(currBasicBlock, succBlocksOfIfBlock, stmts, bottomBlocks, conditionalOperatorEndPos, conditionalOperatorBlockSet) {
|
|
1168
|
+
const oldSuccBlocks = Array.from(currBasicBlock.getSuccessors());
|
|
1169
|
+
currBasicBlock.getSuccessors().splice(0, oldSuccBlocks.length, ...succBlocksOfIfBlock);
|
|
1170
|
+
oldSuccBlocks.forEach((succBlock) => {
|
|
1171
|
+
const originalPreds = succBlock.getPredecessors();
|
|
1172
|
+
for (let i = 0; i < originalPreds.length; i++) {
|
|
1173
|
+
if (originalPreds[i] === currBasicBlock) {
|
|
1174
|
+
succBlock.getPredecessors().splice(i, 1);
|
|
1175
|
+
break;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
if (conditionalOperatorEndPos === stmts.length - 1) {
|
|
1180
|
+
oldSuccBlocks.forEach((oldSuccBlock) => {
|
|
1181
|
+
bottomBlocks.forEach((bottomBlock) => {
|
|
1182
|
+
bottomBlock.addSuccessorBlock(oldSuccBlock);
|
|
1183
|
+
oldSuccBlock.addSuccessorBlock(bottomBlock);
|
|
1184
|
+
});
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
else {
|
|
1188
|
+
const insertSuccBlock = new BasicBlock_1.BasicBlock();
|
|
1189
|
+
insertSuccBlock.getStmts().push(...stmts.slice(conditionalOperatorEndPos + 1, stmts.length));
|
|
1190
|
+
oldSuccBlocks.forEach((oldSuccBlock) => {
|
|
1191
|
+
insertSuccBlock.addSuccessorBlock(oldSuccBlock);
|
|
1192
|
+
oldSuccBlock.addPredecessorBlock(insertSuccBlock);
|
|
1193
|
+
});
|
|
1194
|
+
bottomBlocks.forEach((bottomBlock) => {
|
|
1195
|
+
bottomBlock.addSuccessorBlock(insertSuccBlock);
|
|
1196
|
+
insertSuccBlock.addPredecessorBlock(bottomBlock);
|
|
1197
|
+
});
|
|
1198
|
+
conditionalOperatorBlockSet.add(insertSuccBlock);
|
|
1199
|
+
this.removeUnnecessaryBlocksInConditionalOperator(insertSuccBlock, conditionalOperatorBlockSet);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
removeUnnecessaryBlocksInConditionalOperator(bottomBlock, allBlocks) {
|
|
1203
|
+
const firstStmtInBottom = bottomBlock.getStmts()[0];
|
|
1204
|
+
if (!(firstStmtInBottom instanceof Stmt_1.ArkAssignStmt)) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
const targetValue = firstStmtInBottom.getLeftOp();
|
|
1208
|
+
const tempResultValue = firstStmtInBottom.getRightOp();
|
|
1209
|
+
if (!(targetValue instanceof Local_1.Local && IRUtils_1.IRUtils.isTempLocal(tempResultValue))) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
bottomBlock.remove(firstStmtInBottom);
|
|
1213
|
+
const oldPredecessors = bottomBlock.getPredecessors();
|
|
1214
|
+
const newPredecessors = [];
|
|
1215
|
+
for (const predecessor of oldPredecessors) {
|
|
1216
|
+
newPredecessors.push(...this.replaceTempResultcursively(predecessor, targetValue, tempResultValue, allBlocks));
|
|
1217
|
+
}
|
|
1218
|
+
bottomBlock.getPredecessors().splice(0, oldPredecessors.length, ...newPredecessors);
|
|
1219
|
+
newPredecessors.forEach((newPredecessor) => {
|
|
1220
|
+
newPredecessor.setSuccessorBlock(0, bottomBlock);
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
replaceTempResultcursively(currBottomBlock, targetLocal, tempResultLocal, allBlocks) {
|
|
1224
|
+
const stmts = currBottomBlock.getStmts();
|
|
1225
|
+
const stmtsCnt = stmts.length;
|
|
1226
|
+
let tempResultReassignStmt = null;
|
|
1227
|
+
for (let i = stmtsCnt - 1; i >= 0; i--) {
|
|
1228
|
+
const stmt = stmts[i];
|
|
1229
|
+
if (stmt instanceof Stmt_1.ArkAssignStmt && stmt.getLeftOp() === tempResultLocal) {
|
|
1230
|
+
if (IRUtils_1.IRUtils.isTempLocal(stmt.getRightOp()) && this.isNewDefLocal(stmt.getRightOp(), stmts, i)) {
|
|
1231
|
+
tempResultReassignStmt = stmt;
|
|
1232
|
+
}
|
|
1233
|
+
else {
|
|
1234
|
+
stmt.setLeftOp(targetLocal);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
let newBottomBlocks = [];
|
|
1239
|
+
if (tempResultReassignStmt) {
|
|
1240
|
+
const oldPredecessors = currBottomBlock.getPredecessors();
|
|
1241
|
+
const newPredecessors = [];
|
|
1242
|
+
const prevTempResultLocal = tempResultReassignStmt.getRightOp();
|
|
1243
|
+
for (const predecessor of oldPredecessors) {
|
|
1244
|
+
newPredecessors.push(...this.replaceTempResultcursively(predecessor, targetLocal, prevTempResultLocal, allBlocks));
|
|
1245
|
+
}
|
|
1246
|
+
currBottomBlock.remove(tempResultReassignStmt);
|
|
1247
|
+
if (currBottomBlock.getStmts().length === 0) {
|
|
1248
|
+
// remove this block
|
|
1249
|
+
newBottomBlocks = newPredecessors;
|
|
1250
|
+
allBlocks.delete(currBottomBlock);
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
currBottomBlock.getPredecessors().splice(0, oldPredecessors.length, ...newPredecessors);
|
|
1254
|
+
newPredecessors.forEach((newPredecessor) => {
|
|
1255
|
+
newPredecessor.setSuccessorBlock(0, currBottomBlock);
|
|
1256
|
+
});
|
|
1257
|
+
newBottomBlocks = [currBottomBlock];
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
newBottomBlocks = [currBottomBlock];
|
|
1262
|
+
}
|
|
1263
|
+
return newBottomBlocks;
|
|
1264
|
+
}
|
|
1265
|
+
isNewDefLocal(local, stmts, pos) {
|
|
1266
|
+
for (let i = pos - 1; i >= 0; i++) {
|
|
1267
|
+
const stmt = stmts[i];
|
|
1268
|
+
if (stmt instanceof Stmt_1.ArkAssignStmt && stmt.getLeftOp() === local) {
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
return true;
|
|
1273
|
+
}
|
|
1274
|
+
rebuildBlocksInLoop(blockBuilderToCfgBlock, blocksContainLoopCondition, cfg) {
|
|
1069
1275
|
for (const blockBuilder of blocksContainLoopCondition) {
|
|
1070
1276
|
if (!blockBuilderToCfgBlock.get(blockBuilder)) {
|
|
1071
1277
|
continue;
|
|
@@ -1074,38 +1280,11 @@ class CfgBuilder {
|
|
|
1074
1280
|
const blockId = block.getId();
|
|
1075
1281
|
const stmts = block.getStmts();
|
|
1076
1282
|
const stmtsCnt = stmts.length;
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
for (let i = 0; i < stmtsCnt; i++) {
|
|
1081
|
-
const stmt = stmts[i];
|
|
1082
|
-
if (stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Expr_1.AbstractInvokeExpr) {
|
|
1083
|
-
const invokeExpr = stmt.getRightOp();
|
|
1084
|
-
if (invokeExpr.getMethodSignature().getMethodSubSignature().getMethodName() == Builtin_1.Builtin.ITERATOR_NEXT) {
|
|
1085
|
-
iteratorNextStmtIdx = i;
|
|
1086
|
-
continue;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
if (stmt.toString() == ArkIRTransformer_1.DUMMY_INITIALIZER_STMT) {
|
|
1090
|
-
dummyInitializerStmtIdx = i;
|
|
1091
|
-
continue;
|
|
1092
|
-
}
|
|
1093
|
-
if (stmt instanceof Stmt_1.ArkIfStmt) {
|
|
1094
|
-
ifStmtIdx = i;
|
|
1095
|
-
break;
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
if (iteratorNextStmtIdx != -1 || dummyInitializerStmtIdx != -1) {
|
|
1099
|
-
// put statements into block before condition
|
|
1100
|
-
const lastStmtIdxBeforeCondition = iteratorNextStmtIdx != -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx;
|
|
1283
|
+
const { ifStmtIdx, iteratorNextStmtIdx, dummyInitializerStmtIdx } = this.findIteratorIdx(stmts);
|
|
1284
|
+
if (iteratorNextStmtIdx !== -1 || dummyInitializerStmtIdx !== -1) {
|
|
1285
|
+
const lastStmtIdxBeforeCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx;
|
|
1101
1286
|
const stmtsInsertBeforeCondition = stmts.slice(0, lastStmtIdxBeforeCondition);
|
|
1102
|
-
let prevBlockBuilderContainsLoop =
|
|
1103
|
-
for (const prevBlockBuilder of blockBuilder.lasts) {
|
|
1104
|
-
if (prevBlockBuilder.id < blockId && blocksContainLoopCondition.has(prevBlockBuilder)) {
|
|
1105
|
-
prevBlockBuilderContainsLoop = true;
|
|
1106
|
-
break;
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1287
|
+
let prevBlockBuilderContainsLoop = this.doesPrevBlockBuilderContainLoop(blockBuilder, blockId, blocksContainLoopCondition);
|
|
1109
1288
|
if (prevBlockBuilderContainsLoop) {
|
|
1110
1289
|
// should create an extra block when previous block contains loop condition
|
|
1111
1290
|
this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, blockBuilder, stmtsInsertBeforeCondition, false, cfg);
|
|
@@ -1115,27 +1294,11 @@ class CfgBuilder {
|
|
|
1115
1294
|
const blockBeforeCondition = blockBuilderToCfgBlock.get(blockBuilderBeforeCondition);
|
|
1116
1295
|
blockBeforeCondition === null || blockBeforeCondition === void 0 ? void 0 : blockBeforeCondition.getStmts().push(...stmtsInsertBeforeCondition);
|
|
1117
1296
|
}
|
|
1118
|
-
if (dummyInitializerStmtIdx
|
|
1297
|
+
if (dummyInitializerStmtIdx !== -1 && ifStmtIdx !== stmtsCnt - 1) {
|
|
1119
1298
|
// put incrementor statements into block which reenters condition
|
|
1120
|
-
|
|
1121
|
-
const blockBuildersReenterCondition = [];
|
|
1122
|
-
for (const prevBlockBuilder of blockBuilder.lasts) {
|
|
1123
|
-
const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder);
|
|
1124
|
-
if (prevBlock.getId() > blockId) {
|
|
1125
|
-
blockBuildersReenterCondition.push(prevBlockBuilder);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
if (blockBuildersReenterCondition.length > 1 || blocksContainLoopCondition.has(blockBuildersReenterCondition[0])) {
|
|
1129
|
-
// put incrementor statements into an extra block
|
|
1130
|
-
this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, blockBuilder, stmtsReenterCondition, true, cfg);
|
|
1131
|
-
}
|
|
1132
|
-
else {
|
|
1133
|
-
// put incrementor statements into prev reenter block
|
|
1134
|
-
const blockReenterCondition = blockBuilderToCfgBlock.get(blockBuildersReenterCondition[0]);
|
|
1135
|
-
blockReenterCondition === null || blockReenterCondition === void 0 ? void 0 : blockReenterCondition.getStmts().push(...stmtsReenterCondition);
|
|
1136
|
-
}
|
|
1299
|
+
this.adjustIncrementorStmts(stmts, ifStmtIdx, blockBuilder, blockId, blockBuilderToCfgBlock, blocksContainLoopCondition, cfg);
|
|
1137
1300
|
}
|
|
1138
|
-
else if (iteratorNextStmtIdx
|
|
1301
|
+
else if (iteratorNextStmtIdx !== -1) {
|
|
1139
1302
|
// put statements which get value of iterator into block after condition
|
|
1140
1303
|
const blockBuilderAfterCondition = blockBuilder.nexts[0];
|
|
1141
1304
|
const blockAfterCondition = blockBuilderToCfgBlock.get(blockBuilderAfterCondition);
|
|
@@ -1143,37 +1306,21 @@ class CfgBuilder {
|
|
|
1143
1306
|
blockAfterCondition === null || blockAfterCondition === void 0 ? void 0 : blockAfterCondition.getStmts().splice(0, 0, ...stmtsAfterCondition);
|
|
1144
1307
|
}
|
|
1145
1308
|
// remove statements which should not in condition
|
|
1146
|
-
const firstStmtIdxInCondition = iteratorNextStmtIdx
|
|
1309
|
+
const firstStmtIdxInCondition = iteratorNextStmtIdx !== -1 ? iteratorNextStmtIdx : dummyInitializerStmtIdx + 1;
|
|
1147
1310
|
stmts.splice(0, firstStmtIdxInCondition);
|
|
1148
1311
|
stmts.splice(ifStmtIdx - firstStmtIdxInCondition + 1);
|
|
1149
1312
|
}
|
|
1150
1313
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
for (const stmt of cfg.getStmts()) {
|
|
1159
|
-
stmt.setCfg(cfg);
|
|
1160
|
-
}
|
|
1161
|
-
const originalCfg = new Cfg_1.Cfg();
|
|
1162
|
-
const originalCfgBlock = new BasicBlock_1.BasicBlock();
|
|
1163
|
-
for (let i = 0; i < stmtsInOriginalCfg.length; i++) {
|
|
1164
|
-
if (i === 0) {
|
|
1165
|
-
originalCfg.setStartingStmt(stmtsInOriginalCfg[i]);
|
|
1314
|
+
}
|
|
1315
|
+
doesPrevBlockBuilderContainLoop(currBlockBuilder, currBlockId, blocksContainLoopCondition) {
|
|
1316
|
+
let prevBlockBuilderContainsLoop = false;
|
|
1317
|
+
for (const prevBlockBuilder of currBlockBuilder.lasts) {
|
|
1318
|
+
if (prevBlockBuilder.id < currBlockId && blocksContainLoopCondition.has(prevBlockBuilder)) {
|
|
1319
|
+
prevBlockBuilderContainsLoop = true;
|
|
1320
|
+
break;
|
|
1166
1321
|
}
|
|
1167
|
-
originalCfgBlock.addStmt(stmtsInOriginalCfg[i]);
|
|
1168
1322
|
}
|
|
1169
|
-
|
|
1170
|
-
return {
|
|
1171
|
-
cfg: cfg,
|
|
1172
|
-
originalCfg: originalCfg,
|
|
1173
|
-
stmtToOriginalStmt: stmtToOriginalStmt,
|
|
1174
|
-
locals: arkIRTransformer.getLocals(),
|
|
1175
|
-
aliasTypeMap: arkIRTransformer.getAliasTypeMap(),
|
|
1176
|
-
};
|
|
1323
|
+
return prevBlockBuilderContainsLoop;
|
|
1177
1324
|
}
|
|
1178
1325
|
insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, conditionBlockBuilder, stmtsInsertBeforeCondition, collectReenter, cfg) {
|
|
1179
1326
|
const blockId = conditionBlockBuilder.id;
|
|
@@ -1213,7 +1360,7 @@ class CfgBuilder {
|
|
|
1213
1360
|
for (const prevBlockBuilder of collectedBlockBuilders) {
|
|
1214
1361
|
const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder);
|
|
1215
1362
|
for (let j = 0; j < prevBlockBuilder.nexts.length; j++) {
|
|
1216
|
-
if (prevBlockBuilder.nexts[j]
|
|
1363
|
+
if (prevBlockBuilder.nexts[j] === conditionBlockBuilder) {
|
|
1217
1364
|
prevBlockBuilder.nexts[j] = blockBuilderInsertBeforeCondition;
|
|
1218
1365
|
prevBlock.setSuccessorBlock(j, blockInsertBeforeCondition);
|
|
1219
1366
|
break;
|
|
@@ -1237,5 +1384,54 @@ class CfgBuilder {
|
|
|
1237
1384
|
cfg.addBlock(blockInsertBeforeCondition);
|
|
1238
1385
|
blockBuilderToCfgBlock.set(blockBuilderInsertBeforeCondition, blockInsertBeforeCondition);
|
|
1239
1386
|
}
|
|
1387
|
+
findIteratorIdx(stmts) {
|
|
1388
|
+
let ifStmtIdx = -1;
|
|
1389
|
+
let iteratorNextStmtIdx = -1;
|
|
1390
|
+
let dummyInitializerStmtIdx = -1;
|
|
1391
|
+
const stmtsCnt = stmts.length;
|
|
1392
|
+
for (let i = 0; i < stmtsCnt; i++) {
|
|
1393
|
+
const stmt = stmts[i];
|
|
1394
|
+
if (stmt instanceof Stmt_1.ArkAssignStmt && stmt.getRightOp() instanceof Expr_1.AbstractInvokeExpr) {
|
|
1395
|
+
const invokeExpr = stmt.getRightOp();
|
|
1396
|
+
if (invokeExpr.getMethodSignature().getMethodSubSignature()
|
|
1397
|
+
.getMethodName() === Builtin_1.Builtin.ITERATOR_NEXT) {
|
|
1398
|
+
iteratorNextStmtIdx = i;
|
|
1399
|
+
continue;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
if (stmt.toString() === ArkIRTransformer_1.ArkIRTransformer.DUMMY_LOOP_INITIALIZER_STMT) {
|
|
1403
|
+
dummyInitializerStmtIdx = i;
|
|
1404
|
+
continue;
|
|
1405
|
+
}
|
|
1406
|
+
if (stmt instanceof Stmt_1.ArkIfStmt) {
|
|
1407
|
+
ifStmtIdx = i;
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
return {
|
|
1412
|
+
ifStmtIdx: ifStmtIdx,
|
|
1413
|
+
iteratorNextStmtIdx: iteratorNextStmtIdx,
|
|
1414
|
+
dummyInitializerStmtIdx: dummyInitializerStmtIdx,
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
adjustIncrementorStmts(stmts, ifStmtIdx, currBlockBuilder, currBlockId, blockBuilderToCfgBlock, blocksContainLoopCondition, cfg) {
|
|
1418
|
+
const stmtsReenterCondition = stmts.slice(ifStmtIdx + 1);
|
|
1419
|
+
const blockBuildersReenterCondition = [];
|
|
1420
|
+
for (const prevBlockBuilder of currBlockBuilder.lasts) {
|
|
1421
|
+
const prevBlock = blockBuilderToCfgBlock.get(prevBlockBuilder);
|
|
1422
|
+
if (prevBlock.getId() > currBlockId) {
|
|
1423
|
+
blockBuildersReenterCondition.push(prevBlockBuilder);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
if (blockBuildersReenterCondition.length > 1 || blocksContainLoopCondition.has(blockBuildersReenterCondition[0])) {
|
|
1427
|
+
// put incrementor statements into an extra block
|
|
1428
|
+
this.insertBeforeConditionBlockBuilder(blockBuilderToCfgBlock, currBlockBuilder, stmtsReenterCondition, true, cfg);
|
|
1429
|
+
}
|
|
1430
|
+
else {
|
|
1431
|
+
// put incrementor statements into prev reenter block
|
|
1432
|
+
const blockReenterCondition = blockBuilderToCfgBlock.get(blockBuildersReenterCondition[0]);
|
|
1433
|
+
blockReenterCondition === null || blockReenterCondition === void 0 ? void 0 : blockReenterCondition.getStmts().push(...stmtsReenterCondition);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1240
1436
|
}
|
|
1241
1437
|
exports.CfgBuilder = CfgBuilder;
|