fastruby 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG +17 -1
  2. data/Rakefile +1 -1
  3. data/ext/fastruby_base/fastruby_base.inl +81 -3
  4. data/lib/fastruby/fastruby_sexp.rb +21 -0
  5. data/lib/fastruby/getlocals.rb +2 -1
  6. data/lib/fastruby/object.rb +1 -1
  7. data/lib/fastruby/sexp_extension.rb +189 -0
  8. data/lib/fastruby/sexp_extension_edges.rb +210 -0
  9. data/lib/fastruby/translator/modules/block.rb +29 -22
  10. data/lib/fastruby/translator/modules/call.rb +211 -34
  11. data/lib/fastruby/translator/modules/defn.rb +64 -29
  12. data/lib/fastruby/translator/modules/exceptions.rb +1 -1
  13. data/lib/fastruby/translator/modules/flow.rb +93 -31
  14. data/lib/fastruby/translator/modules/iter.rb +277 -340
  15. data/lib/fastruby/translator/modules/literal.rb +97 -20
  16. data/lib/fastruby/translator/modules/logical.rb +40 -5
  17. data/lib/fastruby/translator/modules/method_group.rb +41 -19
  18. data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
  19. data/lib/fastruby/translator/modules/variable.rb +151 -42
  20. data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
  21. data/lib/fastruby/translator/translator.rb +389 -302
  22. data/lib/fastruby.rb +1 -1
  23. data/lib/fastruby.rb~ +36 -0
  24. data/spec/edges_helper.rb +91 -0
  25. data/spec/graph/base_spec.rb +35 -0
  26. data/spec/graph/path_spec.rb +48 -0
  27. data/spec/graph/vertex_spec.rb +58 -0
  28. data/spec/ruby/block/proc_as_block_spec.rb +214 -0
  29. data/spec/ruby/block/redo_spec.rb +133 -0
  30. data/spec/ruby/defn/single_function_spec.rb +50 -0
  31. data/spec/scope_mode/base_spec.rb +55 -0
  32. data/spec/scope_mode/block_spec.rb +105 -0
  33. data/spec/scope_mode/call_spec.rb +24 -0
  34. data/spec/scope_mode/exception_spec.rb +34 -0
  35. data/spec/scope_mode/flow_spec.rb +99 -0
  36. data/spec/scope_mode/optimization_spec.rb +130 -0
  37. data/spec/sexp2graph/base_spec.rb +36 -0
  38. data/spec/sexp2graph/exception_spec.rb +172 -0
  39. data/spec/sexp2graph/flow_spec.rb +67 -0
  40. data/spec/sexp2graph/logical_spec.rb +21 -0
  41. data/spec/sexp2graph/variable_spec.rb +26 -0
  42. metadata +110 -120
  43. data/lib/fastruby/self +0 -82
  44. data/lib/len +0 -280
  45. data/spec/block/proc_as_block_spec.rb +0 -111
  46. data/spec/block/redo_spec.rb +0 -67
  47. /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
  48. /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
  49. /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
  50. /data/spec/{block → ruby/block}/break_spec.rb +0 -0
  51. /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
  52. /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
  53. /data/spec/{block → ruby/block}/next_spec.rb +0 -0
  54. /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
  55. /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
  56. /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
  57. /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
  58. /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
  59. /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
  60. /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
  61. /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
  62. /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
  63. /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
  64. /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
  65. /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
  66. /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
  67. /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
  68. /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
  69. /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
  70. /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
  71. /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
  72. /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
  73. /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
  74. /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
  75. /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
  76. /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
  77. /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
  78. /data/spec/{variable_spec.rb → ruby/variable_spec.rb} +0 -0
@@ -34,35 +34,81 @@ module FastRuby
34
34
  literal_value tree[1]
35
35
  end
36
36
 
