Revision: 750 http://trac.macosforge.org/projects/ruby/changeset/750 Author: lsansonetti@apple.com Date: 2008-11-22 21:31:42 -0800 (Sat, 22 Nov 2008) Log Message: ----------- fix for #142 Modified Paths: -------------- MacRuby/trunk/class.c MacRuby/trunk/id.c MacRuby/trunk/id.h MacRuby/trunk/include/ruby/intern.h MacRuby/trunk/vm_insnhelper.c Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2008-11-21 04:15:20 UTC (rev 749) +++ MacRuby/trunk/class.c 2008-11-23 05:31:42 UTC (rev 750) @@ -525,8 +525,10 @@ ary = rb_ary_new(); rb_ivar_set(klass, idIncludedModules, ary); } - if (rb_ary_includes(ary, module)) - return; + else { + if (rb_ary_includes(ary, module)) + return; + } rb_ary_insert(ary, 0, module); long v = RCLASS_VERSION(module) | RCLASS_IS_INCLUDED; @@ -539,6 +541,13 @@ } rb_ary_push(ary, klass); + CFMutableDictionaryRef iv_dict; + + iv_dict = rb_class_ivar_dict(klass); + if (iv_dict != NULL) { + CFDictionaryRemoveValue(iv_dict, (const void *)idAncestors); + } + DLOG("INCM", "%s <- %s", class_getName((Class)klass), class_getName((Class)module)); if (add_methods) { @@ -662,19 +671,35 @@ static void rb_mod_included_modules_nosuper(VALUE, VALUE); VALUE -rb_mod_ancestors(VALUE mod) +rb_mod_ancestors_nocopy(VALUE mod) { - VALUE p, ary = rb_ary_new(); - - for (p = mod; p; p = RCLASS_SUPER(p)) { - rb_ary_push(ary, p); - rb_mod_included_modules_nosuper(p, ary); - if (RCLASS_MODULE(p)) - break; + VALUE ary; + + ary = rb_attr_get(mod, idAncestors); + if (NIL_P(ary)) { + VALUE p; + + ary = rb_ary_new(); + + for (p = mod; p; p = RCLASS_SUPER(p)) { + rb_ary_push(ary, p); + rb_mod_included_modules_nosuper(p, ary); + if (RCLASS_MODULE(p)) + break; + } + + rb_ivar_set(mod, idAncestors, ary); } + return ary; } +VALUE +rb_mod_ancestors(VALUE mod) +{ + return rb_ary_dup(rb_mod_ancestors_nocopy(mod)); +} + static int ins_methods_push(VALUE name, long type, VALUE ary, long visi) { Modified: MacRuby/trunk/id.c =================================================================== --- MacRuby/trunk/id.c 2008-11-21 04:15:20 UTC (rev 749) +++ MacRuby/trunk/id.c 2008-11-23 05:31:42 UTC (rev 750) @@ -94,4 +94,5 @@ idIncludedModules = rb_intern("__included_modules__"); idIncludedInClasses = rb_intern("__included_in_classes__"); + idAncestors = rb_intern("__ancestors__"); } Modified: MacRuby/trunk/id.h =================================================================== --- MacRuby/trunk/id.h 2008-11-21 04:15:20 UTC (rev 749) +++ MacRuby/trunk/id.h 2008-11-23 05:31:42 UTC (rev 750) @@ -76,5 +76,6 @@ extern SEL sel_zone; extern ID idIncludedModules; extern ID idIncludedInClasses; +extern ID idAncestors; #endif #endif /* RUBY_ID_H */ Modified: MacRuby/trunk/include/ruby/intern.h =================================================================== --- MacRuby/trunk/include/ruby/intern.h 2008-11-21 04:15:20 UTC (rev 749) +++ MacRuby/trunk/include/ruby/intern.h 2008-11-23 05:31:42 UTC (rev 750) @@ -167,6 +167,7 @@ VALUE rb_mod_included_modules(VALUE); VALUE rb_mod_include_p(VALUE, VALUE); VALUE rb_mod_ancestors(VALUE); +VALUE rb_mod_ancestors_nocopy(VALUE); VALUE rb_class_instance_methods(int, VALUE*, VALUE); VALUE rb_class_public_instance_methods(int, VALUE*, VALUE); VALUE rb_class_protected_instance_methods(int, VALUE*, VALUE); Modified: MacRuby/trunk/vm_insnhelper.c =================================================================== --- MacRuby/trunk/vm_insnhelper.c 2008-11-21 04:15:20 UTC (rev 749) +++ MacRuby/trunk/vm_insnhelper.c 2008-11-23 05:31:42 UTC (rev 750) @@ -829,23 +829,7 @@ } else { #if WITH_OBJC - if (flag & VM_CALL_SUPER_BIT) { - VALUE k; - for (k = CLASS_OF(recv); k != 0; k = RCLASS_SUPER(k)) { - VALUE ary = rb_attr_get(k, idIncludedModules); - if (ary != Qnil) { - int i, count = RARRAY_LEN(ary); - for (i = 0; i < count; i++) { - VALUE imod = RARRAY_AT(ary, i); - mn = rb_objc_method_node(imod, id, NULL, NULL); - if (mn != NULL) { - goto start_method_dispatch; - } - } - } - } - } - else if (mcache != NULL) { + if (mcache != NULL) { struct rb_objc_method_sig sig; if (rb_objc_fill_sig(recv, (Class)klass, mcache->as.rcall.sel, &sig, NULL)) { /* the class probably implements forwardInvocation: */ @@ -1445,17 +1429,17 @@ static inline VALUE vm_search_normal_superclass(VALUE klass, VALUE recv) { - if (TYPE(klass) == T_CLASS) { - klass = RCLASS_SUPER(klass); - } - else if (TYPE(klass) == T_MODULE) { - VALUE k = CLASS_OF(recv); - while (k) { - if (TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass) { - klass = RCLASS_SUPER(k); + VALUE ary; + int i, count; + + ary = rb_mod_ancestors_nocopy(CLASS_OF(recv)); + count = RARRAY_LEN(ary); + for (i = 0; i < count; i++) { + if (RARRAY_AT(ary, i) == klass) { + if (i < count) { + klass = RARRAY_AT(ary, i + 1); break; } - k = RCLASS_SUPER(k); } } return klass; @@ -1466,10 +1450,8 @@ 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; + VALUE k; if (idNew == 0) { idNew = rb_intern("new"); @@ -1477,45 +1459,8 @@ idNew3 = rb_intern("__new__"); } - if (idPreviousKlass == 0) { - idPreviousKlass = rb_intern("__previous_sklass__"); - } - - ary = rb_attr_get(klass, idIncludedModules); - if (ary != Qnil) { - int i, count = RARRAY_LEN(ary); - for (i = 0; i < count; i++) { - VALUE saved_imod_super, imod; - NODE *mn; - IMP imp; - SEL sel; - - imod = RARRAY_AT(ary, i); - saved_imod_super = RCLASS_SUPER(imod); - RCLASS_SUPER(imod) = 0; - mn = rb_objc_method_node(imod, mid, &imp, &sel); - RCLASS_SUPER(imod) = saved_imod_super; - if (imp != NULL) { - rb_ivar_set(imod, idPreviousKlass, klass); - *mnp = mn; - *impp = imp; - *selp = sel; - return imod; - } - } - } - - iv_dict = rb_class_ivar_dict(klass); - if (iv_dict != NULL - && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, - (const void *)idPreviousKlass, - (const void **)&k)) { - CFDictionaryRemoveValue(iv_dict, (const void *)idPreviousKlass); - klass = k; - } - 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) {
participants (1)
-
source_changes@macosforge.org