Ejemplo n.º 1
0
VALUE
rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
{
    VALUE recur, ary, klass;
    st_table *list;

    if (argc == 0) {
	recur = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &recur);
    }
    klass = CLASS_OF(obj);
    list = st_init_numtable();
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
	st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
	klass = RCLASS_SUPER(klass);
    }
    if (RTEST(recur)) {
	while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
	    st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
	    klass = RCLASS_SUPER(klass);
	}
    }
    ary = rb_ary_new();
    st_foreach(list, ins_methods_i, ary);
    st_free_table(list);

    return ary;
}
Ejemplo n.º 2
0
VALUE
rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
{
    VALUE recur, ary, klass, origin;
    st_table *list, *mtbl;

    if (argc == 0) {
	recur = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &recur);
    }
    klass = CLASS_OF(obj);
    origin = RCLASS_ORIGIN(klass);
    list = st_init_numtable();
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
	if ((mtbl = RCLASS_M_TBL(origin)) != 0)
	    st_foreach(mtbl, method_entry_i, (st_data_t)list);
	klass = RCLASS_SUPER(klass);
    }
    if (RTEST(recur)) {
	while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
	    if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
		st_foreach(mtbl, method_entry_i, (st_data_t)list);
	    klass = RCLASS_SUPER(klass);
	}
    }
    ary = rb_ary_new();
    st_foreach(list, ins_methods_i, ary);
    st_free_table(list);

    return ary;
}
Ejemplo n.º 3
0
void
rb_undef(VALUE klass, ID id)
{
    VALUE origin;
    NODE *body;

    if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
	rb_secure(4);
    }
    if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
	rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
		 rb_id2name(id));
    }
    rb_frozen_class_p(klass);
    if (id == object_id || id == __send__ || id == idInitialize) {
	rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
    }
    body = search_method(klass, id, &origin);
    if (!body || !body->nd_body) {
	const char *s0 = " class";
	VALUE c = klass;

	if (FL_TEST(c, FL_SINGLETON)) {
	    VALUE obj = rb_iv_get(klass, "__attached__");

	    switch (TYPE(obj)) {
	      case T_MODULE:
	      case T_CLASS:
		c = obj;
		s0 = "";
	    }
	}
	else if (TYPE(c) == T_MODULE) {
	    s0 = " module";
	}
	rb_name_error(id, "undefined method `%s' for%s `%s'",
		      rb_id2name(id), s0, rb_class2name(c));
    }

    rb_add_method(klass, id, 0, NOEX_PUBLIC);

    if (FL_TEST(klass, FL_SINGLETON)) {
	rb_funcall(rb_iv_get(klass, "__attached__"),
		   singleton_undefined, 1, ID2SYM(id));
    }
    else {
	rb_funcall(klass, undefined, 1, ID2SYM(id));
    }
}
Ejemplo n.º 4
0
static VALUE
singleton_class_clone_int(VALUE obj, VALUE nklass)
{
    VALUE klass = RBASIC(obj)->klass;

    if (!FL_TEST(klass, FL_SINGLETON))
	return klass;
    else {
	/* copy singleton(unnamed) class */
	NEWOBJ(clone, struct RClass);
	OBJSETUP(clone, 0, RBASIC(klass)->flags);

	if (BUILTIN_TYPE(obj) == T_CLASS) {
	    RBASIC(clone)->klass = (VALUE)clone;
	}
	else {
	    RBASIC(clone)->klass = rb_singleton_class_clone(klass);
	}

	clone->super = RCLASS(klass)->super;
	clone->iv_tbl = 0;
	clone->m_tbl = 0;
	if (RCLASS(klass)->iv_tbl) {
	    clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
	}
	clone->m_tbl = st_init_numtable();
	st_foreach(RCLASS(klass)->m_tbl, (int (*)(...))clone_method, NIL_P(nklass) ? (VALUE)clone : nklass);
	rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
	FL_SET(clone, FL_SINGLETON);
	return (VALUE)clone;
    }
}
Ejemplo n.º 5
0
static int
total_i(void *vstart, void *vend, size_t stride, void *ptr)
{
    VALUE v;
    struct total_data *data = (struct total_data *)ptr;

    for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags) {
	    switch (BUILTIN_TYPE(v)) {
	      case T_NONE:
	      case T_ICLASS:
	      case T_NODE:
	      case T_ZOMBIE:
		continue;
	      case T_CLASS:
		if (FL_TEST(v, FL_SINGLETON))
		  continue;
	      default:
		if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
		    data->total += memsize_of(v);
		}
	    }
	}
    }

    return 0;
}
Ejemplo n.º 6
0
static VALUE superclass_name(VALUE module)
{
  if(TYPE(module) == T_MODULE)
  {
    return Qnil;
  }
  else
  {
    VALUE super = RCLASS_SUPER(module);

    while(TYPE(super) == T_ICLASS)
    {
      super = RCLASS_SUPER(super);
    }

    if(!super)
    {
      return Qnil;
    }

    if(FL_TEST(super, FL_SINGLETON))
    {
      VALUE v = rb_iv_get(super, "__attached__");
      VALUE name = rb_mod_name(v);
      rb_str_cat2(name, "::<Singleton>");
      return name;
    }
    else
    {
      return rb_mod_name(super);
    }
  }
}
Ejemplo n.º 7
0
static void
call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass)
{
    const char *srcfile = rb_sourcefile();
    VALUE eventname = rb_str_new2(get_event_name(event));
    VALUE filename = srcfile ? rb_str_new2(srcfile) : Qnil;
    VALUE argv[6];
    int line = rb_sourceline();
    rb_thread_t *th = GET_THREAD();

    if (!klass) {
	rb_thread_method_id_and_class(th, &id, &klass);
    }

    if (klass) {
	if (RB_TYPE_P(klass, T_ICLASS)) {
	    klass = RBASIC(klass)->klass;
	}
	else if (FL_TEST(klass, FL_SINGLETON)) {
	    klass = rb_iv_get(klass, "__attached__");
	}
    }

    argv[0] = eventname;
    argv[1] = filename;
    argv[2] = INT2FIX(line);
    argv[3] = id ? ID2SYM(id) : Qnil;
    argv[4] = (self && srcfile) ? rb_binding_new() : Qnil;
    argv[5] = klass ? klass : Qnil;

    rb_proc_call_with_block(proc, 6, argv, Qnil);
}
Ejemplo n.º 8
0
/* :nodoc: */
VALUE
rb_mod_init_copy(VALUE clone, VALUE orig)
{
    rb_obj_init_copy(clone, orig);
    if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
	RBASIC(clone)->klass = rb_singleton_class_clone(orig);
    }
    RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
    if (RCLASS_IV_TBL(orig)) {
	ID id;

	RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
	CONST_ID(id, "__classpath__");
	st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
	CONST_ID(id, "__classid__");
	st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
    }
    if (RCLASS_M_TBL(orig)) {
	struct clone_method_data data;
	data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
	data.klass = clone;
	st_foreach(RCLASS_M_TBL(orig), clone_method,
		   (st_data_t)&data);
    }

    return clone;
}
Ejemplo n.º 9
0
void
rb_gc_copy_finalizer(VALUE dest, VALUE obj)
{
    VALUE table;

    if (__os_finalizers == NULL)
	return;

    if (NATIVE(obj)) {
	if (!rb_objc_flag_check((void *)obj, FL_FINALIZE))
	    return;
    }
    else {
	if (!FL_TEST(obj, FL_FINALIZE))
	    return;
    }

    table = (VALUE)CFDictionaryGetValue((CFDictionaryRef)__os_finalizers,
	(const void *)obj);

    if (table == 0) {
	CFDictionaryRemoveValue(__os_finalizers, (const void *)dest);
    }
    else {
	CFDictionarySetValue(__os_finalizers, (const void *)dest, 
	    (const void *)table);	
    }
}
Ejemplo n.º 10
0
static VALUE
klass_name(VALUE klass)
{
    VALUE result = Qnil;
    
    if (klass == 0 || klass == Qnil)
    {
        result = rb_str_new2("Global");
    }
    else if (BUILTIN_TYPE(klass) == T_MODULE)
    {
        result = rb_inspect(klass);
    }
    else if (BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON))
    {
        result = figure_singleton_name(klass);
    }
    else if (BUILTIN_TYPE(klass) == T_CLASS)
    {
        result = rb_inspect(klass);
    }
    else
    {
        /* Should never happen. */
        result = rb_str_new2("Unknown");
    }

    return result;
}
Ejemplo n.º 11
0
Archivo: class.c Proyecto: genki/ruby
VALUE
rb_singleton_class(VALUE obj)
{
    VALUE klass;

    if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
	rb_raise(rb_eTypeError, "can't define singleton");
    }
    if (rb_special_const_p(obj)) {
	SPECIAL_SINGLETON(Qnil, rb_cNilClass);
	SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
	SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
	rb_bug("unknown immediate %ld", obj);
    }

    DEFER_INTS;
    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
	rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
	klass = RBASIC(obj)->klass;
    }
    else {
	klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
    }
    if (OBJ_TAINTED(obj)) {
	OBJ_TAINT(klass);
    }
    else {
	FL_UNSET(klass, FL_TAINT);
    }
    if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
    ALLOW_INTS;

    return klass;
}
Ejemplo n.º 12
0
VALUE
rb_singleton_class_clone(VALUE obj)
{
    VALUE klass = RBASIC(obj)->klass;

    if (!FL_TEST(klass, FL_SINGLETON))
	return klass;
    else {
	struct clone_method_data data;
	/* copy singleton(unnamed) class */
        VALUE clone = class_alloc(RBASIC(klass)->flags, 0);

	if (BUILTIN_TYPE(obj) == T_CLASS) {
	    RBASIC(clone)->klass = (VALUE)clone;
	}
	else {
	    RBASIC(clone)->klass = rb_singleton_class_clone(klass);
	}

	RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
	if (RCLASS_IV_TBL(klass)) {
	    RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
	}
	RCLASS_M_TBL(clone) = st_init_numtable();
	data.tbl = RCLASS_M_TBL(clone);
	data.klass = (VALUE)clone;
	st_foreach(RCLASS_M_TBL(klass), clone_method,
		   (st_data_t)&data);
	rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
	FL_SET(clone, FL_SINGLETON);
	return (VALUE)clone;
    }
}
Ejemplo n.º 13
0
static VALUE
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
{
    VALUE ary;
    int recur, prepended = 0;
    st_table *list;

    if (argc == 0) {
	recur = TRUE;
    }
    else {
	VALUE r;
	rb_scan_args(argc, argv, "01", &r);
	recur = RTEST(r);
    }

    if (!recur && RCLASS_ORIGIN(mod) != mod) {
	mod = RCLASS_ORIGIN(mod);
	prepended = 1;
    }

    list = st_init_numtable();
    for (; mod; mod = RCLASS_SUPER(mod)) {
	if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
	if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
	if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
	if (!recur) break;
    }
    ary = rb_ary_new();
    st_foreach(list, func, ary);
    st_free_table(list);

    return ary;
}
Ejemplo n.º 14
0
/*!
 * Creates a meta^(n+1)-class for a meta^(n)-class.
 * \param metaclass     a class of a class
 * \return              the created meta^(n+1)-class.
 * \pre \a metaclass is a metaclass
 * \post the class of \a metaclass is the returned class.
 */
static VALUE
make_metametaclass(VALUE metaclass)
{
    VALUE metametaclass, super_of_metaclass;

    if (RBASIC(metaclass)->klass == metaclass) { /* for meta^(n)-class of Class */
        metametaclass = rb_class_boot(Qnil);
        RBASIC(metametaclass)->klass = metametaclass;
    }
    else {
        metametaclass = rb_class_boot(Qnil);
        RBASIC(metametaclass)->klass =
            (RBASIC(RBASIC(metaclass)->klass)->klass == RBASIC(metaclass)->klass)
            ? make_metametaclass(RBASIC(metaclass)->klass)
            : RBASIC(RBASIC(metaclass)->klass)->klass;
    }

    FL_SET(metametaclass, FL_SINGLETON);
    rb_singleton_class_attached(metametaclass, metaclass);
    RBASIC(metaclass)->klass = metametaclass;

    super_of_metaclass = RCLASS_SUPER(metaclass);
    while (FL_TEST(super_of_metaclass, T_ICLASS)) {
        super_of_metaclass = RCLASS_SUPER(super_of_metaclass);
    }
    RCLASS_SUPER(metametaclass) =
        rb_iv_get(RBASIC(super_of_metaclass)->klass, "__attached__") == super_of_metaclass
        ? RBASIC(super_of_metaclass)->klass
        : make_metametaclass(super_of_metaclass);
    OBJ_INFECT(metametaclass, RCLASS_SUPER(metametaclass));

    return metametaclass;
}
Ejemplo n.º 15
0
static VALUE
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE))
{
    VALUE ary;
    int recur;
    st_table *list;

    if (argc == 0) {
	recur = TRUE;
    }
    else {
	VALUE r;
	rb_scan_args(argc, argv, "01", &r);
	recur = RTEST(r);
    }

    list = st_init_numtable();
    for (; mod; mod = RCLASS_SUPER(mod)) {
	st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
	if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
	if (FL_TEST(mod, FL_SINGLETON)) continue;
	if (!recur) break;
    }
    ary = rb_ary_new();
    st_foreach(list, func, ary);
    st_free_table(list);

    return ary;
}
Ejemplo n.º 16
0
static int
include_modules_at(const VALUE klass, VALUE c, VALUE module)
{
    VALUE p, iclass;
    int method_changed = 0, constant_changed = 0;
    const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));

    while (module) {
	int superclass_seen = FALSE;

	if (RCLASS_ORIGIN(module) != module)
	    goto skip;
	if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
	    return -1;
	/* ignore if the module included already in superclasses */
	for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
	    switch (BUILTIN_TYPE(p)) {
	      case T_ICLASS:
		if (RCLASS_M_TBL_WRAPPER(p) == RCLASS_M_TBL_WRAPPER(module)) {
		    if (!superclass_seen) {
			c = p;  /* move insertion point */
		    }
		    goto skip;
		}
		break;
	      case T_CLASS:
		superclass_seen = TRUE;
		break;
	    }
	}
	iclass = rb_include_class_new(module, RCLASS_SUPER(c));
	c = RCLASS_SET_SUPER(c, iclass);

	if (BUILTIN_TYPE(module) == T_ICLASS) {
	    rb_module_add_to_subclasses_list(RBASIC(module)->klass, iclass);
	} else {
	    rb_module_add_to_subclasses_list(module, iclass);
	}

	if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
	    VALUE refined_class =
		rb_refinement_module_get_refined_class(klass);

	    st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i,
		       (st_data_t) refined_class);
	    FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
	}
	if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
	    method_changed = 1;
	if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries)
	    constant_changed = 1;
      skip:
	module = RCLASS_SUPER(module);
    }

    if (method_changed) rb_clear_method_cache_by_class(klass);
    if (constant_changed) rb_clear_constant_cache();

    return method_changed;
}
Ejemplo n.º 17
0
void
rb_alias(VALUE klass, ID name, ID def)
{
    NODE *orig_fbody, *node, *method;
    VALUE singleton = 0;
    st_data_t data;

    rb_frozen_class_p(klass);
    if (klass == rb_cObject) {
	rb_secure(4);
    }
    orig_fbody = search_method(klass, def, 0);
    if (!orig_fbody || !orig_fbody->nd_body) {
	if (TYPE(klass) == T_MODULE) {
	    orig_fbody = search_method(rb_cObject, def, 0);
	}
    }
    if (!orig_fbody || !orig_fbody->nd_body) {
	rb_print_undef(klass, def, 0);
    }
    if (FL_TEST(klass, FL_SINGLETON)) {
	singleton = rb_iv_get(klass, "__attached__");
    }

    orig_fbody->nd_cnt++;

    if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
	node = (NODE *)data;
	if (node) {
	    if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) {
		rb_warning("discarding old %s", rb_id2name(name));
	    }
	    if (nd_type(node->nd_body->nd_body) == NODE_CFUNC) {
		rb_vm_check_redefinition_opt_method(node);
	    }
	}
    }

    st_insert(RCLASS_M_TBL(klass), name,
	      (st_data_t) NEW_FBODY(
		  method = NEW_METHOD(orig_fbody->nd_body->nd_body,
			     orig_fbody->nd_body->nd_clss,
			     NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def));
    method->nd_file = (void *)def;

    rb_clear_cache_by_id(name);

    if (!ruby_running) return;

    if (singleton) {
	rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
    }
    else {
	rb_funcall(klass, added, 1, ID2SYM(name));
    }
}
Ejemplo n.º 18
0
VALUE Looksee_singleton_instance(VALUE self, VALUE klass) {
  if (!SPECIAL_CONST_P(klass) && BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON)) {
    VALUE object;
    if (!Looksee_method_table_lookup(RCLASS_IV_TBL(klass), rb_intern("__attached__"), (st_data_t *)&object))
      rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object");
    return object;
  } else {
    return Qnil;
  }
}
Ejemplo n.º 19
0
Archivo: mri.c Proyecto: hkraji/looksee
VALUE Looksee_singleton_instance(VALUE self, VALUE singleton_class) {
  if (BUILTIN_TYPE(singleton_class) == T_CLASS && FL_TEST(singleton_class, FL_SINGLETON)) {
    VALUE object;
    if (!Looksee_method_table_lookup(RCLASS_IV_TBL(singleton_class), rb_intern("__attached__"), (st_data_t *)&object))
      rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object");
    return object;
  } else {
    rb_raise(rb_eTypeError, "expected singleton class, got %s", rb_obj_classname(singleton_class));
  }
}
Ejemplo n.º 20
0
Archivo: class.c Proyecto: fi8on/ruby
/*!
 * Attach a object to a singleton class.
 * @pre \a klass is the singleton class of \a obj.
 */