37
- def to_c_hash(tree)
37
+ def to_c_hash(tree, result_var = nil)
38
+
39
+ hash_tmp_var = "_hash_"+rand(1000000).to_s
40
+ key_tmp_var = "_key_"+rand(1000000).to_s
41
+ value_tmp_var = "_value_"+rand(1000000).to_s
38
42
 
39
43
  hash_aset_code = ""
40
44
  (0..(tree.size-3)/2).each do |i|
41
45
  strkey = to_c tree[1 + i * 2]
42
46
  strvalue = to_c tree[2 + i * 2]
43
- hash_aset_code << "rb_hash_aset(hash, #{strkey}, #{strvalue});"
47
+ hash_aset_code << "
48
+ {
49
+ VALUE #{key_tmp_var} = Qnil;
50
+ VALUE #{value_tmp_var} = Qnil;
51
+
52
+ #{to_c tree[1 + i * 2], key_tmp_var};
53
+ #{to_c tree[2 + i * 2], value_tmp_var};
54
+
55
+ rb_hash_aset(#{hash_tmp_var}, #{key_tmp_var}, #{value_tmp_var});
56
+ }
57
+ "
58
+ end
59
+
60
+ code = "
61
+ {
62
+ VALUE #{hash_tmp_var} = rb_hash_new();
63
+ #{hash_aset_code};
64
+ #{
65
+ if result_var
66
+ "#{result_var} = #{hash_tmp_var}"
67
+ else
68
+ "return #{hash_tmp_var}"
69
+ end
70
+ };
71
+ }
72
+ "
73
+
74
+ if result_var
75
+ code
76
+ else
77
+ inline_block code
44
78
  end
45
-
46
- anonymous_function{ |name| "
47
- static VALUE #{name}(VALUE value_params) {
48
- #{@frame_struct} *pframe;
49
- #{@locals_struct} *plocals;
50
- pframe = (void*)value_params;
51
- plocals = (void*)pframe->plocals;
52
-
53
- VALUE hash = rb_hash_new();
54
- #{hash_aset_code}
55
- return hash;
56
- }
57
- " } + "((VALUE)pframe)"
58
79
  end
59
80
 
60
- def to_c_array(tree)
81
+ def to_c_array(tree, result_var = nil)
61
82
  if tree.size > 1
62
- strargs = tree[1..-1].map{|subtree| to_c subtree}.join(",")
63
- "rb_ary_new3(#{tree.size-1}, #{strargs})"
83
+ if result_var
84
+ prefix = "_array_element_" + rand(10000000).to_s + "_"
85
+ "
86
+ {
87
+ #{
88
+ (0..tree.size-2).map{|x|
89
+ "VALUE #{prefix}#{x};"
90
+ }.join("\n");
91
+ }
92
+
93
+ #{
94
+ (0..tree.size-2).map{|x|
95
+ to_c(tree[x+1], prefix+x.to_s)
96
+ }.join("\n");
97
+ }
98
+
99
+ #{result_var} = rb_ary_new3(#{tree.size-1}, #{(0..tree.size-2).map{|x| prefix+x.to_s}.join(",")} );
100
+ }
101
+ "
102
+ else
103
+ strargs = tree[1..-1].map{|subtree| to_c subtree}.join(",")
104
+ "rb_ary_new3(#{tree.size-1}, #{strargs})"
105
+ end
64
106
  else
107
+ if result_var
108
+ "#{result_var} = rb_ary_new3(0);"
109
+ else
65
110
  "rb_ary_new3(0)"
111
+ end
66
112
  end
67
113
  end
68
114
 
@@ -78,8 +124,39 @@ module FastRuby
78
124
  "Qtrue"
79
125
  end
80
126
 
