fastruby 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +10 -0
 - data/Rakefile +4 -2
 - data/benchmarks/benchmark.rb +20 -44
 - data/benchmarks/benchmark.rb~ +47 -0
 - data/benchmarks/benchmark2.rb +19 -45
 - data/benchmarks/benchmark2.rb~ +46 -0
 - data/benchmarks/benchmark3.rb +19 -45
 - data/benchmarks/benchmark3.rb~ +46 -0
 - data/benchmarks/benchmark4.rb +30 -65
 - data/benchmarks/benchmark4.rb~ +61 -0
 - data/benchmarks/benchmark5.rb +25 -55
 - data/benchmarks/benchmark5.rb~ +54 -0
 - data/benchmarks/benchmark6.rb +19 -40
 - data/benchmarks/benchmark6.rb~ +41 -0
 - data/benchmarks/benchmark7.rb +23 -52
 - data/benchmarks/benchmark7.rb~ +48 -0
 - data/ext/fastruby_base/fastruby_base.inl +1 -0
 - data/lib/fastruby/builder.rb +128 -76
 - data/lib/fastruby/cache/cache.rb +9 -5
 - data/lib/fastruby/fastruby_sexp.rb +18 -0
 - data/lib/fastruby/inliner/inliner.rb +68 -0
 - data/lib/fastruby/inliner/modules/call.rb +150 -0
 - data/lib/fastruby/inliner/modules/recursive.rb +35 -0
 - data/lib/fastruby/object.rb +17 -32
 - data/lib/fastruby/reductor/modules/case.rb +49 -0
 - data/lib/{fastruby.rb~ → fastruby/reductor/modules/for.rb} +11 -13
 - data/lib/fastruby/reductor/modules/nontree.rb +31 -0
 - data/lib/fastruby/reductor/modules/recursive.rb +31 -0
 - data/lib/fastruby/reductor/reductor.rb +39 -0
 - data/lib/fastruby/set_tree.rb +7 -1
 - data/lib/fastruby/sexp_extension.rb +6 -0
 - data/lib/fastruby/translator/modules/block.rb +4 -4
 - data/lib/fastruby/translator/modules/call.rb +9 -26
 - data/lib/fastruby/translator/modules/defn.rb +5 -3
 - data/lib/fastruby/translator/modules/directive.rb +42 -0
 - data/lib/fastruby/translator/modules/exceptions.rb +12 -30
 - data/lib/fastruby/translator/modules/flow.rb +33 -83
 - data/lib/fastruby/translator/modules/iter.rb +4 -7
 - data/lib/fastruby/translator/modules/literal.rb +11 -25
 - data/lib/fastruby/translator/modules/logical.rb +5 -3
 - data/lib/fastruby/translator/modules/method_group.rb +4 -3
 - data/lib/fastruby/translator/modules/nonlocal.rb +7 -5
 - data/lib/fastruby/translator/modules/static.rb +242 -0
 - data/lib/fastruby/translator/modules/variable.rb +16 -9
 - data/lib/fastruby/translator/scope_mode_helper.rb +2 -27
 - data/lib/fastruby/translator/translator.rb +131 -60
 - data/lib/fastruby/translator/translator_modules.rb +6 -2
 - data/lib/fastruby.rb +1 -1
 - data/spec/reductor/base_spec.rb +46 -0
 - data/spec/ruby/base_spec.rb~ +394 -0
 - data/spec/ruby/block/arguments_spec.rb~ +214 -0
 - data/spec/ruby/block/proc_as_block_spec.rb~ +23 -0
 - data/spec/ruby/block/retry_spec.rb~ +43 -0
 - data/spec/ruby/block_spec.rb~ +520 -0
 - data/spec/ruby/defn/replacement_spec.rb~ +102 -0
 - data/spec/ruby/integrity_spec.rb~ +40 -0
 - data/spec/ruby/singleton_spec.rb~ +76 -0
 - data/spec/scope_mode/base_spec.rb +14 -5
 - data/spec/scope_mode/block_spec.rb +18 -9
 - data/spec/scope_mode/call_spec.rb +11 -2
 - data/spec/scope_mode/exception_spec.rb +11 -2
 - data/spec/scope_mode/flow_spec.rb +18 -8
 - data/spec/scope_mode/optimization_spec.rb +21 -13
 - data/spec/static/base_spec.rb +54 -0
 - data/spec/static/flow_spec.rb +48 -0
 - data/spec/static/operator_spec.rb +104 -0
 - metadata +58 -8
 
| 
         @@ -26,6 +26,7 @@ require "fastruby/set_tree" 
     | 
|
| 
       26 
26 
     | 
    
         
             
            require "fastruby/exceptions"
         
     | 
| 
       27 
27 
     | 
    
         
             
            require "fastruby/translator/translator_modules"
         
     | 
| 
       28 
28 
     | 
    
         
             
            require "fastruby/translator/scope_mode_helper"
         
     | 
