Revision: 4535 http://trac.macosforge.org/projects/ruby/changeset/4535 Author: lsansonetti@apple.com Date: 2010-09-22 17:44:01 -0700 (Wed, 22 Sep 2010) Log Message: ----------- fix a bug in the super dispatcher: in case we can't locate the receiver's class in the ancestors chain, because it may have been extended, let's assume the super method will be in the direct superclass instead Modified Paths: -------------- MacRuby/trunk/class.c MacRuby/trunk/dispatcher.cpp Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2010-09-22 20:53:10 UTC (rev 4534) +++ MacRuby/trunk/class.c 2010-09-23 00:44:01 UTC (rev 4535) @@ -714,8 +714,6 @@ * Math.ancestors #=> [Math] */ -static void rb_mod_included_modules_nosuper(VALUE, VALUE); - VALUE rb_mod_ancestors_nocopy(VALUE mod) { Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2010-09-22 20:53:10 UTC (rev 4534) +++ MacRuby/trunk/dispatcher.cpp 2010-09-23 00:44:01 UTC (rev 4535) @@ -282,13 +282,15 @@ const int count = RARRAY_LEN(ary); bool klass_located = false; #if ROXOR_VM_DEBUG - printf("locating super method %s of class %s in ancestor chain: ", - sel_getName(sel), rb_class2name((VALUE)klass)); + printf("locating super method %s of class %s (%p) in ancestor chain: ", + sel_getName(sel), rb_class2name((VALUE)klass), klass); for (int i = 0; i < count; i++) { - printf("%s ", rb_class2name(RARRAY_AT(ary, i))); + VALUE sk = RARRAY_AT(ary, i); + printf("%s (%p) ", rb_class2name(sk), (void *)sk); } printf("\n"); #endif +try_again: for (int i = 0; i < count; i++) { if (!klass_located && RARRAY_AT(ary, i) == (VALUE)self_class) { klass_located = true; @@ -296,6 +298,9 @@ if (klass_located) { if (i < count - 1) { VALUE k = RARRAY_AT(ary, i + 1); +#if ROXOR_VM_DEBUG + printf("looking in %s\n", rb_class2name((VALUE)k)); +#endif Method method = class_getInstanceMethod((Class)k, sel); if (method == NULL) { @@ -323,6 +328,14 @@ } } } + if (!klass_located) { + // Could not locate the receiver's class in the ancestors list. + // It probably means that the receiver has been extended somehow. + // We therefore assume that the super method will be in the direct + // superclass. + klass_located = true; + goto try_again; + } *super_class_p = NULL; return NULL;