Modified: MacRuby/trunk/bin/rubyc (4536 => 4537)
--- MacRuby/trunk/bin/rubyc 2010-09-23 21:33:11 UTC (rev 4536)
+++ MacRuby/trunk/bin/rubyc 2010-09-24 08:32:18 UTC (rev 4537)
@@ -177,7 +177,7 @@
# Compile the assembly.
tmp_obj = gen_tmpfile(base + arch, 'o')
- execute("#{@gcc} -c -arch #{arch} \"#{asm}\" -o \"#{tmp_obj}\"")
+ execute("#{@gcc} -fexceptions -c -arch #{arch} \"#{asm}\" -o \"#{tmp_obj}\"")
tmp_objs << tmp_obj
end
@@ -200,10 +200,10 @@
# Generate main file.
main_txt = <<EOS
extern "C" {
+ void rb_mrep_register(void *);
void *#{init_func}(void *, void *);
- void *rb_vm_top_self(void);
__attribute__((constructor)) static void __init__(void) {
- #{init_func}(rb_vm_top_self(), 0);
+ rb_mrep_register((void *)#{init_func});
}
}
EOS
@@ -212,7 +212,7 @@
main = gen_tmpfile('main', 'c')
File.open(main, 'w') { |io| io.write(main_txt) }
linkf = @internal ? "-L. -lmacruby" : "-L#{RbConfig::CONFIG['libdir']} -lmacruby"
- execute("#{@gcxx} \"#{main}\" -dynamic -bundle -undefined suppress -flat_namespace #{arch_flags} #{linkf} \"#{obj}\" -o \"#{output}\"")
+ execute("#{@gcxx} \"#{main}\" -fexceptions -dynamic -bundle -undefined suppress -flat_namespace #{arch_flags} #{linkf} \"#{obj}\" -o \"#{output}\"")
strip(output)
end
Modified: MacRuby/trunk/dln.c (4536 => 4537)
--- MacRuby/trunk/dln.c 2010-09-23 21:33:11 UTC (rev 4536)
+++ MacRuby/trunk/dln.c 2010-09-24 08:32:18 UTC (rev 4537)
@@ -10,7 +10,10 @@
**********************************************************************/
#include "ruby/macruby.h"
+#include "ruby/node.h"
+#include "vm.h"
#include "dln.h"
+
#include <stdlib.h>
#include <alloca.h>
#include <string.h>
@@ -73,6 +76,17 @@
bool ruby_is_miniruby = false;
+// This function is called back from .rbo files' gcc constructors, passing a
+// pointer to their entry point function, during dlopen(). The entry point
+// function is called right after dlopen() directly. This is because C++
+// exceptions raised within a gcc constructor are not properly propagated.
+static void *__mrep__ = NULL;
+void
+rb_mrep_register(void *imp)
+{
+ __mrep__ = imp;
+}
+
void*
dln_load(const char *file, bool call_init)
{
@@ -92,6 +106,7 @@
void *handle;
/* Load file */
+ __mrep__ = NULL;
if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
error = dln_strerror();
goto failed;
@@ -108,6 +123,10 @@
/* Call the init code */
(*init_fct)();
}
+ else {
+ assert(__mrep__ != NULL);
+ ((IMP)__mrep__)((id)rb_vm_top_self(), 0);
+ }
return handle;
}