void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
    if (FL_TEST(klass, FL_SINGLETON)) {
	if (!RCLASS_IV_TBL(klass)) {
	    RCLASS_IV_TBL(klass) = st_init_numtable();
	}
	st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
    }
}
Ejemplo n.º 21
0
void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
    if (FL_TEST(klass, FL_SINGLETON)) {
	if (!RCLASS(klass)->iv_tbl) {
	    RCLASS(klass)->iv_tbl = st_init_numtable();
	}
	st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
    }
}
Ejemplo n.º 22
0
VALUE
rb_profile_frame_singleton_method_p(VALUE frame)
{
    VALUE klass = rb_iseq_klass(frame2iseq(frame));
    if (klass && !NIL_P(klass) && FL_TEST(klass, FL_SINGLETON)) {
	return Qtrue;
    }
    else {
	return Qfalse;
    }
}
Ejemplo n.º 23
0
/* :nodoc: */
VALUE
rb_class_init_copy(VALUE clone, VALUE orig)
{
    if (RCLASS_SUPER(clone) != 0) {
	rb_raise(rb_eTypeError, "already initialized class");
    }
    if (FL_TEST(orig, FL_SINGLETON)) {
	rb_raise(rb_eTypeError, "can't copy singleton class");
    }
    return rb_mod_init_copy(clone, orig);
}
Ejemplo n.º 24
0
void
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
    if (FL_TEST(klass, FL_SINGLETON)) {
	ID attached;
	if (!RCLASS_IV_TBL(klass)) {
	    RCLASS_IV_TBL(klass) = st_init_numtable();
	}
	CONST_ID(attached, "__attached__");
	st_insert(RCLASS_IV_TBL(klass), attached, obj);
    }
}
Ejemplo n.º 25
0
VALUE
rb_class_new(VALUE super)
{
    Check_Type(super, T_CLASS);
    if (super == rb_cClass) {
	rb_raise(rb_eTypeError, "can't make subclass of Class");
    }
    if (FL_TEST(super, FL_SINGLETON)) {
	rb_raise(rb_eTypeError, "can't make subclass of virtual class");
    }
    return rb_class_boot(super);
}
Ejemplo n.º 26
0
/*!
 * Returns the singleton class of \a obj, or nil if obj is not a
 * singleton object.
 *
 * \param obj an arbitrary object.
 * \return the singleton class or nil.
 */
