fastruby 0.0.18 → 0.0.19

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