[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