81
- def to_c_dot2(tree)
82
- "rb_range_new(#{to_c tree[1]}, #{to_c tree[2]},0)"
127
+ def to_c_dot2(tree, result_var = nil)
128
+
129
+ begin_var = "_begin"+rand(10000000).to_s
130
+ end_var = "_end"+rand(10000000).to_s
131
+
132
+ if result_var
133
+ "
134
+ {
135
+ VALUE #{begin_var} = Qnil;
136
+ VALUE #{end_var} = Qnil;
137
+
138
+ #{to_c tree[1], begin_var};
139
+ #{to_c tree[2], end_var};
140
+
141
+ #{result_var} = rb_range_new(#{begin_var}, #{end_var},0);
142
+ }
143
+ "
144
+ else
145
+ if result_var
146
+ "
147
+ {
148
+ VALUE #{begin_var} = Qnil;
149
+ VALUE #{end_var} = Qnil;
150
+ #{to_c tree[1], begin_var};
151
+ #{to_c tree[2], end_var};
152
+
153
+ #{result_var} = rb_range_new(#{begin_var}, #{end_var},0)
154
+ }
155
+ "
156
+ else
157
+ "rb_range_new(#{to_c tree[1]}, #{to_c tree[2]},0)"
158
+ end
159
+ end
83
160
  end
84
161
 
85
162
  end
@@ -22,16 +22,51 @@ module FastRuby
22
22
  module LogicalOperatorTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_and(tree)
26
- "(RTEST(#{to_c tree[1]}) && RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
25
+ def to_c_and(tree, return_var = nil)
26
+ if return_var
27
+ "
28
+ {
29
+ VALUE op1 = Qnil;
30
+ VALUE op2 = Qnil;
31
+ #{to_c tree[1], "op1"};
32
+ #{to_c tree[2], "op2"};
33
+ #{return_var} = (RTEST(op1) && RTEST(op2)) ? Qtrue : Qfalse;
34
+ }
35
+ "
36
+ else
37
+ "(RTEST(#{to_c tree[1]}) && RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
38
+ end
39
+
27
40
  end
28
41
 
29
- def to_c_or(tree)
42
+ def to_c_or(tree, return_var = nil)
43
+ if return_var
44
+ "
45
+ {
46
+ VALUE op1 = Qnil;
47
+ VALUE op2 = Qnil;
48
+ #{to_c tree[1], "op1"};
49
+ #{to_c tree[2], "op2"};
50
+ #{return_var} = (RTEST(op1) || RTEST(op2)) ? Qtrue : Qfalse;
51
+ }
52
+ "
53
+ else
30
54
  "(RTEST(#{to_c tree[1]}) || RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
55
+ end
31
56
  end
32
57
 
33
- def to_c_not(tree)
34
- "RTEST(#{to_c tree[1]}) ? Qfalse : Qtrue"
58
+ def to_c_not(tree, return_var = nil)
59
+ if return_var
60
+ "
61
+ {
62
+ VALUE op1 = Qnil;
63
+ #{to_c tree[1], "op1"};
64
+ #{return_var} = (RTEST(op1)) ? Qfalse: Qtrue;
65
+ }
66
+ "
67
+ else
68
+ "RTEST(#{to_c tree[1]}) ? Qfalse : Qtrue"
69
+ end
35
70
  end
36
71
 
37
72
  end
@@ -22,47 +22,64 @@ module FastRuby
22
22
  module BlockTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_class(tree)
25
+ def to_c_class(tree, result_var = nil)
26
26
  str_class_name = get_class_name(tree[1])
27
27
  container_tree = get_container_tree(tree[1])
28
28
 
29
29
  if container_tree == s(:self)
30
30
  method_group("
31
+ VALUE superklass = rb_cObject;
32
+ #{
33
+ if tree[2]
34
+ to_c tree[2], "superklass"
35
+ end
36
+ };
31
37
  VALUE tmpklass = rb_define_class(
32
38
  #{str_class_name.inspect},
33
- #{tree[2] ? to_c(tree[2]) : "rb_cObject"}
39
+ superklass
34
40
  );
35
- ", tree[3])
41
+ ", tree[3], result_var)
36
42
  else
