fastruby 0.0.16 → 0.0.17
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 +17 -1
 - data/Rakefile +1 -1
 - data/ext/fastruby_base/fastruby_base.inl +81 -3
 - data/lib/fastruby/fastruby_sexp.rb +21 -0
 - data/lib/fastruby/getlocals.rb +2 -1
 - data/lib/fastruby/object.rb +1 -1
 - data/lib/fastruby/sexp_extension.rb +189 -0
 - data/lib/fastruby/sexp_extension_edges.rb +210 -0
 - data/lib/fastruby/translator/modules/block.rb +29 -22
 - data/lib/fastruby/translator/modules/call.rb +211 -34
 - data/lib/fastruby/translator/modules/defn.rb +64 -29
 - data/lib/fastruby/translator/modules/exceptions.rb +1 -1
 - data/lib/fastruby/translator/modules/flow.rb +93 -31
 - data/lib/fastruby/translator/modules/iter.rb +277 -340
 - data/lib/fastruby/translator/modules/literal.rb +97 -20
 - data/lib/fastruby/translator/modules/logical.rb +40 -5
 - data/lib/fastruby/translator/modules/method_group.rb +41 -19
 - data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
 - data/lib/fastruby/translator/modules/variable.rb +151 -42
 - data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
 - data/lib/fastruby/translator/translator.rb +389 -302
 - data/lib/fastruby.rb +1 -1
 - data/lib/fastruby.rb~ +36 -0
 - data/spec/edges_helper.rb +91 -0
 - data/spec/graph/base_spec.rb +35 -0
 - data/spec/graph/path_spec.rb +48 -0
 - data/spec/graph/vertex_spec.rb +58 -0
 - data/spec/ruby/block/proc_as_block_spec.rb +214 -0
 - data/spec/ruby/block/redo_spec.rb +133 -0
 - data/spec/ruby/defn/single_function_spec.rb +50 -0
 - data/spec/scope_mode/base_spec.rb +55 -0
 - data/spec/scope_mode/block_spec.rb +105 -0
 - data/spec/scope_mode/call_spec.rb +24 -0
 - data/spec/scope_mode/exception_spec.rb +34 -0
 - data/spec/scope_mode/flow_spec.rb +99 -0
 - data/spec/scope_mode/optimization_spec.rb +130 -0
 - data/spec/sexp2graph/base_spec.rb +36 -0
 - data/spec/sexp2graph/exception_spec.rb +172 -0
 - data/spec/sexp2graph/flow_spec.rb +67 -0
 - data/spec/sexp2graph/logical_spec.rb +21 -0
 - data/spec/sexp2graph/variable_spec.rb +26 -0
 - metadata +110 -120
 - data/lib/fastruby/self +0 -82
 - data/lib/len +0 -280
 - data/spec/block/proc_as_block_spec.rb +0 -111
 - data/spec/block/redo_spec.rb +0 -67
 - /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
 - /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/break_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/next_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
 - /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
 - /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
 - /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
 - /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
 - /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
 - /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
 - /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
 - /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
 - /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
 - /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
 - /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
 - /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
 - /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
 - /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
 - /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
 - /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
 - /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
 - /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
 - /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
 - /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
 - /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
 - /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
 - /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
 - /data/spec/{variable_spec.rb → ruby/variable_spec.rb} +0 -0
 
| 
         @@ -33,10 +33,10 @@ module FastRuby 
     | 
|
| 
       33 
33 
     | 
    
         
             
                      pframe = (void*)frame_param;
         
     | 
| 
       34 
