[macruby-changes] [543] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Sep 1 20:30:10 PDT 2008
Revision: 543
http://trac.macosforge.org/projects/ruby/changeset/543
Author: lsansonetti at apple.com
Date: 2008-09-01 20:30:09 -0700 (Mon, 01 Sep 2008)
Log Message:
-----------
fixes for #121, #117 and #52
Modified Paths:
--------------
MacRuby/trunk/class.c
MacRuby/trunk/objc.m
MacRuby/trunk/object.c
MacRuby/trunk/test/ruby/test_objc.rb
MacRuby/trunk/vm_eval.c
MacRuby/trunk/vm_insnhelper.c
Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/class.c 2008-09-02 03:30:09 UTC (rev 543)
@@ -61,17 +61,27 @@
return (VALUE)obj;
}
-static VALUE
-rb_objc_init(VALUE rcv)
+static BOOL
+rb_obj_imp_isEqual(void *rcv, SEL sel, void *obj)
{
- rb_funcall(rcv, idInitialize, 0);
+ return rb_funcall((VALUE)rcv, idEq, 1, OC2RB(obj)) == Qtrue;
+}
+
+static void *
+rb_obj_imp_init(void *rcv, SEL sel)
+{
+ rb_funcall((VALUE)rcv, idInitialize, 0);
return rcv;
}
-static BOOL
-rb_obj_imp_isEqual(void *rcv, SEL sel, void *obj)
+static VALUE
+rb_objc_init(VALUE rcv)
{
- return rb_funcall((VALUE)rcv, idEq, 1, OC2RB(obj)) == Qtrue;
+ IMP imp = class_getMethodImplementation((Class)CLASS_OF(rcv), selInit);
+ if (imp != NULL && imp != (IMP)rb_obj_imp_init) {
+ return (VALUE)((void *(*)(void *, SEL))*imp)((void *)rcv, selInit);
+ }
+ return rcv;
}
void
@@ -79,14 +89,17 @@
{
rb_define_alloc_func(klass, rb_class_allocate_instance);
rb_define_singleton_method(klass, "new", rb_class_new_instance, -1);
+ rb_define_singleton_method(klass, "__new__", rb_class_new_instance, -1);
rb_define_method(klass, "dup", rb_obj_dup, 0);
- rb_define_method(klass, "init", rb_objc_init, 0);
+ rb_define_method(klass, "initialize", rb_objc_init, 0);
rb_define_method(klass, "initialize_copy", rb_obj_init_copy, 1);
static SEL sel_isEqual = 0;
if (sel_isEqual == 0)
sel_isEqual = sel_registerName("isEqual:");
class_addMethod((Class)klass, sel_isEqual, (IMP)rb_obj_imp_isEqual, "c@:@");
+
+ class_addMethod((Class)klass, selInit, (IMP)rb_obj_imp_init, "@@:");
}
static VALUE
@@ -548,7 +561,7 @@
static void
rb_mod_included_modules_nosuper(VALUE mod, VALUE ary)
{
- VALUE inc_mods = rb_ivar_get(mod, idIncludedModules);
+ VALUE inc_mods = rb_attr_get(mod, idIncludedModules);
if (inc_mods != Qnil) {
int i, count = RARRAY_LEN(inc_mods);
for (i = 0; i < count; i++) {
@@ -680,6 +693,11 @@
Method *methods;
unsigned int i, count;
+ /* XXX:
+ * - fails to ignore undefined methods (#undef_method)
+ * - does not filter public/private/protected methods
+ */
+
methods = class_copyMethodList((Class)mod, &count);
if (methods != NULL) {
for (i = 0; i < count; i++) {
@@ -691,6 +709,7 @@
char buf[100];
BOOL is_ruby_method;
size_t len;
+ IMP imp;
method = methods[i];
@@ -698,12 +717,15 @@
if (sel == sel_ignored)
continue;
- sel_name = (char *)sel;
- is_ruby_method = rb_objc_method_node3(method_getImplementation(method)) != NULL;
+ imp = method_getImplementation(method);
+ if (imp == NULL)
+ continue;
+ is_ruby_method = rb_objc_method_node3(imp) != NULL;
if (!is_ruby_method && objc_methods == Qfalse)
continue;
+ sel_name = (char *)sel;
len = strlen(sel_name);
if (is_ruby_method && len > 8 && sel_name[0] == '_' && sel_name[1] == '_' && sel_name[2] == 'r' && sel_name[3] == 'b' && sel_name[4] == '_' && sel_name[len - 1] == '_' && sel_name[len - 2] == '_') {
Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/objc.m 2008-09-02 03:30:09 UTC (rev 543)
@@ -3163,7 +3163,7 @@
CFRunLoopAddTimer(CFRunLoopGetMain(), timer, kCFRunLoopDefaultMode);
}
- rb_define_method(rb_cBasicObject, "__super_objc_send__", rb_super_objc_send, -1);
+ rb_define_method(rb_cNSObject, "__super_objc_send__", rb_super_objc_send, -1);
Method m = class_getInstanceMethod(objc_getClass("NSKeyValueUnnestedProperty"), sel_registerName("isaForAutonotifying"));
assert(m != NULL);
Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/object.c 2008-09-02 03:30:09 UTC (rev 543)
@@ -1480,7 +1480,7 @@
{
VALUE obj;
- if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
+ if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject && klass != rb_cObject) {
rb_raise(rb_eTypeError, "can't instantiate uninitialized class");
}
if (RCLASS_SINGLETON(klass)) {
@@ -2441,26 +2441,32 @@
void
Init_Object(void)
{
- rb_cNSObject = rb_cObject = (VALUE)objc_getClass("NSObject");
+ rb_cObject = rb_cNSObject = (VALUE)objc_getClass("NSObject");
rb_const_set(rb_cObject, rb_intern("Object"), rb_cNSObject);
rb_set_class_path(rb_cObject, rb_cObject, "NSObject");
- rb_cBasicObject = rb_cObject; // TODO
+ rb_cBasicObject = (VALUE)objc_duplicateClass((Class)rb_cObject, "BasicObject", 0);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
RCLASS_SUPER(*(Class *)rb_cNSObject) = rb_cClass;
- rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
+ rb_define_private_method(rb_cNSObject, "initialize", rb_obj_dummy, 0);
rb_define_method(rb_cNSObject, "==", rb_obj_equal, 1);
rb_define_method(rb_cNSObject, "equal?", rb_obj_equal, 1);
rb_define_method(rb_cNSObject, "!", rb_obj_not, 0);
rb_define_method(rb_cNSObject, "!=", rb_obj_not_equal, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_added", rb_obj_dummy, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_removed", rb_obj_dummy, 1);
- rb_define_private_method(rb_cBasicObject, "singleton_method_undefined", rb_obj_dummy, 1);
+ rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
+ rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
+ rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
+ rb_define_method(rb_cBasicObject, "!", rb_obj_not, 0);
+ rb_define_method(rb_cBasicObject, "!=", rb_obj_not_equal, 1);
+ rb_define_private_method(rb_cNSObject, "singleton_method_added", rb_obj_dummy, 1);
+ rb_define_private_method(rb_cNSObject, "singleton_method_removed", rb_obj_dummy, 1);
+ rb_define_private_method(rb_cNSObject, "singleton_method_undefined", rb_obj_dummy, 1);
+
rb_mKernel = rb_define_module("Kernel");
- rb_include_module(rb_cObject, rb_mKernel);
+ rb_include_module(rb_cNSObject, rb_mKernel);
rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1);
rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1);
rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1);
Modified: MacRuby/trunk/test/ruby/test_objc.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_objc.rb 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/test/ruby/test_objc.rb 2008-09-02 03:30:09 UTC (rev 543)
@@ -388,4 +388,18 @@
assert(s.respond_to?('setString:'))
assert(s.respond_to?('performSelector:withObject:'))
end
+
+ class TestCallSuperOverridenNew
+ def self.new(x)
+ super
+ end
+ def initialize(x)
+ @x = x
+ end
+ attr_reader :x
+ end
+ def test_call_super_overriden_new
+ o = TestCallSuperOverridenNew.new(42)
+ assert_equal(42, o.x)
+ end
end
Modified: MacRuby/trunk/vm_eval.c
===================================================================
--- MacRuby/trunk/vm_eval.c 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/vm_eval.c 2008-09-02 03:30:09 UTC (rev 543)
@@ -1341,17 +1341,15 @@
rb_define_global_function("loop", rb_f_loop, 0);
-#if WITH_OBJC
rb_define_method(rb_cNSObject, "instance_eval", rb_obj_instance_eval, -1);
rb_define_method(rb_cNSObject, "instance_exec", rb_obj_instance_exec, -1);
rb_define_private_method(rb_cNSObject, "method_missing", rb_method_missing, -1);
rb_define_method(rb_cNSObject, "__send__", rb_f_send, -1);
-#else
+
rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1);
rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1);
rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1);
rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1);
-#endif
rb_define_method(rb_mKernel, "send", rb_f_send, -1);
rb_define_method(rb_mKernel, "public_send", rb_f_public_send, -1);
Modified: MacRuby/trunk/vm_insnhelper.c
===================================================================
--- MacRuby/trunk/vm_insnhelper.c 2008-09-01 21:08:39 UTC (rev 542)
+++ MacRuby/trunk/vm_insnhelper.c 2008-09-02 03:30:09 UTC (rev 543)
@@ -1418,12 +1418,20 @@
#if WITH_OBJC
static inline VALUE
-vm_search_normal_superclass2(VALUE klass, VALUE recv, ID mid, NODE **mnp, IMP *impp, SEL *selp)
+vm_search_normal_superclass2(VALUE klass, VALUE recv, ID mid, NODE **mnp,
+ IMP *impp, SEL *selp)
{
static ID idPreviousKlass = 0;
+ static ID idNew = 0, idNew2 = 0, idNew3 = 0;
CFMutableDictionaryRef iv_dict;
VALUE ary, k;
+ if (idNew == 0) {
+ idNew = rb_intern("new");
+ idNew2 = rb_intern("new:");
+ idNew3 = rb_intern("__new__");
+ }
+
if (idPreviousKlass == 0) {
idPreviousKlass = rb_intern("__previous_sklass__");
}
@@ -1453,11 +1461,27 @@
}
iv_dict = rb_class_ivar_dict(klass);
- if (iv_dict != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)idPreviousKlass, (const void **)&k)) {
+ if (iv_dict != NULL
+ && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict,
+ (const void *)idPreviousKlass,
+ (const void **)&k)) {
CFDictionaryRemoveValue(iv_dict, (const void *)idPreviousKlass);
klass = k;
}
- return vm_search_normal_superclass(klass, recv);
+
+ k = vm_search_normal_superclass(klass, recv);
+
+ /* because #new is added on every new NSObject subclasses, and if overriden
+ we should still call our implementation with super */
+ if ((mid == idNew || mid == idNew2) && k == *(VALUE *)rb_cNSObject) {
+ *mnp = rb_objc_method_node(klass, idNew3, impp, selp);
+ if (*mnp == NULL)
+ rb_bug("can't look up __new__ in klass `%s'\n",
+ class_getName((Class)klass));
+ k = klass;
+ }
+
+ return k;
}
#endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080901/c7f7d24e/attachment-0001.html
More information about the macruby-changes
mailing list