Permalink
Browse files

in the objc->ruby 32-bit stub convert ruby exceptions to objc

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 c80c60a583f0821933454961e83da1b104e48ddd
Showing with 60 additions and 18 deletions.
  1. +40 −17 compiler.cpp
  2. +2 −1 compiler.h
  3. +18 −0 vm.cpp
View
@@ -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(),
"",
@@ -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(),
@@ -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 {
@@ -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:
{
@@ -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;
@@ -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) {
@@ -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;
}
View
@@ -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);
@@ -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);
View
18 vm.cpp
@@ -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)
{
@@ -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)
@@ -2844,6 +2861,7 @@ rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1,
}
throw;
}
+ return Qnil; // never reached
}
extern "C"

0 comments on commit c80c60a

Please sign in to comment.