arkanalyzer 1.0.39 → 1.0.41

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.
Files changed (103) hide show
  1. package/config/arkanalyzer.json +6 -2
  2. package/lib/Config.d.ts +1 -0
  3. package/lib/Config.d.ts.map +1 -1
  4. package/lib/Scene.d.ts +6 -5
  5. package/lib/Scene.d.ts.map +1 -1
  6. package/lib/Scene.js +36 -18
  7. package/lib/callgraph/algorithm/ClassHierarchyAnalysis.d.ts.map +1 -1
  8. package/lib/callgraph/algorithm/ClassHierarchyAnalysis.js +3 -4
  9. package/lib/callgraph/algorithm/RapidTypeAnalysis.d.ts.map +1 -1
  10. package/lib/callgraph/algorithm/RapidTypeAnalysis.js +7 -8
  11. package/lib/callgraph/model/CallGraph.d.ts +5 -5
  12. package/lib/callgraph/model/CallGraph.d.ts.map +1 -1
  13. package/lib/callgraph/model/CallGraph.js +18 -21
  14. package/lib/callgraph/model/CallSite.d.ts +16 -6
  15. package/lib/callgraph/model/CallSite.d.ts.map +1 -1
  16. package/lib/callgraph/model/CallSite.js +48 -8
  17. package/lib/callgraph/model/builder/CallGraphBuilder.d.ts +0 -1
  18. package/lib/callgraph/model/builder/CallGraphBuilder.d.ts.map +1 -1
  19. package/lib/callgraph/model/builder/CallGraphBuilder.js +0 -8
  20. package/lib/callgraph/pointerAnalysis/Pag.d.ts +3 -6
  21. package/lib/callgraph/pointerAnalysis/Pag.d.ts.map +1 -1
  22. package/lib/callgraph/pointerAnalysis/Pag.js +6 -29
  23. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts +6 -15
  24. package/lib/callgraph/pointerAnalysis/PagBuilder.d.ts.map +1 -1
  25. package/lib/callgraph/pointerAnalysis/PagBuilder.js +61 -85
  26. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts +2 -1
  27. package/lib/callgraph/pointerAnalysis/PointerAnalysis.d.ts.map +1 -1
  28. package/lib/callgraph/pointerAnalysis/PointerAnalysis.js +12 -8
  29. package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts +10 -3
  30. package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.d.ts.map +1 -1
  31. package/lib/callgraph/pointerAnalysis/PointerAnalysisConfig.js +20 -5
  32. package/lib/callgraph/pointerAnalysis/context/Context.d.ts +69 -0
  33. package/lib/callgraph/pointerAnalysis/context/Context.d.ts.map +1 -0
  34. package/lib/callgraph/pointerAnalysis/context/Context.js +202 -0
  35. package/lib/callgraph/pointerAnalysis/context/ContextItem.d.ts +40 -0
  36. package/lib/callgraph/pointerAnalysis/context/ContextItem.d.ts.map +1 -0
  37. package/lib/callgraph/pointerAnalysis/context/ContextItem.js +99 -0
  38. package/lib/callgraph/pointerAnalysis/context/ContextSelector.d.ts +46 -0
  39. package/lib/callgraph/pointerAnalysis/context/ContextSelector.d.ts.map +1 -0
  40. package/lib/callgraph/pointerAnalysis/context/ContextSelector.js +138 -0
  41. package/lib/core/base/Expr.d.ts.map +1 -1
  42. package/lib/core/base/Expr.js +11 -1
  43. package/lib/core/base/Local.js +1 -1
  44. package/lib/core/common/ArkIRTransformer.d.ts +2 -0
  45. package/lib/core/common/ArkIRTransformer.d.ts.map +1 -1
  46. package/lib/core/common/ArkIRTransformer.js +90 -0
  47. package/lib/core/common/ArkValueTransformer.d.ts +1 -1
  48. package/lib/core/common/ArkValueTransformer.d.ts.map +1 -1
  49. package/lib/core/common/ArkValueTransformer.js +48 -33
  50. package/lib/core/common/Builtin.d.ts.map +1 -1
  51. package/lib/core/common/Builtin.js +2 -2
  52. package/lib/core/common/DummyMainCreater.js +1 -1
  53. package/lib/core/common/IRInference.d.ts +1 -0
  54. package/lib/core/common/IRInference.d.ts.map +1 -1
  55. package/lib/core/common/IRInference.js +60 -44
  56. package/lib/core/common/ModelUtils.d.ts +1 -0
  57. package/lib/core/common/ModelUtils.d.ts.map +1 -1
  58. package/lib/core/common/ModelUtils.js +7 -0
  59. package/lib/core/common/SdkUtils.d.ts +14 -1
  60. package/lib/core/common/SdkUtils.d.ts.map +1 -1
  61. package/lib/core/common/SdkUtils.js +118 -24
  62. package/lib/core/common/TypeInference.d.ts +2 -1
  63. package/lib/core/common/TypeInference.d.ts.map +1 -1
  64. package/lib/core/common/TypeInference.js +21 -12
  65. package/lib/core/common/ValueUtil.d.ts +1 -0
  66. package/lib/core/common/ValueUtil.d.ts.map +1 -1
  67. package/lib/core/common/ValueUtil.js +7 -0
  68. package/lib/core/graph/BaseExplicitGraph.d.ts +1 -0
  69. package/lib/core/graph/BaseExplicitGraph.d.ts.map +1 -1
  70. package/lib/core/graph/BaseExplicitGraph.js +3 -0
  71. package/lib/core/graph/Scc.js +1 -1
  72. package/lib/core/graph/builder/CfgBuilder.d.ts +2 -0
  73. package/lib/core/graph/builder/CfgBuilder.d.ts.map +1 -1
  74. package/lib/core/graph/builder/CfgBuilder.js +59 -7
  75. package/lib/core/model/ArkImport.js +1 -1
  76. package/lib/core/model/ArkMethod.d.ts.map +1 -1
  77. package/lib/core/model/ArkMethod.js +8 -2
  78. package/lib/core/model/builder/ArkClassBuilder.js +21 -1
  79. package/lib/core/model/builder/ArkMethodBuilder.d.ts.map +1 -1
  80. package/lib/core/model/builder/ArkMethodBuilder.js +2 -2
  81. package/lib/core/model/builder/builderUtils.d.ts.map +1 -1
  82. package/lib/core/model/builder/builderUtils.js +2 -1
  83. package/lib/index.d.ts +0 -1
  84. package/lib/index.d.ts.map +1 -1
  85. package/lib/index.js +2 -4
  86. package/lib/save/JsonPrinter.d.ts +1 -0
  87. package/lib/save/JsonPrinter.d.ts.map +1 -1
  88. package/lib/save/JsonPrinter.js +15 -5
  89. package/lib/save/arkir/ArkIRMethodPrinter.d.ts.map +1 -1
  90. package/lib/save/arkir/ArkIRMethodPrinter.js +13 -5
  91. package/lib/save/source/SourceBody.d.ts +1 -1
  92. package/lib/save/source/SourceBody.d.ts.map +1 -1
  93. package/lib/save/source/SourceBody.js +3 -2
  94. package/lib/save/source/SourceStmt.d.ts.map +1 -1
  95. package/lib/save/source/SourceStmt.js +12 -4
  96. package/lib/save/source/SourceTransformer.d.ts +3 -3
  97. package/lib/save/source/SourceTransformer.d.ts.map +1 -1
  98. package/lib/save/source/SourceTransformer.js +11 -10
  99. package/lib/transformer/StaticSingleAssignmentFormer.js +1 -1
  100. package/package.json +7 -7
  101. package/lib/callgraph/pointerAnalysis/Context.d.ts +0 -38
  102. package/lib/callgraph/pointerAnalysis/Context.d.ts.map +0 -1
  103. package/lib/callgraph/pointerAnalysis/Context.js +0 -154
