fastruby 0.0.15 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/README +2 -0
- data/Rakefile +2 -2
- data/ext/fastruby_base/extconf.rb +11 -1
- data/ext/fastruby_base/fastruby_base.inl +47 -3
- data/lib/fastruby/builder.rb +15 -2
- data/lib/fastruby/cache/cache.rb +2 -2
- data/lib/fastruby/inline_extension.rb +13 -60
- data/lib/fastruby/object.rb +1 -1
- data/lib/fastruby/self +82 -0
- data/lib/fastruby/sexp_extension.rb +13 -5
- data/lib/fastruby/translator/modules/block.rb +3 -3
- data/lib/fastruby/translator/modules/call.rb +2 -2
- data/lib/fastruby/translator/modules/defn.rb +3 -1
- data/lib/fastruby/translator/modules/iter.rb +85 -22
- data/lib/fastruby/translator/modules/variable.rb +5 -1
- data/lib/fastruby/translator/translator.rb +53 -14
- data/lib/fastruby.rb +8 -1
- data/lib/len +280 -0
- data/spec/block/callcc_spec.rb +3 -0
- data/spec/block_spec.rb +16 -0
- data/spec/defn/multiple_args_spec.rb +2 -2
- metadata +11 -12
- data/lib/targetted +0 -84
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -57,6 +57,8 @@ I will stabilize the API and document it for next releases. I promise
|
|
57
57
|
|
58
58
|
== Known Limitations & Issues
|
59
59
|
|
60
|
+
* fastruby now works with ruby1.9, but features specific to ruby1.9 (such fibers and new hash notation) will not work or will work with unexpected behaviour
|
61
|
+
* fastruby on ruby1.8 is faster than ruby1.8 on a few cases (see benchmarks) but is slower than ruby1.9
|
60
62
|
* callcc is not supported, it works but using it may result in unexpected behaviour
|
61
63
|
* calls with blocks to ruby or cruby methods are almost as slow as normal ruby (if the called method is defined by fastruby, the call is pretty fast)
|
62
64
|
* replacement of methods using identical code strings will work, but it will generate duplicated objects on the cache each time te snippet run
|
data/Rakefile
CHANGED
@@ -7,13 +7,13 @@ require "rspec/core/rake_task"
|
|
7
7
|
|
8
8
|
spec = Gem::Specification.new do |s|
|
9
9
|
s.name = 'fastruby'
|
10
|
-
s.version = '0.0.
|
10
|
+
s.version = '0.0.16'
|
11
11
|
s.author = 'Dario Seminara'
|
12
12
|
s.email = 'robertodarioseminara@gmail.com'
|
13
13
|
s.platform = Gem::Platform::RUBY
|
14
14
|
s.summary = 'fast execution of ruby code'
|
15
15
|
s.homepage = "http://github.com/tario/fastruby"
|
16
|
-
s.add_dependency "RubyInline", "= 3.
|
16
|
+
s.add_dependency "RubyInline", "= 3.11.0"
|
17
17
|
s.add_dependency "ruby_parser", "= 2.0.6"
|
18
18
|
s.has_rdoc = true
|
19
19
|
s.extra_rdoc_files = [ 'README' ]
|
@@ -1,7 +1,17 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
dir_config('fastruby_base')
|
3
3
|
CONFIG['CC'] = 'gcc'
|
4
|
-
create_makefile('fastruby_base')
|
5
4
|
|
5
|
+
ruby_version = Config::CONFIG["ruby_version"]
|
6
|
+
ruby_version = ruby_version.split(".")[0..1].join(".")
|
6
7
|
|
8
|
+
if ruby_version == "1.8"
|
9
|
+
$CFLAGS = $CFLAGS + " -DRUBY_1_8"
|
10
|
+
elsif ruby_version == "1.9"
|
11
|
+
$CFLAGS = $CFLAGS + " -DRUBY_1_9"
|
12
|
+
else
|
13
|
+
print "ERROR: unknown ruby version: #{ruby_version}\n"
|
14
|
+
print "try passing the rubyversion by argument (1.8 or 1.9)\n"
|
15
|
+
end
|
7
16
|
|
17
|
+
create_makefile('fastruby_base')
|
@@ -1,6 +1,10 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
+
#include "setjmp.h"
|
3
|
+
|
4
|
+
#ifdef RUBY_1_8
|
2
5
|
#include "node.h"
|
3
6
|
#include "env.h"
|
7
|
+
#endif
|
4
8
|
|
5
9
|
VALUE rb_cStackChunk;
|
6
10
|
VALUE rb_cFastRubyThreadData;
|
@@ -26,6 +30,47 @@ struct FASTRUBYTHREADDATA {
|
|
26
30
|
void* last_plocals;
|
27
31
|
};
|
28
32
|
|
33
|
+
#ifdef RUBY_1_8
|
34
|
+
#define _RARRAY_LEN(x) (RARRAY(x)->len)
|
35
|
+
#define _RSTRING_PTR(x) (RSTRING(x)->ptr)
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#ifdef RUBY_1_9
|
39
|
+
|
40
|
+
void* rb_method_entry(VALUE klass, ID id);
|
41
|
+
void* rb_global_entry(ID id);
|
42
|
+
|
43
|
+
typedef struct RNode {
|
44
|
+
unsigned long flags;
|
45
|
+
char *nd_file;
|
46
|
+
union {
|
47
|
+
struct RNode *node;
|
48
|
+
ID id;
|
49
|
+
VALUE value;
|
50
|
+
VALUE (*cfunc)(ANYARGS);
|
51
|
+
ID *tbl;
|
52
|
+
} u1;
|
53
|
+
union {
|
54
|
+
struct RNode *node;
|
55
|
+
ID id;
|
56
|
+
long argc;
|
57
|
+
VALUE value;
|
58
|
+
} u2;
|
59
|
+
union {
|
60
|
+
struct RNode *node;
|
61
|
+
ID id;
|
62
|
+
long state;
|
63
|
+
struct rb_global_entry *entry;
|
64
|
+
long cnt;
|
65
|
+
VALUE value;
|
66
|
+
} u3;
|
67
|
+
} NODE;
|
68
|
+
|
69
|
+
|
70
|
+
#define _RARRAY_LEN(x) RARRAY_LEN(x)
|
71
|
+
#define _RSTRING_PTR(x) RSTRING_PTR(x)
|
72
|
+
#endif
|
73
|
+
|
29
74
|
struct METHOD {
|
30
75
|
VALUE klass, rklass;
|
31
76
|
VALUE recv;
|
@@ -235,8 +280,7 @@ static VALUE clear_method_hash_addresses(VALUE klass,VALUE rb_method_hash) {
|
|
235
280
|
VALUE rb_values = rb_funcall(rb_method_hash, rb_intern("values"),0);
|
236
281
|
void** address;
|
237
282
|
int i;
|
238
|
-
|
239
|
-
for (i = 0; i < RARRAY(rb_values)->len; i++) {
|
283
|
+
for (i = 0; i < _RARRAY_LEN(rb_values); i++) {
|
240
284
|
address = (void**)FIX2LONG(rb_ary_entry(rb_values,i));
|
241
285
|
*address = 0;
|
242
286
|
}
|
@@ -246,7 +290,7 @@ static VALUE clear_method_hash_addresses(VALUE klass,VALUE rb_method_hash) {
|
|
246
290
|
}
|
247
291
|
|
248
292
|
static VALUE has_fastruby_function(VALUE self, VALUE rb_method_hash, VALUE mname) {
|
249
|
-
ID id = rb_intern(
|
293
|
+
ID id = rb_intern(_RSTRING_PTR(mname));
|
250
294
|
VALUE tmp = rb_hash_aref(rb_method_hash, LONG2FIX(id));
|
251
295
|
|
252
296
|
if (tmp != Qnil) {
|
data/lib/fastruby/builder.rb
CHANGED
@@ -18,7 +18,6 @@ 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/inline_extension"
|
22
21
|
require "fastruby/method_extension"
|
23
22
|
require "fastruby/logging"
|
24
23
|
require "fastruby/getlocals"
|
@@ -58,6 +57,7 @@ module FastRuby
|
|
58
57
|
require "fastruby/translator/translator"
|
59
58
|
require "rubygems"
|
60
59
|
require "inline"
|
60
|
+
require "fastruby/inline_extension"
|
61
61
|
|
62
62
|
context = FastRuby::Context.new
|
63
63
|
context.locals = locals
|
@@ -105,10 +105,23 @@ module FastRuby
|
|
105
105
|
|
106
106
|
begin
|
107
107
|
|
108
|
+
unless $inline_extra_flags
|
109
|
+
$inline_extra_flags = true
|
110
|
+
|
111
|
+
['CFLAGS','CXXFLAGS','OPTFLAGS','cflags','cxxflags','optflags'].each do |name|
|
112
|
+
RbConfig::CONFIG[name].gsub!(/\-O\d/,"-O1") if RbConfig::CONFIG[name]
|
113
|
+
end
|
114
|
+
|
115
|
+
if RUBY_VERSION =~ /^1\.8/
|
116
|
+
RbConfig::CONFIG['CFLAGS'] << " -DRUBY_1_8 -Wno-clobbered"
|
117
|
+
elsif RUBY_VERSION =~ /^1\.9/
|
118
|
+
RbConfig::CONFIG['CFLAGS'] << " -DRUBY_1_9 -Wno-clobbered"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
108
122
|
@owner.class_eval do
|
109
123
|
inline :C do |builder|
|
110
124
|
builder.inc << context.extra_code
|
111
|
-
builder.include "<node.h>"
|
112
125
|
builder.init_extra = context.init_extra
|
113
126
|
|
114
127
|
def builder.generate_ext
|
data/lib/fastruby/cache/cache.rb
CHANGED
@@ -18,7 +18,7 @@ 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 "
|
21
|
+
require "digest"
|
22
22
|
require "fileutils"
|
23
23
|
|
24
24
|
module FastRuby
|
@@ -37,7 +37,7 @@ module FastRuby
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def hash_snippet(snippet, addition)
|
40
|
-
SHA1.hexdigest(snippet + addition)
|
40
|
+
Digest::SHA1.hexdigest(snippet + addition)
|
41
41
|
end
|
42
42
|
|
43
43
|
def insert(hash,path)
|
@@ -21,67 +21,20 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
|
21
21
|
module Inline
|
22
22
|
class C
|
23
23
|
attr_reader :inc
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
method_name ||= test_to_normal function_name
|
36
|
-
return_type = signature['return']
|
37
|
-
arity = options[:arity] || signature['arity']
|
38
|
-
|
39
|
-
raise ArgumentError, "too many arguments" if arity > MAGIC_ARITY_THRESHOLD
|
40
|
-
|
41
|
-
if expand_types then
|
42
|
-
prefix = "static VALUE #{function_name}("
|
43
|
-
if arity <= MAGIC_ARITY then
|
44
|
-
prefix += "int argc, VALUE *argv, VALUE self"
|
45
|
-
else
|
46
|
-
prefix += "VALUE self"
|
47
|
-
prefix += signature['args'].map { |arg, type| ", VALUE _#{arg}"}.join
|
48
|
-
end
|
49
|
-
prefix += ") {\n"
|
50
|
-
prefix += signature['args'].map { |arg, type|
|
51
|
-
" #{type} #{arg} = #{ruby2c(type)}(_#{arg});\n"
|
52
|
-
}.join
|
53
|
-
|
54
|
-
# replace the function signature (hopefully) with new sig (prefix)
|
55
|
-
result.sub!(/[^;\/\"\>]+#{function_name}\s*\([^\{]+\{/, "\n" + prefix)
|
56
|
-
result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
|
57
|
-
unless return_type == "void" then
|
58
|
-
raise SyntaxError, "Couldn't find return statement for #{function_name}" unless
|
59
|
-
result =~ /return/
|
60
|
-
else
|
61
|
-
result.sub!(/\s*\}\s*\Z/, "\nreturn Qnil;\n}")
|
62
|
-
end
|
63
|
-
else
|
64
|
-
prefix = "static #{return_type} #{function_name}("
|
65
|
-
result.sub!(/[^;\/\"\>]+#{function_name}\s*\(/, prefix)
|
66
|
-
result.sub!(/\A\n/, '') # strip off the \n in front in case we added it
|
24
|
+
|
25
|
+
def module_name
|
26
|
+
unless defined? @module_name then
|
27
|
+
module_name = if @mod.name
|
28
|
+
@mod.name.gsub('::','__')
|
29
|
+
else
|
30
|
+
rand(1000000000000000).to_s
|
31
|
+
end
|
32
|
+
md5 = Digest::MD5.new
|
33
|
+
@sig.keys.sort_by { |x| x.to_s }.each { |m| md5 << m.to_s }
|
34
|
+
@module_name = "Inline_#{module_name}_#{md5}"
|
67
35
|
end
|
68
|
-
|
69
|
-
|
70
|
-
$1.split(/\n/).size
|
71
|
-
else
|
72
|
-
warn "WAR\NING: Can't find signature in #{result.inspect}\n" unless $TESTING
|
73
|
-
0
|
74
|
-
end
|
75
|
-
|
76
|
-
file, line = caller[1].split(/:/)
|
77
|
-
result = "# line #{line.to_i + delta} \"#{file}\"\n" + result unless $DEBUG and not $TESTING
|
78
|
-
|
79
|
-
@src << result
|
80
|
-
@sig[function_name] = [arity,singleton,method_name]
|
81
|
-
|
82
|
-
return result if $TESTING
|
83
|
-
end # def generate
|
84
|
-
|
36
|
+
@module_name
|
37
|
+
end
|
85
38
|
end
|
86
39
|
end
|
87
40
|
|
data/lib/fastruby/object.rb
CHANGED
@@ -81,7 +81,7 @@ class Object
|
|
81
81
|
|
82
82
|
return unless tree
|
83
83
|
method_name = "_anonymous_" + rand(100000000000).to_s
|
84
|
-
Object.execute_tree(FastRuby.encapsulate_tree(tree,method_name), :main => method_name, :self => self, :snippet_hash => snippet_hash
|
84
|
+
Object.execute_tree(FastRuby.encapsulate_tree(tree,method_name), {:main => method_name, :self => self, :snippet_hash => snippet_hash}.merge(options_hash))
|
85
85
|
|
86
86
|
else
|
87
87
|
|
data/lib/fastruby/self
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
translator/modules/variable.rb 27| "rb_cvar_get(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]})"
|
2
|
+
translator/modules/variable.rb 31| "__rb_cvar_set(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]},#{to_c tree[2]},Qfalse)"
|
3
|
+
translator/modules/variable.rb 55| "rb_const_get(CLASS_OF(plocals->self), #{intern_num(tree[1])})"
|
4
|
+
translator/modules/variable.rb 170| "rb_ivar_defined(plocals->self,#{intern_num tree[1][1]}) ? #{literal_value "instance-variable"} : Qnil"
|
5
|
+
translator/modules/defn.rb 46| rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);
|
6
|
+
translator/modules/defn.rb 48| #{global_klass_variable} = plocals->self;
|
7
|
+
translator/modules/method_group.rb 115| plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
|
8
|
+
translator/modules/method_group.rb 120| plocals->active = Qtrue;
|
9
|
+
translator/modules/method_group.rb 121| plocals->self = self;
|
10
|
+
translator/modules/method_group.rb 122| plocals->targetted = Qfalse;
|
11
|
+
translator/modules/method_group.rb 123| plocals->call_frame = LONG2FIX(0);
|
12
|
+
translator/modules/method_group.rb 134| plocals->active = Qfalse;
|
13
|
+
translator/modules/iter.rb 107| str_arg_initialization << "plocals->#{args_tree[1]} = arg;"
|
14
|
+
translator/modules/iter.rb 111| plocals->#{args_tree[1]} = arg;
|
15
|
+
translator/modules/iter.rb 113| plocals->#{args_tree[1]} = rb_ary_entry(arg,0);
|
16
|
+
translator/modules/iter.rb 138| str_arg_initialization << "plocals->#{arguments[i].last} = rb_ary_entry(arg,#{i});\n"
|
17
|
+
translator/modules/iter.rb 140| str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(_RARRAY_LEN(arg)-#{i});\n
|
18
|
+
translator/modules/iter.rb 144| rb_ary_store(plocals->#{arg.last.last},i-#{i},rb_ary_entry(arg,i));
|
19
|
+
translator/modules/iter.rb 156| str_recv = "plocals->self" unless recv_tree
|
20
|
+
translator/modules/iter.rb 209| str_recv = "plocals->self" unless recv_tree
|
21
|
+
translator/modules/iter.rb 286| if (plocals->targetted == 1) {
|
22
|
+
translator/modules/iter.rb 341| if (plocals->targetted == 1) {
|
23
|
+
translator/modules/iter.rb 342| if (plocals->active == Qfalse) {
|
24
|
+
translator/modules/iter.rb 451| fastruby_str_arg_initialization = "plocals->#{args_tree[1]} = argv[0];"
|
25
|
+
translator/modules/iter.rb 458| fastruby_str_arg_initialization << "plocals->#{arg.last} = #{i} < argc ? argv[#{i}] : Qnil;\n"
|
26
|
+
translator/modules/iter.rb 460| fastruby_str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(#{arguments.size-1-i});\n
|
27
|
+
translator/modules/iter.rb 464| rb_ary_store(plocals->#{arg.last.last},i-#{i},argv[i]);
|
28
|
+
translator/modules/iter.rb 513| str_recv = "plocals->self"
|
29
|
+
translator/modules/iter.rb 537| VALUE old_call_frame = plocals->call_frame;
|
30
|
+
translator/modules/iter.rb 538| plocals->call_frame = LONG2FIX(&call_frame);
|
31
|
+
translator/modules/iter.rb 551| plocals->call_frame = old_call_frame;
|
32
|
+
translator/modules/iter.rb 561| pframe->next_recv = #{recv_tree ? to_c(recv_tree) : "plocals->self"};
|
33
|
+
translator/modules/iter.rb 646| current_plocals->active = Qfalse;
|
34
|
+
translator/modules/iter.rb 647| current_plocals = (typeof(current_plocals))FIX2LONG(current_plocals->parent_locals);
|
35
|
+
translator/modules/iter.rb 657| current_plocals->active = Qtrue;
|
36
|
+
translator/modules/iter.rb 658| current_plocals = (typeof(current_plocals))FIX2LONG(current_plocals->parent_locals);
|
37
|
+
translator/modules/iter.rb 684| plocals->call_frame = old_call_frame;
|
38
|
+
translator/modules/iter.rb 693| plocals->call_frame = old_call_frame;
|
39
|
+
translator/modules/block.rb 36| if (FIX2LONG(plocals->block_function_address) == 0) {
|
40
|
+
translator/modules/block.rb 39| return ((VALUE(*)(int,VALUE*,VALUE,VALUE))FIX2LONG(plocals->block_function_address))(size, block_args, FIX2LONG(plocals->block_function_param), (VALUE)pframe);
|
41
|
+
translator/modules/nonlocal.rb 27| plocals->return_value = #{to_c(tree[1])};
|
42
|
+
translator/modules/nonlocal.rb 28| plocals->targetted = 1;
|
43
|
+
translator/modules/nonlocal.rb 41| target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
44
|
+
translator/modules/nonlocal.rb 47| plocals->call_frame = LONG2FIX(0);
|
45
|
+
translator/modules/nonlocal.rb 60| target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
46
|
+
translator/translator.rb 213| VALUE old_call_frame = plocals->call_frame;
|
47
|
+
translator/translator.rb 214| plocals->call_frame = LONG2FIX(&call_frame);
|
48
|
+
translator/translator.rb 226| plocals->call_frame = old_call_frame;
|
49
|
+
translator/translator.rb 232| plocals->call_frame = old_call_frame;
|
50
|
+
translator/translator.rb 243| plocals->call_frame = old_call_frame;
|
51
|
+
translator/translator.rb 398| plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
|
52
|
+
translator/translator.rb 402| plocals->active = Qtrue;
|
53
|
+
translator/translator.rb 403| plocals->targetted = Qfalse;
|
54
|
+
translator/translator.rb 404| plocals->pframe = LONG2FIX(&frame);
|
55
|
+
translator/translator.rb 420| plocals->active = Qfalse;
|
56
|
+
translator/translator.rb 422| return plocals->return_value;
|
57
|
+
translator/translator.rb 425| plocals->self = self;
|
58
|
+
translator/translator.rb 430| "plocals->#{arg} = #{arg};\n"
|
59
|
+
translator/translator.rb 433| plocals->block_function_address = LONG2FIX(0);
|
60
|
+
translator/translator.rb 434| plocals->block_function_param = LONG2FIX(Qnil);
|
61
|
+
translator/translator.rb 435| plocals->call_frame = LONG2FIX(0);
|
62
|
+
translator/translator.rb 445| plocals->active = Qfalse;
|
63
|
+
translator/translator.rb 525| "plocals->#{arg} = argv[#{i}];\n"
|
64
|
+
translator/translator.rb 547| plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new3(0);
|
65
|
+
translator/translator.rb 551| plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new4(
|
66
|
+
translator/translator.rb 570| plocals->#{block_argument.to_s.gsub("&","")} = #{to_c FastRuby::FastRubySexp.from_sexp(proc_reyield_block_tree)};
|
67
|
+
translator/translator.rb 616| plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
|
68
|
+
translator/translator.rb 621| plocals->active = Qtrue;
|
69
|
+
translator/translator.rb 622| plocals->targetted = Qfalse;
|
70
|
+
translator/translator.rb 623| plocals->pframe = LONG2FIX(&frame);
|
71
|
+
translator/translator.rb 624| plocals->call_frame = LONG2FIX(0);
|
72
|
+
translator/translator.rb 633| plocals->active = Qfalse;
|
73
|
+
translator/translator.rb 642| if (plocals->targetted == Qfalse || aux != FASTRUBY_TAG_RETURN) {
|
74
|
+
translator/translator.rb 650| return plocals->return_value;
|
75
|
+
translator/translator.rb 653| plocals->self = self;
|
76
|
+
translator/translator.rb 659| plocals->block_function_address = LONG2FIX(pblock->block_function_address);
|
77
|
+
translator/translator.rb 660| plocals->block_function_param = LONG2FIX(pblock->block_function_param);
|
78
|
+
translator/translator.rb 662| plocals->block_function_address = LONG2FIX(0);
|
79
|
+
translator/translator.rb 663| plocals->block_function_param = LONG2FIX(Qnil);
|
80
|
+
translator/translator.rb 674| plocals->active = Qfalse;
|
81
|
+
translator/translator.rb 693| "plocals->"
|
82
|
+
translator/translator.rb 759| return "FIX2LONG(plocals->block_function_address) == 0 ? Qfalse : Qtrue"
|
@@ -26,12 +26,20 @@ class Object
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
module FastRuby
|
30
|
+
class FastRubySexp
|
31
|
+
def self.from_sexp(value)
|
32
|
+
ary = FastRuby::FastRubySexp.new
|
33
|
+
value.each do |x|
|
34
|
+
ary << x.to_fastruby_sexp
|
35
|
+
end
|
36
|
+
ary
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
29
41
|
class Sexp
|
30
42
|
def to_fastruby_sexp
|
31
|
-
|
32
|
-
each do |x|
|
33
|
-
ary << x.to_fastruby_sexp
|
34
|
-
end
|
35
|
-
ary
|
43
|
+
FastRuby::FastRubySexp.from_sexp(self)
|
36
44
|
end
|
37
45
|
end
|
@@ -49,7 +49,7 @@ module FastRuby
|
|
49
49
|
VALUE splat_array = #{to_c(splat_arg[1])};
|
50
50
|
|
51
51
|
if (CLASS_OF(splat_array) == rb_cArray) {
|
52
|
-
VALUE block_args[
|
52
|
+
VALUE block_args[_RARRAY_LEN(splat_array) + #{tree.size}];
|
53
53
|
int i;
|
54
54
|
#{
|
55
55
|
(0..tree.size-3).map{|i|
|
@@ -57,11 +57,11 @@ module FastRuby
|
|
57
57
|
}.join(";\n")
|
58
58
|
};
|
59
59
|
|
60
|
-
for (i=0; i<
|
60
|
+
for (i=0; i<_RARRAY_LEN(splat_array); i++) {
|
61
61
|
block_args[i+#{tree.size-2}] = rb_ary_entry(splat_array,i);
|
62
62
|
}
|
63
63
|
|
64
|
-
return #{anonymous_function(&block_code)}((VALUE)pframe, block_args,
|
64
|
+
return #{anonymous_function(&block_code)}((VALUE)pframe, block_args, _RARRAY_LEN(splat_array) + #{tree.size-2});
|
65
65
|
} else {
|
66
66
|
VALUE block_args[1+#{tree.size}];
|
67
67
|
#{
|
@@ -86,7 +86,7 @@ module FastRuby
|
|
86
86
|
}
|
87
87
|
|
88
88
|
int argc = #{args.size-2};
|
89
|
-
VALUE argv[#{args.size} +
|
89
|
+
VALUE argv[#{args.size} + _RARRAY_LEN(array)];
|
90
90
|
|
91
91
|
#{
|
92
92
|
i = -1
|
@@ -96,7 +96,7 @@ module FastRuby
|
|
96
96
|
}.join(";\n")
|
97
97
|
};
|
98
98
|
|
99
|
-
int array_len =
|
99
|
+
int array_len = _RARRAY_LEN(array);
|
100
100
|
|
101
101
|
int i;
|
102
102
|
for (i=0; i<array_len;i++) {
|
@@ -41,7 +41,9 @@ module FastRuby
|
|
41
41
|
alt_options.delete(:main)
|
42
42
|
|
43
43
|
inline_block "
|
44
|
-
|
44
|
+
|
45
|
+
usleep(0);
|
46
|
+
rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);
|
45
47
|
|
46
48
|
#{global_klass_variable} = plocals->self;
|
47
49
|
// set tree
|
@@ -103,22 +103,39 @@ module FastRuby
|
|
103
103
|
|
104
104
|
if not args_tree
|
105
105
|
elsif args_tree.first == :lasgn
|
106
|
-
|
106
|
+
if RUBY_VERSION =~ /^1\.8/
|
107
|
+
str_arg_initialization << "plocals->#{args_tree[1]} = arg;"
|
108
|
+
elsif RUBY_VERSION =~ /^1\.9/
|
109
|
+
str_arg_initialization << "
|
110
|
+
if (TYPE(arg) != T_ARRAY) {
|
111
|
+
plocals->#{args_tree[1]} = arg;
|
112
|
+
} else {
|
113
|
+
plocals->#{args_tree[1]} = rb_ary_entry(arg,0);
|
114
|
+
}
|
115
|
+
"
|
116
|
+
end
|
107
117
|
elsif args_tree.first == :masgn
|
108
118
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if (arg !=
|
119
|
+
if RUBY_VERSION =~ /^1\.8/
|
120
|
+
str_arg_initialization << "
|
121
|
+
{
|
122
|
+
if (TYPE(arg) != T_ARRAY) {
|
123
|
+
if (arg != Qnil) {
|
124
|
+
arg = rb_ary_new4(1,&arg);
|
125
|
+
} else {
|
126
|
+
arg = rb_ary_new2(0);
|
127
|
+
}
|
128
|
+
} else if (_RARRAY_LEN(arg) <= 1) {
|
113
129
|
arg = rb_ary_new4(1,&arg);
|
114
|
-
} else {
|
115
|
-
arg = rb_ary_new2(0);
|
116
130
|
}
|
117
|
-
} else if (RARRAY(arg)->len <= 1) {
|
118
|
-
arg = rb_ary_new4(1,&arg);
|
119
131
|
}
|
120
|
-
|
121
|
-
|
132
|
+
"
|
133
|
+
elsif RUBY_VERSION =~ /^1\.9/
|
134
|
+
str_arg_initialization << "
|
135
|
+
{
|
136
|
+
}
|
137
|
+
"
|
138
|
+
end
|
122
139
|
|
123
140
|
arguments = args_tree[1][1..-1]
|
124
141
|
|
@@ -127,10 +144,10 @@ module FastRuby
|
|
127
144
|
if arg[0] == :lasgn
|
128
145
|
str_arg_initialization << "plocals->#{arguments[i].last} = rb_ary_entry(arg,#{i});\n"
|
129
146
|
elsif arg[0] == :splat
|
130
|
-
str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(
|
147
|
+
str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(_RARRAY_LEN(arg)-#{i});\n
|
131
148
|
|
132
149
|
int i;
|
133
|
-
for (i=#{i};i<
|
150
|
+
for (i=#{i};i<_RARRAY_LEN(arg);i++){
|
134
151
|
rb_ary_store(plocals->#{arg.last.last},i-#{i},rb_ary_entry(arg,i));
|
135
152
|
}
|
136
153
|
"
|
@@ -158,7 +175,7 @@ module FastRuby
|
|
158
175
|
}
|
159
176
|
|
160
177
|
int argc = #{call_args_tree.size-2};
|
161
|
-
VALUE argv[#{call_args_tree.size} +
|
178
|
+
VALUE argv[#{call_args_tree.size} + _RARRAY_LEN(array)];
|
162
179
|
|
163
180
|
#{
|
164
181
|
i = -1
|
@@ -168,7 +185,7 @@ module FastRuby
|
|
168
185
|
}.join(";\n")
|
169
186
|
};
|
170
187
|
|
171
|
-
int array_len =
|
188
|
+
int array_len = _RARRAY_LEN(array);
|
172
189
|
|
173
190
|
int i;
|
174
191
|
for (i=0; i<array_len;i++) {
|
@@ -239,10 +256,35 @@ module FastRuby
|
|
239
256
|
}
|
240
257
|
|
241
258
|
end
|
259
|
+
|
260
|
+
argument_array_read = "
|
261
|
+
VALUE arg;
|
262
|
+
#{
|
263
|
+
# TODO: access directly to argc and argv for optimal execution
|
264
|
+
if RUBY_VERSION =~ /^1\.9/
|
265
|
+
"
|
266
|
+
if (TYPE(arg_) == T_ARRAY) {
|
267
|
+
if (_RARRAY_LEN(arg_) <= 1) {
|
268
|
+
arg = rb_ary_new4(argc,argv);
|
269
|
+
} else {
|
270
|
+
arg = arg_;
|
271
|
+
}
|
272
|
+
} else {
|
273
|
+
arg = rb_ary_new4(argc,argv);
|
274
|
+
}
|
275
|
+
"
|
276
|
+
else
|
277
|
+
"arg = arg_;"
|
278
|
+
end
|
279
|
+
}
|
280
|
+
"
|
281
|
+
|
242
282
|
|
243
283
|
rb_funcall_block_code_with_lambda = proc { |name| "
|
244
|
-
static VALUE #{name}(VALUE
|
284
|
+
static VALUE #{name}(VALUE arg_, VALUE _plocals, int argc, VALUE* argv) {
|
245
285
|
// block for call to #{call_tree[2]}
|
286
|
+
#{argument_array_read}
|
287
|
+
|
246
288
|
VALUE last_expression = Qnil;
|
247
289
|
|
248
290
|
#{@frame_struct} frame;
|
@@ -299,8 +341,10 @@ module FastRuby
|
|
299
341
|
}
|
300
342
|
|
301
343
|
rb_funcall_block_code_proc_new = proc { |name| "
|
302
|
-
static VALUE #{name}(VALUE
|
344
|
+
static VALUE #{name}(VALUE arg_, VALUE _plocals, int argc, VALUE* argv) {
|
303
345
|
// block for call to #{call_tree[2]}
|
346
|
+
#{argument_array_read}
|
347
|
+
|
304
348
|
VALUE last_expression = Qnil;
|
305
349
|
|
306
350
|
#{@frame_struct} frame;
|
@@ -353,8 +397,10 @@ module FastRuby
|
|
353
397
|
|
354
398
|
|
355
399
|
rb_funcall_block_code = proc { |name| "
|
356
|
-
static VALUE #{name}(VALUE
|
400
|
+
static VALUE #{name}(VALUE arg_, VALUE _plocals, int argc, VALUE* argv) {
|
357
401
|
// block for call to #{call_tree[2]}
|
402
|
+
#{argument_array_read}
|
403
|
+
|
358
404
|
VALUE last_expression = Qnil;
|
359
405
|
|
360
406
|
#{@frame_struct} frame;
|
@@ -391,7 +437,14 @@ module FastRuby
|
|
391
437
|
}
|
392
438
|
|
393
439
|
rb_funcall_block_code_callcc = proc { |name| "
|
394
|
-
static VALUE #{name}(VALUE arg, VALUE _plocals) {
|
440
|
+
static VALUE #{name}(VALUE arg, VALUE _plocals, int argc, VALUE* argv) {
|
441
|
+
#{
|
442
|
+
# TODO: access directly to argc and argv for optimal execution
|
443
|
+
if RUBY_VERSION =~ /^1\.9/
|
444
|
+
"arg = rb_ary_new4(argc,argv);"
|
445
|
+
end
|
446
|
+
}
|
447
|
+
|
395
448
|
// block for call to #{call_tree[2]}
|
396
449
|
VALUE last_expression = Qnil;
|
397
450
|
|
@@ -419,7 +472,7 @@ module FastRuby
|
|
419
472
|
}
|
420
473
|
}
|
421
474
|
|
422
|
-
if (rb_obj_is_kind_of(arg,
|
475
|
+
if (rb_obj_is_kind_of(arg, rb_const_get(rb_cObject, #{intern_num :Continuation}))) {
|
423
476
|
struct FASTRUBYTHREADDATA* thread_data = frame.thread_data;
|
424
477
|
rb_ivar_set(arg,#{intern_num :__stack_chunk},thread_data->rb_stack_chunk);
|
425
478
|
}
|
@@ -549,8 +602,12 @@ module FastRuby
|
|
549
602
|
VALUE saved_rb_stack_chunk = Qnil;
|
550
603
|
|
551
604
|
pframe->next_recv = #{recv_tree ? to_c(recv_tree) : "plocals->self"};
|
552
|
-
|
605
|
+
#ifdef RUBY_1_8
|
553
606
|
NODE* node = rb_method_node(CLASS_OF(pframe->next_recv), #{intern_num mname});
|
607
|
+
#endif
|
608
|
+
#ifdef RUBY_1_9
|
609
|
+
void* node = rb_method_entry(CLASS_OF(pframe->next_recv), #{intern_num mname});
|
610
|
+
#endif
|
554
611
|
|
555
612
|
if (node == #{@callcc_node_gvar}) {
|
556
613
|
|
@@ -586,7 +643,6 @@ module FastRuby
|
|
586
643
|
frame_call(
|
587
644
|
protected_block(inline_block("
|
588
645
|
|
589
|
-
NODE* node = rb_method_node(CLASS_OF(pframe->next_recv), #{intern_num mname});
|
590
646
|
void* caller_func;
|
591
647
|
void* block_func;
|
592
648
|
typeof(plocals) current_plocals;
|
@@ -594,6 +650,13 @@ module FastRuby
|
|
594
650
|
if (pframe->thread_data == 0) pframe->thread_data = rb_current_thread_data();
|
595
651
|
void* last_plocals = pframe->thread_data->last_plocals;
|
596
652
|
|
653
|
+
#ifdef RUBY_1_8
|
654
|
+
NODE* node = rb_method_node(CLASS_OF(pframe->next_recv), #{intern_num mname});
|
655
|
+
#endif
|
656
|
+
#ifdef RUBY_1_9
|
657
|
+
void* node = rb_method_entry(CLASS_OF(pframe->next_recv), #{intern_num mname});
|
658
|
+
#endif
|
659
|
+
|
597
660
|
if (
|
598
661
|
node == #{@proc_node_gvar} ||
|
599
662
|
node == #{@lambda_node_gvar}
|
@@ -159,7 +159,11 @@ module FastRuby
|
|
159
159
|
elsif nt == :const
|
160
160
|
"rb_const_defined(rb_cObject, #{intern_num tree[1][1]}) ? #{literal_value "constant"} : Qnil"
|
161
161
|
elsif nt == :call
|
162
|
-
|
162
|
+
if RUBY_VERSION =~ /^1\.8/
|
163
|
+
"rb_method_node(CLASS_OF(#{to_c tree[1][1]}), #{intern_num tree[1][2]}) ? #{literal_value "method"} : Qnil"
|
164
|
+
else
|
165
|
+
"rb_method_entry(CLASS_OF(#{to_c tree[1][1]}), #{intern_num tree[1][2]}) ? #{literal_value "method"} : Qnil"
|
166
|
+
end
|
163
167
|
elsif nt == :yield
|
164
168
|
"rb_block_given_p() ? #{literal_value "yield"} : Qnil"
|
165
169
|
elsif nt == :ivar
|