fastruby 0.0.19 → 0.0.20
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 +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
|