Skip to content

Instantly share code, notes, and snippets.

@takaokouji
Created May 3, 2011 15:42
Show Gist options
  • Save takaokouji/953571 to your computer and use it in GitHub Desktop.
Save takaokouji/953571 to your computer and use it in GitHub Desktop.
fixed break, next and redo with ensure block (before refactor)
diff --git a/compiler.cpp b/compiler.cpp
index 1ae055a..55188a0 100644
--- a/compiler.cpp
+++ b/compiler.cpp
@@ -2006,12 +2006,24 @@ RoxorCompiler::compile_jump(NODE *node)
compile_landing_pad_footer();
}
if (within_loop) {
- BranchInst::Create(current_loop_end_bb, bb);
- current_loop_exit_val->addIncoming(val, bb);
+ if (ensure_bb == NULL) {
+ BranchInst::Create(current_loop_end_bb, bb);
+ current_loop_exit_val->addIncoming(val, bb);
+ }
+ else {
+ BranchInst::Create(ensure_bb, bb);
+ ensure_pn->addIncoming(val, bb);
+ }
}
else if (within_block) {
- compile_break_val(val);
- ReturnInst::Create(context, val, bb);
+ if (ensure_bb == NULL) {
+ compile_break_val(val);
+ ReturnInst::Create(context, val, bb);
+ }
+ else {
+ BranchInst::Create(ensure_bb, bb);
+ ensure_pn->addIncoming(val, bb);
+ }
}
else {
rb_raise(rb_eLocalJumpError, "unexpected break");
@@ -2041,6 +2053,9 @@ RoxorCompiler::compile_jump(NODE *node)
compile_landing_pad_footer();
}
if (within_loop) {
+ if (ensure_node != NULL) {
+ compile_node(ensure_node);
+ }
BranchInst::Create(current_loop_body_bb, bb);
}
else if (within_block) {
@@ -4735,7 +4750,33 @@ RoxorCompiler::compile_node0(NODE *node)
compile_set_has_ensure(old_has_ensure);
compile_node(node->nd_ensr);
// the return value is the PHINode from all the return
- compile_simple_return(new_ensure_pn);
+ const bool within_loop = current_loop_begin_bb != NULL
+ && current_loop_body_bb != NULL
+ && current_loop_end_bb != NULL;
+ const bool within_block = block_declaration;
+ if (within_loop) {
+ if (ensure_bb == NULL) {
+ BranchInst::Create(current_loop_end_bb, bb);
+ current_loop_exit_val->addIncoming(new_ensure_pn, bb);
+ }
+ else {
+ BranchInst::Create(ensure_bb, bb);
+ ensure_pn->addIncoming(new_ensure_pn, bb);
+ }
+ }
+ else if (within_block) {
+ if (ensure_bb == NULL) {
+ compile_break_val(new_ensure_pn);
+ ReturnInst::Create(context, new_ensure_pn, bb);
+ }
+ else {
+ BranchInst::Create(ensure_bb, bb);
+ ensure_pn->addIncoming(new_ensure_pn, bb);
+ }
+ }
+ else {
+ compile_simple_return(new_ensure_pn);
+ }
}
// we also have to compile the ensure
diff --git a/test_vm/block.rb b/test_vm/block.rb
index 8dc6c70..3bedd49 100644
--- a/test_vm/block.rb
+++ b/test_vm/block.rb
@@ -183,10 +183,10 @@ assert "42", "i=0; while i<1; begin; i=2; next; ensure; p 42; end; end"
assert "42", "begin p proc { break 24 }.call rescue LocalJumpError; p 42 end", :known_bug => true
assert "42", "def foo; yield; end; foo { break }; 1.times {p 42}"
-assert "42", "1.times { begin; break; ensure; p 42; end }", :known_bug => true
-assert "42", "i=0; while i<1; begin; break; ensure; p 42; end; end", :known_bug => true
+assert "42", "1.times { begin; break; ensure; p 42; end }"
+assert "42", "i=0; while i<1; begin; break; ensure; p 42; end; end"
-assert "42\n42", "i=0; while true; begin; break if i>0; i=1; redo; ensure; p 42; end; end", :known_bug => true
+assert "42\n42", "i=0; while true; begin; break if i>0; i=1; redo; ensure; p 42; end; end"
assert "42", "p [42].map { |x| x }.map { |y| y }[0]"
diff --git a/test_vm/dispatch.rb b/test_vm/dispatch.rb
index d8f025a..c2716f1 100644
--- a/test_vm/dispatch.rb
+++ b/test_vm/dispatch.rb
@@ -141,7 +141,7 @@ assert ":ok", "def foo(*args); :ok; end; p foo"
assert ":ok", "def foo(&block); :ok; end; p foo"
assert ":ok", "def foo(*args, &block); :ok; end; p foo"
assert ":ok", "def foo(x, *args, &block); x; end; p foo(:ok)"
-assert ":ok", "def f(&proc) p :ok; end; f(&nil)", :known_bug => true
+assert ":ok", "def f(&proc) p :ok; end; f(&nil)"
assert ":ok", %{
def foo(&block) p(block ? :ko : :ok) end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment