[macruby-changes] [2747] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 7 13:46:01 PDT 2009


Revision: 2747
          http://trac.macosforge.org/projects/ruby/changeset/2747
Author:   lsansonetti at apple.com
Date:     2009-10-07 13:46:01 -0700 (Wed, 07 Oct 2009)
Log Message:
-----------
objc exceptions should now be catchable in ruby

Modified Paths:
--------------
    MacRuby/trunk/dispatcher.cpp
    MacRuby/trunk/objc.h
    MacRuby/trunk/objc.m
    MacRuby/trunk/rakelib/builder.rake
    MacRuby/trunk/rakelib/builder.rb
    MacRuby/trunk/vm.cpp

Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/dispatcher.cpp	2009-10-07 20:46:01 UTC (rev 2747)
@@ -391,6 +391,33 @@
     return __rb_vm_rcall(self, sel, node->ruby_imp, arity, argc, argv);
 }
 
+static
+#if __LP64__
+// This method can't be inlined in 32-bit because @try compiles as a call
+// to setjmp().
+force_inline
+#endif
+VALUE
+__rb_vm_objc_dispatch(rb_vm_objc_stub_t *stub, IMP imp, id rcv, SEL sel,
+	int argc, const VALUE *argv)
+{
+    @try {
+	return (*stub)(imp, rcv, sel, argc, argv);
+    }
+    @catch (id exc) {
+	VALUE rbexc = rb_oc2rb_exception(exc);
+#if __LP64__
+	if (rb_vm_current_exception() == Qnil) {
+	    rb_vm_set_current_exception(rbexc);	
+	}
+	throw;
+#else
+	rb_exc_raise(rbexc);
+#endif
+    }
+    abort(); // never reached
+}
+
 static void
 fill_rcache(struct mcache *cache, Class klass, SEL sel,
 	rb_vm_method_node_t *node)
@@ -783,7 +810,8 @@
 	    }
 	}
 
-	return (*ocache.stub)(ocache.imp, ocrcv, sel, argc, argv);
+	return __rb_vm_objc_dispatch(ocache.stub, ocache.imp, ocrcv, sel,
+		argc, argv);
     }
     else if (cache->flag == MCACHE_FCALL) {
 #if ROXOR_VM_DEBUG

Modified: MacRuby/trunk/objc.h
===================================================================
--- MacRuby/trunk/objc.h	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/objc.h	2009-10-07 20:46:01 UTC (rev 2747)
@@ -77,7 +77,8 @@
 bool rb_objc_symbolize_address(void *addr, void **start, char *name,
 	size_t name_len);
 
-id rb_objc_create_exception(VALUE exc);
+id rb_rb2oc_exception(VALUE exc);
+VALUE rb_oc2rb_exception(id exc);
 
 static inline int
 SubtypeUntil(const char *type, char end)

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/objc.m	2009-10-07 20:46:01 UTC (rev 2747)
@@ -622,7 +622,7 @@
 }
 
 id
-rb_objc_create_exception(VALUE exc)
+rb_rb2oc_exception(VALUE exc)
 {
     NSString *name = [NSString stringWithUTF8String:rb_obj_classname(exc)];
     NSString *reason = [(id)exc performSelector:@selector(message)];
@@ -637,6 +637,15 @@
     return [NSException exceptionWithName:name reason:reason userInfo:dict];
 }
 
+VALUE
+rb_oc2rb_exception(id exc)
+{
+    char buf[1000];
+    snprintf(buf, sizeof buf, "%s: %s", [[exc name] UTF8String],
+	    [[exc reason] UTF8String]);
+    return rb_exc_new2(rb_eRuntimeError, buf);
+}
+
 void *placeholder_String = NULL;
 void *placeholder_Dictionary = NULL;
 void *placeholder_Array = NULL;

Modified: MacRuby/trunk/rakelib/builder.rake
===================================================================
--- MacRuby/trunk/rakelib/builder.rake	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/rakelib/builder.rake	2009-10-07 20:46:01 UTC (rev 2747)
@@ -35,8 +35,15 @@
   end
 end
 
+desc "Build the markgc tool"
+task :mark_gc do
+  if !File.exist?('markgc')
+    sh "/usr/bin/gcc -std=c99 markgc.c -o markgc -Wno-format"
+  end
+end
+
 desc "Build known objects"
-task :objects => [:config_h, :dtrace_h, :revision_h] do
+task :objects => [:config_h, :dtrace_h, :revision_h, :mark_gc] do
   sh "/usr/bin/ruby tool/compile_prelude.rb prelude.rb miniprelude.c.new"
   if !File.exist?('miniprelude.c') or File.read('miniprelude.c') != File.read('miniprelude.c.new')
     mv('miniprelude.c.new', 'miniprelude.c')
@@ -62,7 +69,14 @@
   if !File.exist?('node_name.inc') or File.mtime('include/ruby/node.h') > File.mtime('node_name.inc')
     sh("/usr/bin/ruby -n tool/node_name.rb include/ruby/node.h > node_name.inc")
   end
+  t = File.exist?('dispatcher.o') ? File.mtime('dispatcher.o') : nil
   $builder.build
+  if t == nil or File.mtime('dispatcher.o') > t
+    # dispatcher.o must be marked as GC compliant to avoid a linker problem.
+    # We do not build it using -fobjc-gc because gcc generates unnecessary (and slow) write
+    # barriers.
+    sh "./markgc ./dispatcher.o"
+  end
 end
 
 desc "Create miniruby"

Modified: MacRuby/trunk/rakelib/builder.rb
===================================================================
--- MacRuby/trunk/rakelib/builder.rb	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/rakelib/builder.rb	2009-10-07 20:46:01 UTC (rev 2747)
@@ -113,8 +113,8 @@
 }
 
 OBJS_CFLAGS = {
-  # Make sure everything gets inlined properly.
-  'dispatcher' => '-Winline --param inline-unit-growth=10000 --param large-function-growth=10000'
+  # Make sure everything gets inlined properly + compile as Objective-C++.
+  'dispatcher' => '-Winline --param inline-unit-growth=10000 --param large-function-growth=10000 -x objective-c++'
 }
 
 class Builder

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2009-10-07 12:56:17 UTC (rev 2746)
+++ MacRuby/trunk/vm.cpp	2009-10-07 20:46:01 UTC (rev 2747)
@@ -2784,7 +2784,7 @@
 {
 #if __LP64__
     // In 64-bit, an Objective-C exception is a C++ exception.
-    id exc = rb_objc_create_exception(GET_VM()->current_exception());
+    id exc = rb_rb2oc_exception(GET_VM()->current_exception());
     objc_exception_throw(exc);
 #else
     void *exc = __cxa_allocate_exception(0);
@@ -2799,7 +2799,7 @@
 {
     VALUE exc = GET_VM()->current_exception();
     if (exc != Qnil) {
-	id ocexc = rb_objc_create_exception(exc);
+	id ocexc = rb_rb2oc_exception(exc);
 	objc_exception_throw(ocexc);
     }
     else {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091007/165937f4/attachment.html>


More information about the macruby-changes mailing list