Пример #1
0
static VALUE
method_eq(VALUE method, SEL sel, VALUE other)
{
    rb_vm_method_t *m1, *m2;

    if (CLASS_OF(method) != CLASS_OF(other)) {
	return Qfalse;
    }

    Data_Get_Struct(method, rb_vm_method_t, m1);
    Data_Get_Struct(other, rb_vm_method_t, m2);

    if (m1->oclass != m2->oclass
	|| m1->rclass != m2->rclass
	|| m1->recv != m2->recv) {
	return Qfalse;
    }

    IMP m1_imp = m1->node == NULL
	? class_getMethodImplementation((Class)m1->oclass, m1->sel)
	: m1->node->objc_imp;
    IMP m2_imp = m2->node == NULL
	? class_getMethodImplementation((Class)m2->oclass, m2->sel)
	: m2->node->objc_imp;
    if (m1_imp != m2_imp) {
	return Qfalse;
    }

    return Qtrue;
}
Пример #2
0
static inline bool
sel_equal(Class klass, SEL x, SEL y)
{
    if (x == y) {
	return true;
    }

    IMP x_imp = class_getMethodImplementation(klass, x);
    IMP y_imp = class_getMethodImplementation(klass, y);
    return x_imp == y_imp;
}
Пример #3
0
static void *
rb_obj_imp_description(void *rcv, SEL sel)
{
    // If #description and #to_s are the same method (ex. when aliased)
    Class rcv_class = (Class)CLASS_OF(rcv);
    IMP desc_imp = class_getMethodImplementation(rcv_class, selDescription);
    IMP to_s_imp = class_getMethodImplementation(rcv_class, selToS);
    if (desc_imp == to_s_imp) {
	return (void *)rb_any_to_string((VALUE)rcv, sel);
    }
    return (void *)rb_vm_call(OC2RB(rcv), selToS, 0, NULL);
}
Пример #4
0
/// @see http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html
XAOriginImpType originImplementationType(Class cls, SEL selector)
{
  Class superclass;
  if (!class_respondsToSelector(cls, selector)) {
    return XAOriginImpTypeNotExists;
  } else if ((superclass = class_getSuperclass(cls)) &&
             (class_getMethodImplementation(cls, selector) == class_getMethodImplementation(superclass, selector))) {
    return XAOriginImpTypeExistsInSuperclass;
  } else {
    return XAOriginImpTypeExists;
  }
}
Пример #5
0
void releaseNSObject(id a) {
  if (!impRelease) {
    selRelease = sel_registerName("release:");
    impRelease = class_getMethodImplementation((Class)objc_getClass("NSObject"), selRelease);
  }
  impRelease(a, selRelease);
}
Пример #6
0
void retainNSObject(id a) {
  if (!impRetain) {
    selRetain  = sel_registerName("retain:");
    impRetain = class_getMethodImplementation((Class)objc_getClass("NSObject"), selRetain);
  }
  impRetain(a, selRetain);
}
Пример #7
0
void
Init_eval_method(void)
{
    rb_objc_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
    rb_objc_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
    selRespondToDefault = sel_registerName("respond_to_missing?:");
    basic_respond_to_imp = class_getMethodImplementation((Class)rb_mKernel,
	    selRespondTo);

    rb_objc_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
    rb_objc_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
    rb_objc_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
    rb_objc_define_private_method(rb_cModule, "public", rb_mod_public, -1);
    rb_objc_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
    rb_objc_define_private_method(rb_cModule, "private", rb_mod_private, -1);
    rb_objc_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);

    rb_objc_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
    rb_objc_define_method(rb_cModule, "public_method_defined?",
	    rb_mod_public_method_defined, 1);
    rb_objc_define_method(rb_cModule, "private_method_defined?",
	    rb_mod_private_method_defined, 1);
    rb_objc_define_method(rb_cModule, "protected_method_defined?",
	    rb_mod_protected_method_defined, 1);
    rb_objc_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
    rb_objc_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);

    VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
    rb_objc_define_method(cTopLevel, "public", top_public, -1);
    rb_objc_define_method(cTopLevel, "private", top_private, -1);

    object_id = rb_intern("object_id");
    __send__ = rb_intern("__send__");
    eqq = rb_intern("===");
    each = rb_intern("each");
    aref = rb_intern("[]");
    aset = rb_intern("[]=");
    match = rb_intern("=~");
    missing = rb_intern("method_missing");
    added = rb_intern("method_added");
    singleton_added = rb_intern("singleton_method_added");
    removed = rb_intern("method_removed");
    singleton_removed = rb_intern("singleton_method_removed");
    undefined = rb_intern("method_undefined");
    singleton_undefined = rb_intern("singleton_method_undefined");
}
Пример #8
0
bool
RoxorCore::respond_to(VALUE obj, VALUE klass, SEL sel, bool priv,
	bool check_override)
{
    if (klass == Qnil) {
	klass = CLASS_OF(obj);
    }
    else {
	assert(!check_override);
    }

    IMP imp = NULL;
    const bool overriden = check_override
	? ((imp = class_getMethodImplementation((Class)klass, selRespondTo))
		!= basic_respond_to_imp)
	: false;

    if (!overriden) {
	lock();
	const long key = respond_to_key((Class)klass, sel);
	std::map<long, int>::iterator iter = respond_to_cache.find(key);
	int iter_cached = (iter != respond_to_cache.end());
	unlock();
	int status;
	if (iter_cached) {
	    status = iter->second;
	}
	else {
	    Method m = class_getInstanceMethod((Class)klass, sel);
	    if (m == NULL) {
		const char *selname = sel_getName(sel);
		sel = helper_sel(selname, strlen(selname));
		if (sel != NULL) {
		    m = class_getInstanceMethod((Class)klass, sel);
		}
	    }

	    IMP imp = method_getImplementation(m);
	    if (UNAVAILABLE_IMP(imp) || imp == (IMP)rb_f_notimplement) {
		status = RESPOND_TO_NOT_EXIST;
	    }
	    else {
		rb_vm_method_node_t *node = method_node_get(m);
		if (node != NULL && (node->flags & VM_METHOD_PRIVATE)) {
		    status = RESPOND_TO_PRIVATE;
		}
		else {
		    status = RESPOND_TO_PUBLIC;
		}
	    }
	    lock();
	    respond_to_cache[key] = status;
	    unlock();
	}
	return status == RESPOND_TO_PUBLIC
	    || (priv && status == RESPOND_TO_PRIVATE);
    }
    else {
	if (imp == NULL || imp == _objc_msgForward) {
	    // The class does not respond to respond_to?:, it's probably
	    // NSProxy-based.
	    return false;
	}
	VALUE args[2];
	int n = 0;
	args[n++] = ID2SYM(rb_intern(sel_getName(sel)));
	if (priv) {
	    rb_vm_method_node_t *node = method_node_get(imp);
	    if (node != NULL
		    && (2 < node->arity.min
			|| (node->arity.max != -1 && 2 > node->arity.max))) {
		// Do nothing, custom respond_to? method incompatible arity.
	    }
	    else {
		args[n++] = Qtrue;
	    }
	}
	return rb_vm_call(obj, selRespondTo, n, args) == Qtrue;
    }
}