[macruby-changes] [5043] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu Dec 16 22:18:02 PST 2010


Revision: 5043
          http://trac.macosforge.org/projects/ruby/changeset/5043
Author:   lsansonetti at apple.com
Date:     2010-12-16 22:17:58 -0800 (Thu, 16 Dec 2010)
Log Message:
-----------
move the conformsToProtocol: and performSelector: custom methods on direct pure-Ruby subclasses

Modified Paths:
--------------
    MacRuby/trunk/array.c
    MacRuby/trunk/hash.c
    MacRuby/trunk/objc.h
    MacRuby/trunk/objc.m
    MacRuby/trunk/object.c
    MacRuby/trunk/string.c
    MacRuby/trunk/time.c

Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/array.c	2010-12-17 06:17:58 UTC (rev 5043)
@@ -3686,6 +3686,7 @@
     Init_NSArray();
 
     rb_cRubyArray = rb_define_class("Array", rb_cNSMutableArray);
+    rb_objc_install_NSObject_special_methods((Class)rb_cRubyArray);
 
     rb_objc_define_method(*(VALUE *)rb_cRubyArray, "new",
 	    rb_class_new_instance_imp, -1);

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/hash.c	2010-12-17 06:17:58 UTC (rev 5043)
@@ -1784,6 +1784,7 @@
     id_yield = rb_intern("yield");
 
     rb_cRubyHash = rb_define_class("Hash", rb_cNSMutableHash);
+    rb_objc_install_NSObject_special_methods((Class)rb_cRubyHash);
 
     rb_objc_define_method(*(VALUE *)rb_cRubyHash, "new",
 	    rb_class_new_instance_imp, -1);

Modified: MacRuby/trunk/objc.h
===================================================================
--- MacRuby/trunk/objc.h	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/objc.h	2010-12-17 06:17:58 UTC (rev 5043)
@@ -257,6 +257,7 @@
 void rb_objc_force_class_initialize(Class klass);
 void rb_objc_fix_relocatable_load_path(void);
 void rb_objc_load_loaded_frameworks_bridgesupport(void);
