fastruby 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/CHANGELOG +10 -0
  2. data/Rakefile +2 -1
  3. data/benchmarks/benchmark.rb~ +2 -4
  4. data/benchmarks/benchmark3.rb~ +2 -4
  5. data/ext/fastruby_base/fastruby_base.inl +1 -1
  6. data/lib/fastruby/builder.rb +8 -7
  7. data/lib/fastruby/fastruby_sexp.rb +18 -0
  8. data/lib/fastruby/inliner/modules/call.rb +254 -67
  9. data/lib/fastruby/inliner/modules/recursive.rb +5 -0
  10. data/lib/fastruby/reductor/modules/case.rb +2 -1
  11. data/lib/fastruby/translator/modules/block.rb +65 -59
  12. data/lib/fastruby/translator/modules/call.rb +7 -4
  13. data/lib/fastruby/translator/modules/exceptions.rb +66 -64
  14. data/lib/fastruby/translator/modules/flow.rb +8 -8
  15. data/lib/fastruby/translator/modules/literal.rb +5 -4
  16. data/lib/fastruby/translator/modules/method_group.rb +6 -5
  17. data/lib/fastruby/translator/modules/nonlocal.rb +153 -11
  18. data/lib/fastruby/translator/modules/static.rb +8 -8
  19. data/lib/fastruby/translator/modules/variable.rb +15 -15
  20. data/lib/fastruby/translator/translator.rb +156 -59
  21. data/lib/fastruby.rb +1 -1
  22. data/lib/fastruby.rb~ +36 -0
  23. data/spec/fastruby/inliner/modules/call_spec.rb +0 -0
  24. data/spec/fastruby/translator/modules/nonlocal_spec.rb +0 -0
  25. data/spec/fastruby/translator/translator_spec.rb +0 -0
  26. data/spec/ruby/base_spec.rb~ +5 -5
  27. data/spec/ruby/block/break_spec.rb~ +236 -0
  28. data/spec/ruby/block/lambda_spec.rb~ +38 -0
  29. data/spec/ruby/block/next_spec.rb~ +85 -0
  30. data/spec/ruby/call/base_call_spec.rb~ +83 -0
  31. data/spec/ruby/defn/replacement_spec.rb +52 -2
  32. data/spec/ruby/defn/replacement_spec.rb~ +52 -2
  33. data/spec/ruby/exception/base_spec.rb +22 -1
  34. data/spec/ruby/return_spec.rb~ +99 -0
  35. 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 code + "; return last_expression;"
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 "VALUE #{result_var} = Qnil;\n" + code + "
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 << #{FastRuby.fastruby_load_path.inspect}
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 inline_block(code, repass_var = nil, nolocals = false)
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(inner_code, always_rescue = false,repass_var = nil, nolocals = false)
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
- inline_block "
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
- ", repass_var, nolocals
1080
+ "
1009
1081
  else
1010
- inline_block "
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
- ", repass_var, nolocals
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
@@ -32,5 +32,5 @@ class Object
32
32
  end
33
33
 
34
34
  module FastRuby
35
- VERSION = "0.0.18" unless defined? FastRuby::VERSION
35
+ VERSION = "0.0.19" unless defined? FastRuby::VERSION
36
36
  end
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
@@ -204,13 +204,13 @@ describe FastRuby, "fastruby" do
204
204
  "
205
205
 
206
206
  fastruby "
207
- def foo(xz,a,b)
207
+ def foo(x,a,b)
208
208
  bar(
209
- if (xz)
210
- xz.to_s
209
+ if (x)
210
+ x.to_s
211
211
  a
212
212
  else
213
- xz.to_s
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