Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7363b57

Browse files
committed
JS: Instantiate shared SSA library
JS: Remove with statement comment
1 parent a258489 commit 7363b57

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

javascript/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies:
99
codeql/dataflow: ${workspace}
1010
codeql/mad: ${workspace}
1111
codeql/regex: ${workspace}
12+
codeql/ssa: ${workspace}
1213
codeql/tutorial: ${workspace}
1314
codeql/util: ${workspace}
1415
codeql/xml: ${workspace}

javascript/ql/lib/semmle/javascript/BasicBlocks.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import javascript
77
private import internal.StmtContainers
88
private import semmle.javascript.internal.CachedStages
99

10+
module BasicBlockInternal {
11+
// TODO: Expose these as public predicate in a private module instead of this hack.
12+
predicate getImmediateBasicBlockDominator = immediateDominator/1;
13+
}
14+
1015
/**
1116
* Holds if `nd` starts a new basic block.
1217
*/
@@ -280,6 +285,11 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer {
280285
* Gets the basic block that immediately dominates this basic block.
281286
*/
282287
ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) }
288+
289+
/**
290+
* Holds if this if a basic block whose last node is an exit node.
291+
*/
292+
predicate isExitBlock() { exitBB(this) }
283293
}
284294

285295
/**
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Instantiates the shared SSA library for JavaScript, but only to establish use-use flow.
3+
*
4+
* JavaScript's old SSA library is still responsible for the ordinary SSA flow.
5+
*/
6+
7+
private import javascript as js
8+
private import codeql.ssa.Ssa
9+
10+
private module SsaConfig implements InputSig<js::DbLocation> {
11+
class ControlFlowNode = js::ControlFlowNode;
12+
13+
class BasicBlock = js::BasicBlock;
14+
15+
class ExitBasicBlock extends BasicBlock {
16+
ExitBasicBlock() { this.isExitBlock() }
17+
}
18+
19+
class SourceVariable = js::PurelyLocalVariable; // TODO: include 'this' as it is relevant for use-use flow
20+
21+
pragma[nomagic]
22+
private js::EntryBasicBlock getEntryBlock(js::StmtContainer container) {
23+
result.getContainer() = container
24+
}
25+
26+
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
27+
certain = true and
28+
(
29+
bb.defAt(i, v, _)
30+
or
31+
// Implicit initialization and function parameters
32+
bb = getEntryBlock(v.getDeclaringContainer()) and
33+
i = -1
34+
)
35+
}
36+
37+
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
38+
bb.useAt(i, v, _) and certain = true
39+
}
40+
41+
predicate getImmediateBasicBlockDominator =
42+
js::BasicBlockInternal::getImmediateBasicBlockDominator/1;
43+
44+
pragma[inline]
45+
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
46+
}
47+
48+
import Make<js::DbLocation, SsaConfig>
49+
50+
private module SsaDataflowInput implements DataFlowIntegrationInputSig {
51+
class Expr extends js::VarUse {
52+
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
53+
}
54+
55+
predicate ssaDefAssigns(WriteDefinition def, Expr value) { none() } // Not handled here
56+
57+
class Parameter = js::Parameter;
58+
59+
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here
60+
61+
abstract class Guard extends Expr { } // empty class
62+
63+
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { none() }
64+
65+
js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) { none() }
66+
}
67+
68+
import DataFlowIntegration<SsaDataflowInput>

0 commit comments

Comments
 (0)