37
43
  method_group("
38
- VALUE container_klass = #{to_c(container_tree)};
44
+ VALUE container_klass = Qnil;
45
+ VALUE superklass = rb_cObject;
46
+
47
+ #{
48
+ if tree[2]
49
+ to_c tree[2], "superklass"
50
+ end
51
+ };
52
+
53
+ #{to_c(container_tree, "container_klass")};
39
54
  VALUE tmpklass = rb_define_class_under(
40
55
  container_klass,
41
56
  #{str_class_name.inspect},
42
- #{tree[2] ? to_c(tree[2]) : "rb_cObject"}
57
+ superklass
43
58
  );
44
- ", tree[3])
59
+ ", tree[3], result_var)
45
60
  end
46
61
  end
47
62
 
48
- def to_c_module(tree)
63
+ def to_c_module(tree, result_var = nil)
49
64
  str_class_name = get_class_name(tree[1])
50
65
  container_tree = get_container_tree(tree[1])
51
66
 
52
67
  if container_tree == s(:self)
53
68
  method_group("
54
69
  VALUE tmpklass = rb_define_module(#{str_class_name.inspect});
55
- ", tree[2])
70
+ ", tree[2], result_var)
56
71
  else
57
72
  method_group("
58
- VALUE container_klass = #{to_c(container_tree)};
73
+ VALUE container_klass = Qnil;
74
+
75
+ #{to_c(container_tree, "container_klass")};
59
76
  VALUE tmpklass = rb_define_module_under(container_klass,#{str_class_name.inspect});
60
- ", tree[2])
77
+ ", tree[2], result_var)
61
78
  end
62
79
  end
63
80
 
64
81
  private
65
- def method_group(init_code, tree)
82
+ def method_group(init_code, tree, result_var)
66
83
 
67
84
  alt_locals = Set.new
68
85
  alt_locals << :self
@@ -112,7 +129,7 @@ private
112
129
 
113
130
  plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
114
131
 
115
- plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
132
+ plocals->parent_locals = frame.thread_data->last_plocals;
116
133
  void* old_parent_locals = frame.thread_data->last_plocals;
117
134
  frame.thread_data->last_plocals = plocals;
118
135
 
@@ -120,7 +137,7 @@ private
120
137
  plocals->active = Qtrue;
121
138
  plocals->self = self;
122
139
  plocals->targetted = Qfalse;
123
- plocals->call_frame = LONG2FIX(0);
140
+ plocals->call_frame = 0;
124
141
 
125
142
  #{to_c tree};
126
143
 
@@ -141,17 +158,22 @@ private
141
158
  }
142
159
  end
143
160
 
144
- inline_block("
161
+ code = "
162
+ {
145
163
  #{init_code}
146
164
 
147
165
  rb_funcall(tmpklass, #{intern_num :__id__},0);
148
166
 
149
167
  #{fun}(tmpklass);
150
- return Qnil;
151
-
152
-
153
- ")
154
-
168
+ }
169
+ "
170
+
171
+ if result_var
172
+ code + "\n#{result_var} = Qnil;\n"
173
+ else
174
+ inline_block code + "\nreturn Qnil;\n"
175
+ end
176
+
155
177
  end
156
178
 
157
179
  def get_class_name(argument)
@@ -22,70 +22,115 @@ module FastRuby
22
22
  module NonLocalTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_return(tree)
26
- inline_block "
27
- plocals->return_value = #{to_c(tree[1])};
28
- plocals->targetted = 1;
29
- longjmp(pframe->jmp, FASTRUBY_TAG_RETURN);
25
+ def to_c_return(tree, return_variable = nil)
26
+ code = "
27
+ #{to_c(tree[1],"last_expression")};
28
+ goto local_return;
30
29
  return Qnil;
31
30
  "
31
+ if return_variable
32
+ code
33
+ else
34
+ inline_block code
35
+ end
32
36
  end
33
37
 
34
- def to_c_break(tree)
35
- inline_block(
36
- "
38
+ def to_c_break(tree, result_var = nil)
39
+
40
+ value_tmp_var = "value_" + rand(10000000).to_s
41
+
42
+ code = "
37
43
 
38
- VALUE value = #{tree[1] ? to_c(tree[1]) : "Qnil"};
44
+ {
45
+ VALUE #{value_tmp_var} = Qnil;
46
+ #{
47
+ if tree[1]
48
+ to_c(tree[1], value_tmp_var)
49
+ end
50
+ };
39
51
 
40
52
  typeof(pframe) target_frame_;
41
- target_frame_ = (void*)FIX2LONG(plocals->call_frame);
53
+ target_frame_ = (void*)plocals->call_frame;
42
54
 
43
55
  if (target_frame_ == 0) {
44
56
  #{_raise("rb_eLocalJumpError","illegal break")};
45
57
  }
46
58
 
47
- plocals->call_frame = LONG2FIX(0);
59
+ plocals->call_frame = 0;
48
60
 
49
- target_frame_->return_value = value;
61
+ target_frame_->return_value = #{value_tmp_var};
50
62
  target_frame_->targetted = 1;
51
63
  pframe->thread_data->exception = Qnil;
52
- longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);"
53
- )
64
+ longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);
65
+
66
+ }
67
+ "
68
+
69
+ if result_var
70
+ code
71
+ else
72
+ inline_block code
73
+ end
54
74
  end
55
75
 
56
- def to_c_retry(tree)
57
- inline_block(
58
- "
76
+ def to_c_retry(tree, result_var = nil)
77
+ code = "
78
+ {
59
79
  typeof(pframe) target_frame_;
60
- target_frame_ = (void*)FIX2LONG(plocals->call_frame);
80
+ target_frame_ = (void*)plocals->call_frame;
61
81
 
62
82
  if (target_frame_ == 0) {
63
83
  #{_raise("rb_eLocalJumpError","illegal retry")};
64
84
  }
65
85
 
66
86
  target_frame_->targetted = 1;
67
- longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);"
68
- )
87
+ longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);
88
+ }
89
+ "
90
+ if result_var
91
+ code
92
+ else
93
+ inline_block code
94
+ end
69
95
  end
