fastruby 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,14 +18,10 @@ you should have received a copy of the gnu general public license
18
18
  along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  =end
21
- require "fastruby/translator"
22
21
  require "fastruby/builder"
23
22
  require "fastruby/getlocals"
24
23
  require "fastruby/method_extension"
25
- require "fastruby/translator"
26
- require "ruby_parser"
27
- require "inline"
28
-
24
+ require "fastruby/cache/cache"
29
25
 
30
26
  # clean rubyinline cache
31
27
  system("rm -fr #{ENV["HOME"]}/.ruby_inline/*")
@@ -47,313 +43,106 @@ module FastRuby
47
43
  s(:scope, s(:block, generated_tree)))
48
44
  end
49
45
 
50
- generated_tree
46
+ generated_tree.to_fastruby_sexp
51
47
  end
52
48
  end
53
49
 
54
50
  class Object
55
-
56
51
  def fastruby(argument, *options_hashes)
57
- tree = nil
58
-
59
- if argument.instance_of? Sexp
60
- tree = argument
61
- elsif argument.instance_of? String
62
- tree = RubyParser.new.parse(argument)
63
- else
64
- raise ArgumentError
52
+ options_hash = {:validate_lvar_types => true}
53
+ options_hash[:no_cache] = true if ENV['FASTRUBY_NO_CACHE'] == "1"
54
+ options_hashes.each do |opt|
55
+ options_hash.merge!(opt)
65
56
  end
66
57
 
67
- return unless tree
58
+ objs = Array.new
68
59
 
69
- if tree[0] == :class
70
- classname = Object.to_class_name tree[1]
60
+ unless options_hash[:no_cache]
61
+ snippet_hash = FastRuby.cache.hash_snippet(argument,options_hash[:validate_lvar_types].to_s)
62
+ objs = FastRuby.cache.retrieve(snippet_hash)
63
+ end
71
64
 
72
- if tree[2]
73
- superclassname = Object.to_class_name tree[2]
65
+ if objs.empty?
74
66
 