| 
      
 29 
     | 
    
         
            +
            require "define_method_handler"
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
            module FastRuby
         
     | 
| 
       31 
32 
     | 
    
         
             
              class Context
         
     | 
| 
         @@ -39,12 +40,66 @@ module FastRuby 
     | 
|
| 
       39 
40 
     | 
    
         
             
                attr_reader :init_extra
         
     | 
| 
       40 
41 
     | 
    
         
             
                attr_reader :extra_code
         
     | 
| 
       41 
42 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
                 
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                   
     | 
| 
      
 43 
     | 
    
         
            +
                class Value
         
     | 
| 
      
 44 
     | 
    
         
            +
                  attr_accessor :value
         
     | 
| 
      
 45 
     | 
    
         
            +
                  def initialize(v); @value = v; end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
                
         
     | 
| 
      
 48 
     | 
    
         
            +
                def self.define_translator_for(ntype, options = {}, &blk)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  condition_blk = proc do |*x|
         
     | 
| 
      
 50 
     | 
    
         
            +
                    tree = x.first; tree.node_type == ntype
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  
         
     | 
| 
      
 53 
     | 
    
         
            +
                  if options[:arity]
         
     | 
| 
      
 54 
     | 
    
         
            +
                    if options[:arity] == 1
         
     | 
| 
      
 55 
     | 
    
         
            +
                      condition_blk = proc do |*x|
         
     | 
| 
      
 56 
     | 
    
         
            +
                        tree = x.first; x.size == 1 and tree.node_type == ntype
         
     | 
| 
      
 57 
     | 
    
         
            +
                      end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  
         
     | 
| 
      
 61 
     | 
    
         
            +
                  define_method_handler(:to_c, options, &blk).condition &condition_blk
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                define_method_handler(:to_c, :priority => 10000){|*x|
         
     | 
| 
      
 65 
     | 
    
         
            +
                    "Qnil"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  }.condition{|*x| x.size == 1 and (not x.first)}
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                define_method_handler(:to_c, :priority => 1000){|tree, result_var|
         
     | 
| 
      
 69 
     | 
    
         
            +
                    "#{result_var} = #{to_c(tree)};"
         
     | 
| 
      
 70 
     | 
    
         
            +
                  }.condition{|*x| x.size == 2 and (not x.first)}
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                define_method_handler(:to_c, :priority => -9000){ |tree, result_var|
         
     | 
| 
      
 73 
     | 
    
         
            +
                  "#{result_var} = #{to_c(tree)};"
         
     | 
| 
      
 74 
     | 
    
         
            +
                }.condition{|*x| x.size == 2 }
         
     | 
| 
      
 75 
     | 
    
         
            +
                
         
     | 
| 
      
 76 
     | 
    
         
            +
                define_method_handler(:to_c, :priority => -10000) do |tree, result_var=nil|
         
     | 
| 
      
 77 
     | 
    
         
            +
                  raise "undefined translator for node type :#{tree.node_type}"
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
                
         
     | 
| 
      
 80 
     | 
    
         
            +
                define_method_handler(:initialize_to_c){|*x|}.condition{|*x|false}
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                define_translator_for(:call, :priority => 100){ |tree, result_var=nil|
         
     | 
| 
      
 83 
     | 
    
         
            +
                  tree[2] = :fastruby_require
         
     | 
| 
      
 84 
     | 
    
         
            +
                  to_c(tree)
         
     | 
| 
      
 85 
     | 
    
         
            +
                }.condition{|*x|
         
     | 
| 
      
 86 
     | 
    
         
            +
                  tree = x.first; tree.node_type == :call && tree[2] == :require
         
     | 
| 
      
 87 
     | 
    
         
            +
                }
         
     | 
| 
      
 88 
     | 
    
         
            +
                
         
     | 
| 
      
 89 
     | 
    
         
            +
                define_method_handler(:infer_value, :priority => -1000) do |tree|
         
     | 
| 
      
 90 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                TranslatorModules.instance.each_under(FastRuby.fastruby_load_path + "/fastruby/translator/modules/") do |path|
         
     | 
| 
      
 94 
     | 
    
         
            +
                  groupname = path.split("/").last.split(".").first.to_sym
         
     | 
| 
      
 95 
     | 
    
         
            +
                  handler_scope(:group => groupname) do
         
     | 
| 
      
 96 
     | 
    
         
            +
                    require path
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
       45 
98 
     | 
    
         
             
                end
         
     | 
| 
       46 
99 
     | 
    
         | 
| 
       47 
100 
     | 
    
         
             
                def initialize(common_func = true)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  initialize_to_c
         
     | 
| 
      
 102 
     | 
    
         
            +
                  
         
     | 
| 
       48 
103 
     | 
    
         
             
                  @infer_lvar_map = Hash.new
         
     | 
| 
       49 
104 
     | 
    
         
             
                  @no_cache = false
         
     | 
