Class: Crokus::CFGBuilder
Instance Attribute Summary
Attributes inherited from Transformer
#code
Instance Method Summary
collapse
-
#build(ast) ⇒ Object
-
#initialize ⇒ CFGBuilder
constructor
A new instance of CFGBuilder.
-
#visitAssign(assign, args = nil) ⇒ Object
-
#visitBody(body, args = nil) ⇒ Object
-
#visitBreak(brk, args = nil) ⇒ Object
-
#visitContinue(cont, args = nil) ⇒ Object
-
#visitDoWhile(dowhile, args = nil) ⇒ Object
-
#visitElse(else_, args = nil) ⇒ Object
-
#visitFor(for_, args = nil) ⇒ Object
-
#visitFunCall(fcall, args = nil) ⇒ Object
-
#visitFunction(func, args = nil) ⇒ Object
-
#visitIf(if_, args = nil) ⇒ Object
-
#visitLabeledStmt(assign, args = nil) ⇒ Object
-
#visitPostFixAccu(accu, args = nil) ⇒ Object
-
#visitPreFixAccu(accu, args = nil) ⇒ Object
-
#visitReturn(ret, args = nil) ⇒ Object
-
#visitSwitch(switch, args = nil) ⇒ Object
-
#visitWhile(while_, args = nil) ⇒ Object
Methods inherited from Transformer
#transform, #visitAddressOf, #visitArrayOf, #visitArrayOrStructInit, #visitArrow, #visitBinary, #visitCase, #visitCastedExpr, #visitCasting, #visitCharLit, #visitCommaStmt, #visitCondExpr, #visitDecl, #visitDefine, #visitDeref, #visitDesignUnit, #visitDotted, #visitFloatLit, #visitFormalArg, #visitFunctionProto, #visitGoto, #visitIdent, #visitInclude, #visitIndexed, #visitIntLit, #visitLabelledStmt, #visitParenth, #visitPointerTo, #visitSizeof, #visitStrLit, #visitStruct, #visitToken, #visitType, #visitTypedef, #visitUnary
Constructor Details
Returns a new instance of CFGBuilder.
12
13
14
15
|
# File 'lib/crokus/cfg_builder.rb', line 12
def initialize
@ind=-2
@verbose=false
end
|
Instance Method Details
#build(ast) ⇒ Object
17
18
19
|
# File 'lib/crokus/cfg_builder.rb', line 17
def build ast
ast.accept(self)
end
|
#visitAssign(assign, args = nil) ⇒ Object
39
40
41
|
# File 'lib/crokus/cfg_builder.rb', line 39
def visitAssign assign,args=nil
@current << assign
end
|
#visitBody(body, args = nil) ⇒ Object
35
36
37
|
# File 'lib/crokus/cfg_builder.rb', line 35
def visitBody body,args=nil
body.each{|stmt| stmt.accept(self,args)}
end
|
#visitBreak(brk, args = nil) ⇒ Object
77
78
79
80
81
82
|
# File 'lib/crokus/cfg_builder.rb', line 77
def visitBreak brk,args=nil
@current << brk
@current.to @current_break_dest
@cfg << unreachable = BasicBlock.new
@current = unreachable
end
|
#visitContinue(cont, args = nil) ⇒ Object
84
85
86
87
88
89
|
# File 'lib/crokus/cfg_builder.rb', line 84
def visitContinue cont,args=nil
@current << cont
@current.to @current_continue_dest
@cfg << unreachable = BasicBlock.new
@current = unreachable
end
|
#visitDoWhile(dowhile, args = nil) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/crokus/cfg_builder.rb', line 161
def visitDoWhile dowhile,args=nil
@cfg << cond_bb = BasicBlock.new
@current_continue_dest = cond_bb @cfg << trueBranch = BasicBlock.new
@cfg << falseBranch = BasicBlock.new
@current.to trueBranch
@current = trueBranch
dowhile.body.accept(self)
@current.to cond_bb
@current = cond_bb
cond=dowhile.cond.accept(self)
cond_bb << ITE.new(cond,trueBranch,falseBranch)
cond_bb.to trueBranch
cond_bb.to falseBranch
@current = falseBranch
end
|
#visitElse(else_, args = nil) ⇒ Object
111
112
113
|
# File 'lib/crokus/cfg_builder.rb', line 111
def visitElse else_,args=nil
else_.body.accept(self)
end
|
#visitFor(for_, args = nil) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/crokus/cfg_builder.rb', line 135
def visitFor for_,args=nil
for_.init.each{|stmt| stmt.accept(self)}
cond=for_.cond.accept(self)
@cfg << cond_bb = BasicBlock.new
@cfg << trueBranch = BasicBlock.new
@cfg << falseBranch = BasicBlock.new
@cfg << postBranch = BasicBlock.new
@current_continue_dest = postBranch
@current_break_dest = falseBranch
@current.to cond_bb
cond_bb << ITE.new(cond,trueBranch,falseBranch)
cond_bb.to trueBranch
cond_bb.to falseBranch
@current= trueBranch
for_.body.accept(self) @current.to postBranch
@current=postBranch
for_.increment.accept(self)
@current.to cond_bb
@current=falseBranch
end
|
#visitFunCall(fcall, args = nil) ⇒ Object
131
132
133
|
# File 'lib/crokus/cfg_builder.rb', line 131
def visitFunCall fcall,args=nil
@current << fcall
end
|
#visitFunction(func, args = nil) ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/crokus/cfg_builder.rb', line 21
def visitFunction func,args=nil
puts " |--[+] visitFunction '#{func.name}'" unless $options[:mute]
@cfg=CFG.new(func.name)
@current=@cfg.starter
func.body.accept(self)
@cfg.print
@cfg=CFGCleaner.new.clean(@cfg)
@cfg=CFGOptimizer.new.clean(@cfg)
@cfg.name=Ident.new(Token.create "#{@cfg.name}_clean")
func.cfg=@cfg
puts " "*5+"|--[+] cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
@cfg.print
end
|
#visitIf(if_, args = nil) ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/crokus/cfg_builder.rb', line 91
def visitIf if_,args=nil
cond=if_.cond.accept(self,:as_expr)
@cfg << trueBranch =BasicBlock.new
@cfg << falseBranch=BasicBlock.new
@cfg << mergeBranch=BasicBlock.new
@current << ITE.new(cond,trueBranch,falseBranch)
@current.to trueBranch
@current.to falseBranch
@current=trueBranch
if_.body.accept(self) @current.to mergeBranch
@current=falseBranch
if_.else.accept(self) if if_.else @current.to mergeBranch
@current=mergeBranch
end
|
#visitLabeledStmt(assign, args = nil) ⇒ Object
43
44
45
|
# File 'lib/crokus/cfg_builder.rb', line 43
def visitLabeledStmt assign,args=nil
@current << assign
end
|
#visitPostFixAccu(accu, args = nil) ⇒ Object
51
52
53
|
# File 'lib/crokus/cfg_builder.rb', line 51
def visitPostFixAccu accu,args=nil
@current << accu
end
|
#visitPreFixAccu(accu, args = nil) ⇒ Object
47
48
49
|
# File 'lib/crokus/cfg_builder.rb', line 47
def visitPreFixAccu accu,args=nil
@current << accu
end
|
#visitReturn(ret, args = nil) ⇒ Object
157
158
159
|
# File 'lib/crokus/cfg_builder.rb', line 157
def visitReturn ret,args=nil
@current << ret
end
|
#visitSwitch(switch, args = nil) ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/crokus/cfg_builder.rb', line 55
def visitSwitch switch,args=nil
@cfg << finalBranch=BasicBlock.new
@current_break_dest=finalBranch
for cas in switch.cases
cond=Binary.new(switch.expr,EQUAL,cas.expr)
@cfg << trueBranch=BasicBlock.new
@cfg << falseBranch=BasicBlock.new
@current << ITE.new(cond,trueBranch,falseBranch)
@current.to trueBranch
@current.to falseBranch
@current = trueBranch
cas.body.accept(self)
@current = falseBranch
end
if switch.default
switch.default.accept(self)
@current.to finalBranch
end
@current=finalBranch
end
|
#visitWhile(while_, args = nil) ⇒ Object
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'lib/crokus/cfg_builder.rb', line 115
def visitWhile while_,args=nil
cond=while_.cond.accept(self,:as_expr)
@cfg << cond_bb = BasicBlock.new
@current_cond = cond_bb @cfg << trueBranch = BasicBlock.new
@cfg << falseBranch = BasicBlock.new
@current.to cond_bb
cond_bb << ITE.new(cond,trueBranch,falseBranch)
cond_bb.to trueBranch
cond_bb.to falseBranch
@current = trueBranch
while_.body.accept(self) @current.to cond_bb
@current=falseBranch
end
|