[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