fastruby 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +10 -0
- data/Rakefile +2 -1
- data/benchmarks/benchmark.rb~ +2 -4
- data/benchmarks/benchmark3.rb~ +2 -4
- data/ext/fastruby_base/fastruby_base.inl +1 -1
- data/lib/fastruby/builder.rb +8 -7
- data/lib/fastruby/fastruby_sexp.rb +18 -0
- data/lib/fastruby/inliner/modules/call.rb +254 -67
- data/lib/fastruby/inliner/modules/recursive.rb +5 -0
- data/lib/fastruby/reductor/modules/case.rb +2 -1
- data/lib/fastruby/translator/modules/block.rb +65 -59
- data/lib/fastruby/translator/modules/call.rb +7 -4
- data/lib/fastruby/translator/modules/exceptions.rb +66 -64
- data/lib/fastruby/translator/modules/flow.rb +8 -8
- data/lib/fastruby/translator/modules/literal.rb +5 -4
- data/lib/fastruby/translator/modules/method_group.rb +6 -5
- data/lib/fastruby/translator/modules/nonlocal.rb +153 -11
- data/lib/fastruby/translator/modules/static.rb +8 -8
- data/lib/fastruby/translator/modules/variable.rb +15 -15
- data/lib/fastruby/translator/translator.rb +156 -59
- data/lib/fastruby.rb +1 -1
- data/lib/fastruby.rb~ +36 -0
- 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/base_spec.rb~ +5 -5
- data/spec/ruby/block/break_spec.rb~ +236 -0
- data/spec/ruby/block/lambda_spec.rb~ +38 -0
- data/spec/ruby/block/next_spec.rb~ +85 -0
- data/spec/ruby/call/base_call_spec.rb~ +83 -0
- data/spec/ruby/defn/replacement_spec.rb +52 -2
- data/spec/ruby/defn/replacement_spec.rb~ +52 -2
- data/spec/ruby/exception/base_spec.rb +22 -1
- data/spec/ruby/return_spec.rb~ +99 -0
- metadata +30 -10
@@ -86,7 +86,7 @@ module FastRuby
|
|
86
86
|
|
87
87
|
result_variable = result_variable_ || "last_expression"
|
88
88
|
|
89
|
-
code = "
|
89
|
+
code = proc {"
|
90
90
|
{
|
91
91
|
VALUE condition_result;
|
92
92
|
#{to_c condition_tree, "condition_result"};
|
@@ -99,12 +99,12 @@ module FastRuby
|
|
99
99
|
" : ""
|
100
100
|
}
|
101
101
|
}
|
102
|
-
"
|
102
|
+
"}
|
103
103
|
|
104
104
|
if result_variable_
|
105
|
-
code
|
105
|
+
code.call
|
106
106
|
else
|
107
|
-
inline_block
|
107
|
+
inline_block(&code) + "; return last_expression;"
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -112,7 +112,7 @@ module FastRuby
|
|
112
112
|
begin_while = "begin_while_"+rand(10000000).to_s
|
113
113
|
end_while = "end_while_"+rand(10000000).to_s
|
114
114
|
aux_varname = "_aux_" + rand(10000000).to_s
|
115
|
-
code = "
|
115
|
+
code = proc {"
|
116
116
|
{
|
117
117
|
VALUE while_condition;
|
118
118
|
VALUE #{aux_varname};
|
@@ -132,12 +132,12 @@ module FastRuby
|
|
132
132
|
end
|
133
133
|
}
|
134
134
|
}
|
135
|
-
"
|
135
|
+
"}
|
136
136
|
|
137
137
|
if result_var
|
138
|
-
code
|
138
|
+
code.call
|
139
139
|
else
|
140
|
-
inline_block code
|
140
|
+
inline_block &code
|
141
141
|
end
|
142
142
|
|
143
143
|
end
|
@@ -101,17 +101,17 @@ module FastRuby
|
|
101
101
|
result_var = result_var_ || "value"
|
102
102
|
|
103
103
|
if tree[1].instance_of? Symbol
|
104
|
-
code = "
|
104
|
+
code = proc{"
|
105
105
|
{
|
106
106
|
// set constant #{tree[1].to_s}
|
107
107
|
#{to_c tree[2], result_var};
|
108
108
|
rb_const_set(rb_cObject, #{intern_num tree[1]}, #{result_var});
|
109
109
|
}
|
110
|
-
"
|
110
|
+
"}
|
111
111
|
elsif tree[1].instance_of? FastRuby::FastRubySexp
|
112
112
|
|
113
113
|
if tree[1].node_type == :colon2
|
114
|
-
code = "
|
114
|
+
code = proc{"
|
115
115
|
{
|
116
116
|
// set constant #{tree[1].to_s}
|
117
117
|
#{to_c tree[2], result_var};
|
@@ -119,25 +119,25 @@ module FastRuby
|
|
119
119
|
#{to_c tree[1][1], "klass"};
|
120
120
|
rb_const_set(klass, #{intern_num tree[1][2]}, #{result_var});
|
121
121
|
}
|
122
|
-
"
|
122
|
+
"}
|
123
123
|
elsif tree[1].node_type == :colon3
|
124
|
-
code = "
|
124
|
+
code = proc{"
|
125
125
|
{
|
126
126
|
// set constant #{tree[1].to_s}
|
127
127
|
#{to_c tree[2], result_var};
|
128
128
|
rb_const_set(rb_cObject, #{intern_num tree[1][1]}, #{result_var});
|
129
129
|
}
|
130
|
-
"
|
130
|
+
"}
|
131
131
|
end
|
132
|
-
|
132
|
+
end
|
133
|
+
|
133
134
|
if result_var_
|
134
|
-
code
|
135
|
+
code.call
|
135
136
|
else
|
136
|
-
inline_block
|
137
|
+
inline_block{"VALUE #{result_var} = Qnil;\n" + code.call + "
|
137
138
|
return #{result_var};
|
138
|
-
"
|
139
|
+
"}
|
139
140
|
end
|
140
|
-
end
|
141
141
|
end
|
142
142
|
|
143
143
|
define_translator_for(:colon3, :method => :to_c_colon3, :arity => 1)
|
@@ -147,7 +147,7 @@ module FastRuby
|
|
147
147
|
|
148
148
|
define_translator_for(:colon2, :method => :to_c_colon2)
|
149
149
|
def to_c_colon2(tree, result_var = nil)
|
150
|
-
code = "
|
150
|
+
code = proc{ "
|
151
151
|
{
|
152
152
|
VALUE klass = Qnil;
|
153
153
|
|
@@ -191,12 +191,12 @@ module FastRuby
|
|
191
191
|
end
|
192
192
|
}
|
193
193
|
}
|
194
|
-
"
|
194
|
+
"}
|
195
195
|
|
196
196
|
if result_var
|
197
|
-
code
|
197
|
+
code.call
|
198
198
|
else
|
199
|
-
inline_block code
|
199
|
+
inline_block &code
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
@@ -96,10 +96,21 @@ module FastRuby
|
|
96
96
|
require path
|
97
97
|
end
|
98
98
|
end
|
99
|
+
|
100
|
+
def catch_block(*catchs)
|
101
|
+
old_catch_blocks = @catch_blocks.dup
|
102
|
+
begin
|
103
|
+
catchs.each &@catch_blocks.method(:<<)
|
104
|
+
return yield
|
105
|
+
ensure
|
106
|
+
@catch_blocks = old_catch_blocks
|
107
|
+
end
|
108
|
+
end
|
99
109
|
|
100
110
|
def initialize(common_func = true)
|
101
111
|
initialize_to_c
|
102
112
|
|
113
|
+
@catch_blocks = []
|
103
114
|
@infer_lvar_map = Hash.new
|
104
115
|
@no_cache = false
|
105
116
|
@extra_code = ""
|
@@ -149,7 +160,9 @@ module FastRuby
|
|
149
160
|
"
|
150
161
|
|
151
162
|
ruby_code = "
|
152
|
-
$LOAD_PATH
|
163
|
+
unless $LOAD_PATH.include? #{FastRuby.fastruby_load_path.inspect}
|
164
|
+
$LOAD_PATH << #{FastRuby.fastruby_load_path.inspect}
|
165
|
+
end
|
153
166
|
require #{FastRuby.fastruby_script_path.inspect}
|
154
167
|
"
|
155
168
|
|
@@ -855,7 +868,32 @@ end
|
|
855
868
|
}
|
856
869
|
end
|
857
870
|
|
858
|
-
def
|
871
|
+
def catch_on_throw
|
872
|
+
old_catch_jmp_on_throw = @catch_jmp_on_throw || false
|
873
|
+
@catch_jmp_on_throw = true
|
874
|
+
begin
|
875
|
+
ret = yield
|
876
|
+
ensure
|
877
|
+
@catch_jmp_on_throw = old_catch_jmp_on_throw
|
878
|
+
end
|
879
|
+
|
880
|
+
ret
|
881
|
+
end
|
882
|
+
|
883
|
+
def inline_block(*args)
|
884
|
+
|
885
|
+
unless block_given?
|
886
|
+
code = args.first
|
887
|
+
return inline_block(*args[1..-1]) {
|
888
|
+
code
|
889
|
+
}
|
890
|
+
end
|
891
|
+
|
892
|
+
repass_var = args[0]
|
893
|
+
nolocals = args[1] || false
|
894
|
+
|
895
|
+
code = catch_on_throw{ yield }
|
896
|
+
|
859
897
|
anonymous_function{ |name| "
|
860
898
|
static VALUE #{name}(VALUE param#{repass_var ? ",void* " + repass_var : "" }) {
|
861
899
|
#{@frame_struct} * volatile pframe = (void*)param;
|
@@ -866,6 +904,24 @@ end
|
|
866
904
|
#{code}
|
867
905
|
return Qnil;
|
868
906
|
|
907
|
+
|
908
|
+
#{@catch_blocks.map { |cb|
|
909
|
+
"#{cb.to_s}_end:
|
910
|
+
|
911
|
+
plocals->return_value = last_expression;
|
912
|
+
plocals->targetted = 1;
|
913
|
+
longjmp(pframe->jmp, #{intern_num( cb.to_s + "_end")});
|
914
|
+
|
915
|
+
#{cb.to_s}_start:
|
916
|
+
|
917
|
+
plocals->return_value = last_expression;
|
918
|
+
plocals->targetted = 1;
|
919
|
+
longjmp(pframe->jmp, #{intern_num( cb.to_s + "_start")});
|
920
|
+
|
921
|
+
"
|
922
|
+
|
923
|
+
}.join("\n")
|
924
|
+
}
|
869
925
|
#{unless nolocals
|
870
926
|
"
|
871
927
|
local_return:
|
@@ -893,7 +949,23 @@ fastruby_local_next:
|
|
893
949
|
"rb_funcall(#{proced.__id__}, #{intern_num :call}, 1, #{parameter})"
|
894
950
|
end
|
895
951
|
|
896
|
-
def protected_block(
|
952
|
+
def protected_block(*args)
|
953
|
+
unless block_given?
|
954
|
+
inner_code = args.first
|
955
|
+
return protected_block(*args[1..-1]) {
|
956
|
+
inner_code
|
957
|
+
}
|
958
|
+
end
|
959
|
+
|
960
|
+
repass_var = args[1]
|
961
|
+
nolocals = args[2] || false
|
962
|
+
|
963
|
+
inline_block(repass_var, nolocals) do
|
964
|
+
generate_protected_block(yield, *args)
|
965
|
+
end
|
966
|
+
end
|
967
|
+
|
968
|
+
def generate_protected_block(inner_code, always_rescue = false,repass_var = nil, nolocals = false)
|
897
969
|
body = nil
|
898
970
|
rescue_args = nil
|
899
971
|
|
@@ -993,7 +1065,7 @@ fastruby_local_next:
|
|
993
1065
|
rescue_code = "rb_rescue2(#{body}, #{rescue_args}, #{rescue_body}, (VALUE)&str, rb_eException, (VALUE)0)"
|
994
1066
|
|
995
1067
|
if always_rescue
|
996
|
-
|
1068
|
+
"
|
997
1069
|
#{return_err_struct} str;
|
998
1070
|
|
999
1071
|
str.state = 0;
|
@@ -1005,9 +1077,9 @@ fastruby_local_next:
|
|
1005
1077
|
#{wrapper_code}
|
1006
1078
|
|
1007
1079
|
return result;
|
1008
|
-
"
|
1080
|
+
"
|
1009
1081
|
else
|
1010
|
-
|
1082
|
+
"
|
1011
1083
|
VALUE result;
|
1012
1084
|
#{return_err_struct} str;
|
1013
1085
|
|
@@ -1026,7 +1098,7 @@ fastruby_local_next:
|
|
1026
1098
|
}
|
1027
1099
|
|
1028
1100
|
return result;
|
1029
|
-
"
|
1101
|
+
"
|
1030
1102
|
end
|
1031
1103
|
end
|
1032
1104
|
|
@@ -1289,6 +1361,73 @@ fastruby_local_next:
|
|
1289
1361
|
"
|
1290
1362
|
}
|
1291
1363
|
|
1364
|
+
update_cfunc_method = anonymous_function{ |funcname| "
|
1365
|
+
static VALUE #{funcname}(){
|
1366
|
+
void** default_address = (void**)#{cfunc_address_name};
|
1367
|
+
ID default_id = rb_intern(\"default\");
|
1368
|
+
VALUE recvtype = #{recvdump};
|
1369
|
+
|
1370
|
+
if (1) {
|
1371
|
+
*default_address = 0;
|
1372
|
+
|
1373
|
+
#ifdef RUBY_1_8
|
1374
|
+
|
1375
|
+
// this only works with ruby1.8
|
1376
|
+
|
1377
|
+
NODE* body = rb_method_node(recvtype,#{intern_num mname});
|
1378
|
+
if (body != 0) {
|
1379
|
+
if (nd_type(body) == NODE_CFUNC) {
|
1380
|
+
if (body->nd_argc == #{args_tree.size-1}) {
|
1381
|
+
*default_address = #{cfunc_wrapper};
|
1382
|
+
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1383
|
+
} else if (body->nd_argc == -1) {
|
1384
|
+
*default_address = #{cfunc_wrapper_1};
|
1385
|
+
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1386
|
+
} else if (body->nd_argc == -2) {
|
1387
|
+
*default_address = #{cfunc_wrapper_2};
|
1388
|
+
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1389
|
+
}
|
1390
|
+
}
|
1391
|
+
}
|
1392
|
+
#endif
|
1393
|
+
#ifdef RUBY_1_9
|
1394
|
+
rb_method_entry_t* me = rb_method_entry(recvtype,#{intern_num mname});
|
1395
|
+
if (me != 0) {
|
1396
|
+
rb_method_definition_t* def = me->def;
|
1397
|
+
|
1398
|
+
if (def->type == VM_METHOD_TYPE_CFUNC) {
|
1399
|
+
if (def->body.cfunc.argc == #{args_tree.size-1}) {
|
1400
|
+
*default_address = #{cfunc_wrapper};
|
1401
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1402
|
+
} else if (def->body.cfunc.argc == -1) {
|
1403
|
+
*default_address = #{cfunc_wrapper_1};
|
1404
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1405
|
+
} else if (def->body.cfunc.argc == -2) {
|
1406
|
+
*default_address = #{cfunc_wrapper_2};
|
1407
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1408
|
+
}
|
1409
|
+
}
|
1410
|
+
}
|
1411
|
+
#endif
|
1412
|
+
|
1413
|
+
if (recvtype != Qnil) {
|
1414
|
+
rb_funcall(
|
1415
|
+
recvtype,
|
1416
|
+
#{intern_num :register_method_value},
|
1417
|
+
3,
|
1418
|
+
#{literal_value mname},
|
1419
|
+
PTR2NUM(default_id),
|
1420
|
+
PTR2NUM(default_address)
|
1421
|
+
);
|
1422
|
+
}
|
1423
|
+
}
|
1424
|
+
return Qnil;
|
1425
|
+
}
|
1426
|
+
"
|
1427
|
+
}
|
1428
|
+
|
1429
|
+
|
1430
|
+
|
1292
1431
|
if recvdump and recvtype
|
1293
1432
|
init_extra << "
|
1294
1433
|
{
|
@@ -1332,58 +1471,16 @@ fastruby_local_next:
|
|
1332
1471
|
if (default_address==0) {
|
1333
1472
|
default_address = malloc(sizeof(void*));
|
1334
1473
|
*default_address = 0;
|
1335
|
-
|
1336
|
-
#ifdef RUBY_1_8
|
1337
|
-
|
1338
|
-
// this only works with ruby1.8
|
1339
|
-
|
1340
|
-
NODE* body = rb_method_node(recvtype,#{intern_num mname});
|
1341
|
-
if (body != 0) {
|
1342
|
-
if (nd_type(body) == NODE_CFUNC) {
|
1343
|
-
if (body->nd_argc == #{args_tree.size-1}) {
|
1344
|
-
*default_address = #{cfunc_wrapper};
|
1345
|
-
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1346
|
-
} else if (body->nd_argc == -1) {
|
1347
|
-
*default_address = #{cfunc_wrapper_1};
|
1348
|
-
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1349
|
-
} else if (body->nd_argc == -2) {
|
1350
|
-
*default_address = #{cfunc_wrapper_2};
|
1351
|
-
#{cfunc_real_address_name} = (void*)body->nd_cfnc;
|
1352
|
-
}
|
1353
|
-
}
|
1354
|
-
}
|
1355
|
-
#endif
|
1356
|
-
#ifdef RUBY_1_9
|
1357
|
-
rb_method_entry_t* me = rb_method_entry(recvtype,#{intern_num mname});
|
1358
|
-
if (me != 0) {
|
1359
|
-
rb_method_definition_t* def = me->def;
|
1360
|
-
|
1361
|
-
if (def->type == VM_METHOD_TYPE_CFUNC) {
|
1362
|
-
if (def->body.cfunc.argc == #{args_tree.size-1}) {
|
1363
|
-
*default_address = #{cfunc_wrapper};
|
1364
|
-
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1365
|
-
} else if (def->body.cfunc.argc == -1) {
|
1366
|
-
*default_address = #{cfunc_wrapper_1};
|
1367
|
-
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1368
|
-
} else if (def->body.cfunc.argc == -2) {
|
1369
|
-
*default_address = #{cfunc_wrapper_2};
|
1370
|
-
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1371
|
-
}
|
1372
|
-
}
|
1373
|
-
}
|
1374
|
-
#endif
|
1375
|
-
|
1376
|
-
if (recvtype != Qnil) {
|
1377
|
-
rb_funcall(
|
1378
|
-
recvtype,
|
1379
|
-
#{intern_num :register_method_value},
|
1380
|
-
3,
|
1381
|
-
#{literal_value mname},
|
1382
|
-
PTR2NUM(default_id),
|
1383
|
-
PTR2NUM(default_address)
|
1384
|
-
);
|
1385
|
-
}
|
1386
1474
|
}
|
1475
|
+
#{cfunc_address_name} = default_address;
|
1476
|
+
|
1477
|
+
#{update_cfunc_method}();
|
1478
|
+
rb_iterate(#{anonymous_function{|funcname|
|
1479
|
+
"static VALUE #{funcname}(VALUE recv) {
|
1480
|
+
return rb_funcall(recv, #{intern_num :observe}, 1, #{literal_value(alt_method_name + "#" + cfunc_address_name)});
|
1481
|
+
}
|
1482
|
+
"
|
1483
|
+
}},fastruby_method,#{update_cfunc_method},Qnil);
|
1387
1484
|
|
1388
1485
|
if (address==0) {
|
1389
1486
|
address = malloc(sizeof(void*));
|
@@ -1403,7 +1500,6 @@ fastruby_local_next:
|
|
1403
1500
|
}
|
1404
1501
|
|
1405
1502
|
#{address_name} = address;
|
1406
|
-
#{cfunc_address_name} = default_address;
|
1407
1503
|
#{name} = (void*)#{generic_wrapper};
|
1408
1504
|
}
|
1409
1505
|
"
|
@@ -1418,6 +1514,7 @@ fastruby_local_next:
|
|
1418
1514
|
end
|
1419
1515
|
|
1420
1516
|
def intern_num(symbol)
|
1517
|
+
symbol = symbol.to_sym
|
1421
1518
|
@intern_num_hash = Hash.new unless @intern_num_hash
|
1422
1519
|
return @intern_num_hash[symbol] if @intern_num_hash[symbol]
|
1423
1520
|
|
data/lib/fastruby.rb
CHANGED
data/lib/fastruby.rb~
ADDED
@@ -0,0 +1,36 @@
|
|
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/exceptions"
|
22
|
+
require "fastruby/object"
|
23
|
+
require "fastruby/exceptions"
|
24
|
+
require "fastruby/custom_require"
|
25
|
+
require "fastruby/set_tree"
|
26
|
+
require "base64"
|
27
|
+
|
28
|
+
class Object
|
29
|
+
def self.decode64(value)
|
30
|
+
Base64.decode64(value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module FastRuby
|
35
|
+
VERSION = "0.0.18" unless defined? FastRuby::VERSION
|
36
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
data/spec/ruby/base_spec.rb~
CHANGED
@@ -204,13 +204,13 @@ describe FastRuby, "fastruby" do
|
|
204
204
|
"
|
205
205
|
|
206
206
|
fastruby "
|
207
|
-
def foo(
|
207
|
+
def foo(x,a,b)
|
208
208
|
bar(
|
209
|
-
if (
|
210
|
-
|
209
|
+
if (x)
|
210
|
+
x.to_s
|
211
211
|
a
|
212
212
|
else
|
213
|
-
|
213
|
+
x.to_s
|
214
214
|
b
|
215
215
|
end
|
216
216
|
) {
|
@@ -391,4 +391,4 @@ describe FastRuby, "fastruby" do
|
|
391
391
|
::J57.new.bar.should be == 43
|
392
392
|
end
|
393
393
|
|
394
|
-
end
|
394
|
+
end
|