[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