[macruby-changes] [5265] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Mar 7 20:49:56 PST 2011


Revision: 5265
          http://trac.macosforge.org/projects/ruby/changeset/5265
Author:   lsansonetti at apple.com
Date:     2011-03-07 20:49:56 -0800 (Mon, 07 Mar 2011)
Log Message:
-----------
fix a bug when compiling recursive method calls when methods actually re-define themselves on the fly (this fixes the mustache library)

Modified Paths:
--------------
    MacRuby/trunk/compiler.cpp
    MacRuby/trunk/vm.cpp

Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp	2011-03-08 03:31:53 UTC (rev 5264)
+++ MacRuby/trunk/compiler.cpp	2011-03-08 04:49:56 UTC (rev 5265)
@@ -3098,22 +3098,52 @@
 	const unsigned long argc = args == NULL ? 0 : args->nd_alen;
 
 	if (f->arg_size() - 2 == argc) {
+	    // We check a global variable that we initialize to 0 in order
+	    // to verify that the current method did not overwrite itself.
+	    // This can happen. In this case, we do a normal dispatch.
+	    SEL sel = mid_to_sel(mid, positive_arity ? 1 : 0);
+	    GlobalVariable *gvar = GET_CORE()->redefined_op_gvar(sel, true);
+	    new StoreInst(ConstantInt::get(Type::getInt8Ty(context), 0), gvar,
+		    f->getEntryBlock().getFirstNonPHI());
+	    Value *isNotRedefined = new ICmpInst(*bb, ICmpInst::ICMP_EQ,
+		    new LoadInst(gvar, "", bb), ConstantInt::get(Int8Ty, 0));
+
+	    BasicBlock *thenBB = BasicBlock::Create(context, "op_not_redef", f);
+	    BasicBlock *elseBB = BasicBlock::Create(context, "op_dispatch", f);
+	    BasicBlock *mergeBB = BasicBlock::Create(context, "op_merge", f);
+
+	    BranchInst::Create(thenBB, elseBB, isNotRedefined, bb);
+
+	    // Compile optimized recursive call.
+	    bb = thenBB;
 	    std::vector<Value *> params;
-
 	    Function::arg_iterator arg = f->arg_begin();
-
 	    params.push_back(arg++); // self
 	    params.push_back(arg++); // sel 
-
 	    for (NODE *n = args; n != NULL; n = n->nd_next) {
 		params.push_back(compile_node(n->nd_head));
 	    }
-
 	    CallInst *inst = CallInst::Create(f, params.begin(), params.end(),
 		    "", bb);
-	    // Promote for tail call elimitation.
-	    inst->setTailCall(true);
-	    return cast<Value>(inst);
+	    inst->setTailCall(true); // Promote for tail call elimitation.
+	    Value *optz_value = cast<Value>(inst);
+	    thenBB = bb;
+	    BranchInst::Create(mergeBB, bb);
+
+	    // Compile regular dispatch call.
+	    bb = elseBB;
+	    ID old_current_mid = current_mid;
+	    current_mid = 0; // To force a normal dispatch compilation.
+	    Value *unoptz_value = compile_call(node);
+	    current_mid = old_current_mid;
+	    elseBB = bb;
+	    BranchInst::Create(mergeBB, bb);
+
+	    bb = mergeBB;
+	    PHINode *pn = PHINode::Create(RubyObjTy, "", bb);
+	    pn->addIncoming(optz_value, thenBB);
+	    pn->addIncoming(unoptz_value, elseBB);
+	    return pn;
 	}
     }
 

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2011-03-08 03:31:53 UTC (rev 5264)
+++ MacRuby/trunk/vm.cpp	2011-03-08 04:49:56 UTC (rev 5265)
@@ -907,8 +907,8 @@
 	return true;
     }
 
-    printf("invalid inline op `%s' to invalidate!\n", sel_getName(sel));
-    abort();
+    // Assume yes by default.
+    return true;
 }
 
 static ID
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20110307/fd9e0cc8/attachment.html>


More information about the macruby-changes mailing list