[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 *> ¶ms)
{
@@ -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