[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