70
96
 
71
- def to_c_redo(tree)
97
+ def to_c_redo(tree, result_var = nil)
72
98
  if @on_block
73
- inline_block "
74
- longjmp(pframe->jmp,FASTRUBY_TAG_REDO);
75
- return Qnil;
99
+ code = "
100
+ goto fastruby_local_redo;
76
101
  "
102
+
103
+ if result_var
104
+ code
105
+ else
106
+ inline_block code
107
+ end
77
108
  else
78
109
  _raise("rb_eLocalJumpError","illegal redo");
79
110
  end
80
111
  end
81
112
 
82
- def to_c_next(tree)
113
+ def to_c_next(tree, result_var = nil)
114
+ tmp_varname = "_acc_" + rand(10000000).to_s
83
115
  if @on_block
84
- inline_block "
85
- pframe->thread_data->accumulator = #{tree[1] ? to_c(tree[1]) : "Qnil"};
86
- longjmp(pframe->jmp,FASTRUBY_TAG_NEXT);
87
- return Qnil;
116
+ code = "
117
+ {
118
+ last_expression = Qnil;
119
+
120
+ #{
121
+ if tree[1]
122
+ to_c(tree[1],"last_expression")
123
+ end
124
+ }
125
+ pframe->thread_data->accumulator = last_expression;
126
+ goto fastruby_local_next;
127
+ }
88
128
  "
129
+ if result_var
130
+ code
131
+ else
132
+ inline_block code
133
+ end
89
134
  else
90
135
  _raise("rb_eLocalJumpError","illegal next");
91
136
  end