VALUE
rb_singleton_class_get(VALUE obj)
{
    VALUE klass;

    if (SPECIAL_CONST_P(obj)) {
	return rb_special_singleton_class(obj);
    }
    klass = RBASIC(obj)->klass;
    if (!FL_TEST(klass, FL_SINGLETON)) return Qnil;
    if (rb_ivar_get(klass, id_attached) != obj) return Qnil;
    return klass;
}
Ejemplo n.º 27
0
static void
class_init_copy_check(VALUE clone, VALUE orig)
{
    if (orig == rb_cBasicObject) {
	rb_raise(rb_eTypeError, "can't copy the root class");
    }
    if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
	rb_raise(rb_eTypeError, "already initialized class");
    }
    if (FL_TEST(orig, FL_SINGLETON)) {
	rb_raise(rb_eTypeError, "can't copy singleton class");
    }
}
Ejemplo n.º 28
0
static void
test_garbage_collect(void)
{
    void* p;

    p = mini_gc_malloc(100);
#if 0
    assert(FL_TEST((((Header*)p) - 1), FL_ALLOC));
#endif

    p = 0;
    garbage_collect();
}
Ejemplo n.º 29
0
/*
 * call-seq:
 *   module.dump(limit) => String
 *
 * Dump a module to a string.  The module will be dumped along with its
 * instance methods, class variables, names of included modules, name of
 * superclass, its entire metaclass, and the name of the class.
 *
 * Note that on ruby 1.8 and newer the module is temporarily modified
 * while dumping in order to allow singleton classes to be dumped.  To
 * prevent access to the modifed module, Thread.critical is temporarily
 * set, then restored to its original value once dumping is complete.
 * Note also that because YARV does not support Thread.critical, the
 * user must synchronize access to the class with a Mutex in order to
 * prevent accessing the modified class.
 */
