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
|
@@ -21,6 +21,7 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
|
|
21
21
|
require "set"
|
|
22
22
|
require "sexp"
|
|
23
23
|
require "define_method_handler"
|
|
24
|
+
require "fastruby/modules"
|
|
24
25
|
|
|
25
26
|
module FastRuby
|
|
26
27
|
class Reductor
|
|
@@ -28,12 +29,14 @@ module FastRuby
|
|
|
28
29
|
define_method_handler(:reduce, options, &blk).condition{|tree| tree.respond_to?(:node_type) && tree.node_type == ntype}
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def call(*args)
|
|
33
|
+
reduce *args
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
define_method_handler(:reduce, :priority => -1000) do |tree|
|
|
32
37
|
FastRubySexp.from_sexp(tree)
|
|
33
38
|
end
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
require path
|
|
37
|
-
end
|
|
40
|
+
FastRuby::Modules.load_all("reductor")
|
|
38
41
|
end
|
|
39
42
|
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 "set"
|
|
22
|
+
require "sexp"
|
|
23
|
+
require "define_method_handler"
|
|
24
|
+
require "fastruby/modules"
|
|
25
|
+
|
|
26
|
+
module FastRuby
|
|
27
|
+
class Reductor
|
|
28
|
+
def self.reduce_for(ntype, options = {}, &blk)
|
|
29
|
+
define_method_handler(:reduce, options, &blk).condition{|*x| tree = x.first; tree.respond_to?(:node_type) && tree.node_type == ntype}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def call(*args)
|
|
33
|
+
reduce args.first
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
define_method_handler(:reduce, :priority => -1000) do |*x| tree = x.first;
|
|
37
|
+
FastRubySexp.from_sexp(tree)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
FastRuby::Modules.load_all("reductor")
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/fastruby/builder.rb
CHANGED
|
@@ -22,19 +22,18 @@ require "fastruby/method_extension"
|
|
|
22
22
|
require "fastruby/logging"
|
|
23
23
|
require "fastruby/getlocals"
|
|
24
24
|
require "fastruby_load_path"
|
|
25
|
-
require "fastruby/
|
|
26
|
-
require "fastruby/
|
|
27
|
-
require "
|
|
28
|
-
require "
|
|
29
|
-
require "fastruby/
|
|
25
|
+
require "fastruby/builder/inliner"
|
|
26
|
+
require "fastruby/builder/inferencer"
|
|
27
|
+
require "fastruby/builder/lvar_type"
|
|
28
|
+
require "fastruby/builder/pipeline"
|
|
29
|
+
require "fastruby/builder/locals_inference"
|
|
30
|
+
require "fastruby/builder/inference_updater"
|
|
30
31
|
|
|
31
32
|
require FastRuby.fastruby_load_path + "/../ext/fastruby_base/fastruby_base"
|
|
32
33
|
|
|
33
34
|
module FastRuby
|
|
34
35
|
class Method
|
|
35
|
-
attr_accessor :locals
|
|
36
36
|
attr_accessor :options
|
|
37
|
-
attr_accessor :snippet_hash
|
|
38
37
|
|
|
39
38
|
def initialize(method_name, owner)
|
|
40
39
|
@method_name = method_name
|
|
@@ -69,15 +68,22 @@ module FastRuby
|
|
|
69
68
|
rebuild(signature, noreturn)
|
|
70
69
|
end
|
|
71
70
|
|
|
71
|
+
def has_loops?(tree)
|
|
72
|
+
if tree.respond_to? :node_type
|
|
73
|
+
nt = tree.node_type
|
|
74
|
+
return false if nt == :defn or nt == :defs
|
|
75
|
+
return true if nt == :for or nt == :iter or nt == :while or nt == :retry
|
|
76
|
+
tree.each do |subtree|
|
|
77
|
+
return true if has_loops? subtree
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
false
|
|
81
|
+
end
|
|
82
|
+
|
|
72
83
|
def rebuild(signature, noreturn = false)
|
|
73
84
|
no_cache = false
|
|
74
85
|
mname = FastRuby.make_str_signature(@method_name, signature)
|
|
75
86
|
|
|
76
|
-
inliner = FastRuby::Inliner.new
|
|
77
|
-
|
|
78
|
-
context = FastRuby::Context.new
|
|
79
|
-
context.options = options
|
|
80
|
-
|
|
81
87
|
args_tree = if tree[0] == :defn
|
|
82
88
|
tree[2]
|
|
83
89
|
elsif tree[0] == :defs
|
|
@@ -85,10 +91,15 @@ module FastRuby
|
|
|
85
91
|
else
|
|
86
92
|
raise ArgumentError, "unknown type of method definition #{tree[0]}"
|
|
87
93
|
end
|
|
94
|
+
|
|
95
|
+
impl_tree = if tree[0] == :defn
|
|
96
|
+
tree[3]
|
|
97
|
+
elsif tree[0] == :defs
|
|
98
|
+
tree[4]
|
|
99
|
+
end
|
|
88
100
|
|
|
89
101
|
# create random method name
|
|
90
|
-
|
|
91
|
-
context.alt_method_name = "_" + @method_name.to_s + "_" + rand(10000000000).to_s
|
|
102
|
+
infer_lvar_map = Hash.new
|
|
92
103
|
|
|
93
104
|
(1..signature.size-1).each do |i|
|
|
94
105
|
arg = args_tree[i]
|
|
@@ -97,26 +108,48 @@ module FastRuby
|
|
|
97
108
|
|
|
98
109
|
if arg
|
|
99
110
|
if arg.to_s.match(/\*/)
|
|
100
|
-
|
|
111
|
+
infer_lvar_map[arg.to_s.gsub("*","").to_sym] = Array
|
|
101
112
|
else
|
|
102
|
-
|
|
113
|
+
infer_lvar_map[arg.to_sym] = signature[i]
|
|
103
114
|
end
|
|
104
115
|
end
|
|
105
116
|
end
|
|
106
117
|
end
|
|
107
118
|
|
|
108
|
-
|
|
119
|
+
inferencer = Inferencer.new
|
|
120
|
+
inferencer.infer_self = signature[0]
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
locals_inference = LocalsInference.new
|
|
123
|
+
locals_inference.infer_self = signature[0]
|
|
124
|
+
locals_inference.infer_lvar_map = infer_lvar_map
|
|
125
|
+
|
|
126
|
+
inference_updater = InferenceUpdater.new(inferencer)
|
|
127
|
+
|
|
128
|
+
inliner = FastRuby::Inliner.new(inferencer)
|
|
129
|
+
pipeline = Pipeline.new
|
|
130
|
+
|
|
131
|
+
if options[:validate_lvar_types]
|
|
132
|
+
pipeline << LvarType.new(locals_inference)
|
|
133
|
+
end
|
|
134
|
+
pipeline << locals_inference
|
|
115
135
|
|
|
116
|
-
|
|
117
|
-
|
|
136
|
+
if has_loops?(impl_tree)
|
|
137
|
+
pipeline << inliner
|
|
138
|
+
if options[:validate_lvar_types]
|
|
139
|
+
pipeline << LvarType.new(locals_inference)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
pipeline << inference_updater
|
|
143
|
+
pipeline << inliner
|
|
144
|
+
if options[:validate_lvar_types]
|
|
145
|
+
pipeline << LvarType.new(locals_inference)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
pipeline << inference_updater
|
|
118
149
|
end
|
|
119
150
|
|
|
151
|
+
inlined_tree = pipeline.call(tree)
|
|
152
|
+
|
|
120
153
|
inliner.inlined_methods.each do |inlined_method|
|
|
121
154
|
inlined_method.observe("#{@owner}##{@method_name}#{mname}") do |imethod|
|
|
122
155
|
rebuild(signature, noreturn)
|
|
@@ -133,6 +166,20 @@ module FastRuby
|
|
|
133
166
|
|
|
134
167
|
$last_obj_proc = nil
|
|
135
168
|
if paths.empty?
|
|
169
|
+
unless Object.respond_to? :inline
|
|
170
|
+
require "rubygems"
|
|
171
|
+
require "inline"
|
|
172
|
+
require "fastruby/inline_extension"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
unless defined? FastRuby::Context
|
|
176
|
+
require "fastruby/translator/translator"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context = FastRuby::Context.new(true, inferencer)
|
|
180
|
+
context.options = options
|
|
181
|
+
context.locals = FastRuby::GetLocalsProcessor.get_locals(inlined_tree)
|
|
182
|
+
|
|
136
183
|
FastRuby.logger.info "Compiling #{@owner}::#{@method_name} for signature #{signature.inspect}"
|
|
137
184
|
c_code = context.to_c_method(inlined_tree,signature)
|
|
138
185
|
|
|
@@ -248,8 +295,9 @@ module FastRuby
|
|
|
248
295
|
@method_hash = Hash.new unless @method_hash
|
|
249
296
|
@method_hash[method_name]
|
|
250
297
|
end
|
|
251
|
-
|
|
298
|
+
|
|
252
299
|
def method_added(method_name)
|
|
300
|
+
clear_method_hash_addresses(@method_hash[method_name]) if @method_hash and @method_hash[method_name]
|
|
253
301
|
FastRuby.unset_tree(self,method_name)
|
|
254
302
|
end
|
|
255
303
|
|
|
@@ -0,0 +1,311 @@
|
|
|
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 "fastruby/method_extension"
|
|
22
|
+
require "fastruby/logging"
|
|
23
|
+
require "fastruby/getlocals"
|
|
24
|
+
require "fastruby_load_path"
|
|
25
|
+
require "fastruby/builder/inliner"
|
|
26
|
+
require "fastruby/builder/inferencer"
|
|
27
|
+
require "fastruby/builder/lvar_type"
|
|
28
|
+
require "fastruby/builder/pipeline"
|
|
29
|
+
require "fastruby/builder/locals_inference"
|
|
30
|
+
require "fastruby/builder/inference_updater"
|
|
31
|
+
|
|
32
|
+
require FastRuby.fastruby_load_path + "/../ext/fastruby_base/fastruby_base"
|
|
33
|
+
|
|
34
|
+
module FastRuby
|
|
35
|
+
class Method
|
|
36
|
+
attr_accessor :options
|
|
37
|
+
|
|
38
|
+
def initialize(method_name, owner)
|
|
39
|
+
@method_name = method_name
|
|
40
|
+
@owner = owner
|
|
41
|
+
@observers = Hash.new
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def observe(key, &blk)
|
|
45
|
+
@observers[key] = blk
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def tree_changed
|
|
49
|
+
@observers.values.each do |observer|
|
|
50
|
+
observer.call(self)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def build(signature, noreturn = false)
|
|
55
|
+
return nil unless tree
|
|
56
|
+
|
|
57
|
+
no_cache = false
|
|
58
|
+
mname = FastRuby.make_str_signature(@method_name, signature)
|
|
59
|
+
|
|
60
|
+
if @owner.respond_to? :method_hash
|
|
61
|
+
method_hash = @owner.method_hash(@method_name.to_sym) || {}
|
|
62
|
+
if (@owner.has_fastruby_function(method_hash,mname.to_s))
|
|
63
|
+
FastRuby.logger.info "NOT Building #{@owner}::#{@method_name} for signature #{signature.inspect}, it's already done"
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
rebuild(signature, noreturn)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def has_loops?(tree)
|
|
72
|
+
if tree.respond_to? :node_type
|
|
73
|
+
nt = tree.node_type
|
|
74
|
+
return false if nt == :defn or nt == :defs
|
|
75
|
+
return true if nt == :for or nt == :iter or nt == :while or nt == :retry
|
|
76
|
+
tree.each do |subtree|
|
|
77
|
+
return true if has_loops? subtree
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def rebuild(signature, noreturn = false)
|
|
84
|
+
no_cache = false
|
|
85
|
+
mname = FastRuby.make_str_signature(@method_name, signature)
|
|
86
|
+
|
|
87
|
+
args_tree = if tree[0] == :defn
|
|
88
|
+
tree[2]
|
|
89
|
+
elsif tree[0] == :defs
|
|
90
|
+
tree[3]
|
|
91
|
+
else
|
|
92
|
+
raise ArgumentError, "unknown type of method definition #{tree[0]}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
impl_tree = if tree[0] == :defn
|
|
96
|
+
tree[3]
|
|
97
|
+
elsif tree[0] == :defs
|
|
98
|
+
tree[4]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# create random method name
|
|
102
|
+
infer_lvar_map = Hash.new
|
|
103
|
+
|
|
104
|
+
(1..signature.size-1).each do |i|
|
|
105
|
+
arg = args_tree[i]
|
|
106
|
+
|
|
107
|
+
if arg.instance_of? Symbol
|
|
108
|
+
|
|
109
|
+
if arg
|
|
110
|
+
if arg.to_s.match(/\*/)
|
|
111
|
+
infer_lvar_map[arg.to_s.gsub("*","").to_sym] = Array
|
|
112
|
+
else
|
|
113
|
+
infer_lvar_map[arg.to_sym] = signature[i]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
inferencer = Inferencer.new
|
|
120
|
+
inferencer.infer_self = signature[0]
|
|
121
|
+
|
|
122
|
+
locals_inference = LocalsInference.new
|
|
123
|
+
locals_inference.infer_self = signature[0]
|
|
124
|
+
locals_inference.infer_lvar_map = infer_lvar_map
|
|
125
|
+
|
|
126
|
+
inference_updater = InferenceUpdater.new(inferencer)
|
|
127
|
+
|
|
128
|
+
inliner = FastRuby::Inliner.new(inferencer)
|
|
129
|
+
pipeline = Pipeline.new
|
|
130
|
+
|
|
131
|
+
if options[:validate_lvar_types]
|
|
132
|
+
pipeline << LvarType.new(locals_inference)
|
|
133
|
+
end
|
|
134
|
+
pipeline << locals_inference
|
|
135
|
+
|
|
136
|
+
if has_loops?(impl_tree)
|
|
137
|
+
pipeline << inliner
|
|
138
|
+
if options[:validate_lvar_types]
|
|
139
|
+
pipeline << LvarType.new(locals_inference)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
pipeline << inference_updater
|
|
143
|
+
pipeline << inliner
|
|
144
|
+
if options[:validate_lvar_types]
|
|
145
|
+
pipeline << LvarType.new(locals_inference)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
pipeline << inference_updater
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
inlined_tree = pipeline.call(tree)
|
|
152
|
+
|
|
153
|
+
inliner.inlined_methods.each do |inlined_method|
|
|
154
|
+
inlined_method.observe("#{@owner}##{@method_name}#{mname}") do |imethod|
|
|
155
|
+
rebuild(signature, noreturn)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
alt_options = options.dup
|
|
160
|
+
alt_options.delete(:self)
|
|
161
|
+
|
|
162
|
+
require "pry"; binding.pry
|
|
163
|
+
code_sha1 = FastRuby.cache.hash_snippet(inlined_tree.inspect, FastRuby::VERSION + signature.map(&:to_s).join('-') + alt_options.inspect)
|
|
164
|
+
|
|
165
|
+
paths = FastRuby.cache.retrieve(code_sha1)
|
|
166
|
+
|
|
167
|
+
$last_obj_proc = nil
|
|
168
|
+
if paths.empty?
|
|
169
|
+
unless Object.respond_to? :inline
|
|
170
|
+
require "rubygems"
|
|
171
|
+
require "inline"
|
|
172
|
+
require "fastruby/inline_extension"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
unless defined? FastRuby::Context
|
|
176
|
+
require "fastruby/translator/translator"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context = FastRuby::Context.new(true, inferencer)
|
|
180
|
+
context.options = options
|
|
181
|
+
context.locals = FastRuby::GetLocalsProcessor.get_locals(inlined_tree)
|
|
182
|
+
|
|
183
|
+
FastRuby.logger.info "Compiling #{@owner}::#{@method_name} for signature #{signature.inspect}"
|
|
184
|
+
c_code = context.to_c_method(inlined_tree,signature)
|
|
185
|
+
|
|
186
|
+
unless options[:main]
|
|
187
|
+
context.define_method_at_init(@method_name, args_tree.size+1, signature)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
so_name = nil
|
|
191
|
+
|
|
192
|
+
old_class_self = $class_self
|
|
193
|
+
$class_self = @owner
|
|
194
|
+
|
|
195
|
+
begin
|
|
196
|
+
|
|
197
|
+
unless $inline_extra_flags
|
|
198
|
+
$inline_extra_flags = true
|
|
199
|
+
|
|
200
|
+
['CFLAGS','CXXFLAGS','OPTFLAGS','cflags','cxxflags','optflags'].each do |name|
|
|
201
|
+
RbConfig::CONFIG[name].gsub!(/\-O\d/,"-O1") if RbConfig::CONFIG[name]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
if RUBY_VERSION =~ /^1\.8/
|
|
205
|
+
RbConfig::CONFIG['CFLAGS'] << " -DRUBY_1_8 -Wno-clobbered"
|
|
206
|
+
elsif RUBY_VERSION =~ /^1\.9/
|
|
207
|
+
RbConfig::CONFIG['CFLAGS'] << " -DRUBY_1_9 -Wno-clobbered"
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
@owner.class_eval do
|
|
212
|
+
inline :C do |builder|
|
|
213
|
+
builder.inc << context.extra_code
|
|
214
|
+
builder.init_extra = context.init_extra
|
|
215
|
+
|
|
216
|
+
def builder.generate_ext
|
|
217
|
+
ext = []
|
|
218
|
+
|
|
219
|
+
@inc.unshift "#include \"ruby.h\""
|
|
220
|
+
|
|
221
|
+
ext << @inc
|
|
222
|
+
ext << nil
|
|
223
|
+
ext << @src.join("\n\n")
|
|
224
|
+
ext << nil
|
|
225
|
+
ext << nil
|
|
226
|
+
ext << "#ifdef __cplusplus"
|
|
227
|
+
ext << "extern \"C\" {"
|
|
228
|
+
ext << "#endif"
|
|
229
|
+
ext << " void Init_#{module_name}() {"
|
|
230
|
+
|
|
231
|
+
ext << @init_extra.join("\n") unless @init_extra.empty?
|
|
232
|
+
|
|
233
|
+
ext << nil
|
|
234
|
+
ext << " }"
|
|
235
|
+
ext << "#ifdef __cplusplus"
|
|
236
|
+
ext << "}"
|
|
237
|
+
ext << "#endif"
|
|
238
|
+
ext << nil
|
|
239
|
+
|
|
240
|
+
ext.join "\n"
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
builder.c c_code
|
|
244
|
+
so_name = builder.so_name
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
unless no_cache
|
|
249
|
+
no_cache = context.no_cache
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
unless no_cache
|
|
253
|
+
FastRuby.cache.insert(code_sha1, so_name)
|
|
254
|
+
end
|
|
255
|
+
ensure
|
|
256
|
+
$class_self = old_class_self
|
|
257
|
+
end
|
|
258
|
+
else
|
|
259
|
+
paths.each do |path|
|
|
260
|
+
require path
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
if $last_obj_proc
|
|
265
|
+
FastRuby.cache.register_proc(code_sha1, $last_obj_proc)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
$class_self = @owner
|
|
269
|
+
begin
|
|
270
|
+
FastRuby.cache.execute(code_sha1, signature, @owner)
|
|
271
|
+
ensure
|
|
272
|
+
$class_self = old_class_self
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
observe("#{@owner}##{@method_name}#{mname}") do |imethod|
|
|
276
|
+
if tree
|
|
277
|
+
rebuild(signature, noreturn)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
module BuilderModule
|
|
284
|
+
def build(signature, method_name, noreturn = false)
|
|
285
|
+
fastruby_method(method_name.to_sym).build(signature, noreturn)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def register_method_value(method_name,key,value)
|
|
289
|
+
@method_hash = Hash.new unless @method_hash
|
|
290
|
+
@method_hash[method_name] = Hash.new unless @method_hash[method_name]
|
|
291
|
+
@method_hash[method_name][key] = value
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def method_hash(method_name)
|
|
295
|
+
@method_hash = Hash.new unless @method_hash
|
|
296
|
+
@method_hash[method_name]
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def method_added(method_name)
|
|
300
|
+
clear_method_hash_addresses(@method_hash[method_name]) if @method_hash and @method_hash[method_name]
|
|
301
|
+
FastRuby.unset_tree(self,method_name)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def fastruby_method(mname_)
|
|
305
|
+
mname = mname_.to_sym
|
|
306
|
+
@fastruby_method = Hash.new unless @fastruby_method
|
|
307
|
+
@fastruby_method[mname] = FastRuby::Method.new(mname,self) unless @fastruby_method[mname]
|
|
308
|
+
@fastruby_method[mname]
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
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 "fastruby/sexp_extension"
|
|
22
|
+
|
|
23
|
+
class Fixnum
|
|
24
|
+
fastruby(:fastruby_only => true, :skip_reduce => true) do
|
|
25
|
+
if RUBY_VERSION =~ /^1\\.9/
|
|
26
|
+
def +(b)
|
|
27
|
+
if b._class == Fixnum
|
|
28
|
+
_static{LONG2NUM(FIX2LONG(self)+FIX2LONG(b))}
|
|
29
|
+
elsif b._class == Bignum
|
|
30
|
+
_static{rb_big_plus(b,self)}
|
|
31
|
+
elsif b._class == Float
|
|
32
|
+
_static{DBL2NUM(FIX2LONG(self) + RFLOAT_VALUE(b))}
|
|
33
|
+
else
|
|
34
|
+
_static{rb_num_coerce_bin(self, b, inline_c("'+'"))}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def -(b)
|
|
39
|
+
if b._class == Fixnum
|
|
40
|
+
_static{LONG2NUM(FIX2LONG(self)-FIX2LONG(b))}
|
|
41
|
+
elsif b._class == Bignum
|
|
42
|
+
_static{rb_big_minus(rb_int2big(FIX2LONG(self)),b)}
|
|
43
|
+
elsif b._class == Float
|
|
44
|
+
_static{DBL2NUM(FIX2LONG(self) - RFLOAT_VALUE(b))}
|
|
45
|
+
else
|
|
46
|
+
_static{rb_num_coerce_bin(self, b, inline_c("'-'"))}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def >(y)
|
|
51
|
+
if y._class == Fixnum
|
|
52
|
+
_static{FIX2LONG(self)>FIX2LONG(y) ? true: false }
|
|
53
|
+
elsif y._class == Bignum
|
|
54
|
+
_static{FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(self)), y)) > 0 ? true : false}
|
|
55
|
+
elsif y._class == Float
|
|
56
|
+
_static{FIX2LONG(self) > RFLOAT_VALUE(y) ? true : false}
|
|
57
|
+
else
|
|
58
|
+
_static{rb_num_coerce_relop(self, y, inline_c("'>'"))}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def <(y)
|
|
63
|
+
if y._class == Fixnum
|
|
64
|
+
_static{FIX2LONG(self)<FIX2LONG(y) ? true: false }
|
|
65
|
+
elsif y._class == Bignum
|
|
66
|
+
_static{FIX2INT(rb_big_cmp(rb_int2big(FIX2LONG(self)), y)) < 0 ? true : false}
|
|
67
|
+
elsif y._class == Float
|
|
68
|
+
_static{FIX2LONG(self) < RFLOAT_VALUE(y) ? true : false}
|
|
69
|
+
else
|
|
70
|
+
_static{rb_num_coerce_relop(self, y, inline_c("'<'"))}
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|