@@ -75,7 +75,95 @@ predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c)
75
75
76
76
/** Defines the CFG by dispatch on the various AST types. */
77
77
module Trees {
78
- // TODO
78
+ class ScriptBlockTree extends PreOrderTree instanceof ScriptBlock {
79
+ final override predicate last ( AstNode last , Completion c ) {
80
+ last ( super .getEndBlock ( ) , last , c )
81
+ or
82
+ not exists ( super .getEndBlock ( ) ) and
83
+ last ( super .getProcessBlock ( ) , last , c )
84
+ or
85
+ not exists ( super .getEndBlock ( ) ) and
86
+ not exists ( super .getProcessBlock ( ) ) and
87
+ last ( super .getBeginBlock ( ) , last , c )
88
+ or
89
+ not exists ( super .getEndBlock ( ) ) and
90
+ not exists ( super .getProcessBlock ( ) ) and
91
+ not exists ( super .getBeginBlock ( ) ) and
92
+ last = this and
93
+ completionIsSimple ( c )
94
+ }
95
+
96
+ final override predicate propagatesAbnormal ( AstNode child ) {
97
+ child = [ super .getBeginBlock ( ) , super .getProcessBlock ( ) , super .getEndBlock ( ) ]
98
+ }
99
+
100
+ final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
101
+ pred = this and
102
+ (
103
+ first ( super .getBeginBlock ( ) , succ )
104
+ or
105
+ not exists ( super .getBeginBlock ( ) ) and
106
+ first ( super .getProcessBlock ( ) , succ )
107
+ or
108
+ not exists ( super .getBeginBlock ( ) ) and
109
+ not exists ( super .getProcessBlock ( ) ) and
110
+ first ( super .getEndBlock ( ) , succ )
111
+ ) and
112
+ completionIsSimple ( c )
113
+ or
114
+ last ( super .getBeginBlock ( ) , pred , c ) and
115
+ c instanceof NormalCompletion and
116
+ (
117
+ first ( super .getProcessBlock ( ) , succ )
118
+ or
119
+ not exists ( super .getProcessBlock ( ) ) and
120
+ first ( super .getEndBlock ( ) , succ )
121
+ or
122
+ not exists ( super .getProcessBlock ( ) ) and
123
+ not exists ( super .getEndBlock ( ) ) and
124
+ succ = this
125
+ )
126
+ or
127
+ last ( super .getProcessBlock ( ) , pred , c ) and
128
+ c instanceof NormalCompletion and
129
+ (
130
+ // If we process multiple items we will loop back to the process block
131
+ first ( super .getProcessBlock ( ) , succ )
132
+ or
133
+ // Once we're done process all items we will go to the end block
134
+ first ( super .getEndBlock ( ) , succ )
135
+ )
136
+ }
137
+ }
138
+
139
+ class NamedBlockTree extends StandardPostOrderTree instanceof NamedBlock {
140
+ // TODO: Handle trap
141
+ override AstNode getChildNode ( int i ) { result = super .getStatement ( i ) }
142
+ }
143
+
144
+ class AssignStmtTree extends StandardPostOrderTree instanceof AssignStmt {
145
+ override AstNode getChildNode ( int i ) {
146
+ i = 0 and result = super .getLeftHandSide ( )
147
+ or
148
+ i = 1 and result = super .getRightHandSide ( )
149
+ }
150
+ }
151
+
152
+ class VarAccessTree extends LeafTree instanceof VarAccess { }
153
+
154
+ class BinaryExprTree extends StandardPostOrderTree instanceof BinaryExpr {
155
+ override AstNode getChildNode ( int i ) {
156
+ i = 0 and result = super .getLeft ( )
157
+ or
158
+ i = 1 and result = super .getRight ( )
159
+ }
160
+ }
161
+
162
+ class ConstExprTree extends LeafTree instanceof ConstExpr { }
163
+
164
+ class CmdExprTree extends StandardPreOrderTree instanceof CmdExpr {
165
+ override AstNode getChildNode ( int i ) { i = 0 and result = super .getExpr ( ) }
166
+ }
79
167
}
80
168
81
169
private import Scope
0 commit comments