[macruby-changes] [4537] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Sep 24 01:32:22 PDT 2010


Revision: 4537
          http://trac.macosforge.org/projects/ruby/changeset/4537
Author:   lsansonetti at apple.com
Date:     2010-09-24 01:32:18 -0700 (Fri, 24 Sep 2010)
Log Message:
-----------
fix a bug when exceptions raised inside .rbo entry point functions would not be properly propagated since the entry point was directly executed from the dylib constructor trampoline which isn't compiled with unwind tables; instead we now call the entry point right after dlopen() (which is exception safe) and use the constructor to register a pointer to it

Modified Paths:
--------------
    MacRuby/trunk/bin/rubyc
    MacRuby/trunk/dln.c

Modified: MacRuby/trunk/bin/rubyc
===================================================================
--- 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
===================================================================
--- 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;
     }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100924/ab42d49c/attachment.html>


More information about the macruby-changes mailing list