[macruby-changes] [978] MacRuby/branches/experimental/roxor.cpp

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 17 20:43:15 PDT 2009


Revision: 978
          http://trac.macosforge.org/projects/ruby/changeset/978
Author:   lsansonetti at apple.com
Date:     2009-03-17 20:43:14 -0700 (Tue, 17 Mar 2009)
Log Message:
-----------
implemented retry

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-18 01:59:26 UTC (rev 977)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-18 03:43:14 UTC (rev 978)
@@ -205,6 +205,7 @@
 	ID self_id;
 	Value *current_self;
 	bool current_block;
+	BasicBlock *begin_bb;
 	BasicBlock *rescue_bb;
 	NODE *current_block_node;
 	Function *current_block_func;
@@ -299,6 +300,7 @@
 	Value *compile_const(ID id, Value *outer);
 	Value *compile_defined_expression(NODE *node);
 	Value *compile_dstr(NODE *node);
+	void compile_dead_branch(void);
 
 	Value *get_var(ID name, std::map<ID, Value *> &container, 
 		       bool do_assert) {
@@ -507,6 +509,7 @@
     fname = _fname;
 
     bb = NULL;
+    begin_bb = NULL;
     rescue_bb = NULL;
     current_mid = 0;
     current_instance_method = false;
@@ -1208,6 +1211,15 @@
     return CallInst::Create(newStringFunc, params.begin(), params.end(), "", bb);
 }
 
+void
+RoxorCompiler::compile_dead_branch(void)
+{
+    // To not complicate the compiler even more, let's be very lazy here and
+    // continue on a dead branch. Hopefully LLVM will be smart enough to eliminate
+    // it at compilation time.
+    bb = BasicBlock::Create("DEAD", bb->getParent());
+}
+
 Value *
 RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc, std::vector<Value *> &params)
 {
@@ -3005,15 +3017,24 @@
 
 		    ReturnInst::Create(val, bb);
 		}
-
-		// To not complicate the compiler even more, let's be very lazy here and
-		// continue on a dead branch. Hopefully LLVM will be smart enough to eliminate
-		// it at compilation time.
-		bb = BasicBlock::Create("DEAD", bb->getParent());
+		compile_dead_branch();
 		return val;
 	    }
 	    break;
 
+	case NODE_RETRY:
+	    {
+		if (begin_bb == NULL) {
+		    rb_raise(rb_eSyntaxError, "unexpected retry");
+		}
+		// TODO raise a SyntaxError if called outside of a "rescue"
+		// block.
+		BranchInst::Create(begin_bb, bb);
+		compile_dead_branch();
+		return nilVal;
+	    }
+	    break;
+
 	case NODE_CONST:
 	    assert(node->nd_vid > 0);
 	    return compile_const(node->nd_vid, compile_current_class());
@@ -3213,10 +3234,12 @@
 		NODE *n = node;
 		Value *val = NULL;
 
+		DEBUG_LEVEL_INC();
 		while (n != NULL && nd_type(n) == NODE_BLOCK) {
 		    val = n->nd_head == NULL ? nilVal : compile_node(n->nd_head);
 		    n = n->nd_next;
 		}
+		DEBUG_LEVEL_DEC();
 
 		return val;
 	    }
@@ -3384,10 +3407,7 @@
 	    break;
 
 	case NODE_BEGIN:
-	    if (node->nd_body != NULL) {
-		return compile_node(node->nd_body);
-	    }
-	    return nilVal;
+	    return node->nd_body == NULL ? nilVal : compile_node(node->nd_body);
 
 	case NODE_RESCUE:
 	    {
@@ -3396,14 +3416,19 @@
 
 		Function *f = bb->getParent();
 
+		BasicBlock *old_begin_bb = begin_bb;
+		begin_bb = BasicBlock::Create("begin", f);
+
 		BasicBlock *old_rescue_bb = rescue_bb;
 		BasicBlock *new_rescue_bb = BasicBlock::Create("rescue", f);
 		BasicBlock *merge_bb = BasicBlock::Create("merge", f);
 
 		// Begin code.
+		BranchInst::Create(begin_bb, bb);
+		bb = begin_bb;
 		rescue_bb = new_rescue_bb;
 		Value *begin_val = compile_node(node->nd_head);
-		BasicBlock *begin_bb = bb;
+		BasicBlock *real_begin_bb = bb;
 		rescue_bb = old_rescue_bb;
 		BranchInst::Create(merge_bb, bb);
 		
@@ -3459,10 +3484,12 @@
 		BranchInst::Create(merge_bb, bb);
 
 		PHINode *pn = PHINode::Create(RubyObjTy, "rescue_result", merge_bb);
-		pn->addIncoming(begin_val, begin_bb);
+		pn->addIncoming(begin_val, real_begin_bb);
 		pn->addIncoming(rescue_val, new_rescue_bb);
 		bb = merge_bb;
 
+		begin_bb = old_begin_bb;
+
 		return pn;
 	    }
 	    break;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090317/6dcb384d/attachment-0001.html>


More information about the macruby-changes mailing list