34 
     | 
    
         
             
                      plocals = (void*)pframe->plocals;
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                      if ( 
     | 
| 
      
 36 
     | 
    
         
            +
                      if ((plocals->block_function_address) == 0) {
         
     | 
| 
       37 
37 
     | 
    
         
             
                        #{_raise("rb_eLocalJumpError", "no block given")};
         
     | 
| 
       38 
38 
     | 
    
         
             
                      } else {
         
     | 
| 
       39 
     | 
    
         
            -
                        return ((VALUE(*)(int,VALUE*,VALUE,VALUE)) 
     | 
| 
      
 39 
     | 
    
         
            +
                        return ((VALUE(*)(int,VALUE*,VALUE,VALUE))(plocals->block_function_address))(size, block_args, (VALUE)(plocals->block_function_param), (VALUE)pframe);
         
     | 
| 
       40 
40 
     | 
    
         
             
                      }
         
     | 
| 
       41 
41 
     | 
    
         
             
                    }
         
     | 
| 
       42 
42 
     | 
    
         
             
                  "
         
     | 
| 
         @@ -45,15 +45,20 @@ module FastRuby 
     | 
|
| 
       45 
45 
     | 
    
         
             
                  splat_arg = tree.find{|x| x == :yield ? false : x[0] == :splat}
         
     | 
| 
       46 
46 
     | 
    
         
             
                  ret = nil      
         
     | 
| 
       47 
47 
     | 
    
         
             
                  if splat_arg
         
     | 
| 
       48 
     | 
    
         
            -
                    ret =  
     | 
| 
       49 
     | 
    
         
            -
                      VALUE splat_array =  
     | 
| 
      
 48 
     | 
    
         
            +
                    ret = "
         
     | 
| 
      
 49 
     | 
    
         
            +
                      VALUE splat_array = Qnil;
         
     | 
| 
      
 50 
     | 
    
         
            +
                      VALUE block_aux = Qnil;
         
     | 
| 
      
 51 
     | 
    
         
            +
                       #{to_c(splat_arg[1], "splat_array")};
         
     | 
| 
       50 
52 
     | 
    
         | 
| 
       51 
53 
     | 
    
         
             
                      if (CLASS_OF(splat_array) == rb_cArray) {
         
     | 
| 
       52 
54 
     | 
    
         
             
                        VALUE block_args[_RARRAY_LEN(splat_array) + #{tree.size}];
         
     | 
| 
       53 
55 
     | 
    
         
             
                        int i;
         
     | 
| 
       54 
56 
     | 
    
         
             
                        #{ 
         
     | 
| 
       55 
57 
     | 
    
         
             
                          (0..tree.size-3).map{|i|
         
     | 
| 
       56 
     | 
    
         
            -
                            " 
     | 
| 
      
 58 
     | 
    
         
            +
                            "
         
     | 
| 
      
 59 
     | 
    
         
            +
                            #{to_c(tree[i+1], "block_aux")};
         
     | 
| 
      
 60 
     | 
    
         
            +
                            block_args[#{i}] = block_aux;
         
     | 
| 
      
 61 
     | 
    
         
            +
                            "
         
     | 
| 
       57 
62 
     | 
    
         
             
                          }.join(";\n")
         
     | 
| 
       58 
63 
     | 
    
         
             
                        };
         
     | 
| 
       59 
64 
     | 
    
         | 
| 
         @@ -61,53 +66,55 @@ module FastRuby 
     | 
|
| 
       61 
66 
     | 
    
         
             
                          block_args[i+#{tree.size-2}] = rb_ary_entry(splat_array,i);
         
     | 
| 
       62 
67 
     | 
    
         
             
                        }
         
     | 
| 
       63 
68 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                         
     | 
| 
      
 69 
     | 
    
         
            +
                        last_expression = #{anonymous_function(&block_code)}((VALUE)pframe, block_args, _RARRAY_LEN(splat_array) + #{tree.size-2});
         
     | 
| 
       65 
70 
     | 
    
         
             
                      } else {
         
     | 
| 
       66 
71 
     | 
    
         
             
                        VALUE block_args[1+#{tree.size}];
         
     | 
| 
       67 
72 
     | 
    
         
             
                        #{ 
         
     | 
| 
       68 
73 
     | 
    
         
             
                          (0..tree.size-3).map{|i|
         
     | 
| 
       69 
     | 
    
         
            -
                            " 
     | 
| 
      
 74 
     | 
    
         
            +
                            "
         
     | 
| 
      
 75 
     | 
    
         
            +
                            #{to_c(tree[i+1], "block_aux")};
         
     | 
| 
      
 76 
     | 
    
         
            +
                            block_args[#{i}] = block_aux;
         
     | 
| 
      
 77 
     | 
    
         
            +
                            "
         
     | 
| 
       70 
78 
     | 
    
         
             
                          }.join(";\n")
         
     | 
| 
       71 
79 
     | 
    
         
             
                        };
         
     | 
| 
       72 
80 
     | 
    
         | 
| 
       73 
81 
     | 
    
         
             
                        block_args[#{tree.size-2}] = splat_array;
         
     | 
| 
       74 
     | 
    
         
            -
                         
     | 
| 
      
 82 
     | 
    
         
            +
                        last_expression = #{anonymous_function(&block_code)}((VALUE)pframe, block_args, #{tree.size-1});
         
     | 
| 
       75 
83 
     | 
    
         
             
                      }
         
     | 
| 
       76 
84 
     | 
    
         | 
| 
       77 
85 
     | 
    
         
             
                    "
         
     | 
| 
       78 
86 
     | 
    
         
             
                  else
         
     | 
| 
       79 
87 
     | 
    
         
             
                    ret = if tree.size > 1
         
     | 
| 
       80 
     | 
    
         
            -
                        anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){#{tree[1..-1].map{|subtree| to_c subtree}.join(",")}},#{tree.size-1})"
         
     | 
| 
      
 88 
     | 
    
         
            +
                        "last_expression = " + anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){#{tree[1..-1].map{|subtree| to_c subtree}.join(",")}},#{tree.size-1})"
         
     | 
| 
       81 
89 
     | 
    
         
             
                      else
         
     | 
| 
       82 
     | 
    
         
            -
                        anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){}, #{tree.size-1})"
         
     | 
| 
      
 90 
     | 
    
         
            +
                        "last_expression = " + anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){}, #{tree.size-1})"
         
     | 
| 
       83 
91 
     | 
    
         
             
                      end
         
     | 
| 
       84 
92 
     | 
    
         
             
                  end
         
     | 
| 
       85 
93 
     | 
    
         | 
| 
       86 
94 
     | 
    
         
             
                  protected_block(ret, false)
         
     | 
| 
       87 
95 
     | 
    
         
             
                end
         
     | 
| 
       88 
96 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                def to_c_block(tree)
         
     | 
| 
      
 97 
     | 
    
         
            +
                def to_c_block(tree, result_variable = nil)
         
     | 
| 
       90 
98 
     | 
    
         
             
                  if tree.size == 1
         
     | 
| 
       91 
99 
     | 
    
         
             
                    return inline_block("return Qnil;")
         
     | 
| 
       92 
100 
     | 
    
         
             
                  end
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
      
 101 
     | 
    
         
            +
                  
         
     | 
| 
       94 
102 
     | 
    
         
             
                  str = ""
         
     | 
| 
       95 
103 
     | 
    
         
             
                  str = tree[1..-2].map{ |subtree|
         
     | 
| 
       96 
     | 
    
         
            -
                    to_c(subtree)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    to_c(subtree,"last_expression")
         
     | 
| 
       97 
105 
     | 
    
         
             
                  }.join(";")
         
     | 
| 
       98 
106 
     | 
    
         | 
| 
       99 
107 
     | 
    
         
             
                  if tree[-1]
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                    if tree[-1][0] != :return
         
     | 
| 
       102 
     | 
    
         
            -
                      str = str + ";last_expression = #{to_c(tree[-1])};"
         
     | 
| 
       103 
     | 
    
         
            -
                    else
         
     | 
| 
       104 
     | 
    
         
            -
                      str = str + ";#{to_c(tree[-1])};"
         
     | 
| 
       105 
     | 
    
         
            -
                    end
         
     | 
| 
      
 108 
     | 
    
         
            +
                      str = str + ";#{to_c(tree[-1],"last_expression")};"
         
     | 
| 
       106 
109 
     | 
    
         
             
                  end
         
     | 
| 
       107 
110 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
                   
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
      
 111 
     | 
    
         
            +
                  if result_variable
         
     | 
| 
      
 112 
     | 
    
         
            +
                    str << "#{result_variable} = last_expression;"
         
     | 
| 
      
 113 
     | 
    
         
            +
                    str
         
     | 
| 
      
 114 
     | 
    
         
            +
                  else
         
     | 
| 
      
 115 
     | 
    
         
            +
                    str << "return last_expression;"
         
     | 
| 
      
 116 
     | 
    
         
            +
                    inline_block str
         
     | 
| 
      
 117 
     | 
    
         
            +
                  end
         
     | 
| 
       111 
118 
     | 
    
         
             
                end
         
     | 
| 
       112 
119 
     | 
    
         | 
| 
       113 
120 
     | 
    
         
             
              end
         
     | 
| 
         @@ -23,12 +23,18 @@ module FastRuby 
     | 
|
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
                register_translator_module self
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                def to_c_call(tree,  
     | 
| 
      
 26 
     | 
    
         
            +
                def to_c_call(tree, result_var = nil)
         
     | 
| 
       27 
27 
     | 
    
         
             
                  directive_code = directive(tree)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  repass_var = @repass_var
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       28 
30 
     | 
    
         
             
                  if directive_code
         
     | 
| 
       29 
     | 
    
         
            -
                     
     | 
| 
      
 31 
     | 
    
         
            +
                    if result_var
         
     | 
| 
      
 32 
     | 
    
         
            +
                      return "#{result_var} = #{directive_code};\n"
         
     | 
| 
      
 33 
     | 
    
         
            +
                    else
         
     | 
| 
      
 34 
     | 
    
         
            +
                      return directive_code
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
       30 
36 
     | 
    
         
             
                  end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                  
         
     | 
| 
       32 
38 
     | 
    
         
             
                  if tree[2] == :require
         
     | 
| 
       33 
39 
     | 
    
         
             
                    tree[2] = :fastruby_require
         
     | 
| 
       34 
40 
     | 
    
         
             
                  elsif tree[2] == :raise
         
     | 
| 
         @@ -36,10 +42,11 @@ module FastRuby 
     | 
|
| 
       36 
42 
     | 
    
         
             
                    args = tree[3]
         
     | 
| 
       37 
43 
     | 
    
         
             
                    return _raise(args[1],args[2])
         
     | 
| 
       38 
44 
     | 
    
         
             
                  end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       40 
46 
     | 
    
         
             
                  recv = tree[1]
         
     | 
| 
       41 
47 
     | 
    
         
             
                  mname = tree[2]
         
     | 
| 
       42 
48 
     | 
    
         
             
                  args = tree[3]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  args_tree = tree[3]
         
     | 
| 
       43 
50 
     | 
    
         | 
| 
       44 
51 
     | 
    
         
             
                  # search block_pass on arguments
         
     | 
| 
       45 
52 
     | 
    
         
             
                  block_pass_arg = args.find{|arg| if arg == :arglist
         
     | 
| 
         @@ -47,24 +54,18 @@ module FastRuby 
     | 
|
| 
       47 
54 
     | 
    
         
             
                      else
         
     | 
| 
       48 
55 
     | 
    
         
             
                      arg[0] == :block_pass
         
     | 
| 
       49 
56 
     | 
    
         
             
                        end} 
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       50 
58 
     | 
    
         
             
                  if block_pass_arg
         
     | 
| 
       51 
     | 
    
         
            -
                    
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                    
         
     | 
| 
       60 
     | 
    
         
            -
                    block_arguments_tree = s(:masgn, s(:array, s(:splat, s(:lasgn, :__xblock_arguments))))
         
     | 
| 
       61 
     | 
    
         
            -
                    block_tree = s(:call, block_pass_arg[1], :call, s(:arglist, s(:splat, s(:lvar, :__xblock_arguments))))
         
     | 
| 
       62 
     | 
    
         
            -
                    
         
     | 
| 
       63 
     | 
    
         
            -
                    replace_iter_tree = s(:iter, call_tree, block_arguments_tree, block_tree).to_fastruby_sexp
         
     | 
| 
       64 
     | 
    
         
            -
                    
         
     | 
| 
       65 
     | 
    
         
            -
                    return to_c(replace_iter_tree)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    args_tree = args_tree.dup.reject{|st| 
         
     | 
| 
      
 60 
     | 
    
         
            +
                      if st.respond_to? :node_type
         
     | 
| 
      
 61 
     | 
    
         
            +
                        st.node_type == :block_pass
         
     | 
| 
      
 62 
     | 
    
         
            +
                      else 
         
     | 
| 
      
 63 
     | 
    
         
            +
                        false
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                     }
         
     | 
| 
      
 66 
     | 
    
         
            +
                    args = args_tree
         
     | 
| 
       66 
67 
     | 
    
         
             
                  end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 68 
     | 
    
         
            +
             
         
     | 
| 
       68 
69 
     | 
    
         
             
                  mname = :require_fastruby if mname == :require
         
     | 
| 
       69 
70 
     | 
    
         | 
| 
       70 
71 
     | 
    
         
             
                  argnum = args.size - 1
         
     | 
| 
         @@ -74,12 +75,40 @@ module FastRuby 
     | 
|
| 
       74 
75 
     | 
    
         
             
                  recvtype = infer_type(recv)
         
     | 
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
                  if args.size > 1
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if (not recvtype) or args.last[0] == :splat
         
     | 
| 
      
 79 
     | 
    
         
            +
                      if block_pass_arg
         
     | 
| 
      
 80 
     | 
    
         
            +
                        call_tree = tree.dup
         
     | 
| 
      
 81 
     | 
    
         
            +
                        call_tree[3] = args.select{|arg| if arg == :arglist 
         
     | 
| 
      
 82 
     | 
    
         
            +
                            true
         
     | 
| 
      
 83 
     | 
    
         
            +
                            else
         
     | 
| 
      
 84 
     | 
    
         
            +
                              arg[0] != :block_pass
         
     | 
| 
      
 85 
     | 
    
         
            +
                              end
         
     | 
| 
      
 86 
     | 
    
         
            +
                              }
         
     | 
| 
      
 87 
     | 
    
         
            +
                        
         
     | 
| 
      
 88 
     | 
    
         
            +
                        block_arguments_tree = s(:masgn, s(:array, s(:splat, s(:lasgn, :__xblock_arguments))))
         
     | 
| 
      
 89 
     | 
    
         
            +
                        block_tree = s(:call, s(:lvar, :__x_proc), :call, s(:arglist, s(:splat, s(:lvar, :__xblock_arguments))))
         
     | 
| 
      
 90 
     | 
    
         
            +
                        
         
     | 
| 
      
 91 
     | 
    
         
            +
                        replace_iter_tree = s(:block,
         
     | 
| 
      
 92 
     | 
    
         
            +
                            s(:lasgn, :__x_proc, s(:call, block_pass_arg[1], :to_proc, s(:arglist))),
         
     | 
| 
      
 93 
     | 
    
         
            +
                            s(:iter, call_tree, block_arguments_tree, block_tree)
         
     | 
| 
      
 94 
     | 
    
         
            +
                            ).to_fastruby_sexp
         
     | 
| 
      
 95 
     | 
    
         
            +
                      
         
     | 
| 
      
 96 
     | 
    
         
            +
                        if result_var  
         
     | 
| 
      
 97 
     | 
    
         
            +
                          return to_c(replace_iter_tree,result_var)
         
     | 
| 
      
 98 
     | 
    
         
            +
                        else
         
     | 
| 
      
 99 
     | 
    
         
            +
                          return to_c(replace_iter_tree)
         
     | 
| 
      
 100 
     | 
    
         
            +
                        end
         
     | 
| 
      
 101 
     | 
    
         
            +
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       77 
104 
     | 
    
         
             
                    if args.last[0] == :splat
         
     | 
| 
       78 
     | 
    
         
            -
                       
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
      
 105 
     | 
    
         
            +
                      aux_varname = "_aux_" + rand(1000000).to_s
         
     | 
| 
      
 106 
     | 
    
         
            +
                      code = protected_block(
         
     | 
| 
       80 
107 
     | 
    
         
             
                        "
         
     | 
| 
       81 
108 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                        VALUE array =  
     | 
| 
      
 109 
     | 
    
         
            +
                        VALUE array = Qnil;
         
     | 
| 
      
 110 
     | 
    
         
            +
                        
         
     | 
| 
      
 111 
     | 
    
         
            +
                        #{to_c args.last[1], "array"};
         
     | 
| 
       83 
112 
     | 
    
         | 
| 
       84 
113 
     | 
    
         
             
                        if (TYPE(array) != T_ARRAY) {
         
     | 
| 
       85 
114 
     | 
    
         
             
                          array = rb_ary_new4(1,&array);
         
     | 
| 
         @@ -87,15 +116,21 @@ module FastRuby 
     | 
|
| 
       87 
116 
     | 
    
         | 
| 
       88 
117 
     | 
    
         
             
                        int argc = #{args.size-2};
         
     | 
| 
       89 
118 
     | 
    
         
             
                        VALUE argv[#{args.size} + _RARRAY_LEN(array)];
         
     | 
| 
       90 
     | 
    
         
            -
                        
         
     | 
| 
      
 119 
     | 
    
         
            +
                        VALUE #{aux_varname} = Qnil;
         
     | 
| 
       91 
120 
     | 
    
         
             
                        #{
         
     | 
| 
       92 
121 
     | 
    
         
             
                          i = -1
         
     | 
| 
       93 
122 
     | 
    
         
             
                          args[1..-2].map {|arg|
         
     | 
| 
       94 
123 
     | 
    
         
             
                            i = i + 1
         
     | 
| 
       95 
     | 
    
         
            -
                            " 
     | 
| 
      
 124 
     | 
    
         
            +
                            "#{to_c arg, aux_varname};
         
     | 
| 
      
 125 
     | 
    
         
            +
                            argv[#{i}] = #{aux_varname};
         
     | 
| 
      
 126 
     | 
    
         
            +
                            "
         
     | 
| 
       96 
127 
     | 
    
         
             
                          }.join(";\n")
         
     | 
| 
       97 
128 
     | 
    
         
             
                        };
         
     | 
| 
       98 
129 
     | 
    
         | 
| 
      
 130 
     | 
    
         
            +
                        VALUE recv = Qnil;
         
     | 
| 
      
 131 
     | 
    
         
            +
                        
         
     | 
| 
      
 132 
     | 
    
         
            +
                        #{to_c recv, "recv"};
         
     | 
| 
      
 133 
     | 
    
         
            +
                        
         
     | 
| 
       99 
134 
     | 
    
         
             
                        int array_len = _RARRAY_LEN(array);
         
     | 
| 
       100 
135 
     | 
    
         | 
| 
       101 
136 
     | 
    
         
             
                        int i;
         
     | 
| 
         @@ -104,14 +139,17 @@ module FastRuby 
     | 
|
| 
       104 
139 
     | 
    
         
             
                          argc++; 
         
     | 
| 
       105 
140 
     | 
    
         
             
                        }
         
     | 
| 
       106 
141 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
                         
     | 
| 
       108 
     | 
    
         
            -
                        "
         
     | 
| 
       109 
     | 
    
         
            -
                         
     | 
| 
      
 142 
     | 
    
         
            +
                        last_expression = rb_funcall2(recv, #{intern_num tree[2]}, argc, argv);
         
     | 
| 
      
 143 
     | 
    
         
            +
                        ", true, repass_var)
         
     | 
| 
      
 144 
     | 
    
         
            +
                        
         
     | 
| 
      
 145 
     | 
    
         
            +
                      if result_var
         
     | 
| 
      
 146 
     | 
    
         
            +
                       return "#{result_var} = #{code};\n"
         
     | 
| 
      
 147 
     | 
    
         
            +
                      else
         
     | 
| 
      
 148 
     | 
    
         
            +
                       return code
         
     | 
| 
      
 149 
     | 
    
         
            +
                      end
         
     | 
| 
       110 
150 
     | 
    
         
             
                    end
         
     | 
| 
       111 
151 
     | 
    
         
             
                  end
         
     | 
| 
       112 
152 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                  strargs = args[1..-1].map{|arg| to_c arg}.join(",")
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
153 
     | 
    
         
             
                  if recvtype
         
     | 
| 
       116 
154 
     | 
    
         | 
| 
       117 
155 
     | 
    
         
             
                    address = nil
         
     | 
| 
         @@ -136,19 +174,158 @@ module FastRuby 
     | 
|
| 
       136 
174 
     | 
    
         
             
                      extraargs_signature = ""
         
     | 
| 
       137 
175 
     | 
    
         
             
                    end
         
     | 
| 
       138 
176 
     | 
    
         | 
| 
      
 177 
     | 
    
         
            +
                      block_proc_tree = s(:call, block_pass_arg[1], :to_proc, s(:arglist)) if block_pass_arg
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                      block_wrapping_proc = proc { |name| "
         
     | 
| 
      
 180 
     | 
    
         
            +
                        static VALUE #{name}(int argc, VALUE* argv, VALUE _locals, VALUE _parent_frame) {
         
     | 
| 
      
 181 
     | 
    
         
            +
                          return rb_proc_call(_locals, rb_ary_new4(argc, argv)); 
         
     | 
| 
      
 182 
     | 
    
         
            +
                        }
         
     | 
| 
      
 183 
     | 
    
         
            +
                      "
         
     | 
| 
      
 184 
     | 
    
         
            +
                      }
         
     | 
| 
      
 185 
     | 
    
         
            +
             
         
     | 
| 
       139 
186 
     | 
    
         
             
                      if argnum == 0
         
     | 
| 
       140 
187 
     | 
    
         
             
                        value_cast = "VALUE,VALUE,VALUE"
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                          if block_pass_arg or result_var
         
     | 
| 
      
 191 
     | 
    
         
            +
                            code = "
         
     | 
| 
      
 192 
     | 
    
         
            +
                            {
         
     | 
| 
      
 193 
     | 
    
         
            +
                            VALUE recv = Qnil;
         
     | 
| 
      
 194 
     | 
    
         
            +
                            #{to_c recv, "recv"};
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                            #{@block_struct} block, *pblock = Qfalse;
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                            #{if block_pass_arg
         
     | 
| 
      
 199 
     | 
    
         
            +
                            "
         
     | 
| 
      
 200 
     | 
    
         
            +
                            VALUE proc = Qnil;
         
     | 
| 
      
 201 
     | 
    
         
            +
                            #{to_c(block_proc_tree, "proc") }
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                            VALUE block_address_value = rb_ivar_get(proc, #{intern_num "__block_address"});
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                            if (block_address_value != Qnil) {
         
     | 
| 
      
 206 
     | 
    
         
            +
                              block.block_function_address = NUM2PTR(block_address_value);
         
     | 
| 
      
 207 
     | 
    
         
            +
                              block.block_function_param = NUM2PTR(rb_ivar_get(proc, #{intern_num "__block_param"}));
         
     | 
| 
      
 208 
     | 
    
         
            +
                              block.proc = proc;
         
     | 
| 
      
 209 
     | 
    
         
            +
                              pblock = █
         
     | 
| 
      
 210 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 211 
     | 
    
         
            +
                              // create a block from a proc
         
     | 
| 
      
 212 
     | 
    
         
            +
                              block.block_function_address = ((void*)#{anonymous_function(&block_wrapping_proc)});
         
     | 
| 
      
 213 
     | 
    
         
            +
                              block.block_function_param = (void*)proc;
         
     | 
| 
      
 214 
     | 
    
         
            +
                              block.proc = proc;
         
     | 
| 
      
 215 
     | 
    
         
            +
                              pblock = █
         
     | 
| 
      
 216 
     | 
    
         
            +
                            }
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                            "
         
     | 
| 
      
 219 
     | 
    
         
            +
                            end
         
     | 
| 
      
 220 
     | 
    
         
            +
                            }
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
                            #{if result_var
         
     | 
| 
      
 223 
     | 
    
         
            +
                            "
         
     | 
| 
      
 224 
     | 
    
         
            +
                            #{result_var} = ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe);
         
     | 
| 
      
 225 
     | 
    
         
            +
                            "
         
     | 
| 
      
 226 
     | 
    
         
            +
                            else
         
     | 
| 
      
 227 
     | 
    
         
            +
                            "
         
     | 
| 
      
 228 
     | 
    
         
            +
                            ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe);
         
     | 
| 
      
 229 
     | 
    
         
            +
                            "
         
     | 
| 
      
 230 
     | 
    
         
            +
                            end
         
     | 
| 
      
 231 
     | 
    
         
            +
                            }
         
     | 
| 
      
 232 
     | 
    
         
            +
                            }
         
     | 
| 
      
 233 
     | 
    
         
            +
                            "
         
     | 
| 
      
 234 
     | 
    
         
            +
                          
         
     | 
| 
      
 235 
     | 
    
         
            +
                            result_var ? code : inline_block(code)
         
     | 
| 
      
 236 
     | 
    
         
            +
                          else
         
     | 
| 
      
 237 
     | 
    
         
            +
                             "((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(#{to_c recv}, Qfalse, (VALUE)pframe)"               
         
     | 
| 
      
 238 
     | 
    
         
            +
                          end          
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
       142 
240 
     | 
    
         
             
                      else
         
     | 
| 
       143 
241 
     | 
    
         
             
                        value_cast = ( ["VALUE"]*(args.size) ).join(",") + ",VALUE,VALUE"
         
     | 
| 
       144 
     | 
    
         
            -
                        " 
     | 
| 
      
 242 
     | 
    
         
            +
                        suffix = "_" + rand(1000000).to_s+"_"
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                            strargs = (0..args_tree.size-2).map{|i| "#{suffix}arg#{i}"}.join(",")
         
     | 
| 
      
 245 
     | 
    
         
            +
                          if block_pass_arg or result_var
         
     | 
| 
      
 246 
     | 
    
         
            +
                            code = "
         
     | 
| 
      
 247 
     | 
    
         
            +
                            {
         
     | 
| 
      
 248 
     | 
    
         
            +
                            VALUE recv = Qnil;
         
     | 
| 
      
 249 
     | 
    
         
            +
                            
         
     | 
| 
      
 250 
     | 
    
         
            +
                            #{
         
     | 
| 
      
 251 
     | 
    
         
            +
                            (0..args_tree.size-2).map{ |x|
         
     | 
| 
      
 252 
     | 
    
         
            +
                              "VALUE #{suffix}arg#{x};"
         
     | 
| 
      
 253 
     | 
    
         
            +
                            }.join("\n")
         
     | 
| 
      
 254 
     | 
    
         
            +
                            }
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                            #{
         
     | 
| 
      
 257 
     | 
    
         
            +
                            (0..args_tree.size-2).map{ |x|
         
     | 
| 
      
 258 
     | 
    
         
            +
                              to_c(args_tree[x+1], "#{suffix}arg#{x}") + ";"
         
     | 
| 
      
 259 
     | 
    
         
            +
                            }.join("\n")
         
     | 
| 
      
 260 
     | 
    
         
            +
                            }
         
     | 
| 
      
 261 
     | 
    
         
            +
                            
         
     | 
| 
      
 262 
     | 
    
         
            +
                            #{to_c recv, "recv"};
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                            #{@block_struct} block, *pblock = Qfalse;
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
                            #{if block_pass_arg
         
     | 
| 
      
 267 
     | 
    
         
            +
                            "
         
     | 
| 
      
 268 
     | 
    
         
            +
                            VALUE proc = Qnil;
         
     | 
| 
      
 269 
     | 
    
         
            +
                            #{to_c(block_proc_tree, "proc") }
         
     | 
| 
      
 270 
     | 
    
         
            +
                            VALUE block_address_value = rb_ivar_get(proc, #{intern_num "__block_address"});
         
     | 
| 
      
 271 
     | 
    
         
            +
                            if (block_address_value != Qnil) {
         
     | 
| 
      
 272 
     | 
    
         
            +
                              block.block_function_address = NUM2PTR(block_address_value);
         
     | 
| 
      
 273 
     | 
    
         
            +
                              block.block_function_param = NUM2PTR(rb_ivar_get(proc, #{intern_num "__block_param"}));
         
     | 
| 
      
 274 
     | 
    
         
            +
                              block.proc = proc;
         
     | 
| 
      
 275 
     | 
    
         
            +
                              pblock = █
         
     | 
| 
      
 276 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 277 
     | 
    
         
            +
                              // create a block from a proc
         
     | 
| 
      
 278 
     | 
    
         
            +
                              block.block_function_address = ((void*)#{anonymous_function(&block_wrapping_proc)});
         
     | 
| 
      
 279 
     | 
    
         
            +
                              block.block_function_param = (void*)proc;
         
     | 
| 
      
 280 
     | 
    
         
            +
                              block.proc = proc;
         
     | 
| 
      
 281 
     | 
    
         
            +
                              pblock = █
         
     | 
| 
      
 282 
     | 
    
         
            +
                            }
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
      
 284 
     | 
    
         
            +
                            "
         
     | 
| 
      
 285 
     | 
    
         
            +
                            end
         
     | 
| 
      
 286 
     | 
    
         
            +
                            }
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                            #{if result_var
         
     | 
| 
      
 289 
     | 
    
         
            +
                            "
         
     | 
| 
      
 290 
     | 
    
         
            +
                            #{result_var} = ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, #{strargs});
         
     | 
| 
      
 291 
     | 
    
         
            +
                            "
         
     | 
| 
      
 292 
     | 
    
         
            +
                            else
         
     | 
| 
      
 293 
     | 
    
         
            +
                            "
         
     | 
| 
      
 294 
     | 
    
         
            +
                            ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, #{strargs});
         
     | 
| 
      
 295 
     | 
    
         
            +
                            "
         
     | 
| 
      
 296 
     | 
    
         
            +
                            end
         
     | 
| 
      
 297 
     | 
    
         
            +
                            }
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
                            
         
     | 
| 
      
 300 
     | 
    
         
            +
                            }
         
     | 
| 
      
 301 
     | 
    
         
            +
                            "
         
     | 
| 
      
 302 
     | 
    
         
            +
                            result_var ? code : inline_block(code)
         
     | 
| 
      
 303 
     | 
    
         
            +
                          else
         
     | 
| 
      
 304 
     | 
    
         
            +
                            strargs = args[1..-1].map{|arg| to_c arg}.join(",")
         
     | 
| 
      
 305 
     | 
    
         
            +
                            "((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(#{to_c recv}, Qfalse, (VALUE)pframe, #{strargs})"
         
     | 
| 
      
 306 
     | 
    
         
            +
                          end
         
     | 
| 
       145 
307 
     | 
    
         
             
                      end
         
     | 
| 
       146 
308 
     | 
    
         | 
| 
       147 
309 
     | 
    
         
             
                  else # else recvtype
         
     | 
| 
       148 
310 
     | 
    
         
             
                    if argnum == 0
         
     | 
| 
       149 
     | 
    
         
            -
                      protected_block("rb_funcall(#{to_c recv}, #{intern_num tree[2]}, 0)", true, repass_var)
         
     | 
| 
      
 311 
     | 
    
         
            +
                      code = protected_block("last_expression = rb_funcall(#{to_c recv}, #{intern_num tree[2]}, 0)", true, repass_var)
         
     | 
| 
      
 312 
     | 
    
         
            +
                      if result_var
         
     | 
| 
      
 313 
     | 
    
         
            +
                      "
         
     | 
| 
      
 314 
     | 
    
         
            +
                        #{result_var} = #{code};
         
     | 
| 
      
 315 
     | 
    
         
            +
                      "
         
     | 
| 
      
 316 
     | 
    
         
            +
                      else
         
     | 
| 
      
 317 
     | 
    
         
            +
                        code
         
     | 
| 
      
 318 
     | 
    
         
            +
                      end
         
     | 
| 
       150 
319 
     | 
    
         
             
                    else
         
     | 
| 
       151 
     | 
    
         
            -
                       
     | 
| 
      
 320 
     | 
    
         
            +
                      strargs = args[1..-1].map{|arg| to_c arg}.join(",")
         
     | 
| 
      
 321 
     | 
    
         
            +
                      code = protected_block("last_expression = rb_funcall(#{to_c recv}, #{intern_num tree[2]}, #{argnum}, #{strargs} )", true, repass_var)
         
     | 
| 
      
 322 
     | 
    
         
            +
                      if result_var
         
     | 
| 
      
 323 
     | 
    
         
            +
                      "
         
     | 
| 
      
 324 
     | 
    
         
            +
                        #{result_var} = #{code};
         
     | 
| 
      
 325 
     | 
    
         
            +
                      "
         
     | 
| 
      
 326 
     | 
    
         
            +
                      else
         
     | 
| 
      
 327 
     | 
    
         
            +
                        code
         
     | 
| 
      
 328 
     | 
    
         
            +
                      end
         
     | 
| 
       152 
329 
     | 
    
         
             
                    end
         
     | 
| 
       153 
330 
     | 
    
         
             
                  end # if recvtype
         
     | 
| 
       154 
331 
     | 
    
         
             
                end
         
     | 
| 
         @@ -22,7 +22,7 @@ module FastRuby 
     | 
|
| 
       22 
22 
     | 
    
         
             
              module DefnTranslator
         
     | 
| 
       23 
23 
     | 
    
         
             
                register_translator_module self
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                def to_c_defn(tree)
         
     | 
| 
      
 25 
     | 
    
         
            +
                def to_c_defn(tree, result_var = nil)
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                  method_name = tree[1]
         
     | 
| 
       28 
28 
     | 
    
         
             
                  args_tree = tree[2].select{|x| x.to_s[0] != ?&}
         
     | 
| 
         @@ -40,27 +40,49 @@ module FastRuby 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  alt_options.delete(:self)
         
     | 
| 
       41 
41 
     | 
    
         
             
                  alt_options.delete(:main)
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
      
 43 
     | 
    
         
            +
                  code = "
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
      
 45 
     | 
    
         
            +
                  
         
     | 
| 
      
 46 
     | 
    
         
            +
                    if (rb_obj_is_kind_of(plocals->self, rb_cClass) || rb_obj_is_kind_of(plocals->self, rb_cModule)) {
         
     | 
| 
      
 47 
     | 
    
         
            +
                      rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);
         
     | 
| 
      
 48 
     | 
    
         
            +
                      
         
     | 
| 
      
 49 
     | 
    
         
            +
                      #{global_klass_variable} = plocals->self;
         
     | 
| 
      
 50 
     | 
    
         
            +
                      // set tree
         
     | 
| 
      
 51 
     | 
    
         
            +
                      rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
         
     | 
| 
      
 52 
     | 
    
         
            +
                              #{global_klass_variable},
         
     | 
| 
      
 53 
     | 
    
         
            +
                              rb_str_new2(#{method_name.to_s.inspect}),
         
     | 
| 
      
 54 
     | 
    
         
            +
                              #{literal_value tree},
         
     | 
| 
      
 55 
     | 
    
         
            +
                              #{literal_value snippet_hash},
         
     | 
| 
      
 56 
     | 
    
         
            +
                              #{literal_value alt_options}
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
                              );
         
     | 
| 
      
 59 
     | 
    
         
            +
                      
         
     | 
| 
      
 60 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 61 
     | 
    
         
            +
                      VALUE obj = plocals->self;
         
     | 
| 
      
 62 
     | 
    
         
            +
                      rb_define_singleton_method(obj, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
         
     | 
| 
      
 63 
     | 
    
         
            +
                      
         
     | 
| 
      
 64 
     | 
    
         
            +
                      #{global_klass_variable} = CLASS_OF(obj);
         
     | 
| 
      
 65 
     | 
    
         
            +
                      // set tree
         
     | 
| 
      
 66 
     | 
    
         
            +
                      rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
         
     | 
| 
      
 67 
     | 
    
         
            +
                              #{global_klass_variable},
         
     | 
| 
      
 68 
     | 
    
         
            +
                              rb_str_new2(#{method_name.to_s.inspect}),
         
     | 
| 
      
 69 
     | 
    
         
            +
                              #{literal_value tree},
         
     | 
| 
      
 70 
     | 
    
         
            +
                              #{literal_value snippet_hash},
         
     | 
| 
      
 71 
     | 
    
         
            +
                              #{literal_value alt_options}
         
     | 
| 
      
 72 
     | 
    
         
            +
              
         
     | 
| 
      
 73 
     | 
    
         
            +
                              );
         
     | 
| 
      
 74 
     | 
    
         
            +
                    }
         
     | 
| 
       47 
75 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                    #{global_klass_variable} = plocals->self;
         
     | 
| 
       49 
     | 
    
         
            -
                    // set tree
         
     | 
| 
       50 
     | 
    
         
            -
                    rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
         
     | 
| 
       51 
     | 
    
         
            -
                            #{global_klass_variable},
         
     | 
| 
       52 
     | 
    
         
            -
                            rb_str_new2(#{method_name.to_s.inspect}),
         
     | 
| 
       53 
     | 
    
         
            -
                            #{literal_value tree},
         
     | 
| 
       54 
     | 
    
         
            -
                            #{literal_value snippet_hash},
         
     | 
| 
       55 
     | 
    
         
            -
                            #{literal_value alt_options}
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                            );
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
76 
     | 
    
         
             
                    "
         
     | 
| 
       60 
77 
     | 
    
         | 
| 
      
 78 
     | 
    
         
            +
                  if result_var
         
     | 
| 
      
 79 
     | 
    
         
            +
                    code + "\n#{result_var} = Qnil;"
         
     | 
| 
      
 80 
     | 
    
         
            +
                  else
         
     | 
| 
      
 81 
     | 
    
         
            +
                    inline_block code + "\nreturn Qnil;\n"
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
       61 
83 
     | 
    
         
             
                end
         
     | 
| 
       62 
84 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                def to_c_defs(tree)
         
     | 
| 
      
 85 
     | 
    
         
            +
                def to_c_defs(tree, result_var = nil)
         
     | 
| 
       64 
86 
     | 
    
         
             
                  method_name = tree[2]
         
     | 
| 
       65 
87 
     | 
    
         
             
                  args_tree = tree[3].select{|x| x.to_s[0] != ?&}
         
     | 
| 
       66 
88 
     | 
    
         | 
| 
         @@ -78,9 +100,10 @@ module FastRuby 
     | 
|
| 
       78 
100 
     | 
    
         
             
                  alt_options.delete(:self)
         
     | 
| 
       79 
101 
     | 
    
         
             
                  alt_options.delete(:main)
         
     | 
| 
       80 
102 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
      
 103 
     | 
    
         
            +
                  code = "
         
     | 
| 
       82 
104 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                    VALUE obj =  
     | 
| 
      
 105 
     | 
    
         
            +
                    VALUE obj = Qnil;
         
     | 
| 
      
 106 
     | 
    
         
            +
                    #{to_c tree[1], "obj"};
         
     | 
| 
       84 
107 
     | 
    
         
             
                    rb_define_singleton_method(obj, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
         
     | 
| 
       85 
108 
     | 
    
         | 
| 
       86 
109 
     | 
    
         
             
                    #{global_klass_variable} = CLASS_OF(obj);
         
     | 
| 
         @@ -95,12 +118,22 @@ module FastRuby 
     | 
|
| 
       95 
118 
     | 
    
         
             
                            );
         
     | 
| 
       96 
119 
     | 
    
         | 
| 
       97 
120 
     | 
    
         
             
                    "
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  if result_var
         
     | 
| 
      
 123 
     | 
    
         
            +
                    code + "\n#{result_var} = Qnil;"
         
     | 
| 
      
 124 
     | 
    
         
            +
                  else
         
     | 
| 
      
 125 
     | 
    
         
            +
                    inline_block code + "\nreturn Qnil;\n"
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
       98 
127 
     | 
    
         | 
| 
       99 
128 
     | 
    
         
             
                end
         
     | 
| 
       100 
129 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
                def to_c_scope(tree)
         
     | 
| 
      
 130 
     | 
    
         
            +
                def to_c_scope(tree, result_var = nil)
         
     | 
| 
       102 
131 
     | 
    
         
             
                  if tree[1]
         
     | 
| 
       103 
     | 
    
         
            -
                     
     | 
| 
      
 132 
     | 
    
         
            +
                    if result_var
         
     | 
| 
      
 133 
     | 
    
         
            +
                      to_c(tree[1], result_var)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    else
         
     | 
| 
      
 135 
     | 
    
         
            +
                      to_c(tree[1])
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
       104 
137 
     | 
    
         
             
                  else
         
     | 
| 
       105 
138 
     | 
    
         
             
                    "Qnil"
         
     | 
| 
       106 
139 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -120,11 +153,11 @@ private 
     | 
|
| 
       120 
153 
     | 
    
         
             
                      method_name[1] = 0;
         
     | 
| 
       121 
154 
     | 
    
         | 
| 
       122 
155 
     | 
    
         
             
                      sprintf(method_name+1, \"#{method_name}\");
         
     | 
| 
       123 
     | 
    
         
            -
                      sprintf(method_name+strlen(method_name), \"%lu\",  
     | 
| 
      
 156 
     | 
    
         
            +
                      sprintf(method_name+strlen(method_name), \"%lu\", (unsigned long)NUM2PTR(rb_obj_id(CLASS_OF(self))));
         
     | 
| 
       124 
157 
     | 
    
         | 
| 
       125 
158 
     | 
    
         
             
                                  int i;
         
     | 
| 
       126 
159 
     | 
    
         
             
                                  for (i=0; i<argc_; i++) {
         
     | 
| 
       127 
     | 
    
         
            -
                                    sprintf(method_name+strlen(method_name), \"%lu\",  
     | 
| 
      
 160 
     | 
    
         
            +
                                    sprintf(method_name+strlen(method_name), \"%lu\", (unsigned long)NUM2PTR(rb_obj_id(CLASS_OF(argv[i]))));
         
     | 
| 
       128 
161 
     | 
    
         
             
                                  }
         
     | 
| 
       129 
162 
     | 
    
         | 
| 
       130 
163 
     | 
    
         
             
                      void** address = 0;
         
     | 
| 
         @@ -136,9 +169,9 @@ private 
     | 
|
| 
       136 
169 
     | 
    
         
             
                      rb_method_hash = rb_funcall(klass, #{intern_num :method_hash},1,#{literal_value method_name});
         
     | 
| 
       137 
170 
     | 
    
         | 
| 
       138 
171 
     | 
    
         
             
                      if (rb_method_hash != Qnil) {
         
     | 
| 
       139 
     | 
    
         
            -
                        VALUE tmp = rb_hash_aref(rb_method_hash,  
     | 
| 
      
 172 
     | 
    
         
            +
                        VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
         
     | 
| 
       140 
173 
     | 
    
         
             
                        if (tmp != Qnil) {
         
     | 
| 
       141 
     | 
    
         
            -
                            address = (void**) 
     | 
| 
      
 174 
     | 
    
         
            +
                            address = (void**)NUM2PTR(tmp);
         
     | 
| 
       142 
175 
     | 
    
         
             
                            fptr = *address;
         
     | 
| 
       143 
176 
     | 
    
         
             
                        }
         
     | 
| 
       144 
177 
     | 
    
         
             
                      }
         
     | 
| 
         @@ -159,9 +192,9 @@ private 
     | 
|
| 
       159 
192 
     | 
    
         
             
                        rb_method_hash = rb_funcall(klass, #{intern_num :method_hash},1,#{literal_value method_name});
         
     | 
| 
       160 
193 
     | 
    
         | 
| 
       161 
194 
     | 
    
         
             
                        if (rb_method_hash != Qnil) {
         
     | 
| 
       162 
     | 
    
         
            -
                          VALUE tmp = rb_hash_aref(rb_method_hash,  
     | 
| 
      
 195 
     | 
    
         
            +
                          VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
         
     | 
| 
       163 
196 
     | 
    
         
             
                          if (tmp != Qnil) {
         
     | 
| 
       164 
     | 
    
         
            -
                              address = (void**) 
     | 
| 
      
 197 
     | 
    
         
            +
                              address = (void**)NUM2PTR(tmp);
         
     | 
| 
       165 
198 
     | 
    
         
             
                              fptr = *address;
         
     | 
| 
       166 
199 
     | 
    
         
             
                          }
         
     | 
| 
       167 
200 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -190,16 +223,18 @@ private 
     | 
|
| 
       190 
223 
     | 
    
         
             
                          frame.thread_data = rb_current_thread_data();
         
     | 
| 
       191 
224 
     | 
    
         
             
                          frame.targetted = 0;
         
     | 
| 
       192 
225 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                          VALUE block = Qfalse;
         
     | 
| 
      
 226 
     | 
    
         
            +
                          volatile VALUE block = Qfalse;
         
     | 
| 
       194 
227 
     | 
    
         | 
| 
       195 
228 
     | 
    
         
             
                          if (rb_block_given_p()) {
         
     | 
| 
       196 
229 
     | 
    
         
             
                            struct {
         
     | 
| 
       197 
     | 
    
         
            -
                              void  
     | 
| 
       198 
     | 
    
         
            -
                              void  
     | 
| 
      
 230 
     | 
    
         
            +
                              void* block_function_address;
         
     | 
| 
      
 231 
     | 
    
         
            +
                              void* block_function_param;
         
     | 
| 
      
 232 
     | 
    
         
            +
                              VALUE proc;
         
     | 
| 
       199 
233 
     | 
    
         
             
                            } block_struct;
         
     | 
| 
       200 
234 
     | 
    
         | 
| 
       201 
235 
     | 
    
         
             
                            block_struct.block_function_address = re_yield;
         
     | 
| 
       202 
236 
     | 
    
         
             
                            block_struct.block_function_param = 0;
         
     | 
| 
      
 237 
     | 
    
         
            +
                            block_struct.proc = rb_block_proc();
         
     | 
| 
       203 
238 
     | 
    
         | 
| 
       204 
239 
     | 
    
         
             
                            block = (VALUE)&block_struct;
         
     | 
| 
       205 
240 
     | 
    
         
             
                          }
         
     |