Пример #1
0
VALUE
rb_mod_ancestors(VALUE mod)
{
    // This method should return a new array without classes that should be
    // ignored.
    VALUE ary = rb_mod_ancestors_nocopy(mod);
    VALUE filtered = rb_ary_new();
    for (int i = 0, count = RARRAY_LEN(ary); i < count; i++) {
	VALUE p = RARRAY_AT(ary, i);
	if (!rb_class_hidden(p)) {
	    rb_ary_push(filtered, p);
	}
    }
    return filtered;
}
Пример #2
0
static Method
rb_vm_super_lookup(Class klass, SEL sel, Class *super_class_p)
{
    // Locate the current method implementation.
    Class self_class = klass;
    Method method = class_getInstanceMethod(self_class, sel);
    if (method == NULL) {
	// The given selector does not exist, let's go through
	// #method_missing...
	*super_class_p = NULL;
	return NULL; 
    }
    IMP self_imp = method_getImplementation(method);

    // Iterate over ancestors, locate the current class and return the
    // super method, if it exists.
    VALUE ary = rb_mod_ancestors_nocopy((VALUE)klass);
    const int count = RARRAY_LEN(ary);
    bool klass_located = false;
#if ROXOR_VM_DEBUG
    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++) {
	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;
        }
        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) {
		    continue;
		}

		IMP imp = method_getImplementation(method);
		if (imp == self_imp || UNAVAILABLE_IMP(imp)) {
		    continue;
		}

		VALUE super = RCLASS_SUPER(k);
		if (super != 0 && class_getInstanceMethod((Class)super,
			    sel) == method) {
		    continue;
		}

#if ROXOR_VM_DEBUG
		printf("returning method %p of class %s (#%d)\n",
			method, rb_class2name(k), i + 1);
#endif

		*super_class_p = (Class)k;
		return method;
            }
        }
    }
    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;
}