Skip to content

Commit

Permalink
in the objc->ruby 32-bit stub convert ruby exceptions to objc
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2745 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
lrz committed Oct 7, 2009
1 parent ac3a5b4 commit c80c60a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 18 deletions.
57 changes: 40 additions & 17 deletions compiler.cpp
Expand Up @@ -212,11 +212,10 @@ RoxorCompiler::is_value_a_fixnum(Value *val)
}

Instruction *
RoxorCompiler::compile_protected_call(Function *func,
std::vector<Value *> &params)
RoxorCompiler::compile_protected_call(Value *imp, std::vector<Value *> &params)
{
if (rescue_invoke_bb == NULL) {
CallInst *dispatch = CallInst::Create(func,
CallInst *dispatch = CallInst::Create(imp,
params.begin(),
params.end(),
"",
Expand All @@ -227,7 +226,7 @@ RoxorCompiler::compile_protected_call(Function *func,
BasicBlock *normal_bb = BasicBlock::Create(context, "normal",
bb->getParent());

InvokeInst *dispatch = InvokeInst::Create(func,
InvokeInst *dispatch = InvokeInst::Create(imp,
normal_bb,
rescue_invoke_bb,
params.begin(),
Expand Down Expand Up @@ -1923,6 +1922,19 @@ RoxorCompiler::compile_rethrow_exception(void)
}
}

Value *
RoxorCompiler::compile_current_exception(void)
{
if (currentExceptionFunc == NULL) {
// VALUE rb_vm_current_exception(void);
currentExceptionFunc = cast<Function>(
module->getOrInsertFunction(
"rb_vm_current_exception",
RubyObjTy, NULL));
}
return CallInst::Create(currentExceptionFunc, "", bb);
}

typedef struct rb_vm_immediate_val {
int type;
union {
Expand Down Expand Up @@ -4738,17 +4750,7 @@ RoxorCompiler::compile_node(NODE *node)
break;

case NODE_ERRINFO:
{
if (currentExceptionFunc == NULL) {
// VALUE rb_vm_current_exception(void);
currentExceptionFunc = cast<Function>(
module->getOrInsertFunction(
"rb_vm_current_exception",
RubyObjTy, NULL));
}
return CallInst::Create(currentExceptionFunc, "", bb);
}
break;
return compile_current_exception();

case NODE_ENSURE:
{
Expand Down Expand Up @@ -6758,6 +6760,10 @@ RoxorCompiler::compile_objc_stub(Function *ruby_func, IMP ruby_imp,
Function::arg_iterator arg = f->arg_begin();

bb = BasicBlock::Create(context, "EntryBlock", f);
#if !__LP64__
// Prepare exception handler (see below).
rescue_invoke_bb = BasicBlock::Create(context, "rescue", f);
#endif

Value *sret = NULL;
int sret_i = 0;
Expand Down Expand Up @@ -6805,8 +6811,7 @@ RoxorCompiler::compile_objc_stub(Function *ruby_func, IMP ruby_imp,
}

// Call the Ruby implementation.
Value *ret_val = CallInst::Create(imp, params.begin(), params.end(),
"", bb);
Value *ret_val = compile_protected_call(imp, params);

// Convert the return value into Objective-C type (if any).
if (f_ret_type != VoidTy) {
Expand All @@ -6822,6 +6827,24 @@ RoxorCompiler::compile_objc_stub(Function *ruby_func, IMP ruby_imp,
ReturnInst::Create(context, bb);
}

#if !__LP64__
// The 32-bit Objective-C runtime doesn't use C++ exceptions, therefore
// we must convert Ruby exceptions to Objective-C ones.
bb = rescue_invoke_bb;
compile_landing_pad_header();

Function *ruby2ocExcHandlerFunc = NULL;
if (ruby2ocExcHandlerFunc == NULL) {
// void rb2oc_exc_handler(void);
ruby2ocExcHandlerFunc = cast<Function>(
module->getOrInsertFunction("rb2oc_exc_handler", VoidTy, NULL));
}
CallInst::Create(ruby2ocExcHandlerFunc, "", bb);

compile_landing_pad_footer();
new UnreachableInst(context, bb);
#endif

return f;
}

Expand Down
3 changes: 2 additions & 1 deletion compiler.h
Expand Up @@ -254,7 +254,7 @@ class RoxorCompiler {
return compile_const_pointer(ptr, PtrPtrTy);
}

Instruction *compile_protected_call(Function *func,
Instruction *compile_protected_call(Value *imp,
std::vector<Value *> &params);
void compile_dispatch_arguments(NODE *args,
std::vector<Value *> &arguments, int *pargc);
Expand Down Expand Up @@ -328,6 +328,7 @@ class RoxorCompiler {
Value *compile_landing_pad_header(void);
Value *compile_landing_pad_header(const std::type_info &eh_type);
void compile_landing_pad_footer(bool pop_exception=true);
Value *compile_current_exception(void);
void compile_rethrow_exception(void);
void compile_pop_exception(void);
Value *compile_lvar_slot(ID name);
Expand Down
18 changes: 18 additions & 0 deletions vm.cpp
Expand Up @@ -179,6 +179,7 @@ class RoxorJITManager : public JITMemoryManager {

extern "C" void *__cxa_allocate_exception(size_t);
extern "C" void __cxa_throw(void *, void *, void (*)(void *));
extern "C" void __cxa_rethrow(void);

RoxorCore::RoxorCore(void)
{
Expand Down Expand Up @@ -2791,6 +2792,22 @@ __vm_raise(void)
#endif
}

#if !__LP64__
extern "C"
void
rb2oc_exc_handler(void)
{
VALUE exc = GET_VM()->current_exception();
if (exc != Qnil) {
id ocexc = rb_objc_create_exception(exc);
objc_exception_throw(ocexc);
}
else {
__cxa_rethrow();
}
}
#endif

extern "C"
void
rb_vm_raise_current_exception(void)
Expand Down Expand Up @@ -2844,6 +2861,7 @@ rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1,
}
throw;
}
return Qnil; // never reached
}

extern "C"
Expand Down

0 comments on commit c80c60a

Please sign in to comment.