| 
       50 
105 
     | 
    
         
             
                  @extra_code = ""
         
     | 
| 
         @@ -183,22 +238,32 @@ module FastRuby 
     | 
|
| 
       183 
238 
     | 
    
         
             
                  end
         
     | 
| 
       184 
239 
     | 
    
         
             
                end
         
     | 
| 
       185 
240 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                  
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
                  
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                    if method(mname).arity == 1
         
     | 
| 
       193 
     | 
    
         
            -
                      "#{result_variable} = #{send(mname, tree)};\n"
         
     | 
| 
       194 
     | 
    
         
            -
                    else
         
     | 
| 
       195 
     | 
    
         
            -
                      send(mname, tree, result_variable)
         
     | 
| 
       196 
     | 
    
         
            -
                    end 
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                def _raise(class_tree, message_tree = nil)
         
     | 
| 
      
 243 
     | 
    
         
            +
                  class_tree = to_c class_tree unless class_tree.instance_of? String
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                  if message_tree.instance_of? String
         
     | 
| 
      
 246 
     | 
    
         
            +
                    message_tree = "rb_str_new2(#{message_tree.inspect})"
         
     | 
| 
       197 
247 
     | 
    
         
             
                  else
         
     | 
| 
       198 
     | 
    
         
            -
                     
     | 
| 
      
 248 
     | 
    
         
            +
                    message_tree = to_c message_tree
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                  if message_tree
         
     | 
