Class: Crokus::RandomGen
- Inherits:
-
Object
- Object
- Crokus::RandomGen
- Defined in:
- lib/crokus/cfg_random_gen.rb
Constant Summary collapse
- ARITH =
{ :add => "+", :sub => "-", :mul => "*", :div => "/", #:shift_r => ">>", #:shift_l => "<<", }
- COMP =
{ :gt => ">", :gte => ">=", :lt => "<", :lte => "<=", :eq => "==", :neq => "!=" }
- COMPA =
[:gt,:lt,:eq,:neq,:gte,:lte]
- ACCUM =
[:add_assign,:sub_assign,:mul_assign,:div_assign]
- LOGIC =
[:or,:and,:xor]
- MINUS =
Token.new [:sub,"-",[0,0]]
Instance Attribute Summary collapse
-
#cfg ⇒ Object
Returns the value of attribute cfg.
-
#options ⇒ Object
Returns the value of attribute options.
Instance Method Summary collapse
- #bb_track(bb) ⇒ Object
- #create_assign ⇒ Object
- #create_assignee ⇒ Object
- #create_binary_expression(depth) ⇒ Object
- #create_binary_op ⇒ Object
- #create_cfg ⇒ Object
- #create_cond_op ⇒ Object
- #create_condition ⇒ Object
- #create_expression ⇒ Object
- #create_inputs ⇒ Object
- #create_internal_arrays ⇒ Object
- #create_output_assigns ⇒ Object
- #create_outputs ⇒ Object
- #create_unary_expression ⇒ Object
- #create_variables ⇒ Object
- #gen_dot ⇒ Object
- #gen_for_block(level) ⇒ Object
- #gen_if_block(level) ⇒ Object
- #gen_plain_block(level) ⇒ Object
- #gen_while_block(level) ⇒ Object
- #generate_c ⇒ Object
- #init_cfg ⇒ Object
- #init_random_generators ⇒ Object
-
#initialize(options = {}) ⇒ RandomGen
constructor
A new instance of RandomGen.
- #populate(bb) ⇒ Object
- #populate_all ⇒ Object
- #print_infos ⇒ Object
- #rec_create_bbs(level = 0) ⇒ Object
- #register_readables(ary) ⇒ Object
- #run(params) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ RandomGen
Returns a new instance of RandomGen.
19 20 21 |
# File 'lib/crokus/cfg_random_gen.rb', line 19 def initialize ={} @options= end |
Instance Attribute Details
#cfg ⇒ Object
Returns the value of attribute cfg.
17 18 19 |
# File 'lib/crokus/cfg_random_gen.rb', line 17 def cfg @cfg end |
#options ⇒ Object
Returns the value of attribute options.
16 17 18 |
# File 'lib/crokus/cfg_random_gen.rb', line 16 def @options end |
Instance Method Details
#bb_track(bb) ⇒ Object
134 135 136 137 |
# File 'lib/crokus/cfg_random_gen.rb', line 134 def bb_track bb bb << fcall=FunCall.new(Ident.create("printf"),[StrLit.create("cfg track : %s\\n"),StrLit.create(bb.label)]) bb << SemicolonStmt.new(nil) end |
#create_assign ⇒ Object
232 233 234 235 236 |
# File 'lib/crokus/cfg_random_gen.rb', line 232 def create_assign lhs=create_assignee rhs=create_expression() Assign.new(lhs,ASSIGN,rhs) end |
#create_assignee ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/crokus/cfg_random_gen.rb', line 238 def create_assignee if @params["nb_int_arrays"]>0 case r=rand(0..10) when 0..3 name,size=@cfg.infos["internal_arrays"].sample.first var=@readables.sample @readables.rotate! abs_func=Ident.new(Token.create "abs") return Indexed.new(name,FunCall.new(abs_func,[Binary.new(var,MOD,size)])) end end assignee=@vars.first @vars.rotate! return assignee end |
#create_binary_expression(depth) ⇒ Object
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/crokus/cfg_random_gen.rb', line 266 def create_binary_expression depth if depth <= 1 lhs=create_unary_expression rhs=create_unary_expression else lhs=create_binary_expression(depth-1) rhs=create_binary_expression(depth-1) end op=create_binary_op if op.val=="/" and lhs.to_s=="0" return create_binary_expression(depth) else return Parenth.new(Binary.new(lhs,op,rhs)) end end |
#create_binary_op ⇒ Object
306 307 308 309 310 311 312 |
# File 'lib/crokus/cfg_random_gen.rb', line 306 def create_binary_op kind,val=ARITH.sample if @params["accept_integer_division"]==false and kind==:div return create_binary_op # retry end Token.new([kind,val,[0,0]]) end |
#create_cfg ⇒ Object
109 110 111 112 113 114 |
# File 'lib/crokus/cfg_random_gen.rb', line 109 def create_cfg puts " |-->[+] building cfg" while @cfg.size < @params["nb_basic_blocks"] rec_create_bbs end end |
#create_cond_op ⇒ Object
314 315 316 317 |
# File 'lib/crokus/cfg_random_gen.rb', line 314 def create_cond_op kind,val=COMP.sample Token.new([kind,val,[0,0]]) end |
#create_condition ⇒ Object
254 255 256 257 258 259 |
# File 'lib/crokus/cfg_random_gen.rb', line 254 def create_condition lhs=create_expression() op =create_cond_op() rhs=create_expression() Binary.new(lhs,op,rhs) end |
#create_expression ⇒ Object
261 262 263 264 |
# File 'lib/crokus/cfg_random_gen.rb', line 261 def create_expression depth=@rng["assigns_expression_depth"].call.to_i return create_binary_expression(depth) end |
#create_inputs ⇒ Object
73 74 75 76 77 78 |
# File 'lib/crokus/cfg_random_gen.rb', line 73 def create_inputs name="in_0" @inputs=(1..@params["nb_inputs"]).map{|idx| Ident.new(Token.create name=name.succ)} register_readables @inputs @cfg.infos["inputs"]=@inputs end |
#create_internal_arrays ⇒ Object
100 101 102 103 104 105 106 107 |
# File 'lib/crokus/cfg_random_gen.rb', line 100 def create_internal_arrays @cfg.infos["internal_arrays"]||=[] (1..@params["nb_int_arrays"]).each do |idx| size=@rng["size_int_arrays"].call.to_i size=IntLit.new(Token.create(size.to_s)) @cfg.infos["internal_arrays"] << {Ident.new(Token.create("t#{idx}")) => size} end end |
#create_output_assigns ⇒ Object
93 94 95 96 97 98 |
# File 'lib/crokus/cfg_random_gen.rb', line 93 def create_output_assigns @cfg.infos["output_assigns"]||=[] @outputs.each do |ident| @cfg.infos["output_assigns"] << {ident => create_expression} end end |
#create_outputs ⇒ Object
80 81 82 83 84 |
# File 'lib/crokus/cfg_random_gen.rb', line 80 def create_outputs name="out_0" @outputs=(1..@params["nb_outputs"]).map{|idx| Ident.new(Token.create name=name.succ)} @cfg.infos["outputs"]=@outputs end |
#create_unary_expression ⇒ Object
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/crokus/cfg_random_gen.rb', line 319 def create_unary_expression r=rand(0..10) case r when 1 return IntLit.new Token.create rand(0..255).to_s when 2 return Parenth.new(Unary.new(MINUS,@readables.sample)) when 3 name,size=@cfg.infos["internal_arrays"].sample.first var=@readables.sample abs_func=Ident.new(Token.create "abs") index=FunCall.new(abs_func,[Binary.new(var,MOD,size)]) return Indexed.new(name,index) #eg : t[abs(a % 4)] else return @readables.sample end end |
#create_variables ⇒ Object
86 87 88 89 90 91 |
# File 'lib/crokus/cfg_random_gen.rb', line 86 def create_variables name="`" # succ is 'a' @vars=(1..@params["nb_int_vars"]).map{|idx| Ident.new(Token.create name=name.succ)} register_readables @vars @cfg.infos["int_vars"]=@vars end |
#gen_dot ⇒ Object
47 48 49 |
# File 'lib/crokus/cfg_random_gen.rb', line 47 def gen_dot @cfg.print verbose=false end |
#gen_for_block(level) ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/crokus/cfg_random_gen.rb', line 191 def gen_for_block level @cfg << cond_bb = BasicBlock.new(:start_for => true) @index||="idx_0" @index=@index.succ loop_index=Ident.new Token.create @index cond_bb.infos["loop_index"]=loop_index @cfg.infos["loop_indexes"]||=[] @cfg.infos["loop_indexes"] << loop_index cond_bb.infos["loop_index_bound"]=@rng["forloop_iterations"].call.to_i @cfg << trueBranch = BasicBlock.new @cfg << falseBranch = BasicBlock.new @cfg << postBranch = BasicBlock.new(:loop_body_end => true) # control flow tracking bb_track(cond_bb) bb_track(trueBranch) bb_track(falseBranch) bb_track(postBranch) @current.to cond_bb cond_bb.to trueBranch cond_bb.to falseBranch @current= trueBranch rec_create_bbs(level+1) @current.to postBranch @current=postBranch @current.to cond_bb @current=falseBranch end |
#gen_if_block(level) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/crokus/cfg_random_gen.rb', line 146 def gen_if_block level @current.infos[:cond]=create_condition @current.infos[:start_if]=true @cfg << trueBranch =BasicBlock.new @cfg << falseBranch=BasicBlock.new @cfg << mergeBranch=BasicBlock.new bb_track(trueBranch) bb_track(falseBranch) bb_track(mergeBranch) @current.to trueBranch @current.to falseBranch @current=trueBranch rec_create_bbs(level+1) @current.to mergeBranch @current=falseBranch rec_create_bbs(level+1) @current.to mergeBranch @current=mergeBranch end |
#gen_plain_block(level) ⇒ Object
139 140 141 142 143 144 |
# File 'lib/crokus/cfg_random_gen.rb', line 139 def gen_plain_block level @cfg << bb=BasicBlock.new bb_track(bb) @current.to bb @current=bb end |
#gen_while_block(level) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/crokus/cfg_random_gen.rb', line 171 def gen_while_block level @cfg << cond_bb = BasicBlock.new(:start_while => true) cond_bb.infos[:cond]=create_condition @cfg << trueBranch = BasicBlock.new @cfg << falseBranch = BasicBlock.new bb_track(cond_bb) bb_track(trueBranch) bb_track(falseBranch) @current.to cond_bb cond_bb.to trueBranch cond_bb.to falseBranch @current = trueBranch rec_create_bbs(level+1) @current.to cond_bb @current=falseBranch end |
#generate_c ⇒ Object
337 338 339 |
# File 'lib/crokus/cfg_random_gen.rb', line 337 def generate_c PrinterC.new().print(cfg) end |
#init_cfg ⇒ Object
51 52 53 54 |
# File 'lib/crokus/cfg_random_gen.rb', line 51 def init_cfg @cfg=CFG.new(@params["name"]) @current=@cfg.starter end |
#init_random_generators ⇒ Object
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/crokus/cfg_random_gen.rb', line 56 def init_random_generators puts " |-->[+] init parameterized random generators" @rng={} @params.each do |key,val| if key.start_with? "avg_" name=key[4..-1] @rng[name]=Distribution::Normal.rng(mean=val,sigma=0.5) #sigma=1 ? end end end |
#populate(bb) ⇒ Object
226 227 228 229 230 |
# File 'lib/crokus/cfg_random_gen.rb', line 226 def populate bb @rng["assigns_per_bbs"].call.to_i.times do bb << create_assign end end |
#populate_all ⇒ Object
221 222 223 224 |
# File 'lib/crokus/cfg_random_gen.rb', line 221 def populate_all puts " |-->[+] populate cfg" @cfg.each{|bb| populate bb} end |
#print_infos ⇒ Object
42 43 44 45 |
# File 'lib/crokus/cfg_random_gen.rb', line 42 def print_infos puts " |-->[+] infos about CFG :" puts " |-->[+] #basic blocks : #{@cfg.size}" end |
#rec_create_bbs(level = 0) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/crokus/cfg_random_gen.rb', line 116 def rec_create_bbs level=0 if @cfg.size < @params["nb_basic_blocks"] type = [:plain,:if,:while,:for].sample case type when :plain gen_plain_block(level) when :if gen_if_block(level) when :while gen_while_block(level) if @params["accept_while_loops"] when :for gen_for_block(level) else raise "unknown cfg type : #{type}" end end end |
#register_readables(ary) ⇒ Object
67 68 69 70 71 |
# File 'lib/crokus/cfg_random_gen.rb', line 67 def register_readables ary @readables||=[] @readables << ary @readables.flatten! end |
#run(params) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/crokus/cfg_random_gen.rb', line 23 def run params puts "[+] running random C code generation" puts " |-->[+] reading parameters file '#{params}'" @params=YAML.load(File.read(params)) init_cfg init_random_generators create_inputs create_outputs create_variables create_internal_arrays create_output_assigns create_cfg gen_dot # to see the structure, before hacking the content populate_all generate_c print_infos end |