[macruby-changes] [1189] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Mar 26 16:59:58 PDT 2009


Revision: 1189
          http://trac.macosforge.org/projects/ruby/changeset/1189
Author:   lsansonetti at apple.com
Date:     2009-03-26 16:59:58 -0700 (Thu, 26 Mar 2009)
Log Message:
-----------
implemented ensure without rescue + fixed a bug when compiling the fast eqq within an exception handler

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

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-26 23:37:53 UTC (rev 1188)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-26 23:59:58 UTC (rev 1189)
@@ -285,6 +285,7 @@
 	void compile_dead_branch(void);
 	void compile_landing_pad_header(void);
 	void compile_landing_pad_footer(void);
+	void compile_rethrow_exception(void);
 
 	Value *get_var(ID name, std::map<ID, Value *> &container, 
 		       bool do_assert) {
@@ -1340,6 +1341,20 @@
     CallInst::Create(endCatchFunc, "", bb);
 }
 
+void
+RoxorCompiler::compile_rethrow_exception(void)
+{
+    Function *rethrowFunc = NULL;
+    if (rethrowFunc == NULL) {
+	// void __cxa_rethrow(void);
+	rethrowFunc = cast<Function>(
+		module->getOrInsertFunction("__cxa_rethrow",
+		    Type::VoidTy, NULL));
+    }
+    CallInst::Create(rethrowFunc, "", bb);
+    new UnreachableInst(bb);
+}
+
 Value *
 RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc, std::vector<Value *> &params)
 {
@@ -1514,6 +1529,7 @@
 		BranchInst::Create(then2BB, fastEqqBB, areFixnums, bb);
 		bb = fastEqqBB;
 		fastEqqVal = compile_fast_eqq_call(leftVal, rightVal);
+		fastEqqBB = bb;
 		BranchInst::Create(mergeBB, bb);
 	    }
 	    else {
@@ -3756,13 +3772,16 @@
 
 		    if (n->nd_args == NULL) {
 			// catch StandardError exceptions by default
-			exceptions_to_catch.push_back(ConstantInt::get(RubyObjTy, (long)rb_eStandardError));
+			exceptions_to_catch.push_back(
+				ConstantInt::get(RubyObjTy, 
+				    (long)rb_eStandardError));
 		    }
 		    else {
 			NODE *n2 = n->nd_args;
 			assert(nd_type(n2) == NODE_ARRAY);
 			while (n2 != NULL) {
-			    exceptions_to_catch.push_back(compile_node(n2->nd_head));
+			    exceptions_to_catch.push_back(compile_node(
+					n2->nd_head));
 			    n2 = n2->nd_next;
 			}
 		    }
@@ -3772,9 +3791,11 @@
 			// bool rb_vm_is_eh_active(int argc, ...);
 			std::vector<const Type *> types;
 			types.push_back(Type::Int32Ty);
-			FunctionType *ft = FunctionType::get(Type::Int8Ty, types, true);
+			FunctionType *ft = FunctionType::get(Type::Int8Ty,
+				types, true);
 			isEHActiveFunc = cast<Function>(
-				module->getOrInsertFunction("rb_vm_is_eh_active", ft));
+				module->getOrInsertFunction(
+				    "rb_vm_is_eh_active", ft));
 		    }
 
 		    const int size = exceptions_to_catch.size();
@@ -3785,13 +3806,16 @@
 			    exceptions_to_catch.begin(), 
 			    exceptions_to_catch.end(), "", bb);
 
-		    Value *is_handler_active = new ICmpInst(ICmpInst::ICMP_EQ, handler_active, 
+		    Value *is_handler_active = new ICmpInst(ICmpInst::ICMP_EQ,
+			    handler_active,
 			    ConstantInt::get(Type::Int8Ty, 1), "", bb);
 		    
 		    handler_bb = BasicBlock::Create("handler", f);
-		    BasicBlock *next_handler_bb = BasicBlock::Create("handler", f);
+		    BasicBlock *next_handler_bb =
+			BasicBlock::Create("handler", f);
 
-		    BranchInst::Create(handler_bb, next_handler_bb, is_handler_active, bb);
+		    BranchInst::Create(handler_bb, next_handler_bb,
+			    is_handler_active, bb);
 
 		    bb = handler_bb;
 		    assert(n->nd_body != NULL);
@@ -3799,7 +3823,8 @@
 		    handler_bb = bb;
 		    BranchInst::Create(merge_bb, bb);
 
-		    handlers.push_back(std::pair<Value *, BasicBlock *>(header_val, handler_bb));
+		    handlers.push_back(std::pair<Value *, BasicBlock *>
+			    (header_val, handler_bb));
 
 		    bb = handler_bb = next_handler_bb;
 
@@ -3807,15 +3832,7 @@
 		}
 
 		bb = handler_bb;