@@ -47,11 +47,12 @@ const Local_1 = require("../../core/base/Local");
47
47
  const Type_1 = require("../../core/base/Type");
48
48
  const Constant_1 = require("../../core/base/Constant");
49
49
  const Statistics_1 = require("../common/Statistics");
50
- const Context_1 = require("./Context");
51
50
  const Pag_1 = require("./Pag");
52
51
  const TSConst_1 = require("../../core/common/TSConst");
53
52
  const PTAUtils_1 = require("./PTAUtils");
54
53
  const PointerAnalysisConfig_1 = require("./PointerAnalysisConfig");
54
+ const Context_1 = require("./context/Context");
55
+ const ContextSelector_1 = require("./context/ContextSelector");
55
56
  const logger = logger_1.default.getLogger(logger_1.LOG_MODULE_TYPE.ARKANALYZER, 'PTA');
56
57
  class CSFuncID {
57
58
  constructor(cid, fid) {
@@ -61,15 +62,12 @@ class CSFuncID {
61
62
  }
62
63
  exports.CSFuncID = CSFuncID;
63
64
  class PagBuilder {
64
- constructor(p, cg, s, kLimit, scale) {
65
+ constructor(p, cg, s, config) {
65
66
  this.handledFunc = new Set();
66
67
  this.worklist = [];
67
68
  // TODO: change string to hash value
68
69
  this.staticField2UniqInstanceMap = new Map();
69
70
  this.instanceField2UniqInstanceMap = new Map();
70
- this.cid2ThisRefPtMap = new Map();
71
- this.cid2ThisRefMap = new Map();
72
- this.cid2ThisLocalMap = new Map();
73
71
  this.sdkMethodReturnValueMap = new Map();
74
72
  // record the SDK API param, and create fake Values
75
73
  this.methodParamValueMap = new Map();
@@ -83,11 +81,25 @@ class PagBuilder {
83
81
  this.retriggerNodesList = new Set();
84
82
  this.pag = p;
85
83
  this.cg = cg;
86
- this.scale = scale;
84
+ this.scale = config.analysisScale;
87
85
  this.funcPags = new Map();
88
- this.ctx = new Context_1.KLimitedContextSensitive(kLimit);
89
86
  this.scene = s;
90
87
  this.pagStat = new Statistics_1.PAGStat();
88
+ let kLimit = config.kLimit;
89
+ switch (config.contextType) {
90
+ case PointerAnalysisConfig_1.ContextType.CallSite:
91
+ this.ctxSelector = new ContextSelector_1.KCallSiteContextSelector(kLimit);
92
+ break;
93
+ case PointerAnalysisConfig_1.ContextType.Obj:
94
+ this.ctxSelector = new ContextSelector_1.KObjContextSelector(kLimit);
95
+ break;
96
+ case PointerAnalysisConfig_1.ContextType.Func:
97
+ this.ctxSelector = new ContextSelector_1.KFuncContextSelector(kLimit);
98
+ break;
99
+ default:
100
+ this.ctxSelector = new ContextSelector_1.KCallSiteContextSelector(kLimit);
101
+ break;
102
+ }
91
103
  }
92
104
  buildFuncPagAndAddToWorklist(cs) {
93
105
  if (this.worklist.includes(cs)) {
@@ -109,12 +121,12 @@ class PagBuilder {
109
121
  buildForEntries(funcIDs) {
110
122
  this.worklist = [];
111
123
  funcIDs.forEach(funcID => {
112
- let cid = this.ctx.getNewContextID(funcID);
124
+ let cid = this.ctxSelector.emptyContext(funcID);
113
125
  let csFuncID = new CSFuncID(cid, funcID);
114
126
  this.buildFuncPagAndAddToWorklist(csFuncID);
115
127
  });
116
128
  this.handleReachable();
117
- this.globalThisPagNode = this.getOrNewGlobalThisNode(-1);
129
+ this.globalThisPagNode = this.getOrNewGlobalThisNode(ContextSelector_1.emptyID);
118
130
  this.pag.addPagEdge(this.globalThisPagNode, this.globalThisPagNode, Pag_1.PagEdgeKind.Copy);
119
131
  }
120
132
  handleReachable() {
@@ -131,7 +143,7 @@ class PagBuilder {
131
143
  }
132
144
  build() {
133
145
  for (let funcID of this.cg.getEntries()) {
134
- let cid = this.ctx.getNewContextID(funcID);
146
+ let cid = this.ctxSelector.emptyContext(funcID);
135
147
  let csFuncID = new CSFuncID(cid, funcID);
136
148
  this.buildFuncPagAndAddToWorklist(csFuncID);
137
149
  this.handleReachable();
@@ -193,12 +205,12 @@ class PagBuilder {
193
205
  });
194
206
  return;
195
207
  }
196
- let dycs = this.cg.getDynCallsiteByStmt(stmt);
208
+ let dycs = this.cg.getDynCallSiteByStmt(stmt);
197
209
  if (dycs) {
198
210
  this.addToDynamicCallSite(fpag, dycs);
199
211
  }
200
212
  else {
201
- logger.error(`can not find callsite by stmt: ${stmt.toString()}`);
213
+ logger.error(`can not find callSite by stmt: ${stmt.toString()}`);
202
214
  }
203
215
  }
204
216
  processExternalScopeValue(value, funcID) {
@@ -322,9 +334,10 @@ class PagBuilder {
322
334
  }
323
335
  /// add Copy edges interprocedural
324
336
  addCallsEdgesFromFuncPag(funcPag, cid) {
337
+ var _a, _b;
325
338
  for (let cs of funcPag.getNormalCallSites()) {
326
339
  let ivkExpr = cs.callStmt.getInvokeExpr();
327
- let calleeCid = this.ctx.getOrNewContext(cid, cs.calleeFuncID, true);
340
+ let calleeCid = this.ctxSelector.selectContext(cid, cs, ContextSelector_1.emptyID, cs.calleeFuncID);
328
341
  let calleeCGNode = this.cg.getNode(cs.calleeFuncID);
329
342
  if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
330
343
  this.addStaticPagCallReturnEdge(cs, cid, calleeCid);
@@ -338,19 +351,18 @@ class PagBuilder {
338
351
  if (calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.constructor || calleeCGNode.getKind() === CallGraph_1.CallGraphNodeKind.intrinsic) {
339
352
  let callee = this.scene.getMethod(this.cg.getMethodByFuncID(cs.calleeFuncID));
340
353
  if (ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
341
- let baseNode = this.getOrNewPagNode(cid, ivkExpr.getBase());
342
- let baseNodeID = baseNode.getID();
343
- this.addThisRefCallEdge(baseNodeID, cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID);
354
+ this.addThisRefCallEdge(cid, ivkExpr.getBase(), callee, calleeCid, cs.callerFuncID);
344
355
  }
345
356
  else {
346
357
  logger.error(`constructor or intrinsic func is static ${ivkExpr.toString()}`);
347
358
  }
348
359
  }
360
+ this.cg.addDirectOrSpecialCallEdge((_a = this.cg.getArkMethodByFuncID(cs.callerFuncID)) === null || _a === void 0 ? void 0 : _a.getSignature(), (_b = this.cg.getArkMethodByFuncID(cs.calleeFuncID)) === null || _b === void 0 ? void 0 : _b.getSignature(), cs.callStmt);
349
361
  }
350
362
  return true;
351
363
  }
352
364
  addDynamicCallSite(funcPag, funcID, cid) {
353
- // add dyn callsite in funcpag to base node
365
+ // add dyn callSite in funcpag to base node
354
366
  for (let cs of funcPag.getDynamicCallSites()) {
355
367
  let invokeExpr = cs.callStmt.getInvokeExpr();
356
368
  let base;
@@ -443,8 +455,8 @@ class PagBuilder {
443
455
  if (this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
444
456
  return srcNodes;
445
457
  }
446
- let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
447
- let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
458
+ let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
459
+ let calleeCid = this.ctxSelector.selectContext(cid, staticCS, baseClassPTNode, dstCGNode.getID());
448
460
  if (this.scale === PointerAnalysisConfig_1.PtaAnalysisScale.MethodLevel) {
449
461
  srcNodes.push(...this.addStaticPagCallReturnEdge(staticCS, baseClassPTNode, calleeCid));
450
462
  continue;
@@ -522,7 +534,7 @@ class PagBuilder {
522
534
  srcNodes.push(...this.addStaticPagCallEdge(staticCS, cid, calleeCid, ptNode));
523
535
  // Pass base's pts to callee's this pointer
524
536
  if (!dstCGNode.isSdkMethod() && ivkExpr instanceof Expr_1.ArkInstanceInvokeExpr) {
525
- let srcBaseNode = this.addThisRefCallEdge(baseClassPTNode, cid, ivkExpr.getBase(), callee, calleeCid, staticCS.callerFuncID);
537
+ let srcBaseNode = this.addThisRefCallEdge(cid, ivkExpr.getBase(), callee, calleeCid, staticCS.callerFuncID);
526
538
  if (srcBaseNode !== -1) {
527
539
  srcNodes.push(srcBaseNode);
528
540
  }
@@ -536,7 +548,7 @@ class PagBuilder {
536
548
  if (!(thisValue instanceof Local_1.Local)) {
537
549
  return srcNodes;
538
550
  }
539
- this.addThisRefCallEdge(baseClassPTNode, ptNode.getOriginCid(), thisValue, callee, calleeCid, staticCS.callerFuncID);
551
+ this.addThisRefCallEdge(ptNode.getOriginCid(), thisValue, callee, calleeCid, staticCS.callerFuncID);
540
552
  }
541
553
  return srcNodes;
542
554
  }
@@ -576,7 +588,7 @@ class PagBuilder {
576
588
  break;
577
589
  case PTAUtils_1.BuiltApiType.FunctionBind:
578
590
  /**
579
- * clone the function node and add the this pointer, origin callsite, args offset to it
591
+ * clone the function node and add the this pointer, origin callSite, args offset to it
580
592
  * let f = function.bind(thisArg, arg1, arg2, ...)
581
593
  * f();
582
594
  */
@@ -616,7 +628,7 @@ class PagBuilder {
616
628
  handleFunctionCall(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
617
629
  this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
618
630
  srcNodes.push(...this.addCallParamPagEdge(realCallee, staticCS.args, staticCS.callStmt, cid, calleeCid, 1));
619
- this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid);
631
+ this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
620
632
  }
621
633
  handleFunctionApply(staticCS, cid, calleeCid, realCallee, srcNodes, baseClassPTNode) {
622
634
  this.buildFuncPagAndAddToWorklist(new CSFuncID(calleeCid, staticCS.calleeFuncID));
@@ -626,7 +638,7 @@ class PagBuilder {
626
638
  }
627
639
  let argsRealValues = this.transferArrayValues(callerMethod, staticCS.args[1]);
628
640
  srcNodes.push(...this.addCallParamPagEdge(realCallee, argsRealValues, staticCS.callStmt, cid, calleeCid, 0));
629
- this.addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid);
641
+ this.addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid);
630
642
  }
631
643
  handleFunctionBind(staticCS, cid, baseClassPTNode, srcNodes) {
632
644
  let srcNode = this.pag.getOrClonePagFuncNode(baseClassPTNode);
@@ -641,9 +653,9 @@ class PagBuilder {
641
653
  srcNode.setArgsOffset(1);
642
654
  srcNode.setOriginCid(cid);
643
655
  }
644
- addThisEdge(staticCS, cid, realCallee, srcNodes, baseClassPTNode, calleeCid) {
656
+ addThisEdge(staticCS, cid, realCallee, srcNodes, calleeCid) {
645
657
  if (!(staticCS.args[0] instanceof Constant_1.NullConstant) && !realCallee.isStatic()) {
646
- let srcNodeID = this.addThisRefCallEdge(baseClassPTNode, cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID);
658
+ let srcNodeID = this.addThisRefCallEdge(cid, staticCS.args[0], realCallee, calleeCid, staticCS.callerFuncID);
647
659
  if (srcNodeID !== -1) {
648
660
  srcNodes.push(srcNodeID);
649
661
  }
@@ -701,8 +713,8 @@ class PagBuilder {
701
713
  logger.warn(`\tAdd call edge of unknown call ${callee.getSignature().toString()}`);
702
714
  this.cg.addDynamicCallEdge(callerNode.getID(), dstCGNode.getID(), cs.callStmt);
703
715
  if (!this.cg.detectReachable(dstCGNode.getID(), callerNode.getID())) {
704
- let calleeCid = this.ctx.getOrNewContext(cid, dstCGNode.getID(), true);
705
- let staticCS = new CallGraph_1.CallSite(cs.callStmt, cs.args, dstCGNode.getID(), cs.callerFuncID);
716
+ let staticCS = this.cg.getCallSiteManager().cloneCallSiteFromDyn(cs, dstCGNode.getID());
717
+ let calleeCid = this.ctxSelector.selectContext(cid, staticCS, ContextSelector_1.emptyID, staticCS.calleeFuncID);
706
718
  let staticSrcNodes = this.addStaticPagCallEdge(staticCS, cid, calleeCid);
707
719
  srcNodes.push(...staticSrcNodes);
708
720
  }
@@ -740,8 +752,8 @@ class PagBuilder {
740
752
  }
741
753
  return reAnalyzeNodes;
742
754
  }
743
- addThisRefCallEdge(baseClassPTNode, cid, baseLocal, callee, calleeCid, callerFunID) {
744
- let thisRefNodeID = this.recordThisRefNode(baseClassPTNode, callee, calleeCid);
755
+ addThisRefCallEdge(cid, baseLocal, callee, calleeCid, callerFunID) {
756
+ let thisRefNodeID = this.recordThisRefNode(callee, calleeCid);
745
757
  if (thisRefNodeID === -1) {
746
758
  return -1;
747
759
  }
@@ -763,7 +775,7 @@ class PagBuilder {
763
775
  this.pag.addPagEdge(this.pag.getNode(srcNodeId), thisRefNode, Pag_1.PagEdgeKind.This);
764
776
  return srcNodeId;
765
777
  }
766
- recordThisRefNode(baseClassPTNode, callee, calleeCid) {
778
+ recordThisRefNode(callee, calleeCid) {
767
779
  var _a;
768
780
  if (!callee || !callee.getCfg()) {
769
781
  logger.error(`callee is null`);
@@ -771,25 +783,22 @@ class PagBuilder {
771
783
  }
772
784
  let thisAssignStmt = (_a = callee
773
785
  .getCfg()) === null || _a === void 0 ? void 0 : _a.getStmts().filter(s => s instanceof Stmt_1.ArkAssignStmt && s.getRightOp() instanceof Ref_1.ArkThisRef);
774
- let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt.at(0)).getRightOp();
786
+ let thisPtr = (thisAssignStmt === null || thisAssignStmt === void 0 ? void 0 : thisAssignStmt[0]).getRightOp();
775
787
  if (!thisPtr) {
776
788
  throw new Error('Can not get this ptr');
777
789
  }
778
- // IMPORTANT: set cid 2 base Pt info firstly
779
- this.cid2ThisRefPtMap.set(calleeCid, baseClassPTNode);
780
- let thisRefNode = this.getOrNewThisRefNode(calleeCid, thisPtr);
781
- thisRefNode.addPTNode(baseClassPTNode);
790
+ let thisRefNode = this.getOrNewPagNode(calleeCid, thisPtr);
782
791
  return thisRefNode.getID();
783
792
  }
784
793
  /*
785
794
  * Add copy edges from arguments to parameters
786
- * ret edges from return values to callsite
795
+ * ret edges from return values to callSite
787
796
  * Return src node
788
797
  */
789
798
  addStaticPagCallEdge(cs, callerCid, calleeCid, ptNode) {
790
799
  var _a, _b, _c, _d;
791
800
  if (!calleeCid) {
792
- calleeCid = this.ctx.getOrNewContext(callerCid, cs.calleeFuncID, true);
801
+ calleeCid = this.ctxSelector.selectContext(callerCid, cs, ptNode ? ptNode.getID() : ContextSelector_1.emptyID, cs.calleeFuncID);
793
802
  }
794
803
  let srcNodes = [];
795
804
  // Add reachable
@@ -845,8 +854,8 @@ class PagBuilder {
845
854
  }
846
855
  // add args to parameters edges
847
856
  for (let i = offset; i <= args.length; i++) {
848
- let arg = args.at(i);
849
- let param = params.at(i - offset);
857
+ let arg = args[i];
858
+ let param = params[i - offset];
850
859
  if (!arg || !param) {
851
860
  return srcNodes;
852
861
  }
@@ -872,7 +881,7 @@ class PagBuilder {
872
881
  // container value is the base value of callstmt, its points-to is PagNewContainerExprNode
873
882
  let srcNodes = [];
874
883
  let containerValue = callStmt.getInvokeExpr().getBase();
875
- let param = params.at(0);
884
+ let param = params[0];
876
885
  if (!containerValue || !param) {
877
886
  return srcNodes;
878
887
  }
@@ -924,7 +933,7 @@ class PagBuilder {
924
933
  }
925
934
  addStaticPagCallReturnEdge(cs, callerCid, calleeCid) {
926
935
  if (!calleeCid) {
927
- calleeCid = this.ctx.getOrNewContext(callerCid, cs.calleeFuncID, true);
936
+ calleeCid = this.ctxSelector.selectContext(callerCid, cs, ContextSelector_1.emptyID, cs.calleeFuncID);
928
937
  }
929
938
  let srcNodes = [];
930
939
  // Add reachable
@@ -990,7 +999,7 @@ class PagBuilder {
990
999
  }
991
1000
  // add args to parameters edges
992
1001
  for (let i = 0; i < argNum; i++) {
993
- let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b.at(i);
1002
+ let arg = (_b = cs.args) === null || _b === void 0 ? void 0 : _b[i];
994
1003
  let paramValue;
995
1004
  if (arg instanceof Local_1.Local && arg.getType() instanceof Type_1.FunctionType) {
996
1005
  // TODO: cannot find value
@@ -1019,7 +1028,7 @@ class PagBuilder {
1019
1028
  dstPagNode.setSdkParam();
1020
1029
  let sdkParamInvokeStmt = new Stmt_1.ArkInvokeStmt(new Expr_1.ArkPtrInvokeExpr(arg.getType().getMethodSignature(), paramValue, []));
1021
1030
  // create new DynCallSite
1022
- let sdkParamCallSite = new CallGraph_1.DynCallSite(sdkParamInvokeStmt, undefined, undefined, funcID);
1031
+ let sdkParamCallSite = this.cg.getCallSiteManager().newDynCallSite(sdkParamInvokeStmt, undefined, undefined, funcID);
1023
1032
  dstPagNode.addRelatedDynCallSite(sdkParamCallSite);
1024
1033
  }
1025
1034
  this.pag.addPagEdge(srcPagNode, dstPagNode, Pag_1.PagEdgeKind.Copy, cs.callStmt);
@@ -1028,55 +1037,19 @@ class PagBuilder {
1028
1037
  return srcNodes;
1029
1038
  }
1030
1039
  getOrNewPagNode(cid, v, s) {
1031
- if (v instanceof Ref_1.ArkThisRef) {
1032
- return this.getOrNewThisRefNode(cid, v);
1033
- }
1034
- // this local is also not uniq!!!
1035
- // remove below block once this issue fixed
1036
1040
  // globalThis process can not be removed while all `globalThis` ref is the same Value
1037
- if (v instanceof Local_1.Local) {
1038
- if (v.getName() === 'this') {
1039
- return this.getOrNewThisLoalNode(cid, v, s);
1040
- }
1041
- else if (v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
1042
- // globalThis node has no cid
1043
- return this.getOrNewGlobalThisNode(-1);
1044
- }
1041
+ if (v instanceof Local_1.Local && v.getName() === TSConst_1.GLOBAL_THIS_NAME && v.getDeclaringStmt() == null) {
1042
+ // globalThis node has no cid
1043
+ return this.getOrNewGlobalThisNode(-1);
1045
1044
  }
1046
1045
  if (v instanceof Ref_1.ArkInstanceFieldRef || v instanceof Ref_1.ArkStaticFieldRef) {
1047
1046
  v = this.getRealInstanceRef(v);
1048
1047
  }
1049
1048
  return this.pag.getOrNewNode(cid, v, s);
1050
1049
  }
1051
- /**
1052
- * return ThisRef PAG node according to cid, a cid has a unique ThisRef node
1053
- * @param cid: current contextID
1054
- */
1055
- getOrNewThisRefNode(cid, v) {
1056
- let thisRefNodeID = this.cid2ThisRefMap.get(cid);
1057
- if (!thisRefNodeID) {
1058
- thisRefNodeID = -1;
1059
- }
1060
- let thisRefNode = this.pag.getOrNewThisRefNode(thisRefNodeID, v);
1061
- this.cid2ThisRefMap.set(cid, thisRefNode.getID());
1062
- return thisRefNode;
1063
- }
1064
- // TODO: remove it once this local not uniq issue is fixed
1065
- getOrNewThisLoalNode(cid, v, s) {
1066
- let thisLocalNodeID = this.cid2ThisLocalMap.get(cid);
1067
- if (thisLocalNodeID) {
1068
- return this.pag.getNode(thisLocalNodeID);
1069
- }
1070
- let thisNode = this.pag.getOrNewNode(cid, v, s);
1071
- this.cid2ThisLocalMap.set(cid, thisNode.getID());
1072
- return thisNode;
1073
- }
1074
1050
  getOrNewGlobalThisNode(cid) {
1075
1051
  return this.pag.getOrNewNode(cid, this.getGlobalThisValue());
1076
1052
  }
1077
- getUniqThisLocalNode(cid) {
1078
- return this.cid2ThisLocalMap.get(cid);
1079
- }
1080
1053
  /**
1081
1054
  * search the storage map to get propertyNode with given storage and propertyFieldName
1082
1055
  * @param storage storage type: AppStorage, LocalStorage etc.
@@ -1475,7 +1448,7 @@ class PagBuilder {
1475
1448
  var _a;
1476
1449
  funcPag.addDynamicCallSite(cs);
1477
1450
  this.pagStat.numDynamicCall++;
1478
- logger.trace('[add dynamic callsite] ' + cs.callStmt.toString() + ': ' + ((_a = cs.callStmt.getCfg()) === null || _a === void 0 ? void 0 : _a.getDeclaringMethod().getSignature().toString()));
1451
+ logger.trace('[add dynamic callSite] ' + cs.callStmt.toString() + ': ' + ((_a = cs.callStmt.getCfg()) === null || _a === void 0 ? void 0 : _a.getDeclaringMethod().getSignature().toString()));
1479
1452
  }
1480
1453
  setPtForNode(node, pts) {
1481
1454
  if (!pts) {
@@ -1571,7 +1544,7 @@ class PagBuilder {
1571
1544
  let srcFunc = (_c = src.getDeclaringStmt()) === null || _c === void 0 ? void 0 : _c.getCfg().getDeclaringMethod();
1572
1545
  if (srcFunc) {
1573
1546
  let srcFuncID = this.cg.getCallGraphNodeByMethod(srcFunc.getSignature()).getID();
1574
- let cid = this.ctx.getNewContextID(srcFuncID);
1547
+ let cid = this.ctxSelector.emptyContext(funcID);
1575
1548
  let csFuncID = new CSFuncID(cid, srcFuncID);
1576
1549
  this.buildFuncPagAndAddToWorklist(csFuncID);
1577
1550
  }
@@ -1696,5 +1669,8 @@ class PagBuilder {
1696
1669
  });
1697
1670
  return usedValuesInArray;
1698
1671
  }
1672
+ getContextSelector() {
1673
+ return this.ctxSelector;
1674
+ }
1699
1675
  }
1700
1676
  exports.PagBuilder = PagBuilder;
@@ -25,6 +25,7 @@ export declare class PointerAnalysis extends AbstractAnalysis {
25
25
  start(): void;
26
26
  private postProcess;
27
27
  getPTD(): DiffPTData<NodeID, NodeID, IPtsCollection<NodeID>>;
28
+ getPag(): Pag;
28
29
  getStat(): string;
29
30
  protected preProcessMethod(funcID: FuncID): CallSite[];
30
31
  setEntries(fIds: FuncID[]): void;
@@ -47,7 +48,7 @@ export declare class PointerAnalysis extends AbstractAnalysis {
47
48
  private propagate;
48
49
  /**
49
50
  * 1. 记录被更新的节点(记录cid, nodeid)
50
- * 2. ( PAGLocalNode记录callsite(cid, value唯一)),通过1种的nodeID查询Node,拿到Callsite
51
+ * 2. ( PAGLocalNode记录callSite(cid, value唯一)),通过1种的nodeID查询Node,拿到CallSite
51
52
  * 3. 在addDynamicCall里对传入指针过滤(已处理指针和未处理指针)
52
53
  */
53
54
  private onTheFlyDynamicCallSolve;
@@ -1 +1 @@
1
- {"version":3,"file":"PointerAnalysis.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PointerAnalysis.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysis.ts"],"names":[],"mappings":"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"}
@@ -61,7 +61,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
61
61
  super(s, cg);
62
62
  this.pag = p;
63
63
  this.ptd = new PtsDS_1.DiffPTData(config.ptsCollectionCtor);
64
- this.pagBuilder = new PagBuilder_1.PagBuilder(this.pag, this.cg, s, config.kLimit, config.analysisScale);
64
+ this.pagBuilder = new PagBuilder_1.PagBuilder(this.pag, this.cg, s, config);
65
65
  this.cgBuilder = new CallGraphBuilder_1.CallGraphBuilder(this.cg, s);
66
66
  this.ptaStat = new Statistics_1.PTAStat(this);
67
67
  this.config = config;
@@ -125,13 +125,17 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
125
125
  this.pag.dump(path_1.default.join(this.config.outputDirectory, 'ptaEnd_pag.dot'));
126
126
  this.cg.dump(path_1.default.join(this.config.outputDirectory, 'cgEnd.dot'));
127
127
  }
128
- if (this.config.unhandledFuncDump) {
128
+ if (this.config.debug) {
129
129
  this.dumpUnhandledFunctions();
130
+ this.pagBuilder.getContextSelector().dump(this.config.outputDirectory, this.cg);
130
131
  }
131
132
  }
132
133
  getPTD() {
133
134
  return this.ptd;
134
135
  }
136
+ getPag() {
137
+ return this.pag;
138
+ }
135
139
  getStat() {
136
140
  let ret = this.cg.getStat();
137
141
  ret += '\n' + this.pagBuilder.getStat();
@@ -348,7 +352,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
348
352
  }
349
353
  /**
350
354
  * 1. 记录被更新的节点(记录cid, nodeid)
351
- * 2. ( PAGLocalNode记录callsite(cid, value唯一)),通过1种的nodeID查询Node,拿到Callsite
355
+ * 2. ( PAGLocalNode记录callSite(cid, value唯一)),通过1种的nodeID查询Node,拿到CallSite
352
356
  * 3. 在addDynamicCall里对传入指针过滤(已处理指针和未处理指针)
353
357
  */
354
358
  onTheFlyDynamicCallSolve() {
@@ -377,13 +381,13 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
377
381
  logger.warn(`node ${node.getID()} has no related dynamic call site`);
378
382
  return changed;
379
383
  }
380
- logger.info(`[process dynamic callsite] node ${node.getID()}`);
381
- dynCallSites.forEach(dynCallsite => {
384
+ logger.info(`[process dynamic callSite] node ${node.getID()}`);
385
+ dynCallSites.forEach(dynCallSite => {
382
386
  for (let pt of pts) {
383
- let srcNodes = this.pagBuilder.addDynamicCallEdge(dynCallsite, pt, node.getCid());
387
+ let srcNodes = this.pagBuilder.addDynamicCallEdge(dynCallSite, pt, node.getCid());
384
388
  changed = this.addToReanalyze(srcNodes) || changed;
385
389
  }
386
- processedCallSites.add(dynCallsite);
390
+ processedCallSites.add(dynCallSite);
387
391
  });
388
392
  return changed;
389
393
  }
@@ -394,7 +398,7 @@ class PointerAnalysis extends AbstractAnalysis_1.AbstractAnalysis {
394
398
  logger.warn(`node ${node.getID()} has no related unknown call site`);
395
399
  return changed;
396
400
  }
397
- logger.info(`[process unknown callsite] node ${node.getID()}`);
401
+ logger.info(`[process unknown callSite] node ${node.getID()}`);
398
402
  unknownCallSites.forEach(unknownCallSite => {
399
403
  for (let pt of pts) {
400
404
  let srcNodes = this.pagBuilder.addDynamicCallEdge(unknownCallSite, pt, node.getCid());
@@ -4,18 +4,25 @@ export declare enum PtaAnalysisScale {
4
4
  WholeProgram = 0,
5
5
  MethodLevel = 1
6
6
  }
7
+ export declare enum ContextType {
8
+ CallSite = 0,
9
+ Obj = 1,
10
+ Func = 2
11
+ }
7
12
  export declare class PointerAnalysisConfig {
8
13
  private static instance;
9
14
  kLimit: number;
15
+ contextType: ContextType;
10
16
  outputDirectory: string;
11
17
  detectTypeDiff: boolean;
12
18
  dotDump: boolean;
13
- unhandledFuncDump: boolean;
19
+ debug: boolean;
14
20
  analysisScale: PtaAnalysisScale;
15
21
  ptsCollectionType: PtsCollectionType;
16
22
  ptsCollectionCtor: new () => IPtsCollection<NodeID>;
17
- constructor(kLimit: number, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, unhandledFuncDump?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType);
18
- static create(kLimit: number, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, unhandledFuncDump?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType): PointerAnalysisConfig;
23
+ constructor(kLimit: number, contextType: ContextType, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, debug?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType);
24
+ static dispose(): void;
25
+ static create(kLimit: number, outputDirectory: string, detectTypeDiff?: boolean, dotDump?: boolean, debug?: boolean, analysisScale?: PtaAnalysisScale, ptsCoType?: PtsCollectionType, contextType?: ContextType): PointerAnalysisConfig;
19
26
  static getInstance(): PointerAnalysisConfig;
20
27
  }
21
28
  //# sourceMappingURL=PointerAnalysisConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PointerAnalysisConfig.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA2B,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,oBAAY,gBAAgB;IACxB,YAAY,IAAI;IAChB,WAAW,IAAI;CAClB;AAED,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAwB;IAExC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,gBAAgB,CAAC;IAChC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,UAAU,cAAc,CAAC,MAAM,CAAC,CAAC;gBAOvD,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,iBAAiB,GAAE,OAAe,EAClC,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB;WAuBvB,MAAM,CAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,iBAAiB,GAAE,OAAe,EAClC,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB,GAClC,qBAAqB;WAgBV,WAAW,IAAI,qBAAqB;CAMrD"}
1
+ {"version":3,"file":"PointerAnalysisConfig.d.ts","sourceRoot":"","sources":["../../../src/callgraph/pointerAnalysis/PointerAnalysisConfig.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA2B,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,oBAAY,gBAAgB;IACxB,YAAY,IAAI;IAChB,WAAW,IAAI;CAClB;AAED,oBAAY,WAAW;IACnB,QAAQ,IAAI;IACZ,GAAG,IAAI;IACP,IAAI,IAAI;CACX;AAED,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAwB;IAExC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,gBAAgB,CAAC;IAChC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,UAAU,cAAc,CAAC,MAAM,CAAC,CAAC;gBAOvD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,KAAK,GAAE,OAAe,EACtB,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB;WAyBvB,OAAO,IAAI,IAAI;WASf,MAAM,CAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,cAAc,GAAE,OAAe,EAC/B,OAAO,GAAE,OAAe,EACxB,KAAK,GAAE,OAAe,EACtB,aAAa,GAAE,gBAAgD,EAC/D,SAAS,oBAAwB,EACjC,WAAW,GAAE,WAA8B,GAC5C,qBAAqB;WAiBV,WAAW,IAAI,qBAAqB;CAMrD"}
@@ -37,7 +37,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
37
37
  return result;
38
38
  };
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.PointerAnalysisConfig = exports.PtaAnalysisScale = void 0;
40
+ exports.PointerAnalysisConfig = exports.ContextType = exports.PtaAnalysisScale = void 0;
41
41
  const fs = __importStar(require("fs"));
42
42
  const PtsDS_1 = require("./PtsDS");
43
43
  var PtaAnalysisScale;
@@ -45,12 +45,18 @@ var PtaAnalysisScale;
45
45
  PtaAnalysisScale[PtaAnalysisScale["WholeProgram"] = 0] = "WholeProgram";
46
46
  PtaAnalysisScale[PtaAnalysisScale["MethodLevel"] = 1] = "MethodLevel";
47
47
  })(PtaAnalysisScale = exports.PtaAnalysisScale || (exports.PtaAnalysisScale = {}));
48
+ var ContextType;
49
+ (function (ContextType) {
50
+ ContextType[ContextType["CallSite"] = 0] = "CallSite";
51
+ ContextType[ContextType["Obj"] = 1] = "Obj";
52
+ ContextType[ContextType["Func"] = 2] = "Func";
53
+ })(ContextType = exports.ContextType || (exports.ContextType = {}));
48
54
  class PointerAnalysisConfig {
49
55
  /*
50
56
  * Note: DO NOT use `new PointerAnalysisConfig` to initialize ptaconfig
51
57
  * Use PointerAnalysisConfig.create() for singleton pattern
52
58
  */
53
- constructor(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false, unhandledFuncDump = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set) {
59
+ constructor(kLimit, contextType, outputDirectory, detectTypeDiff = false, dotDump = false, debug = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set) {
54
60
  if (kLimit > 5) {
55
61
  throw new Error('K Limit too large');
56
62
  }
@@ -58,20 +64,29 @@ class PointerAnalysisConfig {
58
64
  this.outputDirectory = outputDirectory;
59
65
  this.detectTypeDiff = detectTypeDiff;
60
66
  this.dotDump = dotDump;
61
- this.unhandledFuncDump = unhandledFuncDump;
67
+ this.debug = debug;
62
68
  this.analysisScale = analysisScale;
63
69
  this.ptsCollectionType = ptsCoType;
64
70
  this.ptsCollectionCtor = (0, PtsDS_1.createPtsCollectionCtor)(ptsCoType);
71
+ this.contextType = contextType;
65
72
  if (!fs.existsSync(outputDirectory)) {
66
73
  fs.mkdirSync(outputDirectory, { recursive: true });
67
74
  }
68
75
  }
76
+ /*
77
+ * Set static field to be null, then all related objects could be freed by GC.
78
+ * Class PointerAnalysisConfig has been exported by ArkAnalyzer, the dispose method should be called by users themselves before free this class.
79
+ */
80
+ static dispose() {
81
+ // @ts-expect-error: only be used to free the memory
82
+ this.instance = null;
83
+ }
69
84
  /*
70
85
  * Create Singleton instance
71
86
  * The instance can be created multi-times and be overwrited
72
87
  */
73
- static create(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false, unhandledFuncDump = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set) {
74
- PointerAnalysisConfig.instance = new PointerAnalysisConfig(kLimit, outputDirectory, detectTypeDiff, dotDump, unhandledFuncDump, analysisScale, ptsCoType);
88
+ static create(kLimit, outputDirectory, detectTypeDiff = false, dotDump = false, debug = false, analysisScale = PtaAnalysisScale.WholeProgram, ptsCoType = PtsDS_1.PtsCollectionType.Set, contextType = ContextType.Func) {
89
+ PointerAnalysisConfig.instance = new PointerAnalysisConfig(kLimit, contextType, outputDirectory, detectTypeDiff, dotDump, debug, analysisScale, ptsCoType);
75
90
  return PointerAnalysisConfig.instance;
76
91
  }
77
92
  /*
@@ -0,0 +1,69 @@
1
+ import { CallGraph } from '../../model/CallGraph';
2
+ import { ContextItemManager } from './ContextItem';
3
+ export type ContextID = number;
4
+ export declare const DUMMY_CID = 0;
5
+ /**
6
+ * An abstract base class representing a context in pointer analysis.
7
+ * A context is an immutable sequence of context elements (represented by their IDs).
8
+ */
9
+ export declare abstract class Context {
10
+ protected contextElems: number[];
11
+ constructor(contextElems?: number[]);
12
+ /**
13
+ * Creates a new empty context instance.
14
+ * This static method must be called on a concrete subclass.
15
+ * @example CallSiteContext.newEmpty()
16
+ */
17
+ static newEmpty<T extends Context>(this: new () => T): T;
18
+ /**
19
+ * Creates a new context instance from an array of element IDs.
20
+ * This static method must be called on a concrete subclass.
21
+ * @param contextElems An array of ContextItem IDs.
22
+ * @example CallSiteContext.new([1, 2])
23
+ */
24
+ static new<T extends Context>(this: new (elems: number[]) => T, contextElems: number[]): T;
25
+ /**
26
+ * Creates a new k-limited context by prepending a new element to an old context.
27
+ * The returned instance has the same type as the `oldCtx`.
28
+ * @param oldCtx The previous context instance.
29
+ * @param elem The ID of the new element to add.
30
+ * @param k The maximum length limit for the context.
31
+ */
32
+ static newKLimitedContext<T extends Context>(oldCtx: T, elem: number, k: number): T;
33
+ /**
34
+ * Truncates an existing context to a specified k-limit.
35
+ * The returned instance has the same type as `ctx`.
36
+ * @param ctx The context instance to truncate.
37
+ * @param k The maximum length limit for the context.
38
+ */
39
+ static kLimitedContext<T extends Context>(ctx: T, k: number): T;
40
+ length(): number;
41
+ get(index: number): number;
42
+ toString(): string;
43
+ abstract append(callSiteID: number, elementID: number, k: number, m: ContextItemManager): Context;
44
+ abstract dump(m: ContextItemManager, cg: CallGraph): string;
45
+ }
46
+ export declare class CallSiteContext extends Context {
47
+ append(callSiteID: number, calleeFunc: number, k: number, m: ContextItemManager): CallSiteContext;
48
+ dump(m: ContextItemManager, cg: CallGraph): string;
49
+ }
50
+ export declare class ObjContext extends Context {
51
+ append(callSiteID: number, objId: number, k: number, m: ContextItemManager): ObjContext;
52
+ dump(m: ContextItemManager, cg: CallGraph): string;
53
+ }
54
+ export declare class FuncContext extends Context {
55
+ append(callSiteID: number, funcId: number, k: number, m: ContextItemManager): FuncContext;
56
+ dump(m: ContextItemManager, cg: CallGraph): string;
57
+ }
58
+ export declare class ContextCache {
59
+ private contextList;
60
+ private contextToIDMap;
61
+ constructor();
62
+ getOrNewContextID(context: Context): ContextID;
63
+ updateContext(id: ContextID, newContext: Context, oldContext: Context): boolean;
64
+ getContextID(context: Context): ContextID | undefined;
65
+ getContext(id: number): Context | undefined;
66
+ getContextList(): Context[];
67
+ dump(m: ContextItemManager, cg: CallGraph): string;
68
+ }
69
+ //# sourceMappingURL=Context.d.ts.map