static VALUE module_dump(VALUE self, VALUE limit)
{
  VALUE flags, instance_methods, class_variables;
  VALUE included_modules, superclass, metaclass, arr, str, class_name;

  limit = INT2NUM(NUM2INT(limit) - 1);

  if(rb_safe_level() >= 4)
  {
    /* no access to potentially sensitive data from the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't dump module");
  }

  flags = INT2NUM(RBASIC(self)->flags);
  instance_methods = instance_method_hash(self);
  class_variables = class_variable_hash(self);
  included_modules = included_modules_list(self);
  superclass = superclass_name(self);
  arr = rb_ary_new();

  if(FL_TEST(self, FL_SINGLETON))
  {
    metaclass = Qnil;
    class_name = Qnil;
  }
  else
  {
    metaclass = rb_singleton_class(self);
    class_name = rb_class_path(self);
  }

  rb_ary_push(arr, flags);
  rb_ary_push(arr, marshal_dump(instance_methods, limit));
  rb_ary_push(arr, marshal_dump(class_variables, limit));
  rb_ary_push(arr, included_modules);
  rb_ary_push(arr, superclass);
  rb_ary_push(arr, marshal_dump(metaclass, limit));
  rb_ary_push(arr, class_name);

  str = marshal_dump(arr, limit);

#if RUBY_VERSION_CODE > 180
  {
    VALUE class_restorer = create_class_restorer(self);
    rb_iv_set(str, "__class_restorer__", class_restorer);
    set_class_restore_state(self);
  }
#endif

  return str;
}
Ejemplo n.º 30
0
int
rb_obj_respond_to(VALUE obj, ID id, int priv)
{
    VALUE klass = CLASS_OF(obj);

    if (rb_method_basic_definition_p(klass, idRespond_to)) {
	return basic_obj_respond_to(obj, id, !priv);
    }
    else {
	int argc = 1;
	VALUE args[2];
	args[0] = ID2SYM(id);
	args[1] = Qtrue;
	if (priv) {
	    if (rb_obj_method_arity(obj, idRespond_to) != 1) {
		argc = 2;
	    }
	    else if (!NIL_P(ruby_verbose)) {
		VALUE klass = CLASS_OF(obj);
		VALUE location = rb_mod_method_location(klass, idRespond_to);
		rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") is"
			" old fashion which takes only one parameter",
			(FL_TEST(klass, FL_SINGLETON) ? obj : klass),
			(FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
			QUOTE_ID(id));
		if (!NIL_P(location)) {
		    VALUE path = RARRAY_AREF(location, 0);
		    VALUE line = RARRAY_AREF(location, 1);
		    if (!NIL_P(path)) {
			rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
					"respond_to? is defined here");
		    }
		}
	    }
	}
	return RTEST(rb_funcall2(obj, idRespond_to, argc,  args));
    }
}