75
- eval("
76
- class #{classname} < #{superclassname}
77
- end
78
- ", $top_level_binding)
67
+ tree = nil
79
68
 
69
+ require "fastruby/fastruby_sexp"
70
+ if argument.instance_of? FastRuby::FastRubySexp
71
+ tree = argument
72
+ elsif argument.instance_of? String
73
+ require "rubygems"
74
+ require "ruby_parser"
75
+ require "fastruby/sexp_extension"
76
+ tree = RubyParser.new.parse(argument).to_fastruby_sexp
80
77
  else
81
- eval("
82
- class #{classname}
83
- end
84
- ", $top_level_binding)
85
- end
86
-
87
- klass = eval(classname)
88
-
89
- method_name = "_anonymous_" + rand(100000000000).to_s
90
- $generated_tree = FastRuby.encapsulate_tree(tree[3],method_name)
91
- $options_hashes = options_hashes
92
-
93
- klass.class_eval do
94
- class << self
95
- fastruby $generated_tree, *$options_hashes
96
- end
78
+ raise ArgumentError
97
79
  end
98
80
 
99
- klass.send(method_name)
100
- elsif tree[0] == :module
101
- modulename = Object.to_class_name tree[1]
102
-
103
- eval("
104
- module #{modulename}
105
- end
106
- ", $top_level_binding)
107
-
108
- klass = eval(modulename)
109
-
110
- method_name = "_anonymous_" + rand(100000000000).to_s
111
- $generated_tree = FastRuby.encapsulate_tree(tree[2],method_name)
112
- $options_hashes = options_hashes
81
+ return unless tree
82
+ method_name = "_anonymous_" + rand(100000000000).to_s
83
+ Object.execute_tree(FastRuby.encapsulate_tree(tree,method_name), :main => method_name, :self => self, :snippet_hash => snippet_hash, *[options_hash])
113
84
 
114
- klass.class_eval do
115
- class << self
116
- fastruby $generated_tree, *$options_hashes
117
- end
118
- end
119
-
120
- klass.send(method_name)
121
- elsif tree[0] == :defn
122
- Object.fastruby_defn(tree, *options_hashes)
123
85
  else
124
- method_name = "_anonymous_" + rand(100000000000).to_s
125
- Object.fastruby(FastRuby.encapsulate_tree(tree,method_name), *options_hashes)
126
- send(method_name)
127
- end
128
- end
129
-
130
- def self.fastruby_defs(*args)
131
- raise NoMethodError, "not implemented yet"
132
- end
133
-
134
- def self.fastruby(argument,*options_hashes)
135
86
 
136
- tree = nil
87
+ objs.sort{|x,y|
88
+ (y =~ /Inline_Object/ ? 1 : 0) - (x =~ /Inline_Object/ ? 1 : 0)
89
+ }.each do |obj|
137
90
 
138
- if argument.instance_of? Sexp
139
- tree = argument
140
- elsif argument.instance_of? String
141
- tree = RubyParser.new.parse(argument)
142
- else
143
- raise ArgumentError
144
- end
145
-
146
- return unless tree
147
-
148
- if tree.node_type == :defn
149
- fastruby_defn(tree,*options_hashes)
150
- else
151
- method_name = "_anonymous_" + rand(100000000000).to_s
152
- $generated_tree = FastRuby.encapsulate_tree(tree,method_name)
153
- $options_hashes = options_hashes
154
-
155
- klass = self
156
- klass.class_eval do
157
- class << self
158
- fastruby_defn($generated_tree,*$options_hashes)
91
+ begin
92
+ $last_obj_proc = nil
93
+ require obj
94
+ if $last_obj_proc
95
+ FastRuby.cache.register_proc(obj, $last_obj_proc)
96
+ end
97
+ FastRuby.cache.execute(obj, self)
98
+ rescue
159
99
  end
160
100
  end
161
-
162
- send(method_name)
163
101
  end
164
-
165
102
  end
166
103
 
167
- def self.fastruby_defn(tree, *options_hashes)
168
-
104
+ def self.execute_tree(argument,*options_hashes)
169
105
  options_hash = {:validate_lvar_types => true}
170
106
  options_hashes.each do |opt|
171
107
  options_hash.merge!(opt)
172
108
  end
173
109
 
174
- if tree[0] == :block
175
- (1..tree.size-1).each do |i|
176
- fastruby(tree[i], *options_hashes)
177
- end
178
-
179
- return
180
- elsif tree[0] != :defn
181
- raise ArgumentError, "Only definition of methods are accepted"
110
+ require "fastruby/fastruby_sexp"
111
+ if argument.instance_of? FastRuby::FastRubySexp
112
+ tree = argument
113
+ elsif argument.instance_of? String
114
+ require "rubygems"
115
+ require "ruby_parser"
116
+ require "fastruby/sexp_extension"
117
+ tree = RubyParser.new.parse(argument).to_fastruby_sexp
118
+ else
119
+ require "pry"
120
+ binding.pry
121
+ raise ArgumentError
182
122
  end
183
123
 
184
124
  method_name = tree[1]
185
- args_tree = tree[2]
186
-
187
- hashname = "$hash" + rand(1000000).to_s
188
125
 
189
- hash = Hash.new
126
+ self_ = options_hash[:self]
127
+ self_ = self unless self_.instance_of? Class
190
128
 
191
- locals = Set.new
192
- locals << :self
129
+ FastRuby.set_tree(self_, method_name, tree, options_hash[:snippet_hash], options_hash)
193
130
 
194
- FastRuby::GetLocalsProcessor.get_locals(tree).each do |local|
195
- locals << local
131
+ class << self
132
+ $metaclass = self
196
133
  end
197
134
 
198
- self_ = self
199
- hash.instance_eval{@klass = self_}
200
- hash.instance_eval{@method_name = method_name}
201
-
202
- class_eval do
203
- class << self
204
- include FastRuby::BuilderModule
205
- end
206
- end
207
-
208
- fastrubym = self_.fastruby_method(method_name)
209
- fastrubym.tree = tree
210
- fastrubym.locals = locals
211
- fastrubym.options = options_hash
212
-
213
- def hash.build(key)
214
- @klass.build(key, @method_name)
215
- end
216
-
217
- eval("#{hashname} = hash")
218
-
219
- value_cast = ( ["VALUE"]*(args_tree.size+2) ).join(",")
220
-
221
- main_signature_argument = args_tree[1..-1].first || "self"
222
-
223
- strmethodargs = ""
224
- strmethodargs_class = (["self"] + args_tree[1..-1]).map{|arg| "CLASS_OF(#{arg.to_s})"}.join(",")
225
-
226
- if args_tree.size > 1
227
- strmethodargs = "self,block,(VALUE)&frame,#{args_tree[1..-1].map(&:to_s).join(",") }"
228
- else
229
- strmethodargs = "self,block,(VALUE)&frame"
230
- end
231
-
232
- strmethod_signature = (["self"] + args_tree[1..-1]).map { |arg|
233
- "sprintf(method_name+strlen(method_name), \"%lu\", CLASS_OF(#{arg}));\n"
234
- }.join
235
-
236
- c_code = "VALUE #{method_name}(#{args_tree[1..-1].map{|arg| "VALUE #{arg}" }.join(",")}) {
237
- VALUE method_hash = (VALUE)#{hash.internal_value};
238
- VALUE klass = (VALUE)#{self.internal_value};
239
-
240
- char method_name[0x100];
241
-
242
- method_name[0] = '_';
243
- method_name[1] = 0;
244
-
245
- sprintf(method_name+1, \"#{method_name}\");
246
- #{strmethod_signature}
247
-
248
- NODE* body;
249
- ID id;
250
-
251
- id = rb_intern(method_name);
252
- body = rb_method_node(klass,id);
253
-
254
- if (body == 0) {
255
- VALUE argv_class[] = {#{strmethodargs_class} };
256
- VALUE signature = rb_ary_new4(#{args_tree.size},argv_class);
257
-
258
- rb_funcall(method_hash, #{:build.to_i}, 1, signature);
259
- body = rb_method_node(klass,id);
260
- }
261
-
262
- if (nd_type(body) == NODE_CFUNC) {
263
- struct {
264
- void* parent_frame;
265
- void* target_frame;
266
- void* plocals;
267
- jmp_buf jmp;
268
- VALUE return_value;
269
- VALUE exception;
270
- int rescue;
271
- } frame;
272
-
273
- frame.target_frame = 0;
274
- frame.parent_frame = 0;
275
- frame.rescue = 0;
276
- frame.exception = Qnil;
277
- frame.return_value = Qnil;
278
-
279
- int argc = body->nd_argc;
280
-
281
- VALUE block = Qfalse;
282
-
283
- if (rb_block_given_p()) {
284
- struct {
285
- void *block_function_address;
286
- void *block_function_param;
287
- } block_struct;
288
-
289
- block_struct.block_function_address = re_yield;
290
- block_struct.block_function_param = 0;
291
-
292
- block = (VALUE)&block_struct;
293
- }
294
-
295
- int aux = setjmp(frame.jmp);
296
- if (aux != 0) {
297
- if (frame.target_frame == (void*)-1) {
298
- rb_funcall(self, #{:raise.to_i}, 1, frame.exception);
299
- }
300
-
301
- if (frame.target_frame != &frame) {
302
- VALUE ex = rb_funcall(
303
- (VALUE)#{FastRuby::Context::UnwindFastrubyFrame.internal_value},
304
- #{:new.to_i},
305
- 3,
306
- frame.exception,
307
- LONG2FIX(frame.target_frame),
308
- frame.return_value
309
- );
310
-
311
- rb_funcall(self, #{:raise.to_i}, 1, ex);
312
- }
313
-
314
- return Qnil;
315
- }
316
-
317
- if (argc == #{args_tree.size+1}) {
318
- return ((VALUE(*)(#{value_cast}))body->nd_cfnc)(#{strmethodargs});
319
- } else if (argc == -1) {
320
- VALUE argv[] = {#{(["block,(VALUE)&frame"]+args_tree[1..-1]).map(&:to_s).join(",")} };
321
- return ((VALUE(*)(int,VALUE*,VALUE))body->nd_cfnc)(#{args_tree.size},argv,self);
322
- } else if (argc == -2) {
323
- VALUE argv[] = {#{(["block,(VALUE)&frame"]+args_tree[1..-1]).map(&:to_s).join(",")} };
324
- return ((VALUE(*)(VALUE,VALUE))body->nd_cfnc)(self, rb_ary_new4(#{args_tree.size},argv));
325
- } else {
326
- rb_raise(rb_eArgError, \"wrong number of arguments (#{args_tree.size-1} for %d)\", argc);
327
- }
328
- }
329
-
330
- return Qnil;
331
- }"
332
-
333
- inline :C do |builder|
334
- builder.include "<node.h>"
335
- builder.inc << "static VALUE re_yield(int argc, VALUE* argv, VALUE param, VALUE _parent_frame) {
336
- return rb_yield_splat(rb_ary_new4(argc,argv));
337
- }"
338
- builder.c c_code
339
- end
135
+ self_.build([$class_self],method_name,true)
340
136
  end
341
137
 
342
- def internal_value
138
+ def gc_register_object
343
139
  $refered_from_code_array = Array.new unless $refered_from_code_array
344
140
  $refered_from_code_array << self
345
-
346
- internal_value_
347
- end
348
-
349
- inline :C do |builder|
350
- builder.c "VALUE internal_value_() {
351
- return INT2FIX(self);
352
- }"
353
141
  end
354
142
 
355
143
  private
356
144
  def self.to_class_name(argument)
145
+ require "sexp"
357
146
  if argument.instance_of? Symbol
358
147
  argument.to_s
359
148
  elsif argument.instance_of? Sexp
@@ -0,0 +1,61 @@
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/builder"
22
+ require "fastruby/getlocals"
23
+ require "fastruby/method_extension"
24
+
25
+ module FastRuby
26
+
27
+ def self.make_str_signature(method_name, signature)
28
+ "_" + method_name.to_s + signature.map(&:__id__).map(&:to_s).join
29
+ end
30
+
31
+ def self.set_builder_module(klass)
32
+ klass.class_eval do
33
+ class << self
34
+ include FastRuby::BuilderModule
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.set_tree(klass, method_name, tree, snippet_hash, options = {})
40
+ locals = Set.new
41
+ locals << :self
42
+
43
+ FastRuby::GetLocalsProcessor.get_locals(tree).each do |local|
44
+ locals << local
45
+ end
46
+
47
+ klass.class_eval do
48
+ class << self
49
+ include FastRuby::BuilderModule
50
+ end
51
+ end
52
+
53
+ fastrubym = klass.fastruby_method(method_name)
54
+ fastrubym.tree = tree
55
+ fastrubym.locals = locals
56
+ fastrubym.options = options
57
+ fastrubym.snippet_hash = snippet_hash
58
+
59
+ nil
60
+ end
61
+ end
@@ -0,0 +1,37 @@
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/fastruby_sexp"
22
+
23
+ class Object
24
+ def to_fastruby_sexp
25
+ self
26
+ end
27
+ end
28
+
29
+ class Sexp
30
+ def to_fastruby_sexp
31
+ ary = FastRuby::FastRubySexp.new
32
+ each do |x|
33
+ ary << x.to_fastruby_sexp
34
+ end
35
+ ary
36
+ end
37
+ end