fastruby 0.0.15 → 0.0.16
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 +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
|