+void rb_objc_install_NSObject_special_methods(Class k);
 
 extern bool rb_objc_enable_ivar_set_kvo_notifications;
 

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/objc.m	2010-12-17 06:17:58 UTC (rev 5043)
@@ -787,14 +787,15 @@
 
 static bool
 conformsToProtocolAndAncestors(void *self, SEL sel, Class klass,
-	void *protocol, IMP super)
+	void *protocol)
 {
-    if (super != NULL) {
-	if (((bool(*)(void *, SEL, Protocol *))super)(self, sel, protocol)) {
-	    return true;
-	}
-    }
     if (protocol != NULL) {
+	for (Class k = klass; k != NULL; k = class_getSuperclass(k)) {
+	    if (class_conformsToProtocol(k, protocol)) {
+		return true;
+	    }
+	}
+
 	Protocol *p = (Protocol *)protocol;
 	if (conformsToProtocol(klass, p)) {
 	    class_addProtocol(klass, p);
@@ -804,90 +805,55 @@
     return false;
 }
 
-static IMP old_conformsToProtocol_imp = NULL;
-
 static bool
 robj_conformsToProtocol(void *self, SEL sel, void *protocol)
 {
     return conformsToProtocolAndAncestors(self, sel, object_getClass(self),
-	    protocol, old_conformsToProtocol_imp);
+	    protocol);
 }
 
-static IMP old_conformsToProtocol_mimp = NULL;
-
 static bool
 robj_conformsToProtocol_m(void *self, SEL sel, void *protocol)
 {
-    return conformsToProtocolAndAncestors(self, sel, (Class)self, protocol,
-	    old_conformsToProtocol_mimp);
+    return conformsToProtocolAndAncestors(self, sel, (Class)self, protocol);
 }
 
-static bool
-performRubyOnlySelector(void *self, SEL msg, int argc, void **argv,
-	id *retval)
-{
-    Method m = class_getInstanceMethod(object_getClass((id)self), msg);
-    if (rb_vm_is_ruby_method(m)) {
-	VALUE rb_args[5];
-	assert(argc < 5);
-	for (int i = 0; i < argc; i++) {
-	    rb_args[i] = OC2RB(argv[i]);
-	}
-	*retval = RB2OC(rb_vm_call(OC2RB(self), msg, argc, rb_args));
-	return true;
-    }
-    return false;
-}
-
-static IMP old_performSelector_imp = NULL;
-
 static id
 robj_performSelector(void *self, SEL sel, SEL msg)
 {
-    id retval = NULL;
-    if (!performRubyOnlySelector(self, msg, 0, NULL, &retval)) {
-	if (old_performSelector_imp != NULL) {
-	    return ((id(*)(void *, SEL, SEL))
-		    old_performSelector_imp) (self, sel, msg);
-	}
-    }
-    return retval;
+    return RB2OC(rb_vm_call(OC2RB(self), msg, 0, NULL));
 }
 
-static IMP old_performSelectorWithObject_imp = NULL;
-
 static id
 robj_performSelectorWithObject(void *self, SEL sel, SEL msg, void *arg)
 {
-    id retval = NULL;
-    if (!performRubyOnlySelector(self, msg, 1, &arg, &retval)) {
-	if (old_performSelectorWithObject_imp != NULL) {
-	    return ((id(*)(void *, SEL, SEL, void *))
-		    old_performSelectorWithObject_imp) (self, sel, msg, arg);
-	}
-    }
-    return retval;
+    VALUE rarg = OC2RB(arg);
+    return RB2OC(rb_vm_call(OC2RB(self), msg, 1, &rarg));
 }
 
-static IMP old_performSelectorWithObjectWithObject_imp = NULL;
-
 static id
 robj_performSelectorWithObjectWithObject(void *self, SEL sel, SEL msg,
 	void *arg1, void *arg2)
 {
-    id retval = NULL;
-    void *args[2] = { arg1, arg2 };
-    if (!performRubyOnlySelector(self, msg, 2, args, &retval)) {
-	if (old_performSelectorWithObjectWithObject_imp != NULL) {
-	    return ((id(*)(void *, SEL, SEL, void *, void *))
-		    old_performSelectorWithObjectWithObject_imp)
-		(self, sel, msg, arg1, arg2);
-	}
-    }
-    return retval;
+    VALUE rarg[2] = { OC2RB(arg1), OC2RB(arg2) };
+    return RB2OC(rb_vm_call(OC2RB(self), msg, 2, rarg));
 }
 
 void
+rb_objc_install_NSObject_special_methods(Class k)
+{
+    SEL sel = sel_registerName("conformsToProtocol:");
+    rb_objc_install_method(k, sel, (IMP)robj_conformsToProtocol);
+    rb_objc_install_method(*(Class *)k, sel, (IMP)robj_conformsToProtocol_m);
+
+    rb_objc_install_method2(k, "performSelector:", (IMP)robj_performSelector);
+    rb_objc_install_method2(k, "performSelector:withObject:",
+	    (IMP)robj_performSelectorWithObject);
+    rb_objc_install_method2(k, "performSelector:withObject:withObject:",
+	    (IMP)robj_performSelectorWithObjectWithObject);  
+}
+
+void
 Init_ObjC(void)
 {
     sel_at = sel_registerName("at:");
@@ -907,24 +873,6 @@
     old_imp_isaForAutonotifying = method_getImplementation(m);
     method_setImplementation(m, (IMP)rb_obj_imp_isaForAutonotifying);
 
-    // Overwrite NSObject's conformsToProtocol:.
-    k = (Class)[NSObject class];
-    SEL sel = sel_registerName("conformsToProtocol:");
-    old_conformsToProtocol_imp = rb_objc_install_method(k, sel,
-	    (IMP)robj_conformsToProtocol);
-    old_conformsToProtocol_mimp = rb_objc_install_method(
-	    *(Class *)k, sel, (IMP)robj_conformsToProtocol_m);
-
-    // Overwrite NSObject's performSelector: and friends.
-    old_performSelector_imp = rb_objc_install_method2(k,
-	    "performSelector:", (IMP)robj_performSelector);
-    old_performSelectorWithObject_imp = rb_objc_install_method2(k,
-	    "performSelector:withObject:",
-	    (IMP)robj_performSelectorWithObject);
-    old_performSelectorWithObjectWithObject_imp = rb_objc_install_method2(k,
-	    "performSelector:withObject:withObject:",
-	    (IMP)robj_performSelectorWithObjectWithObject);  
-
     // Mark Foundation as multithreaded.
     [NSThread detachNewThreadSelector:@selector(self) toTarget:[NSThread class]
 	withObject:nil];

Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/object.c	2010-12-17 06:17:58 UTC (rev 5043)
@@ -2967,6 +2967,7 @@
     RCLASS_SET_VERSION_FLAG(rb_cRubyObject, RCLASS_IS_SINGLETON);
     RCLASS_SET_VERSION_FLAG(rb_cRubyObject, RCLASS_IS_OBJECT_SUBCLASS);
     rb_define_object_special_methods(rb_cRubyObject);
+    rb_objc_install_NSObject_special_methods((Class)rb_cRubyObject);
 
     eqlSel = sel_registerName("eql?:");
 

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/string.c	2010-12-17 06:17:58 UTC (rev 5043)
@@ -5864,6 +5864,7 @@
     Init_NSString();
 
     // rb_cRubyString is defined earlier in Init_PreVM().
+    rb_objc_install_NSObject_special_methods((Class)rb_cRubyString);
     rb_set_class_path(rb_cRubyString, rb_cObject, "String");
     rb_const_set(rb_cObject, rb_intern("String"), rb_cRubyString);
 

Modified: MacRuby/trunk/time.c
===================================================================
--- MacRuby/trunk/time.c	2010-12-17 05:19:18 UTC (rev 5042)
+++ MacRuby/trunk/time.c	2010-12-17 06:17:58 UTC (rev 5043)
@@ -2364,6 +2364,7 @@
 
     rb_cTime = rb_define_class("Time", rb_cNSDate);
     rb_include_module(rb_cTime, rb_mComparable);
+    rb_objc_install_NSObject_special_methods((Class)rb_cTime);
 
     rb_objc_define_method(*(VALUE *)rb_cTime, "alloc", time_s_alloc, 0);
     rb_objc_define_method(*(VALUE *)rb_cTime, "new", rb_class_new_instance_imp,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101216/0a30d077/attachment-0001.html>


More information about the macruby-changes mailing list