fastruby 0.0.19 → 0.0.20
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/{README → README.rdoc} +6 -1
- data/Rakefile +7 -7
- data/benchmarks/benchmark.rb~ +14 -2
- data/ext/fastruby_base/fastruby_base.inl +8 -4
- data/lib/fastruby/builder/inference_updater.rb +76 -0
- data/lib/fastruby/builder/inference_updater.rb~ +76 -0
- data/lib/fastruby/builder/inferencer.rb +38 -0
- data/lib/fastruby/{inliner → builder}/inliner.rb +16 -27
- data/lib/fastruby/builder/inliner.rb~ +60 -0
- data/lib/fastruby/builder/locals_inference.rb +53 -0
- data/lib/fastruby/builder/lvar_type.rb +43 -0
- data/lib/fastruby/builder/lvar_type.rb~ +44 -0
- data/lib/fastruby/builder/pipeline.rb +43 -0
- data/lib/fastruby/builder/pipeline.rb~ +43 -0
- data/lib/fastruby/{reductor → builder}/reductor.rb +6 -3
- data/lib/fastruby/builder/reductor.rb~ +42 -0
- data/lib/fastruby/builder.rb +73 -25
- data/lib/fastruby/builder.rb~ +311 -0
- data/lib/fastruby/corelib/fixnum.rb +75 -0
- data/lib/fastruby/corelib/fixnum.rb~ +146 -0
- data/lib/fastruby/corelib/integer.rb +96 -0
- data/lib/fastruby/corelib/integer.rb~ +96 -0
- data/lib/fastruby/corelib.rb +23 -0
- data/lib/fastruby/corelib.rb~ +23 -0
- data/lib/fastruby/getlocals.rb +3 -1
- data/lib/fastruby/logging.rb +2 -2
- data/lib/fastruby/modules/inferencer/infer.rb +31 -0
- data/lib/fastruby/modules/inferencer/literal.rb +42 -0
- data/lib/fastruby/modules/inliner/call.rb +327 -0
- data/lib/fastruby/{inliner/modules/call.rb → modules/inliner/call.rb~} +14 -24
- data/lib/fastruby/modules/inliner/defn.rb +41 -0
- data/lib/fastruby/modules/inliner/defn.rb~ +29 -0
- data/lib/fastruby/modules/inliner/recursive.rb +40 -0
- data/lib/fastruby/{inliner/modules/recursive.rb → modules/inliner/recursive.rb~} +1 -1
- data/lib/fastruby/modules/lvar_type/call.rb +36 -0
- data/lib/fastruby/modules/lvar_type/call.rb~ +36 -0
- data/lib/fastruby/modules/lvar_type/defn.rb +42 -0
- data/lib/fastruby/modules/lvar_type/defn.rb~ +42 -0
- data/lib/fastruby/modules/lvar_type/lasgn.rb +41 -0
- data/lib/fastruby/modules/lvar_type/lasgn.rb~ +42 -0
- data/lib/fastruby/modules/lvar_type/recursive.rb +33 -0
- data/lib/fastruby/modules/lvar_type/recursive.rb~ +33 -0
- data/lib/fastruby/{reductor/modules → modules/reductor}/case.rb +0 -0
- data/lib/fastruby/modules/reductor/fastruby_flag.rb +33 -0
- data/lib/fastruby/{reductor/modules → modules/reductor}/for.rb +0 -0
- data/lib/fastruby/{reductor/modules → modules/reductor}/nontree.rb +0 -0
- data/lib/fastruby/modules/reductor/nontree.rb~ +32 -0
- data/lib/fastruby/{reductor/modules → modules/reductor}/recursive.rb +1 -1
- data/lib/fastruby/modules/reductor/recursive.rb~ +31 -0
- data/lib/fastruby/{translator/modules → modules/translator}/block.rb +0 -0
- data/lib/fastruby/modules/translator/call.rb +344 -0
- data/lib/fastruby/{translator/modules/call.rb → modules/translator/call.rb~} +24 -3
- data/lib/fastruby/{translator/modules → modules/translator}/defn.rb +10 -9
- data/lib/fastruby/modules/translator/defn.rb~ +267 -0
- data/lib/fastruby/{translator/modules → modules/translator}/directive.rb +3 -1
- data/lib/fastruby/modules/translator/directive.rb~ +44 -0
- data/lib/fastruby/{translator/modules → modules/translator}/exceptions.rb +3 -1
- data/lib/fastruby/modules/translator/exceptions.rb~ +120 -0
- data/lib/fastruby/{translator/modules → modules/translator}/flow.rb +0 -0
- data/lib/fastruby/modules/translator/iter.rb +745 -0
- data/lib/fastruby/{translator/modules/iter.rb → modules/translator/iter.rb~} +103 -48
- data/lib/fastruby/modules/translator/literal.rb +150 -0
- data/lib/fastruby/{translator/modules/literal.rb → modules/translator/literal.rb~} +3 -3
- data/lib/fastruby/{translator/modules → modules/translator}/logical.rb +0 -0
- data/lib/fastruby/{translator/modules → modules/translator}/method_group.rb +0 -0
- data/lib/fastruby/{translator/modules → modules/translator}/nonlocal.rb +18 -6
- data/lib/fastruby/modules/translator/nonlocal.rb~ +298 -0
- data/lib/fastruby/modules/translator/static.rb +290 -0
- data/lib/fastruby/{translator/modules/static.rb → modules/translator/static.rb~} +66 -17
- data/lib/fastruby/modules/translator/variable.rb +280 -0
- data/lib/fastruby/{translator/modules/variable.rb → modules/translator/variable.rb~} +14 -44
- data/lib/fastruby/modules.rb +30 -0
- data/lib/fastruby/object.rb +42 -6
- data/lib/fastruby/object.rb~ +159 -0
- data/lib/fastruby/set_tree.rb +7 -11
- data/lib/fastruby/set_tree.rb~ +71 -0
- data/lib/fastruby/sexp_extension.rb +29 -7
- data/lib/fastruby/sexp_extension.rb~ +262 -0
- data/lib/fastruby/translator/scope_mode_helper.rb~ +138 -0
- data/lib/fastruby/translator/translator.rb +87 -92
- data/lib/fastruby/translator/translator.rb~ +1600 -0
- data/lib/fastruby/translator/translator_modules.rb +3 -1
- data/lib/fastruby/translator/translator_modules.rb~ +53 -0
- data/lib/fastruby.rb +3 -1
- data/lib/fastruby.rb~ +3 -1
- data/lib/fastruby_only/base.rb +1 -0
- data/spec/corelib/numeric/fixnum_spec.rb +110 -0
- data/spec/corelib/numeric/fixnum_spec.rb~ +104 -0
- data/spec/corelib/numeric/integer_spec.rb +173 -0
- data/spec/corelib/numeric/integer_spec.rb~ +173 -0
- data/spec/fastruby_only/base_spec.rb +74 -0
- data/spec/graph/base_spec.rb +2 -1
- data/spec/graph/base_spec.rb~ +35 -0
- data/spec/graph/path_spec.rb +2 -2
- data/spec/graph/path_spec.rb~ +48 -0
- data/spec/graph/vertex_spec.rb +2 -1
- data/spec/graph/vertex_spec.rb~ +58 -0
- data/spec/reductor/base_spec.rb +1 -1
- data/spec/ruby/block/lambda_spec.rb~ +163 -0
- data/spec/ruby/block/proc_as_block_spec.rb~ +69 -1
- data/spec/ruby/block_spec.rb~ +2 -494
- data/spec/ruby/call/base_call_spec.rb +1 -1
- data/spec/ruby/call/base_call_spec.rb~ +2 -60
- data/spec/ruby/defn/replacement_spec.rb +26 -14
- data/spec/ruby/defn/replacement_spec.rb~ +13 -3
- data/spec/ruby/exception/internal_ex_spec.rb~ +86 -0
- data/spec/ruby/integrity_spec.rb~ +35 -1
- data/spec/ruby/variable_spec.rb~ +31 -0
- data/spec/scope_mode/flow_spec.rb +1 -1
- data/spec/scope_mode/flow_spec.rb~ +109 -0
- data/spec/sugar/base_spec.rb +29 -0
- data/spec/sugar/base_spec.rb~ +16 -0
- metadata +100 -43
- data/spec/fastruby/inliner/modules/call_spec.rb +0 -0
- data/spec/fastruby/translator/modules/nonlocal_spec.rb +0 -0
- data/spec/fastruby/translator/translator_spec.rb +0 -0
- data/spec/ruby/block/arguments_spec.rb~ +0 -214
- data/spec/ruby/block/break_spec.rb~ +0 -236
- data/spec/ruby/block/next_spec.rb~ +0 -85
- data/spec/ruby/block/retry_spec.rb~ +0 -43
@@ -0,0 +1,327 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
|
28
|
+
class BlockProcessing
|
29
|
+
def initialize(inlined_name, break_inlined_name)
|
30
|
+
@inlined_name = inlined_name
|
31
|
+
@break_inlined_name = break_inlined_name
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method_handler(:process, :priority => -100) { |tree|
|
35
|
+
tree.map {|subtree| process subtree}
|
36
|
+
}
|
37
|
+
|
38
|
+
define_method_handler(:process, :priority => 1000) { |tree|
|
39
|
+
tree
|
40
|
+
}.condition{|tree| not tree.respond_to?(:node_type) }
|
41
|
+
|
42
|
+
define_method_handler(:process) { |tree|
|
43
|
+
if tree[1]
|
44
|
+
fs(:call, nil, :_throw, fs(:arglist, fs(:lit,@inlined_name.to_sym), process(tree[1])))
|
45
|
+
else
|
46
|
+
fs(:call, nil, :_throw, fs(:arglist, fs(:lit,@inlined_name.to_sym), fs(:nil)))
|
47
|
+
end
|
48
|
+
}.condition{|tree| tree.node_type == :next}
|
49
|
+
|
50
|
+
define_method_handler(:process) { |tree|
|
51
|
+
if tree[1]
|
52
|
+
fs(:call, nil, :_throw, fs(:arglist, fs(:lit,@break_inlined_name.to_sym), process(tree[1])))
|
53
|
+
else
|
54
|
+
fs(:call, nil, :_throw, fs(:arglist, fs(:lit,@break_inlined_name.to_sym), fs(:nil)))
|
55
|
+
end
|
56
|
+
}.condition{|tree| tree.node_type == :break and @break_inlined_name}
|
57
|
+
|
58
|
+
define_method_handler(:process) { |tree|
|
59
|
+
fs(:call, nil, :_loop, fs(:arglist, fs(:lit,@inlined_name.to_sym)))
|
60
|
+
}.condition{|tree| tree.node_type == :redo}
|
61
|
+
|
62
|
+
define_method_handler(:process) { |tree|
|
63
|
+
if tree[3]
|
64
|
+
fs(:iter, process(tree[1]), tree[2], tree[3].duplicate)
|
65
|
+
else
|
66
|
+
fs(:iter, process(tree[1]), tree[2])
|
67
|
+
end
|
68
|
+
}.condition{|tree| tree.node_type == :iter}
|
69
|
+
end
|
70
|
+
|
71
|
+
if "1".respond_to?(:ord)
|
72
|
+
def inline_local_name(method_name, local_name)
|
73
|
+
"__inlined_#{method_name.to_s.gsub("_x_", "_x__x_").gsub(/\W/){|x| "_x_#{x.ord}" }}_#{local_name}".to_sym
|
74
|
+
end
|
75
|
+
else
|
76
|
+
def inline_local_name(method_name, local_name)
|
77
|
+
"__inlined_#{method_name.to_s.gsub("_x_", "_x__x_").gsub(/\W/){|x| "_x_#{x[0]}" }}_#{local_name}".to_sym
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def method_obj_or_gtfo(klass, method_name)
|
82
|
+
return nil unless klass.respond_to?(:fastruby_method)
|
83
|
+
klass.fastruby_method(method_name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_prefix(tree, prefix)
|
87
|
+
tree = tree.duplicate
|
88
|
+
tree.walk_tree do |subtree|
|
89
|
+
if subtree.node_type == :lvar or subtree.node_type == :lasgn
|
90
|
+
subtree[1] = inline_local_name(prefix, subtree[1])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
tree
|
95
|
+
end
|
96
|
+
|
97
|
+
def catch_block(name,tree)
|
98
|
+
fs(:block,fs(:iter, fs(:call, nil, :_catch, fs(:arglist, fs(:lit,name.to_sym))),nil,tree))
|
99
|
+
end
|
100
|
+
|
101
|
+
def method_tree_to_inlined_block(mobject, call_tree, method_name, block_args_tree = nil, block_tree = nil)
|
102
|
+
args_tree = call_tree[3]
|
103
|
+
recv_tree = call_tree[1] || fs(:self)
|
104
|
+
|
105
|
+
target_method_tree = mobject.tree
|
106
|
+
|
107
|
+
@method_index = (@method_index || 0) + 1
|
108
|
+
|
109
|
+
prefix = method_name.to_s + "_" + @method_index.to_s
|
110
|
+
target_method_tree_block = add_prefix(target_method_tree.find_tree(:scope)[1], prefix)
|
111
|
+
|
112
|
+
if target_method_tree_block.find_tree(:return)
|
113
|
+
inlined_name = inline_local_name(method_name, "main_return_tagname")
|
114
|
+
target_method_tree_block = catch_block(inlined_name,target_method_tree_block)
|
115
|
+
|
116
|
+
target_method_tree_block.walk_tree do |subtree|
|
117
|
+
if subtree[0] == :return
|
118
|
+
if subtree[1]
|
119
|
+
subtree[0..-1] = fs(:call, nil, :_throw, fs(:arglist, fs(:lit,inlined_name.to_sym), subtree[1]))
|
120
|
+
else
|
121
|
+
subtree[0..-1] = fs(:call, nil, :_throw, fs(:arglist, fs(:lit,inlined_name.to_sym), fs(:nil)))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
target_method_tree_args = target_method_tree[2]
|
128
|
+
|
129
|
+
newblock = fs(:block)
|
130
|
+
|
131
|
+
(1..args_tree.size-1).each do |i|
|
132
|
+
itype = infer_type(args_tree[i])
|
133
|
+
inlined_name = inline_local_name(prefix, target_method_tree_args[i])
|
134
|
+
newblock << fs(:lasgn, inlined_name, recursive_inline(args_tree[i].duplicate))
|
135
|
+
end
|
136
|
+
|
137
|
+
inlined_name = inline_local_name(prefix, :self)
|
138
|
+
newblock << fs(:lasgn, inlined_name, recv_tree.duplicate)
|
139
|
+
|
140
|
+
return nil if target_method_tree_block.find_tree(:return)
|
141
|
+
|
142
|
+
break_tag = nil
|
143
|
+
|
144
|
+
if block_tree
|
145
|
+
block_tree = recursive_inline(block_tree)
|
146
|
+
if block_tree.find_tree(:break) # FIXME: discard nested iter calls on finding
|
147
|
+
break_tag = inline_local_name(prefix, "__break_tag")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
block_num = 0
|
152
|
+
|
153
|
+
target_method_tree_block.walk_tree do |subtree|
|
154
|
+
if subtree.node_type == :call
|
155
|
+
if subtree[1] == nil
|
156
|
+
if subtree[2] == :block_given?
|
157
|
+
subtree[0..-1] = block_tree ? fs(:true) : fs(:false)
|
158
|
+
else
|
159
|
+
subtree[1] = recv_tree.duplicate
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
if subtree.node_type == :self
|
164
|
+
subtree[0] = :lvar
|
165
|
+
subtree[1] = inline_local_name(prefix, :self)
|
166
|
+
end
|
167
|
+
if subtree.node_type == :yield
|
168
|
+
if block_tree
|
169
|
+
# inline yield
|
170
|
+
yield_call_args = subtree.duplicate
|
171
|
+
|
172
|
+
subtree[0..-1] = fs(:block)
|
173
|
+
|
174
|
+
if block_args_tree
|
175
|
+
return nil if yield_call_args[1..-1].find{|x| x.node_type == :splat}
|
176
|
+
if block_args_tree.node_type == :masgn
|
177
|
+
return nil if block_args_tree[1].size != yield_call_args.size
|
178
|
+
return nil if block_args_tree[1][1..-1].find{|x| x.node_type == :splat}
|
179
|
+
|
180
|
+
(1..yield_call_args.size-1).each do |i|
|
181
|
+
inlined_name = block_args_tree[1][i][1]
|
182
|
+
subtree << fs(:lasgn, inlined_name, yield_call_args[i])
|
183
|
+
end
|
184
|
+
else
|
185
|
+
return nil if 2 != yield_call_args.size
|
186
|
+
|
187
|
+
inlined_name = block_args_tree[1]
|
188
|
+
subtree << fs(:lasgn, inlined_name, yield_call_args[1])
|
189
|
+
end
|
190
|
+
else
|
191
|
+
return nil if yield_call_args.size > 1
|
192
|
+
end
|
193
|
+
|
194
|
+
if block_tree.find_tree(:next) or block_tree.find_tree(:redo) or break_tag
|
195
|
+
inlined_name = inline_local_name(prefix, "block_block_#{block_num}")
|
196
|
+
block_num = block_num + 1
|
197
|
+
|
198
|
+
alt_block_tree = BlockProcessing.new(inlined_name, break_tag).process(block_tree)
|
199
|
+
alt_block_tree = catch_block(inlined_name,alt_block_tree)
|
200
|
+
else
|
201
|
+
alt_block_tree = block_tree.duplicate
|
202
|
+
end
|
203
|
+
subtree << alt_block_tree
|
204
|
+
else
|
205
|
+
subtree[0..-1] = fs(:call, fs(:nil), :raise, fs(:arglist, fs(:const, :LocalJumpError), fs(:str, "no block given")))
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
@inlined_methods << mobject
|
211
|
+
|
212
|
+
if break_tag
|
213
|
+
inner_block = fs(:block)
|
214
|
+
target_method_tree_block[1..-1].each do |subtree|
|
215
|
+
inner_block << subtree
|
216
|
+
end
|
217
|
+
|
218
|
+
newblock << catch_block(break_tag,inner_block)
|
219
|
+
else
|
220
|
+
target_method_tree_block[1..-1].each do |subtree|
|
221
|
+
newblock << subtree
|
222
|
+
end
|
223
|
+
end
|
224
|
+
newblock
|
225
|
+
end
|
226
|
+
|
227
|
+
define_method_handler(:inline) { |tree|
|
228
|
+
ret_tree = fs(:iter)
|
229
|
+
ret_tree << tree[1].duplicate
|
230
|
+
|
231
|
+
call_tree = tree[1]
|
232
|
+
recv_tree = call_tree[1] || fs(:self)
|
233
|
+
method_name = call_tree[2]
|
234
|
+
args_tree = call_tree[3]
|
235
|
+
block_tree = tree[3] || fs(:nil)
|
236
|
+
block_args_tree = tree[2]
|
237
|
+
|
238
|
+
tree[2..-1].each do |subtree|
|
239
|
+
ret_tree << inline(subtree)
|
240
|
+
end
|
241
|
+
|
242
|
+
next ret_tree if block_tree.find_tree(:retry)
|
243
|
+
|
244
|
+
recvtype = infer_type(recv_tree)
|
245
|
+
|
246
|
+
if recvtype
|
247
|
+
# search the tree of target method
|
248
|
+
mobject = method_obj_or_gtfo(recvtype,method_name)
|
249
|
+
|
250
|
+
next ret_tree unless mobject
|
251
|
+
next ret_tree unless mobject.tree
|
252
|
+
|
253
|
+
exit_now = false
|
254
|
+
if block_tree.find_tree(:break) or block_tree.find_tree(:return)
|
255
|
+
mobject.tree.walk_tree do |subtree|
|
256
|
+
if subtree.node_type == :iter
|
257
|
+
if subtree.find_tree(:yield)
|
258
|
+
exit_now = true
|
259
|
+
break
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
next ret_tree if exit_now
|
266
|
+
|
267
|
+
target_method_tree_args = mobject.tree[2]
|
268
|
+
next ret_tree if target_method_tree_args.find{|subtree| subtree.to_s =~ /^\*/}
|
269
|
+
|
270
|
+
method_tree_to_inlined_block(mobject, call_tree, method_name, block_args_tree, block_tree) || ret_tree
|
271
|
+
|
272
|
+
else
|
273
|
+
# nothing to do, we don't know what is the method
|
274
|
+
ret_tree
|
275
|
+
end
|
276
|
+
}.condition{|tree| tree.node_type == :iter}
|
277
|
+
|
278
|
+
define_method_handler(:inline) { |tree|
|
279
|
+
|
280
|
+
next tree if tree.find_tree(:block_pass)
|
281
|
+
|
282
|
+
recv_tree = tree[1] || fs(:self)
|
283
|
+
method_name = tree[2]
|
284
|
+
args_tree = tree[3]
|
285
|
+
|
286
|
+
if method_name == :lvar_type
|
287
|
+
next tree
|
288
|
+
end
|
289
|
+
|
290
|
+
recvtype = infer_type(recv_tree)
|
291
|
+
|
292
|
+
if recvtype
|
293
|
+
# search the tree of target method
|
294
|
+
mobject = method_obj_or_gtfo(recvtype,method_name)
|
295
|
+
|
296
|
+
next recursive_inline(tree) unless mobject
|
297
|
+
next recursive_inline(tree) unless mobject.tree
|
298
|
+
|
299
|
+
exit_now = false
|
300
|
+
mobject.tree.walk_tree do |subtree|
|
301
|
+
if subtree.node_type == :iter
|
302
|
+
if subtree.find_tree(:return)
|
303
|
+
exit_now = true
|
304
|
+
break
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
next recursive_inline(tree) if exit_now
|
310
|
+
|
311
|
+
target_method_tree_args = if mobject.tree.node_type == :defn
|
312
|
+
mobject.tree[2]
|
313
|
+
else
|
314
|
+
mobject.tree[3]
|
315
|
+
end
|
316
|
+
|
317
|
+
next recursive_inline(tree) if target_method_tree_args.find{|subtree| subtree.to_s =~ /^\*/}
|
318
|
+
|
319
|
+
method_tree_to_inlined_block(mobject, tree, method_name) || recursive_inline(tree)
|
320
|
+
|
321
|
+
else
|
322
|
+
# nothing to do, we don't know what is the method
|
323
|
+
recursive_inline(tree)
|
324
|
+
end
|
325
|
+
}.condition{|tree| tree.node_type == :call}
|
326
|
+
end
|
327
|
+
end
|
@@ -32,7 +32,7 @@ module FastRuby
|
|
32
32
|
end
|
33
33
|
|
34
34
|
define_method_handler(:process, :priority => -100) { |tree|
|
35
|
-
tree.map
|
35
|
+
tree.map {|subtree| process subtree}
|
36
36
|
}
|
37
37
|
|
38
38
|
define_method_handler(:process, :priority => 1000) { |tree|
|
@@ -68,8 +68,14 @@ module FastRuby
|
|
68
68
|
}.condition{|tree| tree.node_type == :iter}
|
69
69
|
end
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
if "1".respond_to?(:ord)
|
72
|
+
def inline_local_name(method_name, local_name)
|
73
|
+
"__inlined_#{method_name.to_s.gsub("_x_", "_x__x_").gsub(/\W/){|x| "_x_#{x.ord}" }}_#{local_name}".to_sym
|
74
|
+
end
|
75
|
+
else
|
76
|
+
def inline_local_name(method_name, local_name)
|
77
|
+
"__inlined_#{method_name.to_s.gsub("_x_", "_x__x_").gsub(/\W/){|x| "_x_#{x[0]}" }}_#{local_name}".to_sym
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
81
|
def method_obj_or_gtfo(klass, method_name)
|
@@ -82,7 +88,6 @@ module FastRuby
|
|
82
88
|
tree.walk_tree do |subtree|
|
83
89
|
if subtree.node_type == :lvar or subtree.node_type == :lasgn
|
84
90
|
subtree[1] = inline_local_name(prefix, subtree[1])
|
85
|
-
add_local subtree[1]
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
@@ -126,15 +131,10 @@ module FastRuby
|
|
126
131
|
(1..args_tree.size-1).each do |i|
|
127
132
|
itype = infer_type(args_tree[i])
|
128
133
|
inlined_name = inline_local_name(prefix, target_method_tree_args[i])
|
129
|
-
|
130
|
-
add_local inlined_name
|
131
|
-
|
132
|
-
self.extra_inferences[inlined_name] = itype if itype
|
133
134
|
newblock << fs(:lasgn, inlined_name, recursive_inline(args_tree[i].duplicate))
|
134
135
|
end
|
135
136
|
|
136
137
|
inlined_name = inline_local_name(prefix, :self)
|
137
|
-
add_local inlined_name
|
138
138
|
newblock << fs(:lasgn, inlined_name, recv_tree.duplicate)
|
139
139
|
|
140
140
|
return nil if target_method_tree_block.find_tree(:return)
|
@@ -179,14 +179,12 @@ module FastRuby
|
|
179
179
|
|
180
180
|
(1..yield_call_args.size-1).each do |i|
|
181
181
|
inlined_name = block_args_tree[1][i][1]
|
182
|
-
add_local inlined_name
|
183
182
|
subtree << fs(:lasgn, inlined_name, yield_call_args[i])
|
184
183
|
end
|
185
184
|
else
|
186
185
|
return nil if 2 != yield_call_args.size
|
187
186
|
|
188
187
|
inlined_name = block_args_tree[1]
|
189
|
-
add_local inlined_name
|
190
188
|
subtree << fs(:lasgn, inlined_name, yield_call_args[1])
|
191
189
|
end
|
192
190
|
else
|
@@ -226,10 +224,6 @@ module FastRuby
|
|
226
224
|
newblock
|
227
225
|
end
|
228
226
|
|
229
|
-
define_method_handler(:inline) { |tree|
|
230
|
-
tree
|
231
|
-
}.condition{|tree| tree.node_type == :defs}
|
232
|
-
|
233
227
|
define_method_handler(:inline) { |tree|
|
234
228
|
ret_tree = fs(:iter)
|
235
229
|
ret_tree << tree[1].duplicate
|
@@ -253,8 +247,8 @@ module FastRuby
|
|
253
247
|
# search the tree of target method
|
254
248
|
mobject = method_obj_or_gtfo(recvtype,method_name)
|
255
249
|
|
256
|
-
next
|
257
|
-
next
|
250
|
+
next ret_tree unless mobject
|
251
|
+
next ret_tree unless mobject.tree
|
258
252
|
|
259
253
|
exit_now = false
|
260
254
|
if block_tree.find_tree(:break) or block_tree.find_tree(:return)
|
@@ -268,10 +262,10 @@ module FastRuby
|
|
268
262
|
end
|
269
263
|
end
|
270
264
|
|
271
|
-
next
|
265
|
+
next ret_tree if exit_now
|
272
266
|
|
273
267
|
target_method_tree_args = mobject.tree[2]
|
274
|
-
next
|
268
|
+
next ret_tree if target_method_tree_args.find{|subtree| subtree.to_s =~ /^\*/}
|
275
269
|
|
276
270
|
method_tree_to_inlined_block(mobject, call_tree, method_name, block_args_tree, block_tree) || ret_tree
|
277
271
|
|
@@ -290,11 +284,7 @@ module FastRuby
|
|
290
284
|
args_tree = tree[3]
|
291
285
|
|
292
286
|
if method_name == :lvar_type
|
293
|
-
|
294
|
-
lvar_type = eval(args_tree[2][1].to_s)
|
295
|
-
|
296
|
-
@infer_lvar_map[lvar_name] = lvar_type
|
297
|
-
next recursive_inline(tree)
|
287
|
+
next tree
|
298
288
|
end
|
299
289
|
|
300
290
|
recvtype = infer_type(recv_tree)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
handler_scope :group => :def, :priority => 1000 do
|
28
|
+
define_method_handler(:inline) { |tree|
|
29
|
+
disable_handler_group(:def) do
|
30
|
+
inline(tree)
|
31
|
+
end
|
32
|
+
}.condition{|tree| tree.node_type == :defn}
|
33
|
+
|
34
|
+
define_method_handler(:inline) { |tree|
|
35
|
+
disable_handler_group(:def) do
|
36
|
+
inline(tree)
|
37
|
+
end
|
38
|
+
}.condition{|tree| tree.node_type == :defs}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
|
28
|
+
def recursive_inline(tree)
|
29
|
+
tree.map{|subtree| inline subtree}
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method_handler(:inline, :priority => -100) {|tree|
|
33
|
+
tree.map{|subtree| inline subtree}
|
34
|
+
}.condition{|tree| tree.respond_to?(:node_type)}
|
35
|
+
|
36
|
+
define_method_handler(:inline, :priority => 1000) {|tree|
|
37
|
+
tree
|
38
|
+
}.condition{|tree| not tree.respond_to?(:node_type)}
|
39
|
+
end
|
40
|
+
end
|
@@ -30,7 +30,7 @@ module FastRuby
|
|
30
30
|
end
|
31
31
|
|
32
32
|
define_method_handler(:inline, :priority => -100) {|tree|
|
33
|
-
tree.map
|
33
|
+
tree.map{|subtree| inline subtree}
|
34
34
|
}.condition{|tree| tree.respond_to?(:node_type)}
|
35
35
|
|
36
36
|
define_method_handler(:inline, :priority => 1000) {|tree|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "define_method_handler"
|
22
|
+
|
23
|
+
module FastRuby
|
24
|
+
class LvarType
|
25
|
+
define_method_handler(:process) {|tree|
|
26
|
+
args = tree[3]
|
27
|
+
lvar_name = args[1][1] || args[1][2]
|
28
|
+
lvar_type = eval(args[2][1].to_s)
|
29
|
+
|
30
|
+
@infer_lvar_map[lvar_name] = lvar_type
|
31
|
+
@inferencer.infer_lvar_map[lvar_name] = lvar_type
|
32
|
+
|
33
|
+
fs(:nil)
|
34
|
+
}.condition{|tree| tree && tree.node_type == :call && tree[2] == :lvar_type}
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "define_method_handler"
|
22
|
+
|
23
|
+
module FastRuby
|
24
|
+
class LvarType
|
25
|
+
define_method_handler(:process) {|tree|
|
26
|
+
args = tree[3]
|
27
|
+
lvar_name = args[1][1] || args[1][2]
|
28
|
+
lvar_type = eval(args[2][1].to_s)
|
29
|
+
|
30
|
+
@infer_lvar_map[lvar_name] = lvar_type
|
31
|
+
@inferencer.infer_lvar_map[lvar_name] = lvar_type
|
32
|
+
|
33
|
+
tree
|
34
|
+
}.condition{|tree| tree && tree.node_type == :call && tree[2] == :lvar_type }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "define_method_handler"
|
22
|
+
|
23
|
+
module FastRuby
|
24
|
+
class LvarType
|
25
|
+
define_method_handler(:process) {|tree|
|
26
|
+
if @process_defn_disabled
|
27
|
+
tree
|
28
|
+
else
|
29
|
+
old = @process_defn_disabled
|
30
|
+
@process_defn_disabled = true
|
31
|
+
begin
|
32
|
+
next tree.map{|subtree| process subtree}
|
33
|
+
ensure
|
34
|
+
@process_defn_disabled = old
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
tree
|
39
|
+
}.condition{|tree| tree.node_type == :defn or tree.node_type == :defs}
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|