Class: Crokus::CFGBuilder

Inherits:
Transformer show all
Defined in:
lib/crokus/cfg_builder.rb

Instance Attribute Summary

Attributes inherited from Transformer

#code

Instance Method Summary collapse

Methods inherited from Transformer

#transform, #visitAddressOf, #visitArrayOf, #visitArrayOrStructInit, #visitArrow, #visitBinary, #visitCase, #visitCastedExpr, #visitCasting, #visitCharLit, #visitCommaStmt, #visitCondExpr, #visitDecl, #visitDefine, #visitDeref, #visitDesignUnit, #visitDotted, #visitFloatLit, #visitFormalArg, #visitFunCall, #visitFunctionProto, #visitGoto, #visitIdent, #visitInclude, #visitIndexed, #visitIntLit, #visitLabelledStmt, #visitParenth, #visitPointerTo, #visitReturn, #visitSizeof, #visitStrLit, #visitStruct, #visitToken, #visitType, #visitTypedef, #visitUnary

Constructor Details

#initializeCFGBuilder

Returns a new instance of CFGBuilder.



11
12
13
14
# File 'lib/crokus/cfg_builder.rb', line 11

def initialize
  @ind=-2
  @verbose=false
end

Instance Method Details

#build(ast) ⇒ Object



16
17
18
# File 'lib/crokus/cfg_builder.rb', line 16

def build ast
  ast.accept(self)
end

#visitAssign(assign, args = nil) ⇒ Object

.….……stmts.….….……



37
38
39
# File 'lib/crokus/cfg_builder.rb', line 37

def visitAssign assign,args=nil
  @current << assign
end

#visitBody(body, args = nil) ⇒ Object



33
34
35
# File 'lib/crokus/cfg_builder.rb', line 33

def visitBody body,args=nil
  body.each{|stmt| stmt.accept(self,args)}
end

#visitBreak(brk, args = nil) ⇒ Object



75
76
77
78
79
80
# File 'lib/crokus/cfg_builder.rb', line 75

def visitBreak brk,args=nil
  @current << brk
  @current.to @current_break_dest
  @cfg << unreachable = BasicBlock.new
  @current = unreachable
end

#visitContinue(cont, args = nil) ⇒ Object



82
83
84
85
86
87
# File 'lib/crokus/cfg_builder.rb', line 82

def visitContinue cont,args=nil
  @current << cont
  @current.to @current_continue_dest
  @cfg << unreachable = BasicBlock.new
  @current = unreachable
end

#visitDoWhile(dowhile, args = nil) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/crokus/cfg_builder.rb', line 151

def visitDoWhile dowhile,args=nil
  @cfg << cond_bb     = BasicBlock.new
  @current_continue_dest = cond_bb # for continue stmt !
  @cfg << trueBranch  = BasicBlock.new
  @cfg << falseBranch = BasicBlock.new

  @current.to trueBranch
  @current = trueBranch
  dowhile.body.accept(self) # may modify @current

  @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



109
110
111
# File 'lib/crokus/cfg_builder.rb', line 109

def visitElse else_,args=nil
  else_.body.accept(self)
end

#visitFor(for_, args = nil) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/crokus/cfg_builder.rb', line 129

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) #may modify @current identity
  @current.to postBranch
  @current=postBranch
  for_.increment.accept(self)
  @current.to cond_bb
  @current=falseBranch
end

#visitFunction(func, args = nil) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/crokus/cfg_builder.rb', line 20

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.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



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/crokus/cfg_builder.rb', line 89

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) #may change @current !
  @current.to mergeBranch
  #
  @current=falseBranch
  if_.else.accept(self) if if_.else #may change @current !
  @current.to mergeBranch
  @current=mergeBranch
end

#visitLabeledStmt(assign, args = nil) ⇒ Object



41
42
43
# File 'lib/crokus/cfg_builder.rb', line 41

def visitLabeledStmt assign,args=nil
  @current << assign
end

#visitPostFixAccu(accu, args = nil) ⇒ Object



49
50
51
# File 'lib/crokus/cfg_builder.rb', line 49

def visitPostFixAccu accu,args=nil
  @current << accu
end

#visitPreFixAccu(accu, args = nil) ⇒ Object



45
46
47
# File 'lib/crokus/cfg_builder.rb', line 45

def visitPreFixAccu accu,args=nil
  @current << accu
end

#visitSwitch(switch, args = nil) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/crokus/cfg_builder.rb', line 53

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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/crokus/cfg_builder.rb', line 113

def visitWhile while_,args=nil
  cond=while_.cond.accept(self,:as_expr)
  @cfg << cond_bb     = BasicBlock.new
  @current_cond = cond_bb # for continue stmt !
  @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) #may modify identity of @current
  @current.to cond_bb
  @current=falseBranch
end