fastruby 0.0.5 → 0.0.6

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.
@@ -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