[macruby-changes] [2334] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Sat Aug 15 19:49:56 PDT 2009
Revision: 2334
http://trac.macosforge.org/projects/ruby/changeset/2334
Author: vincent.isambart at gmail.com
Date: 2009-08-15 19:49:56 -0700 (Sat, 15 Aug 2009)
Log Message:
-----------
a return in an ensure should now work properly
Modified Paths:
--------------
MacRuby/trunk/compiler.cpp
MacRuby/trunk/compiler.h
Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp 2009-08-16 02:49:50 UTC (rev 2333)
+++ MacRuby/trunk/compiler.cpp 2009-08-16 02:49:56 UTC (rev 2334)
@@ -1678,13 +1678,7 @@
ReturnInst::Create(val, bb);
}
else {
- if (ensure_bb != NULL) {
- BranchInst::Create(ensure_bb, bb);
- ensure_pn->addIncoming(val, bb);
- }
- else {
- ReturnInst::Create(val, bb);
- }
+ compile_simple_return(val);
}
break;
}
@@ -1697,6 +1691,17 @@
return val;
}
+void RoxorCompiler::compile_simple_return(Value *val)
+{
+ if (ensure_bb != NULL) {
+ BranchInst::Create(ensure_bb, bb);
+ ensure_pn->addIncoming(val, bb);
+ }
+ else {
+ ReturnInst::Create(val, bb);
+ }
+}
+
Value *
RoxorCompiler::compile_class_path(NODE *node, bool *outer)
{
@@ -4504,10 +4509,16 @@
Function *f = bb->getParent();
BasicBlock *old_ensure_bb = ensure_bb;
PHINode *old_ensure_pn = ensure_pn;
- ensure_bb = BasicBlock::Create("ensure", f);
- ensure_pn = PHINode::Create(RubyObjTy, "ensure.phi", ensure_bb);
+ // the ensure for when the block is left with a return
+ BasicBlock *ensure_return_bb = BasicBlock::Create("ensure.for.return", f);
+ // the ensure for when the block is left without using return
+ BasicBlock *ensure_normal_bb = BasicBlock::Create("ensure.no.return", f);
+ PHINode *new_ensure_pn = PHINode::Create(RubyObjTy, "ensure.phi", ensure_return_bb);
+ ensure_pn = new_ensure_pn;
Value *val;
+ ensure_bb = ensure_return_bb;
+
if (nd_type(node->nd_head) != NODE_RESCUE) {
// An ensure without a rescue (Ex. begin; ...; ensure; end)
// we must call the head within an exception handler, then
@@ -4521,8 +4532,7 @@
val = compile_node(node->nd_head);
DEBUG_LEVEL_DEC();
rescue_bb = old_rescue_bb;
- BranchInst::Create(ensure_bb, bb);
- ensure_pn->addIncoming(val, bb);
+ BranchInst::Create(ensure_normal_bb, bb);
bb = new_rescue_bb;
compile_landing_pad_header();
@@ -4531,15 +4541,30 @@
}
else {
val = compile_node(node->nd_head);
- BranchInst::Create(ensure_bb, bb);
- ensure_pn->addIncoming(val, bb);
+ BranchInst::Create(ensure_normal_bb, bb);
}
- val = ensure_pn;
-
- bb = ensure_bb;
ensure_bb = old_ensure_bb;
ensure_pn = old_ensure_pn;
+
+ if (new_ensure_pn->getNumIncomingValues() == 0) {
+ // there was no return in the block so we do not need
+ // to have an ensure block to return the value
+ new_ensure_pn->eraseFromParent();
+ ensure_return_bb->eraseFromParent();
+ }
+ else {
+ // some value was returned in the block so we have to
+ // make a version of the ensure that returns this value
+ bb = ensure_return_bb;
+ compile_node(node->nd_ensr);
+ // the return value is the PHINode from all the return
+ compile_simple_return(new_ensure_pn);
+ }
+
+ // we also have to compile the ensure
+ // for when the block was left without return
+ bb = ensure_normal_bb;
compile_node(node->nd_ensr);
return val;
Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h 2009-08-16 02:49:50 UTC (rev 2333)
+++ MacRuby/trunk/compiler.h 2009-08-16 02:49:56 UTC (rev 2334)
@@ -250,6 +250,7 @@
Value *compile_dstr(NODE *node);
Value *compile_dvar_slot(ID name);
void compile_break_val(Value *val);
+ void compile_simple_return(Value *val);
void compile_return_from_block(Value *val, int id);
void compile_return_from_block_handler(int id);
Value *compile_jump(NODE *node);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090815/20b4249e/attachment.html>
More information about the macruby-changes
mailing list