| 
      
 252 
     | 
    
         
            +
                    return inline_block("
         
     | 
| 
      
 253 
     | 
    
         
            +
                        pframe->thread_data->exception = rb_funcall(#{class_tree}, #{intern_num :exception},1,#{message_tree});
         
     | 
| 
      
 254 
     | 
    
         
            +
                        longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
         
     | 
| 
      
 255 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 256 
     | 
    
         
            +
                        ")
         
     | 
| 
      
 257 
     | 
    
         
            +
                  else
         
     | 
| 
      
 258 
     | 
    
         
            +
                    return inline_block("
         
     | 
| 
      
 259 
     | 
    
         
            +
                        pframe->thread_data->exception = rb_funcall(#{class_tree}, #{intern_num :exception},0);
         
     | 
| 
      
 260 
     | 
    
         
            +
                        longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
         
     | 
| 
      
 261 
     | 
    
         
            +
                        return Qnil;
         
     | 
| 
      
 262 
     | 
    
         
            +
                        ")
         
     | 
| 
       199 
263 
     | 
    
         
             
                  end
         
     | 
| 
       200 
     | 
    
         
            -
                end
         
     | 
| 
       201 
264 
     | 
    
         | 
| 
      
 265 
     | 
    
         
            +
                end
         
     | 
| 
      
 266 
     | 
    
         
            +
                
         
     | 
| 
       202 
267 
     | 
    
         
             
                def anonymous_function(*x)
         
     | 
| 
       203 
268 
     | 
    
         | 
| 
       204 
269 
     | 
    
         
             
                  name = "anonymous" + rand(10000000).to_s
         
     | 
| 
         @@ -280,7 +345,7 @@ module FastRuby 
     | 
|
| 
       280 
345 
     | 
    
         | 
| 
       281 
346 
     | 
    
         
             
                    extra_code << "
         
     | 
| 
       282 
347 
     | 
    
         
             
                      static VALUE #{@alt_method_name}(VALUE self__);
         
     | 
| 
       283 
     | 
    
         
            -
                      static VALUE main_proc_call(VALUE self__, VALUE class_self_) {
         
     | 
| 
      
 348 
     | 
    
         
            +
                      static VALUE main_proc_call(VALUE self__, VALUE signature, VALUE class_self_) {
         
     | 
| 
       284 
349 
     | 
    
         
             
                        #{@alt_method_name}(class_self_);
         
     | 
| 
       285 
350 
     | 
    
         
             
                        return Qnil;
         
     | 
| 
       286 
351 
     | 
    
         
             
                      }
         
     | 
| 
         @@ -290,23 +355,22 @@ module FastRuby 
     | 
|
| 
       290 
355 
     | 
    
         
             
                    init_extra << "
         
     | 
| 
       291 
356 
     | 
    
         
             
                        {
         
     | 
| 
       292 
357 
     | 
    
         
             
                        VALUE newproc = rb_funcall(rb_cObject,#{intern_num :new},0);
         
     | 
| 
       293 
     | 
    
         
            -
                        rb_define_singleton_method(newproc, \"call\", main_proc_call,  
     | 
| 
      
 358 
     | 
    
         
            +
                        rb_define_singleton_method(newproc, \"call\", main_proc_call, 2);
         
     | 
| 
       294 
359 
     | 
    
         
             
                        rb_gv_set(\"$last_obj_proc\", newproc);
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
360 
     | 
    
         
             
                        }
         
     | 
| 
       297 
361 
     | 
    
         
             
                      "
         
     | 
| 
       298 
362 
     | 
    
         
             
                  end
         
     | 
| 
       299 
363 
     | 
    
         
             
                end
         
     | 
| 
       300 
364 
     | 
    
         | 
| 
       301 
     | 
    
         
            -
                def define_method_at_init( 
     | 
| 
       302 
     | 
    
         
            -
                   
     | 
| 
       303 
     | 
    
         
            -
                    {
         
     | 
| 
      
 365 
     | 
    
         
            +
                def define_method_at_init(method_name, size, signature)
         
     | 
| 
      
 366 
     | 
    
         
            +
                  extra_code << "
         
     | 
| 
      
 367 
     | 
    
         
            +
                    static VALUE main_proc_call(VALUE self__, VALUE signature, VALUE class_self_) {
         
     | 
| 
       304 
368 
     | 
    
         
             
                      VALUE method_name = rb_funcall(
         
     | 
| 
       305 
369 
     | 
    
         
             
                            #{literal_value FastRuby},
         
     | 
| 
       306 
370 
     | 
    
         
             
                            #{intern_num :make_str_signature},
         
     | 
| 
       307 
371 
     | 
    
         
             
                            2,
         
     | 
| 
       308 
372 
     | 
    
         
             
                            #{literal_value method_name},
         
     | 
| 
       309 
     | 
    
         
            -
                             
     | 
| 
      
 373 
     | 
    
         
            +
                            signature
         
     | 
| 
       310 
374 
     | 
    
         
             
                            );
         
     | 
| 
       311 
375 
     | 
    
         | 
| 
       312 
376 
     | 
    
         
             
                      ID id = rb_intern(RSTRING_PTR(method_name));
         
     | 
| 
         @@ -315,12 +379,12 @@ module FastRuby 
     | 
|
| 
       315 
379 
     | 
    
         
             
                            #{literal_value FastRuby},
         
     | 
| 
       316 
380 
     | 
    
         
             
                            #{intern_num :set_builder_module},
         
     | 
| 
       317 
381 
     | 
    
         
             
                            1,
         
     | 
| 
       318 
     | 
    
         
            -
                             
     | 
| 
      
 382 
     | 
    
         
            +
                            class_self_
         
     | 
| 
       319 
383 
     | 
    
         
             
                            );
         
     | 
| 
       320 
384 
     | 
    
         | 
| 
       321 
385 
     | 
    
         
             
                      VALUE rb_method_hash;
         
     | 
| 
       322 
386 
     | 
    
         
             
                      void** address = 0;
         
     | 
| 
       323 
     | 
    
         
            -
                      rb_method_hash = rb_funcall( 
     | 
| 
      
 387 
     | 
    
         
            +
                      rb_method_hash = rb_funcall(class_self_, #{intern_num :method_hash},1,#{literal_value method_name});
         
     | 
| 
       324 
388 
     | 
    
         | 
| 
       325 
389 
     | 
    
         
             
                      if (rb_method_hash != Qnil) {
         
     | 
| 
       326 
390 
     | 
    
         
             
                        VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
         
     | 
| 
         @@ -335,15 +399,25 @@ module FastRuby 
     | 
|
| 
       335 
399 
     | 
    
         
             
                      *address = #{alt_method_name};
         
     | 
| 
       336 
400 
     | 
    
         | 
| 
       337 
401 
     | 
    
         
             
                      rb_funcall(
         
     | 
| 
       338 
     | 
    
         
            -
                           
     | 
| 
      
 402 
     | 
    
         
            +
                          class_self_,
         
     | 
| 
       339 
403 
     | 
    
         
             
                          #{intern_num :register_method_value}, 
         
     | 
| 
       340 
404 
     | 
    
         
             
                          3,
         
     | 
| 
       341 
405 
     | 
    
         
             
                          #{literal_value method_name},
         
     | 
| 
       342 
406 
     | 
    
         
             
                          PTR2NUM(id),
         
     | 
| 
       343 
407 
     | 
    
         
             
                          PTR2NUM(address)
         
     | 
| 
       344 
408 
     | 
    
         
             
                          );
         
     | 
| 
      
 409 
     | 
    
         
            +
                          
         
     | 
| 
      
 410 
     | 
    
         
            +
                          return Qnil;
         
     | 
| 
       345 
411 
     | 
    
         
             
                    }
         
     | 
| 
       346 
412 
     | 
    
         
             
                  "
         
     | 
| 
      
 413 
     | 
    
         
            +
                  
         
     | 
| 
      
 414 
     | 
    
         
            +
                  init_extra << "
         
     | 
| 
      
 415 
     | 
    
         
            +
                        {
         
     | 
| 
      
 416 
     | 
    
         
            +
                        VALUE newproc = rb_funcall(rb_cObject,#{intern_num :new},0);
         
     | 
| 
      
 417 
     | 
    
         
            +
                        rb_define_singleton_method(newproc, \"call\", main_proc_call, 2);
         
     | 
| 
      
 418 
     | 
    
         
            +
                        rb_gv_set(\"$last_obj_proc\", newproc);
         
     | 
| 
      
 419 
     | 
    
         
            +
                        }
         
     | 
| 
      
 420 
     | 
    
         
            +
                      "
         
     | 
| 
       347 
421 
     | 
    
         
             
                end
         
     | 
| 
       348 
422 
     | 
    
         | 
| 
       349 
423 
     | 
    
         
             
                def to_c_method(tree, signature = nil)
         
     | 
| 
         @@ -359,7 +433,7 @@ module FastRuby 
     | 
|
| 
       359 
433 
     | 
    
         
             
                    block_argument = tree[3].find{|x| x.to_s[0] == ?&}
         
     | 
| 
       360 
434 
     | 
    
         
             
                    impl_tree = tree[4][1]
         
     | 
| 
       361 
435 
     | 
    
         
             
                  end
         
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
      
 436 
     | 
    
         
            +
                  
         
     | 
| 
       363 
437 
     | 
    
         
             
                  args_tree = original_args_tree.select{|x| x.to_s[0] != ?&}
         
     | 
| 
       364 
438 
     | 
    
         | 
| 
       365 
439 
     | 
    
         
             
                    initialize_method_structs(original_args_tree)
         
     | 
| 
         @@ -1073,22 +1147,31 @@ fastruby_local_next: 
     | 
|
| 
       1073 
1147 
     | 
    
         
             
                  end
         
     | 
| 
       1074 
1148 
     | 
    
         | 
| 
       1075 
1149 
     | 
    
         
             
                  pureruby_wrapper = anonymous_function{ |funcname| "
         
     | 
| 
       1076 
     | 
    
         
            -
                    static VALUE #{funcname}(VALUE self,void* block,void* frame 
     | 
| 
      
 1150 
     | 
    
         
            +
                    static VALUE #{funcname}(VALUE self,void* block,void* frame, int argc, VALUE* argv){
         
     | 
| 
       1077 
1151 
     | 
    
         
             
                      #{@frame_struct}* pframe = frame;
         
     | 
| 
       1078 
     | 
    
         
            -
                      VALUE method_arguments[ 
     | 
| 
       1079 
     | 
    
         
            -
             
     | 
| 
      
 1152 
     | 
    
         
            +
                      VALUE method_arguments[3];
         
     | 
| 
      
 1153 
     | 
    
         
            +
                      
         
     | 
| 
      
 1154 
     | 
    
         
            +
                      method_arguments[0] = (VALUE)argc;
         
     | 
| 
      
 1155 
     | 
    
         
            +
                      method_arguments[1] = (VALUE)argv;
         
     | 
| 
      
 1156 
     | 
    
         
            +
                      method_arguments[2] = (VALUE)self;
         
     | 
| 
      
 1157 
     | 
    
         
            +
                      
         
     | 
| 
       1080 
1158 
     | 
    
         
             
                      return #{
         
     | 
| 
       1081 
     | 
    
         
            -
                        protected_block "last_expression =  
     | 
| 
      
 1159 
     | 
    
         
            +
                        protected_block "last_expression = rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);", false, "method_arguments"
         
     | 
| 
       1082 
1160 
     | 
    
         
             
                        };
         
     | 
| 
       1083 
1161 
     | 
    
         
             
                    }
         
     | 
| 
       1084 
1162 
     | 
    
         
             
                  "
         
     | 
| 
       1085 
1163 
     | 
    
         
             
                  }
         
     | 
| 
       1086 
1164 
     | 
    
         | 
| 
       1087 
1165 
     | 
    
         
             
                  generic_wrapper = anonymous_function{ |funcname| "
         
     | 
| 
       1088 
     | 
    
         
            -
                    static VALUE #{funcname}(VALUE self,void* block,void* frame 
     | 
| 
      
 1166 
     | 
    
         
            +
                    static VALUE #{funcname}(VALUE self,void* block,void* frame, int argc, VALUE* argv){
         
     | 
| 
       1089 
1167 
     | 
    
         | 
| 
       1090 
1168 
     | 
    
         
             
                      #{@frame_struct}* pframe = frame;
         
     | 
| 
       1091 
     | 
    
         
            -
                      VALUE method_arguments[ 
     | 
| 
      
 1169 
     | 
    
         
            +
                      VALUE method_arguments[4];
         
     | 
| 
      
 1170 
     | 
    
         
            +
                      
         
     | 
| 
      
 1171 
     | 
    
         
            +
                      method_arguments[0] = (VALUE)argc;
         
     | 
| 
      
 1172 
     | 
    
         
            +
                      method_arguments[1] = (VALUE)argv;
         
     | 
| 
      
 1173 
     | 
    
         
            +
                      method_arguments[2] = (VALUE)self;
         
     | 
| 
      
 1174 
     | 
    
         
            +
                      method_arguments[3] = (VALUE)block;
         
     | 
| 
       1092 
1175 
     | 
    
         | 
| 
       1093 
1176 
     | 
    
         
             
                      void* fptr = 0;
         
     | 
| 
       1094 
1177 
     | 
    
         | 
| 
         @@ -1106,40 +1189,30 @@ fastruby_local_next: 
     | 
|
| 
       1106 
1189 
     | 
    
         | 
| 
       1107 
1190 
     | 
    
         
             
                      fptr = *#{address_name};
         
     | 
| 
       1108 
1191 
     | 
    
         | 
| 
       1109 
     | 
    
         
            -
                      #{
         
     | 
| 
       1110 
     | 
    
         
            -
                        if args_tree.size < 25
         
     | 
| 
       1111 
     | 
    
         
            -
                        "
         
     | 
| 
       1112 
1192 
     | 
    
         
             
                        if (fptr == 0) {
         
     | 
| 
       1113 
1193 
     | 
    
         
             
                          fptr = *#{cfunc_address_name};
         
     | 
| 
       1114 
1194 
     | 
    
         
             
                          if (fptr != 0) {
         
     | 
| 
       1115 
     | 
    
         
            -
                            VALUE  
     | 
| 
       1116 
     | 
    
         
            -
                            return ( (VALUE(*)(#{value_cast})) (fptr) )((VALUE)params,(VALUE)block,(VALUE)frame#{inprocstrargs});  
         
     | 
| 
      
 1195 
     | 
    
         
            +
                            return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*) ) (fptr) )(self,(VALUE)block,(VALUE)frame, argc, argv);  
         
     | 
| 
       1117 
1196 
     | 
    
         
             
                          }
         
     | 
| 
       1118 
1197 
     | 
    
         
             
                        }
         
     | 
| 
       1119 
     | 
    
         
            -
             
     | 
| 
       1120 
     | 
    
         
            -
                        end
         
     | 
| 
       1121 
     | 
    
         
            -
                      } 
         
     | 
| 
       1122 
     | 
    
         
            -
                      
         
     | 
| 
      
 1198 
     | 
    
         
            +
             
     | 
| 
       1123 
1199 
     | 
    
         
             
                      if (fptr == 0) {
         
     | 
| 
       1124 
1200 
     | 
    
         
             
                        if (block==0) {
         
     | 
| 
       1125 
1201 
     | 
    
         
             
                          return #{
         
     | 
| 
       1126 
     | 
    
         
            -
                            protected_block "last_expression =  
     | 
| 
      
 1202 
     | 
    
         
            +
                            protected_block "last_expression = rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);", false, "method_arguments"
         
     | 
| 
       1127 
1203 
     | 
    
         
             
                            };
         
     | 
| 
       1128 
1204 
     | 
    
         | 
| 
       1129 
1205 
     | 
    
         
             
                        } else {
         
     | 
| 
       1130 
1206 
     | 
    
         
             
                          return #{
         
     | 
| 
       1131 
1207 
     | 
    
         
             
                              protected_block "
         
     | 
| 
       1132 
1208 
     | 
    
         
             
                                    #{@block_struct} *pblock;
         
     | 
| 
       1133 
     | 
    
         
            -
                                    pblock = (typeof(pblock))( ((VALUE*)method_arguments)[ 
     | 
| 
      
 1209 
     | 
    
         
            +
                                    pblock = (typeof(pblock))( ((VALUE*)method_arguments)[3] );
         
     | 
| 
       1134 
1210 
     | 
    
         
             
                                    last_expression = rb_iterate(
         
     | 
| 
       1135 
1211 
     | 
    
         
             
                                    #{anonymous_function{|name|
         
     | 
| 
       1136 
1212 
     | 
    
         
             
                                      "
         
     | 
| 
       1137 
1213 
     | 
    
         
             
                                        static VALUE #{name} (VALUE data) {
         
     | 
| 
       1138 
1214 
     | 
    
         
             
                                          VALUE* method_arguments = (VALUE*)data;
         
     | 
| 
       1139 
     | 
    
         
            -
                                          return  
     | 
| 
       1140 
     | 
    
         
            -
                                            ((VALUE*)method_arguments)[0], 
         
     | 
| 
       1141 
     | 
    
         
            -
                                            #{intern_num mname.to_sym}, 
         
     | 
| 
       1142 
     | 
    
         
            -
                                            #{args_tree.size-1}#{inprocstrargs});
         
     | 
| 
      
 1215 
     | 
    
         
            +
                                          return rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);
         
     | 
| 
       1143 
1216 
     | 
    
         
             
                                        }
         
     | 
| 
       1144 
1217 
     | 
    
         
             
                                      "
         
     | 
| 
       1145 
1218 
     | 
    
         
             
                                    }},
         
     | 
| 
         @@ -1180,19 +1253,20 @@ fastruby_local_next: 
     | 
|
| 
       1180 
1253 
     | 
    
         
             
                        }
         
     | 
| 
       1181 
1254 
     | 
    
         | 
| 
       1182 
1255 
     | 
    
         
             
                      } else {
         
     | 
| 
       1183 
     | 
    
         
            -
                        return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame 
     | 
| 
      
 1256 
     | 
    
         
            +
                        return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame,argc,argv);  
         
     | 
| 
       1184 
1257 
     | 
    
         
             
                      }
         
     | 
| 
       1185 
1258 
     | 
    
         
             
                    }
         
     | 
| 
       1186 
1259 
     | 
    
         
             
                    "
         
     | 
| 
       1187 
1260 
     | 
    
         
             
                  }
         
     | 
| 
       1188 
1261 
     | 
    
         | 
| 
       1189 
1262 
     | 
    
         | 
| 
      
 1263 
     | 
    
         
            +
                  cfuncall1inprocargs = (0..args_tree.size-2).map{|x| "argv[#{x}]"}.join(",")
         
     | 
| 
      
 1264 
     | 
    
         
            +
                  cfuncall1inprocargs = ","+cfuncall1inprocargs if cfuncall1inprocargs != ""
         
     | 
| 
      
 1265 
     | 
    
         
            +
                  
         
     | 
| 
       1190 
1266 
     | 
    
         
             
                  cfunc_value_cast = (["VALUE"]*args_tree.size).join(",")
         
     | 
| 
       1191 
1267 
     | 
    
         
             
                  cfunc_wrapper = anonymous_function{ |funcname| "
         
     | 
| 
       1192 
     | 
    
         
            -
                    static VALUE #{funcname}(VALUE 
     | 
| 
       1193 
     | 
    
         
            -
                        VALUE self 
     | 
| 
       1194 
     | 
    
         
            -
                        VALUE method_arguments[#{args_tree.size}] = {#{toprocstrargs}};
         
     | 
| 
       1195 
     | 
    
         
            -
                        return ( (VALUE(*)(#{cfunc_value_cast})) (#{cfunc_real_address_name}) )(self#{inprocstrargs});
         
     | 
| 
      
 1268 
     | 
    
         
            +
                    static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
         
     | 
| 
      
 1269 
     | 
    
         
            +
                        return ( (VALUE(*)(#{cfunc_value_cast})) (#{cfunc_real_address_name}) )(self#{cfuncall1inprocargs});
         
     | 
| 
       1196 
1270 
     | 
    
         
             
                    }
         
     | 
| 
       1197 
1271 
     | 
    
         
             
                    "
         
     | 
| 
       1198 
1272 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -1201,18 +1275,15 @@ fastruby_local_next: 
     | 
|
| 
       1201 
1275 
     | 
    
         
             
                  strargs_signature = (0..25).map{|x| "VALUE arg#{x}"}.join(",")
         
     | 
| 
       1202 
1276 
     | 
    
         | 
| 
       1203 
1277 
     | 
    
         
             
                  cfunc_wrapper_1 = anonymous_function{ |funcname| "
         
     | 
| 
       1204 
     | 
    
         
            -
                    static VALUE #{funcname}(VALUE 
     | 
| 
       1205 
     | 
    
         
            -
                        VALUE  
     | 
| 
       1206 
     | 
    
         
            -
                        VALUE method_arguments[26] = {#{toprocstrargs}};
         
     | 
| 
       1207 
     | 
    
         
            -
                        return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(NUM2ULONG(params[1]),method_arguments,self);
         
     | 
| 
      
 1278 
     | 
    
         
            +
                    static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
         
     | 
| 
      
 1279 
     | 
    
         
            +
                        return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(argc,argv,self);
         
     | 
| 
       1208 
1280 
     | 
    
         
             
                    }
         
     | 
| 
       1209 
1281 
     | 
    
         
             
                    "
         
     | 
| 
       1210 
1282 
     | 
    
         
             
                  }
         
     | 
| 
       1211 
1283 
     | 
    
         | 
| 
       1212 
1284 
     | 
    
         
             
                  cfunc_wrapper_2 = anonymous_function{ |funcname| "
         
     | 
| 
       1213 
     | 
    
         
            -
                    static VALUE #{funcname}(VALUE 
     | 
| 
       1214 
     | 
    
         
            -
                        VALUE  
     | 
| 
       1215 
     | 
    
         
            -
                        VALUE args = rb_ary_new3(NUM2ULONG(params[1]),#{toprocstrargs});
         
     | 
| 
      
 1285 
     | 
    
         
            +
                    static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
         
     | 
| 
      
 1286 
     | 
    
         
            +
                        VALUE args = rb_ary_new3(argc, argv);
         
     | 
| 
       1216 
1287 
     | 
    
         
             
                        return ( (VALUE(*)(VALUE,VALUE)) (#{cfunc_real_address_name}) )(self,args);
         
     | 
| 
       1217 
1288 
     | 
    
         
             
                    }
         
     | 
| 
       1218 
1289 
     | 
    
         
             
                    "
         
     | 
| 
         @@ -34,11 +34,15 @@ module FastRuby 
     | 
|
| 
       34 
34 
     | 
    
         
             
                  @modls << modl  
         
     | 
| 
       35 
35 
     | 
    
         
             
                end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                def  
     | 
| 
      
 37 
     | 
    
         
            +
                def each_under(dir)
         
     | 
| 
       38 
38 
     | 
    
         
             
                  Dir.glob(dir + "/*.rb") do |x|
         
     | 
| 
       39 
     | 
    
         
            -
                     
     | 
| 
      
 39 
     | 
    
         
            +
                    yield x
         
     | 
| 
       40 
40 
     | 
    
         
             
                  end
         
     | 
| 
       41 
41 
     | 
    
         
             
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def load_under(dir)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  each_under(dir, &method(:require))
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
       42 
46 
     | 
    
         
             
              end
         
     | 
| 
       43 
47 
     | 
    
         
             
            end
         
     | 
| 
       44 
48 
     | 
    
         | 
    
        data/lib/fastruby.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "fastruby"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "fastruby/reductor/reductor"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "fastruby/sexp_extension"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "ruby_parser"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            describe FastRuby, "fastruby" do
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
              def self.test_normal_tree(code)
         
     | 
| 
      
 9 
     | 
    
         
            +
                unmodified_tree = FastRuby::FastRubySexp.from_sexp RubyParser.new.parse code
         
     | 
| 
      
 10 
     | 
    
         
            +
                it "tree for source #{code} should not be changed by reductor" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  obtained_tree = FastRuby::Reductor.new.reduce unmodified_tree
         
     | 
| 
      
 12 
     | 
    
         
            +
                  obtained_tree.should be == unmodified_tree
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
               
         
     | 
| 
      
 16 
     | 
    
         
            +
              it "should reduce for statements into each calls" do
         
     | 
| 
      
 17 
     | 
    
         
            +
               reductor = FastRuby::Reductor.new
         
     | 
| 
      
 18 
     | 
    
         
            +
               
         
     | 
| 
      
 19 
     | 
    
         
            +
               original_tree = fs(:for, fs(:call, nil, :b, fs(:arglist)), fs(:lasgn, :a), fs(:call, nil, :c, fs(:arglist)))
         
     | 
| 
      
 20 
     | 
    
         
            +
               expected_tree = fs(:iter, fs(:call, fs(:call, nil, :b, fs(:arglist)), :each, fs(:arglist)), fs(:lasgn, :a), fs(:call, nil, :c, fs(:arglist)))
         
     | 
| 
      
 21 
     | 
    
         
            +
               obtained_tree = reductor.reduce original_tree
         
     | 
| 
      
 22 
     | 
    
         
            +
               
         
     | 
| 
      
 23 
     | 
    
         
            +
               obtained_tree.should be == expected_tree
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
         
     | 
| 
      
 26 
     | 
    
         
            +
              test_normal_tree "a.foo(b)"
         
     | 
| 
      
 27 
     | 
    
         
            +
              test_normal_tree "if (x); y; else; z; end"
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
              it "should reduce call statements into if arrays" do
         
     | 
| 
      
 30 
     | 
    
         
            +
               reductor = FastRuby::Reductor.new
         
     | 
| 
      
 31 
     | 
    
         
            +
               
         
     | 
| 
      
 32 
     | 
    
         
            +
               original_tree = fs(:case, 
         
     | 
| 
      
 33 
     | 
    
         
            +
                  fs(:call, nil, :a, fs(:arglist)), 
         
     | 
| 
      
 34 
     | 
    
         
            +
                  fs(:when, fs(:array, fs(:call, nil, :b, fs(:arglist))), fs(:call, nil, :c, fs(:arglist))), 
         
     | 
| 
      
 35 
     | 
    
         
            +
                  nil)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
               obtained_tree = reductor.reduce original_tree
         
     | 
| 
      
 38 
     | 
    
         
            +
               
         
     | 
| 
      
 39 
     | 
    
         
            +
               obtained_tree.node_type.should be == :block
         
     | 
| 
      
 40 
     | 
    
         
            +
               obtained_tree[1].node_type.should be == :lasgn
         
     | 
| 
      
 41 
     | 
    
         
            +
               obtained_tree[1].last.should be == s(:call, nil, :a, s(:arglist)).to_fastruby_sexp
         
     | 
| 
      
 42 
     | 
    
         
            +
               obtained_tree[2].node_type.should be == :if
         
     | 
| 
      
 43 
     | 
    
         
            +
               obtained_tree[2][1].node_type.should be == :or
         
     | 
| 
      
 44 
     | 
    
         
            +
               obtained_tree[2][2].should be == original_tree.find_tree(:when).last
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     |