Exemplo n.º 1
0
/*
 * search method entry without the method cache.
 *
 * if you need method entry with method cache (normal case), use
 * rb_method_entry() simply.
 */
rb_method_entry_t *
rb_method_entry_get_without_cache(VALUE klass, ID id,
				  VALUE *defined_class_ptr)
{
    VALUE defined_class;
    rb_method_entry_t *me = search_method(klass, id, &defined_class);

    if (me && me->klass) {
	switch (BUILTIN_TYPE(me->klass)) {
	  case T_CLASS:
	    if (RBASIC(klass)->flags & FL_SINGLETON) break;
	    /* fall through */
	  case T_ICLASS:
	    defined_class = me->klass;
	}
    }

    if (ruby_running) {
	if (OPT_GLOBAL_METHOD_CACHE) {
	    struct cache_entry *ent;
	    ent = GLOBAL_METHOD_CACHE(klass, id);
	    ent->class_serial = RCLASS_SERIAL(klass);
	    ent->method_state = GET_GLOBAL_METHOD_STATE();
	    ent->defined_class = defined_class;
	    ent->mid = id;

	    if (UNDEFINED_METHOD_ENTRY_P(me)) {
		ent->me = 0;
		me = 0;
	    }
	    else {
		ent->me = me;
	    }
	}
	else if (UNDEFINED_METHOD_ENTRY_P(me)) {
	    me = 0;
	}
    }

    if (defined_class_ptr)
	*defined_class_ptr = defined_class;
    return me;
}
Exemplo n.º 2
0
rb_method_entry_t *
rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr)
{
#if OPT_GLOBAL_METHOD_CACHE
    struct cache_entry *ent;
    ent = GLOBAL_METHOD_CACHE(klass, id);
    if (ent->method_state == GET_GLOBAL_METHOD_STATE() &&
	ent->class_serial == RCLASS_SERIAL(klass) &&
	ent->mid == id) {
	if (defined_class_ptr)
	    *defined_class_ptr = ent->defined_class;
#if VM_DEBUG_VERIFY_METHOD_CACHE
	verify_method_cache(klass, id, ent->defined_class, ent->me);
#endif
	return ent->me;
    }
#endif

    return rb_method_entry_get_without_cache(klass, id, defined_class_ptr);
}
Exemplo n.º 3
0
/**
 * Allocates a struct RClass for a new class.
 *
 * \param flags     initial value for basic.flags of the returned class.
 * \param klass     the class of the returned class.
 * \return          an uninitialized Class object.
 * \pre  \p klass must refer \c Class class or an ancestor of Class.
 * \pre  \code (flags | T_CLASS) != 0  \endcode
 * \post the returned class can safely be \c #initialize 'd.
 *
 * \note this function is not Class#allocate.
 */
static VALUE
class_alloc(VALUE flags, VALUE klass)
{
    NEWOBJ_OF(obj, struct RClass, klass, (flags & T_MASK) | (RGENGC_WB_PROTECTED_CLASS ? FL_WB_PROTECTED : 0));
    obj->ptr = ALLOC(rb_classext_t);
    RCLASS_IV_TBL(obj) = 0;
    RCLASS_CONST_TBL(obj) = 0;
    RCLASS_M_TBL_WRAPPER(obj) = 0;
    RCLASS_SET_SUPER((VALUE)obj, 0);
    RCLASS_ORIGIN(obj) = (VALUE)obj;
    RCLASS_IV_INDEX_TBL(obj) = 0;

    RCLASS_EXT(obj)->subclasses = NULL;
    RCLASS_EXT(obj)->parent_subclasses = NULL;
    RCLASS_EXT(obj)->module_subclasses = NULL;
    RCLASS_SERIAL(obj) = rb_next_class_serial();

    RCLASS_REFINED_CLASS(obj) = Qnil;
    RCLASS_EXT(obj)->allocator = 0;
    return (VALUE)obj;
}
Exemplo n.º 4
0
static void
rb_class_clear_method_cache(VALUE klass, VALUE arg)
{
    RCLASS_SERIAL(klass) = rb_next_class_serial();
    rb_class_foreach_subclass(klass, rb_class_clear_method_cache, arg);
}