fastruby 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/README +0 -2
- data/Rakefile +1 -1
- data/benchmarks/benchmark.rb +1 -0
- data/benchmarks/benchmark5.rb +3 -1
- data/ext/fastruby_base/fastruby_base.inl +2 -0
- data/lib/fastruby/builder.rb +18 -42
- data/lib/fastruby/exceptions.rb +8 -0
- data/lib/fastruby/getlocals.rb +17 -0
- data/lib/fastruby/object.rb +1 -31
- data/lib/fastruby/translator/modules/block.rb +44 -22
- data/lib/fastruby/translator/modules/call.rb +25 -1
- data/lib/fastruby/translator/modules/defn.rb +85 -57
- data/lib/fastruby/translator/modules/iter.rb +159 -46
- data/lib/fastruby/translator/modules/method_group.rb +7 -0
- data/lib/fastruby/translator/translator.rb +224 -245
- data/lib/fastruby.rb +1 -1
- data/lib/targetted +84 -0
- data/spec/block/arguments_spec.rb +214 -0
- data/spec/block/block_as_proc_spec.rb +98 -0
- data/spec/block/callcc_spec.rb +233 -0
- data/spec/block/proc_as_block_spec.rb +111 -0
- data/spec/call/base_call_spec.rb +3 -2
- data/spec/defn/default_args_spec.rb +303 -0
- data/spec/defn/multiple_args_spec.rb +35 -0
- data/spec/exception/base_spec.rb +26 -0
- metadata +10 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
0.0.15 Support for continuation objects and callcc
|
2
|
+
|
3
|
+
Fixed fastruby protocol to support unlimited number of arguments from ruby
|
4
|
+
|
5
|
+
Support for default arguments (e.g. def foo(a, b=c.to_s, c=99) )
|
6
|
+
|
7
|
+
Minor fixes to splat arguments on blocks
|
8
|
+
|
9
|
+
Support for receving block as proc (i.e. def foo(&block); end)
|
10
|
+
|
11
|
+
Support for passing proc as block (i.e. foo(&block))
|
12
|
+
|
1
13
|
0.0.14 Support for method replacement ("monkey patching")
|
2
14
|
|
3
15
|
Internal: Implemented method hash to store implementation pointers
|
data/README
CHANGED
@@ -58,9 +58,7 @@ I will stabilize the API and document it for next releases. I promise
|
|
58
58
|
== Known Limitations & Issues
|
59
59
|
|
60
60
|
* callcc is not supported, it works but using it may result in unexpected behaviour
|
61
|
-
* recursive methods will be slow since the optimization of method calls only works with already defined methods
|
62
61
|
* calls with blocks to ruby or cruby methods are almost as slow as normal ruby (if the called method is defined by fastruby, the call is pretty fast)
|
63
|
-
* When calling fastruby methods from normal ruby, the max. number of arguments allowed is 15
|
64
62
|
* replacement of methods using identical code strings will work, but it will generate duplicated objects on the cache each time te snippet run
|
65
63
|
|
66
64
|
== Usage
|
data/Rakefile
CHANGED
data/benchmarks/benchmark.rb
CHANGED
data/benchmarks/benchmark5.rb
CHANGED
@@ -20,8 +20,8 @@ class Y
|
|
20
20
|
i = 1000000
|
21
21
|
|
22
22
|
lvar_type(i,Fixnum)
|
23
|
+
lvar_type(x2,X)
|
23
24
|
|
24
|
-
x2 = 0
|
25
25
|
ret = 0
|
26
26
|
while i > 0
|
27
27
|
x.foo do |x2|
|
@@ -66,6 +66,8 @@ y2 = Y2.new
|
|
66
66
|
x2 = X2.new
|
67
67
|
|
68
68
|
Y.build([Y,X],:bar)
|
69
|
+
X.build([X],:foo)
|
70
|
+
X.build([X],:bar)
|
69
71
|
|
70
72
|
require 'benchmark'
|
71
73
|
|
@@ -23,6 +23,7 @@ struct FASTRUBYTHREADDATA {
|
|
23
23
|
VALUE exception;
|
24
24
|
VALUE accumulator;
|
25
25
|
VALUE rb_stack_chunk;
|
26
|
+
void* last_plocals;
|
26
27
|
};
|
27
28
|
|
28
29
|
struct METHOD {
|
@@ -196,6 +197,7 @@ static inline VALUE rb_thread_data_create() {
|
|
196
197
|
thread_data->exception = Qnil;
|
197
198
|
thread_data->accumulator = Qnil;
|
198
199
|
thread_data->rb_stack_chunk = Qnil;
|
200
|
+
thread_data->last_plocals = 0;
|
199
201
|
|
200
202
|
return ret;
|
201
203
|
}
|
data/lib/fastruby/builder.rb
CHANGED
@@ -27,24 +27,6 @@ require "fastruby_load_path"
|
|
27
27
|
require FastRuby.fastruby_load_path + "/../ext/fastruby_base/fastruby_base"
|
28
28
|
|
29
29
|
module FastRuby
|
30
|
-
|
31
|
-
def self.build_defs(tree, *options)
|
32
|
-
method_name = tree[2].to_s
|
33
|
-
|
34
|
-
FastRuby.logger.info "Building singleton method #{self}::#{@method_name}"
|
35
|
-
|
36
|
-
locals = GetLocalsProcessor.get_locals(tree)
|
37
|
-
locals << :self
|
38
|
-
|
39
|
-
context = FastRuby::Context.new(false)
|
40
|
-
context.locals = locals
|
41
|
-
context.options = options
|
42
|
-
|
43
|
-
context.alt_method_name = "singleton_" + method_name + rand(100000000).to_s
|
44
|
-
|
45
|
-
[context.extra_code + context.to_c_method_defs(tree), context.alt_method_name, context.init_extra]
|
46
|
-
end
|
47
|
-
|
48
30
|
class Method
|
49
31
|
attr_accessor :locals
|
50
32
|
attr_accessor :options
|
@@ -81,19 +63,29 @@ module FastRuby
|
|
81
63
|
context.locals = locals
|
82
64
|
context.options = options
|
83
65
|
|
84
|
-
args_tree = tree[
|
66
|
+
args_tree = if tree[0] == :defn
|
67
|
+
tree[2]
|
68
|
+
elsif tree[0] == :defs
|
69
|
+
tree[3]
|
70
|
+
else
|
71
|
+
raise ArgumentError, "unknown type of method definition #{tree[0]}"
|
72
|
+
end
|
85
73
|
|
86
74
|
# create random method name
|
87
75
|
context.snippet_hash = snippet_hash
|
88
76
|
context.alt_method_name = "_" + @method_name.to_s + "_" + rand(10000000000).to_s
|
89
77
|
|
90
|
-
(1..signature.size).each do |i|
|
78
|
+
(1..signature.size-1).each do |i|
|
91
79
|
arg = args_tree[i]
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
80
|
+
|
81
|
+
if arg.instance_of? Symbol
|
82
|
+
|
83
|
+
if arg
|
84
|
+
if arg.to_s.match(/\*/)
|
85
|
+
context.infer_lvar_map[arg.to_s.gsub("*","").to_sym] = Array
|
86
|
+
else
|
87
|
+
context.infer_lvar_map[arg.to_sym] = signature[i]
|
88
|
+
end
|
97
89
|
end
|
98
90
|
end
|
99
91
|
end
|
@@ -122,11 +114,7 @@ module FastRuby
|
|
122
114
|
def builder.generate_ext
|
123
115
|
ext = []
|
124
116
|
|
125
|
-
|
126
|
-
@inc.unshift "#include \"ruby.h\""
|
127
|
-
else
|
128
|
-
@inc.push "#include \"ruby.h\""
|
129
|
-
end
|
117
|
+
@inc.unshift "#include \"ruby.h\""
|
130
118
|
|
131
119
|
ext << @inc
|
132
120
|
ext << nil
|
@@ -173,18 +161,6 @@ module FastRuby
|
|
173
161
|
unless options[:no_cache]
|
174
162
|
FastRuby.cache.insert(snippet_hash, so_name) unless no_cache
|
175
163
|
end
|
176
|
-
|
177
|
-
ret = Object.new
|
178
|
-
|
179
|
-
ret.extend MethodExtent
|
180
|
-
ret.yield_signature = context.yield_signature
|
181
|
-
|
182
|
-
ret
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
module MethodExtent
|
187
|
-
attr_accessor :yield_signature
|
188
164
|
end
|
189
165
|
end
|
190
166
|
|
data/lib/fastruby/exceptions.rb
CHANGED
@@ -21,4 +21,12 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
|
21
21
|
module FastRuby
|
22
22
|
class TypeMismatchAssignmentException < Exception
|
23
23
|
end
|
24
|
+
|
25
|
+
class JumpTagException < Exception
|
26
|
+
attr_reader :state
|
27
|
+
|
28
|
+
def initialize(state_)
|
29
|
+
@state = state_
|
30
|
+
end
|
31
|
+
end
|
24
32
|
end
|
data/lib/fastruby/getlocals.rb
CHANGED
@@ -34,6 +34,23 @@ module FastRuby
|
|
34
34
|
if tree.node_type == :lasgn
|
35
35
|
@locals << tree[1]
|
36
36
|
end
|
37
|
+
|
38
|
+
if tree[0] == :args
|
39
|
+
|
40
|
+
tree[1..-1].each do |subtree|
|
41
|
+
if subtree.instance_of? Symbol
|
42
|
+
@locals << subtree.to_s.gsub("*","").gsub("&","").to_sym
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if tree.find{|x| x.to_s[0] == ?&}
|
47
|
+
@locals << :__xproc_arguments
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if tree[0] == :block_pass
|
52
|
+
@locals << :__xblock_arguments
|
53
|
+
end
|
37
54
|
|
38
55
|
tree.select{|subtree| subtree.instance_of? FastRuby::FastRubySexp}.each do |subtree|
|
39
56
|
process(subtree)
|
data/lib/fastruby/object.rb
CHANGED
@@ -103,26 +103,13 @@ class Object
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
def self.execute_tree(
|
106
|
+
def self.execute_tree(tree,*options_hashes)
|
107
107
|
options_hash = {:validate_lvar_types => true}
|
108
108
|
options_hashes.each do |opt|
|
109
109
|
options_hash.merge!(opt)
|
110
110
|
end
|
111
111
|
|
112
112
|
require "fastruby/fastruby_sexp"
|
113
|
-
if argument.instance_of? FastRuby::FastRubySexp
|
114
|
-
tree = argument
|
115
|
-
elsif argument.instance_of? String
|
116
|
-
require "rubygems"
|
117
|
-
require "ruby_parser"
|
118
|
-
require "fastruby/sexp_extension"
|
119
|
-
tree = RubyParser.new.parse(argument).to_fastruby_sexp
|
120
|
-
else
|
121
|
-
require "pry"
|
122
|
-
binding.pry
|
123
|
-
raise ArgumentError
|
124
|
-
end
|
125
|
-
|
126
113
|
method_name = tree[1]
|
127
114
|
|
128
115
|
self_ = options_hash[:self]
|
@@ -141,22 +128,5 @@ class Object
|
|
141
128
|
$refered_from_code_array = Array.new unless $refered_from_code_array
|
142
129
|
$refered_from_code_array << self
|
143
130
|
end
|
144
|
-
|
145
|
-
private
|
146
|
-
def self.to_class_name(argument)
|
147
|
-
require "sexp"
|
148
|
-
if argument.instance_of? Symbol
|
149
|
-
argument.to_s
|
150
|
-
elsif argument.instance_of? Sexp
|
151
|
-
if argument[0] == :colon3
|
152
|
-
"::" + to_class_name(argument[1])
|
153
|
-
elsif argument[0] == :colon2
|
154
|
-
to_class_name(argument[1]) + "::" + to_class_name(argument[2])
|
155
|
-
elsif argument[0] == :const
|
156
|
-
to_class_name(argument[1])
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
131
|
end
|
162
132
|
|
@@ -26,7 +26,7 @@ module FastRuby
|
|
26
26
|
def to_c_yield(tree)
|
27
27
|
|
28
28
|
block_code = proc { |name| "
|
29
|
-
static VALUE #{name}(VALUE frame_param, VALUE* block_args) {
|
29
|
+
static VALUE #{name}(VALUE frame_param, VALUE* block_args, int size) {
|
30
30
|
|
31
31
|
#{@locals_struct} *plocals;
|
32
32
|
#{@frame_struct} *pframe;
|
@@ -36,38 +36,60 @@ module FastRuby
|
|
36
36
|
if (FIX2LONG(plocals->block_function_address) == 0) {
|
37
37
|
#{_raise("rb_eLocalJumpError", "no block given")};
|
38
38
|
} else {
|
39
|
-
return ((VALUE(*)(int,VALUE*,VALUE,VALUE))FIX2LONG(plocals->block_function_address))(
|
39
|
+
return ((VALUE(*)(int,VALUE*,VALUE,VALUE))FIX2LONG(plocals->block_function_address))(size, block_args, FIX2LONG(plocals->block_function_param), (VALUE)pframe);
|
40
40
|
}
|
41
41
|
}
|
42
42
|
"
|
43
43
|
}
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
if
|
48
|
-
|
49
|
-
(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
splat_arg = tree.find{|x| x == :yield ? false : x[0] == :splat}
|
46
|
+
ret = nil
|
47
|
+
if splat_arg
|
48
|
+
ret = inline_block "
|
49
|
+
VALUE splat_array = #{to_c(splat_arg[1])};
|
50
|
+
|
51
|
+
if (CLASS_OF(splat_array) == rb_cArray) {
|
52
|
+
VALUE block_args[RARRAY(splat_array)->len + #{tree.size}];
|
53
|
+
int i;
|
54
|
+
#{
|
55
|
+
(0..tree.size-3).map{|i|
|
56
|
+
"block_args[#{i}] = #{to_c(tree[i+1])}"
|
57
|
+
}.join(";\n")
|
58
|
+
};
|
59
|
+
|
60
|
+
for (i=0; i<RARRAY(splat_array)->len; i++) {
|
61
|
+
block_args[i+#{tree.size-2}] = rb_ary_entry(splat_array,i);
|
62
|
+
}
|
63
|
+
|
64
|
+
return #{anonymous_function(&block_code)}((VALUE)pframe, block_args, RARRAY(splat_array)->len + #{tree.size-2});
|
65
|
+
} else {
|
66
|
+
VALUE block_args[1+#{tree.size}];
|
67
|
+
#{
|
68
|
+
(0..tree.size-3).map{|i|
|
69
|
+
"block_args[#{i}] = #{to_c(tree[i+1])}"
|
70
|
+
}.join(";\n")
|
71
|
+
};
|
72
|
+
|
73
|
+
block_args[#{tree.size-2}] = splat_array;
|
74
|
+
return #{anonymous_function(&block_code)}((VALUE)pframe, block_args, #{tree.size-1});
|
75
|
+
}
|
76
|
+
|
77
|
+
"
|
57
78
|
else
|
58
|
-
|
79
|
+
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})"
|
81
|
+
else
|
82
|
+
anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){}, #{tree.size-1})"
|
83
|
+
end
|
59
84
|
end
|
60
|
-
|
61
|
-
ret = if tree.size > 1
|
62
|
-
anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){#{tree[1..-1].map{|subtree| to_c subtree}.join(",")}})"
|
63
|
-
else
|
64
|
-
anonymous_function(&block_code)+"((VALUE)pframe, (VALUE[]){})"
|
65
|
-
end
|
66
|
-
|
85
|
+
|
67
86
|
protected_block(ret, false)
|
68
87
|
end
|
69
88
|
|
70
89
|
def to_c_block(tree)
|
90
|
+
if tree.size == 1
|
91
|
+
return inline_block("return Qnil;")
|
92
|
+
end
|
71
93
|
|
72
94
|
str = ""
|
73
95
|
str = tree[1..-2].map{ |subtree|
|
@@ -36,10 +36,34 @@ module FastRuby
|
|
36
36
|
args = tree[3]
|
37
37
|
return _raise(args[1],args[2])
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
recv = tree[1]
|
41
41
|
mname = tree[2]
|
42
42
|
args = tree[3]
|
43
|
+
|
44
|
+
# search block_pass on arguments
|
45
|
+
block_pass_arg = args.find{|arg| if arg == :arglist
|
46
|
+
false
|
47
|
+
else
|
48
|
+
arg[0] == :block_pass
|
49
|
+
end}
|
50
|
+
if block_pass_arg
|
51
|
+
|
52
|
+
call_tree = tree.dup
|
53
|
+
call_tree[3] = args.select{|arg| if arg == :arglist
|
54
|
+
true
|
55
|
+
else
|
56
|
+
arg[0] != :block_pass
|
57
|
+
end
|
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)
|
66
|
+
end
|
43
67
|
|
44
68
|
mname = :require_fastruby if mname == :require
|
45
69
|
|
@@ -25,8 +25,43 @@ module FastRuby
|
|
25
25
|
def to_c_defn(tree)
|
26
26
|
|
27
27
|
method_name = tree[1]
|
28
|
-
args_tree = tree[2]
|
28
|
+
args_tree = tree[2].select{|x| x.to_s[0] != ?&}
|
29
|
+
|
30
|
+
global_klass_variable = add_global_name("VALUE", "Qnil");
|
31
|
+
|
32
|
+
hash = Hash.new
|
33
|
+
value_cast = ( ["VALUE"]*(args_tree.size+2) ).join(",")
|
34
|
+
|
35
|
+
strmethodargs = "self,block,(VALUE)&frame"
|
36
|
+
|
37
|
+
anonymous_method_name = anonymous_dispatcher(global_klass_variable, method_name)
|
38
|
+
alt_options = options.dup
|
29
39
|
|
40
|
+
alt_options.delete(:self)
|
41
|
+
alt_options.delete(:main)
|
42
|
+
|
43
|
+
inline_block "
|
44
|
+
rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
|
45
|
+
|
46
|
+
#{global_klass_variable} = plocals->self;
|
47
|
+
// set tree
|
48
|
+
rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
|
49
|
+
#{global_klass_variable},
|
50
|
+
rb_str_new2(#{method_name.to_s.inspect}),
|
51
|
+
#{literal_value tree},
|
52
|
+
#{literal_value snippet_hash},
|
53
|
+
#{literal_value alt_options}
|
54
|
+
|
55
|
+
);
|
56
|
+
|
57
|
+
"
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_c_defs(tree)
|
62
|
+
method_name = tree[2]
|
63
|
+
args_tree = tree[3].select{|x| x.to_s[0] != ?&}
|
64
|
+
|
30
65
|
global_klass_variable = add_global_name("VALUE", "Qnil");
|
31
66
|
|
32
67
|
hash = Hash.new
|
@@ -34,9 +69,50 @@ module FastRuby
|
|
34
69
|
|
35
70
|
strmethodargs = "self,block,(VALUE)&frame"
|
36
71
|
|
37
|
-
anonymous_method_name =
|
72
|
+
anonymous_method_name = anonymous_dispatcher(global_klass_variable, method_name)
|
73
|
+
|
74
|
+
alt_options = options.dup
|
75
|
+
|
76
|
+
alt_options.delete(:self)
|
77
|
+
alt_options.delete(:main)
|
78
|
+
|
79
|
+
inline_block "
|
80
|
+
|
81
|
+
VALUE obj = #{to_c tree[1]};
|
82
|
+
rb_define_singleton_method(obj, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
|
83
|
+
|
84
|
+
#{global_klass_variable} = CLASS_OF(obj);
|
85
|
+
// set tree
|
86
|
+
rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
|
87
|
+
#{global_klass_variable},
|
88
|
+
rb_str_new2(#{method_name.to_s.inspect}),
|
89
|
+
#{literal_value tree},
|
90
|
+
#{literal_value snippet_hash},
|
91
|
+
#{literal_value alt_options}
|
92
|
+
|
93
|
+
);
|
94
|
+
|
95
|
+
"
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_c_scope(tree)
|
100
|
+
if tree[1]
|
101
|
+
to_c(tree[1])
|
102
|
+
else
|
103
|
+
"Qnil"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def anonymous_dispatcher(global_klass_variable, method_name)
|
110
|
+
|
111
|
+
strmethodargs = "self,block,(VALUE)&frame"
|
112
|
+
|
113
|
+
anonymous_function{ |anonymous_method_name| "VALUE #{anonymous_method_name}(int argc_, VALUE* argv, VALUE self) {
|
38
114
|
VALUE klass = #{global_klass_variable};
|
39
|
-
char method_name[
|
115
|
+
char method_name[argc_*40+64];
|
40
116
|
|
41
117
|
method_name[0] = '_';
|
42
118
|
method_name[1] = 0;
|
@@ -133,67 +209,19 @@ module FastRuby
|
|
133
209
|
}
|
134
210
|
|
135
211
|
if (frame.targetted == 0) {
|
136
|
-
|
212
|
+
frb_jump_tag(aux);
|
137
213
|
}
|
138
214
|
|
139
215
|
return Qnil;
|
140
216
|
}
|
217
|
+
|
218
|
+
VALUE tmp = Qnil;
|
219
|
+
if (argv == 0) argv = &tmp;
|
141
220
|
|
142
|
-
|
143
|
-
|
144
|
-
#{ (1..15).map{ |i|
|
145
|
-
value_cast = ( ["VALUE"]*(i+3) ).join(",")
|
146
|
-
"if (argc_ == #{i}) return ((VALUE(*)(#{value_cast}))fptr)(#{strmethodargs}, #{(0..i-1).map{|x| "argv[#{x}]"}.join(",")});"
|
147
|
-
}.join("\n");
|
148
|
-
}
|
149
|
-
|
150
|
-
rb_raise(rb_eArgError, \"too many arguments: %d\", argc_);
|
221
|
+
return ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))fptr)(#{strmethodargs}, argc_, argv);
|
151
222
|
}"
|
152
223
|
}
|
153
|
-
|
154
|
-
alt_options = options.dup
|
155
|
-
|
156
|
-
alt_options.delete(:self)
|
157
|
-
alt_options.delete(:main)
|
158
|
-
|
159
|
-
inline_block "
|
160
|
-
rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
|
161
|
-
|
162
|
-
#{global_klass_variable} = plocals->self;
|
163
|
-
// set tree
|
164
|
-
rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
|
165
|
-
#{global_klass_variable},
|
166
|
-
rb_str_new2(#{method_name.to_s.inspect}),
|
167
|
-
#{literal_value tree},
|
168
|
-
#{literal_value snippet_hash},
|
169
|
-
#{literal_value alt_options}
|
170
|
-
|
171
|
-
);
|
172
|
-
|
173
|
-
"
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
def to_c_defs(tree)
|
178
|
-
args_tree = tree[3];
|
179
|
-
|
180
|
-
tmp = FastRuby.build_defs(tree)
|
181
|
-
|
182
|
-
extra_code << tmp[0]
|
183
|
-
@init_extra = @init_extra + tmp[2]
|
184
|
-
|
185
|
-
inline_block "
|
186
|
-
rb_define_singleton_method(#{to_c tree[1]}, \"#{tree[2].to_s}\", (void*)#{tmp[1]}, #{args_tree.size-1});
|
187
|
-
return Qnil;
|
188
|
-
"
|
189
|
-
end
|
190
|
-
|
191
|
-
def to_c_scope(tree)
|
192
|
-
if tree[1]
|
193
|
-
to_c(tree[1])
|
194
|
-
else
|
195
|
-
"Qnil"
|
196
|
-
end
|
224
|
+
|
197
225
|
end
|
198
226
|
end
|
199
227
|
end
|