-		Function *rethrowFunc = NULL;
-		if (rethrowFunc == NULL) {
-		    // void __cxa_rethrow(void);
-		    rethrowFunc = cast<Function>(
-			    module->getOrInsertFunction("__cxa_rethrow",
-				Type::VoidTy, NULL));
-		}
-		CallInst::Create(rethrowFunc, "", bb);
-		new UnreachableInst(bb);
+		compile_rethrow_exception();
 
 		bb = merge_bb;
 		assert(handlers.size() > 0);
@@ -3824,7 +3841,8 @@
 		}
 		else {
 		    PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", bb);
-		    std::vector<std::pair<Value *, BasicBlock *> >::iterator iter = handlers.begin();
+		    std::vector<std::pair<Value *, BasicBlock *> >::iterator
+			iter = handlers.begin();
 		    while (iter != handlers.end()) {
 			pn->addIncoming(iter->first, iter->second);
 			++iter;
@@ -3853,14 +3871,41 @@
 
 		Function *f = bb->getParent();
 		BasicBlock *ensure_bb = BasicBlock::Create("ensure", f);
+		Value *val;
 
-		Value *val = compile_node(node->nd_head);
-		BranchInst::Create(ensure_bb, 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
+		    // branch on the ensure block, then re-raise the potential
+		    // exception.
+		    BasicBlock *new_rescue_bb = BasicBlock::Create("rescue", f);
+		    BasicBlock *old_rescue_bb = rescue_bb;
 
-		bb = ensure_bb;
-		compile_node(node->nd_ensr);
+		    rescue_bb = new_rescue_bb;
+		    DEBUG_LEVEL_INC();
+		    val = compile_node(node->nd_head);
+		    DEBUG_LEVEL_DEC();
+		    rescue_bb = old_rescue_bb;
+		    BranchInst::Create(ensure_bb, bb);
 
-		return val;
+		    bb = new_rescue_bb;
+		    compile_landing_pad_header();
+		    compile_node(node->nd_ensr);
+		    compile_rethrow_exception();
+		    //compile_landing_pad_footer();
+
+		    bb = ensure_bb;
+		    compile_node(node->nd_ensr);
+		}
+		else {
+		    val = compile_node(node->nd_head);
+		    BranchInst::Create(ensure_bb, bb);
+
+		    bb = ensure_bb;
+		    compile_node(node->nd_ensr);
+		}
+
+		return val;//nilVal;
 	    }
 	    break;
 
@@ -4027,14 +4072,16 @@
 
 	case NODE_COLON3:
 	    assert(node->nd_mid > 0);
-	    return compile_const(node->nd_mid, ConstantInt::get(RubyObjTy, (long)rb_cObject));
+	    return compile_const(node->nd_mid,
+		    ConstantInt::get(RubyObjTy, (long)rb_cObject));
 
 	case NODE_CASE:
 	    {
 		Function *f = bb->getParent();
 		BasicBlock *caseMergeBB = BasicBlock::Create("case_merge", f);
 
-		PHINode *pn = PHINode::Create(RubyObjTy, "case_tmp", caseMergeBB);
+		PHINode *pn = PHINode::Create(RubyObjTy, "case_tmp",
+			caseMergeBB);
 
 		Value *comparedToVal = NULL;
 
@@ -4048,14 +4095,16 @@
 		assert(nd_type(subnode) == NODE_WHEN);
 		while ((subnode != NULL) && (nd_type(subnode) == NODE_WHEN)) {
 		    NODE *valueNode = subnode->nd_head;
+		    assert(valueNode != NULL);
+
 		    BasicBlock *thenBB = BasicBlock::Create("then", f);
 
-		    assert(valueNode);
 		    compile_when_arguments(valueNode, comparedToVal, thenBB);
 		    BasicBlock *nextWhenBB = bb;
 
 		    bb = thenBB;
-		    Value *thenVal = subnode->nd_body != NULL ? compile_node(subnode->nd_body) : nilVal;
+		    Value *thenVal = subnode->nd_body != NULL
+			? compile_node(subnode->nd_body) : nilVal;
 		    thenBB = bb;
 
 		    BranchInst::Create(caseMergeBB, thenBB);

Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb	2009-03-26 23:37:53 UTC (rev 1188)
+++ MacRuby/branches/experimental/test_roxor.rb	2009-03-26 23:59:58 UTC (rev 1189)
@@ -1044,7 +1044,10 @@
 
   assert ":ok", "begin; p :ok; rescue; end"
   assert ":ok", "begin; raise; p :nok; rescue; p :ok; end"
-  assert ":ok", "begin; raise; p :nok; ensure; p :ok; end"
+  assert ":ok", %q{
+    def m; begin; raise; ensure; p :ok; end; end
+    begin; m; rescue; end
+  }
 
   assert "42", "x = 40; begin; x += 1; rescue; ensure; x += 1; end; p x"
   assert "42", "x = 40; begin; raise; x = nil; rescue; x += 1; ensure; x += 1; end; p x"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090326/ccc2525b/attachment.html>


More information about the macruby-changes mailing list