Created
May 3, 2011 15:42
-
-
Save takaokouji/953571 to your computer and use it in GitHub Desktop.
fixed break, next and redo with ensure block (before refactor)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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