コード例 #1
0
ファイル: rp_method.c プロジェクト: Angeldude/sonic-pi
void
method_key(prof_method_key_t* key, VALUE klass, ID mid)
{
    /* Is this an include for a module?  If so get the actual
        module class since we want to combine all profiling
        results for that module. */
    if (klass != 0)
        klass = (BUILTIN_TYPE(klass) == T_ICLASS ? RBASIC(klass)->klass : klass);

    key->klass = klass;
    key->mid = mid;
    key->key = (klass << 4) + (mid << 2);
}
コード例 #2
0
ファイル: class.c プロジェクト: Benabik/ruby-concurrent-gc
VALUE
rb_mod_included_modules(VALUE mod)
{
    VALUE ary = rb_ary_new();
    VALUE p;

    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
	if (BUILTIN_TYPE(p) == T_ICLASS) {
	    rb_ary_push(ary, RBASIC(p)->klass);
	}
    }
    return ary;
}
コード例 #3
0
ファイル: class.c プロジェクト: Benabik/ruby-concurrent-gc
VALUE
rb_mod_include_p(VALUE mod, VALUE mod2)
{
    VALUE p;

    Check_Type(mod2, T_MODULE);
    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
	if (BUILTIN_TYPE(p) == T_ICLASS) {
	    if (RBASIC(p)->klass == mod2) return Qtrue;
	}
    }
    return Qfalse;
}
コード例 #4
0
ファイル: objspace.c プロジェクト: DashYang/sim
static int
cos_i(void *vstart, void *vend, size_t stride, void *data)
{
    size_t *counts = (size_t *)data;
    VALUE v = (VALUE)vstart;

    for (;v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags) {
	    counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
	}
    }
    return 0;
}
コード例 #5
0
ファイル: range.c プロジェクト: DashYang/sim
static int
linear_object_p(VALUE obj)
{
    if (FIXNUM_P(obj) || FLONUM_P(obj)) return TRUE;
    if (SPECIAL_CONST_P(obj)) return FALSE;
    switch (BUILTIN_TYPE(obj)) {
      case T_FLOAT:
      case T_BIGNUM:
	return TRUE;
    }
    if (rb_obj_is_kind_of(obj, rb_cNumeric)) return TRUE;
    if (rb_obj_is_kind_of(obj, rb_cTime)) return TRUE;
    return FALSE;
}
コード例 #6
0
ファイル: compar.c プロジェクト: DashYang/sim
void
rb_cmperr(VALUE x, VALUE y)
{
    VALUE classname;

    if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) {
	classname = rb_inspect(y);
    }
    else {
	classname = rb_obj_class(y);
    }
    rb_raise(rb_eArgError, "comparison of %"PRIsVALUE" with %"PRIsVALUE" failed",
	     rb_obj_class(x), classname);
}
コード例 #7
0
ファイル: class.c プロジェクト: takuto-h/ruby
static int
include_modules_at(const VALUE klass, VALUE c, VALUE module)
{
    VALUE p;
    int 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(p) == RCLASS_M_TBL(module)) {
		    if (!superclass_seen) {
			c = p;  /* move insertion point */
		    }
		    goto skip;
		}
		break;
	      case T_CLASS:
		superclass_seen = TRUE;
		break;
	    }
	}
	c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
	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)
	    changed = 1;
	if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries)
	    changed = 1;
      skip:
	module = RCLASS_SUPER(module);
    }

    return changed;
}
コード例 #8
0
ファイル: encoding.c プロジェクト: 217/ruby
static inline int
enc_capable(VALUE obj)
{
    if (SPECIAL_CONST_P(obj)) return SYMBOL_P(obj);
    switch (BUILTIN_TYPE(obj)) {
      case T_STRING:
      case T_REGEXP:
      case T_FILE:
	return TRUE;
      case T_DATA:
	if (is_data_encoding(obj)) return TRUE;
      default:
	return FALSE;
    }
}
コード例 #9
0
ファイル: compar.c プロジェクト: brightbox/deb-ruby2.0
void
rb_cmperr(VALUE x, VALUE y)
{
    const char *classname;

    if (SPECIAL_CONST_P(y) || BUILTIN_TYPE(y) == T_FLOAT) {
	y = rb_inspect(y);
	classname = StringValuePtr(y);
    }
    else {
	classname = rb_obj_classname(y);
    }
    rb_raise(rb_eArgError, "comparison of %s with %s failed",
	     rb_obj_classname(x), classname);
}
コード例 #10
0
ファイル: objspace.c プロジェクト: GunioRobot/ruby
static int
cn_i(void *vstart, void *vend, size_t stride, void *n)
{
    size_t *nodes = (size_t *)n;
    VALUE v = (VALUE)vstart;

    for (; v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
	    size_t s = nd_type((NODE *)v);
	    nodes[s]++;
	}
    }

    return 0;
}
コード例 #11
0
ファイル: class.c プロジェクト: Danylyuk/first_app
VALUE
rb_mod_ancestors(VALUE mod)
{
    VALUE p, ary = rb_ary_new();

    for (p = mod; p; p = RCLASS_SUPER(p)) {
	if (BUILTIN_TYPE(p) == T_ICLASS) {
	    rb_ary_push(ary, RBASIC(p)->klass);
	}
	else if (p == RCLASS_ORIGIN(p)) {
	    rb_ary_push(ary, p);
	}
    }
    return ary;
}
コード例 #12
0
ファイル: class.c プロジェクト: Danylyuk/first_app
VALUE
rb_mod_included_modules(VALUE mod)
{
    VALUE ary = rb_ary_new();
    VALUE p;
    VALUE origin = RCLASS_ORIGIN(mod);

    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
	if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
	    VALUE m = RBASIC(p)->klass;
	    if (RB_TYPE_P(m, T_MODULE))
		rb_ary_push(ary, m);
	}
    }
    return ary;
}
コード例 #13
0
ファイル: encode_decode.c プロジェクト: 6116353/protobuf
static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
  if (str == Qnil) return;

  assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
  upb_sink subsink;

  // Ensure that the string has the correct encoding. We also check at field-set
  // time, but the user may have mutated the string object since then.
  native_slot_validate_string_encoding(upb_fielddef_type(f), str);

  upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
                    &subsink);
  upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
                     RSTRING_LEN(str), NULL);
  upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
}
コード例 #14
0
ファイル: class.c プロジェクト: technohippy/oruby
VALUE
rb_mod_ancestors(VALUE mod)
{
    VALUE p, ary = rb_ary_new();

    for (p = mod; p; p = RCLASS_SUPER(p)) {
	if (FL_TEST(p, FL_SINGLETON))
	    continue;
	if (BUILTIN_TYPE(p) == T_ICLASS) {
	    rb_ary_push(ary, RBASIC(p)->klass);
	}
	else {
	    rb_ary_push(ary, p);
	}
    }
    return ary;
}
コード例 #15
0
ファイル: class.c プロジェクト: fi8on/ruby
void
rb_include_module(VALUE klass, VALUE module)
{
    VALUE p, c;
    int changed = 0;

    rb_frozen_class_p(klass);
    if (!OBJ_UNTRUSTED(klass)) {
	rb_secure(4);
    }

    if (TYPE(module) != T_MODULE) {
	Check_Type(module, T_MODULE);
    }

    OBJ_INFECT(klass, module);
    c = klass;
    while (module) {
	int superclass_seen = FALSE;

	if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
	    rb_raise(rb_eArgError, "cyclic include detected");
	/* 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(p) == RCLASS_M_TBL(module)) {
		    if (!superclass_seen) {
			c = p;  /* move insertion point */
		    }
		    goto skip;
		}
		break;
	      case T_CLASS:
		superclass_seen = TRUE;
		break;
	    }
	}
	c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
	if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
	    changed = 1;
      skip:
	module = RCLASS_SUPER(module);
    }
    if (changed) rb_clear_cache();
}
コード例 #16
0
ファイル: module.c プロジェクト: shmulim/ruby-internal
/* 
 * call-seq:
 *   remove_features(mod) => mod
 *
 * When this module is unincluded from another, Ruby Internal calls
 * remove_features in this module.  The default behavior is to remove
 * the constants, methods, and module variables of this module from
 * _mod_.  If this module has not been included by _mod_, an exception
 * will be raised.
 */
static VALUE module_remove_features(VALUE module, VALUE uninclude)
{
  VALUE prev, mod;

  if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE)
  {
    Check_Type(uninclude, T_CLASS);
  }

  rb_frozen_class_p(uninclude);
  if(!OBJ_TAINTED(uninclude))
  {
    rb_secure(4);
  }

  OBJ_INFECT(uninclude, module);

  if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl)
  {
    rb_raise(rb_eArgError, "Cannot remove module from itself");
  }

  prev = uninclude;
  mod = RCLASS_SUPER(uninclude);

  while(mod)
  {
    if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl)
    {
      RCLASS_SUPER(prev) = RCLASS_SUPER(mod);
      rb_clear_cache();
      return module;
    }

    if(BUILTIN_TYPE(mod) == T_CLASS)
    {
      break;
    }

    prev = mod;
    mod = RCLASS_SUPER(mod);
  }

  rb_raise(rb_eArgError, "Could not find included module");
  return module;
}
コード例 #17
0
ファイル: object2module.c プロジェクト: RavensKrag/texplay
/* a modified version of include_class_new from class.c */
static VALUE
j_class_new(VALUE module, VALUE sup)
{

#ifdef RUBY_19
    VALUE klass = class_alloc(T_ICLASS, rb_cClass);
#else
    NEWOBJ(klass, struct RClass);
    OBJSETUP(klass, rb_cClass, T_ICLASS);
#endif

    if (BUILTIN_TYPE(module) == T_ICLASS) {
        module = KLASS_OF(module);
    }

    if (!RCLASS_IV_TBL(module)) {

        RCLASS_IV_TBL(module) = (struct st_table *)st_init_numtable();
    }

    /* assign iv_tbl, m_tbl and super */
    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
    RCLASS_SUPER(klass) = sup;
    if(TYPE(module) != T_OBJECT) {

        RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
    }
    else {
        RCLASS_M_TBL(klass) = RCLASS_M_TBL(CLASS_OF(module));
    }

    /* */

    if (TYPE(module) == T_ICLASS) {
        KLASS_OF(klass) = KLASS_OF(module);
    }
    else {
        KLASS_OF(klass) = module;
    }

    if(TYPE(module) != T_OBJECT) {
        OBJ_INFECT(klass, module);
        OBJ_INFECT(klass, sup);
    }
    return (VALUE)klass;
}
コード例 #18
0
static inline VALUE
invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
		    VALUE self, int argc, const VALUE *argv,
		    const rb_block_t *blockptr, const NODE *cref)
{
    if (SPECIAL_CONST_P(block->iseq))
	return Qnil;
    else if (BUILTIN_TYPE(block->iseq) != T_NODE) {
	const rb_iseq_t *iseq = block->iseq;
	const rb_control_frame_t *cfp;
	rb_control_frame_t *ncfp;
	int i, opt_pc, arg_size = iseq->arg_size;
	int type = block_proc_is_lambda(block->proc) ?
	  VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;

	rb_vm_set_finish_env(th);

	cfp = th->cfp;
	CHECK_STACK_OVERFLOW(cfp, argc + iseq->stack_max);

	for (i=0; i<argc; i++) {
	    cfp->sp[i] = argv[i];
	}

	opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr,
				     type == VM_FRAME_MAGIC_LAMBDA);

	ncfp = vm_push_frame(th, iseq, type,
			     self, GC_GUARDED_PTR(block->dfp),
			     iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
			     iseq->local_size - arg_size);
	ncfp->me = th->passed_me;
	th->passed_me = 0;
	th->passed_block = blockptr;

	if (cref) {
	    th->cfp->dfp[-1] = (VALUE)cref;
	}

	return vm_exec(th);
    }
    else {
	return vm_yield_with_cfunc(th, block, self, argc, argv, blockptr);
    }
}
コード例 #19
0
ファイル: class.c プロジェクト: asimoov/emscripted-ruby
void
rb_include_module(VALUE klass, VALUE module)
{
    VALUE p, c;
    int changed = 0;

    rb_frozen_class_p(klass);
    if (!OBJ_TAINTED(klass)) {
	rb_secure(4);
    }
    
    if (TYPE(module) != T_MODULE) {
	Check_Type(module, T_MODULE);
    }

    OBJ_INFECT(klass, module);
    c = klass;
    while (module) {
	int superclass_seen = Qfalse;

	if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
	    rb_raise(rb_eArgError, "cyclic include detected");
	/* ignore if the module included already in superclasses */
	for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
	    switch (BUILTIN_TYPE(p)) {
	      case T_ICLASS:
		if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
		    if (!superclass_seen) {
			c = p;	/* move insertion point */
		    }
		    goto skip;
		}
		break;
	      case T_CLASS:
		superclass_seen = Qtrue;
		break;
	    }
	}
	c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
	changed = 1;
      skip:
	module = RCLASS(module)->super;
    }
    if (changed) rb_clear_cache();
}
コード例 #20
0
ファイル: class.c プロジェクト: technohippy/oruby
VALUE
rb_singleton_class(VALUE obj)
{
    VALUE klass;
    ID attached;

    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);
    }

    CONST_ID(attached, "__attached__");
    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
	rb_ivar_get(RBASIC(obj)->klass, attached) == obj) {
	klass = RBASIC(obj)->klass;
    }
    else {
	klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
    }

    if (BUILTIN_TYPE(obj) == T_CLASS) {
	if (rb_iv_get(RBASIC(klass)->klass, "__attached__") != klass)
	    make_metametaclass(klass);
    }
    if (OBJ_TAINTED(obj)) {
	OBJ_TAINT(klass);
    }
    else {
	FL_UNSET(klass, FL_TAINT);
    }
    if (OBJ_UNTRUSTED(obj)) {
	OBJ_UNTRUST(klass);
    }
    else {
	FL_UNSET(klass, FL_UNTRUSTED);
    }
    if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);

    return klass;
}
コード例 #21
0
ファイル: evilr.c プロジェクト: jeremyevans/evilr
/* call-seq:
 *   swap(other) -> self
 * 
 * Swap the contents of the receiver with +other+:
 *
 *   a = []
 *   b = {}
 *   a.swap(b) # => {}
 *   a # => {}
 *   b # => []
 *
 * You cannot swap a Class or Module except with another
 * Class or Module, and you can only swap a Class with a Class and
 * a Module with a Module (no swapping a Class with Module), and you
 * cannot swap immediate values.  If an invalid swap attempt is
 * detected, a  +TypeError+ is raised.*/
static VALUE evilr_swap(VALUE self, VALUE other) {
  char tmp[OBJECT_SIZE];
  evilr__check_immediates(self, other);
  if ((BUILTIN_TYPE(self) == T_MODULE || BUILTIN_TYPE(self) == T_CLASS ||
       BUILTIN_TYPE(other) == T_MODULE || BUILTIN_TYPE(other) == T_CLASS) &&
       BUILTIN_TYPE(self) != BUILTIN_TYPE(other)) {
    rb_raise(rb_eTypeError, "incompatible types used");
  }
  memcpy(tmp, ROBJECT(self), OBJECT_SIZE);
  memcpy(ROBJECT(self), ROBJECT(other), OBJECT_SIZE);
  memcpy(ROBJECT(other), tmp, OBJECT_SIZE);
  return self;
}
コード例 #22
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;
}
コード例 #23
0
ファイル: evilr.c プロジェクト: jeremyevans/evilr
/* call-seq:
 *   evilr_debug_print -> nil
 *
 * Prints to stdout the receiver and all entries in the receiver's klass's super chain,
 * using the pointers of the current entry, it's klass, iv_tbl, m_tbl, and super entry,
 * as well as the entry's flags.  If Class or Module is given, uses their
 * super chain, not the super chain of their klass. If the receiver is an immediate value,
 * a +TypeError+ is raised. */
static VALUE evilr_debug_print(VALUE self) {
  if (self == NULL) {
    return Qnil;
  }
  evilr__check_immediate(self);
  switch(BUILTIN_TYPE(self)) {
    case T_CLASS:
    case T_ICLASS:
    case T_MODULE:
      printf("self %p klass %p flags 0x%lx iv_tbl %p m_tbl %p super %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)RCLASS_IV_TBL(self), (void *)RCLASS_M_TBL(self), (void *)RCLASS_SUPER(self));
      self = RCLASS_SUPER(self);
      break;
    default:
      printf("self %p klass %p flags 0x%lx iv_tbl/ptr %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)ROBJECT_IVPTR(self));
      self = RBASIC_KLASS(self);
      break;
  }
  return evilr_debug_print(self);
}
コード例 #24
0
ファイル: proc.c プロジェクト: RWB01/Code-Translator
static VALUE
proc_arity(VALUE self)
{
    rb_proc_t *proc;
    rb_iseq_t *iseq;
    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    if (iseq && BUILTIN_TYPE(iseq) != T_NODE) {
	if (iseq->arg_rest == 0 && iseq->arg_opts == 0) {
	    return INT2FIX(iseq->argc);
	}
	else {
	    return INT2FIX(-iseq->argc - 1);
	}
    }
    else {
	return INT2FIX(-1);
    }
}
コード例 #25
0
ファイル: error.c プロジェクト: technohippy/oruby
void *
rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
{
    const char *etype;
    static const char mesg[] = "wrong argument type %s (expected %s)";

    if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA) {
	Check_Type(obj, T_DATA);
    }
    if (!RTYPEDDATA_P(obj)) {
	etype = rb_obj_classname(obj);
	rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
    }
    else if (RTYPEDDATA_TYPE(obj) != data_type) {
	etype = RTYPEDDATA_TYPE(obj)->wrap_struct_name;
	rb_raise(rb_eTypeError, mesg, etype, data_type->wrap_struct_name);
    }
    return DATA_PTR(obj);
}
コード例 #26
0
ファイル: objspace.c プロジェクト: riddochc/ruby
static int
cs_i(void *vstart, void *vend, size_t stride, void *n)
{
    struct dynamic_symbol_counts *counts = (struct dynamic_symbol_counts *)n;
    VALUE v = (VALUE)vstart;

    for (; v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_SYMBOL) {
	    ID id = RSYMBOL(v)->id;
	    if ((id & ~ID_SCOPE_MASK) == 0) {
		counts->mortal++;
	    }
	    else {
		counts->immortal++;
	    }
	}
    }

    return 0;
}
コード例 #27
0
ファイル: class.c プロジェクト: Danylyuk/first_app
VALUE
rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
{
    VALUE klass = RBASIC(obj)->klass;

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

	if (BUILTIN_TYPE(obj) == T_CLASS) {
	    RBASIC_SET_CLASS(clone, clone);
	}
	else {
	    RBASIC_SET_CLASS(clone, rb_singleton_class_clone(klass));
	}

	RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass));
	RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
	if (RCLASS_IV_TBL(klass)) {
	    RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(klass));
	}
	if (RCLASS_CONST_TBL(klass)) {
	    struct clone_const_arg arg;
	    RCLASS_CONST_TBL(clone) = st_init_numtable();
	    arg.klass = clone;
	    arg.tbl = RCLASS_CONST_TBL(clone);
	    st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)&arg);
	}
	if (attach != Qundef) {
	    rb_singleton_class_attached(clone, attach);
	}
	RCLASS_M_TBL_INIT(clone);
	st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone);
	rb_singleton_class_attached(RBASIC(clone)->klass, clone);
	FL_SET(clone, FL_SINGLETON);

	return clone;
    }
}
コード例 #28
0
ファイル: objspace.c プロジェクト: GunioRobot/ruby
static int
cto_i(void *vstart, void *vend, size_t stride, void *data)
{
    VALUE hash = (VALUE)data;
    VALUE v = (VALUE)vstart;

    for (; v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
	    VALUE counter = rb_hash_aref(hash, RBASIC(v)->klass);
	    if (NIL_P(counter)) {
		counter = INT2FIX(1);
	    }
	    else {
		counter = INT2FIX(FIX2INT(counter) + 1);
	    }
	    rb_hash_aset(hash, RBASIC(v)->klass, counter);
	}
    }

    return 0;
}
コード例 #29
0
ファイル: class.c プロジェクト: technohippy/oruby
/*!
 * \internal
 * Creates a singleton class for an object.
 *
 * \note DO NOT USE the function in an extension libraries. Use rb_singleton_class.
 * \param obj    An object.
 * \param super  A class from which the singleton class derives.
 *        \note \a super is ignored if \a obj is a metaclass.
 * \return       The singleton class of the object.
 */
VALUE
rb_make_metaclass(VALUE obj, VALUE super)
{
    if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) { /* obj is a metaclass */
        return make_metametaclass(obj);
    }
    else {
	VALUE metasuper;
	VALUE klass = rb_class_boot(super);

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

	metasuper = RBASIC(rb_class_real(super))->klass;
	/* metaclass of a superclass may be NULL at boot time */
	if (metasuper) {
	    RBASIC(klass)->klass = metasuper;
	}
	return klass;
    }
}
コード例 #30
0
ファイル: encoding.c プロジェクト: 217/ruby
int
rb_enc_get_index(VALUE obj)
{
    int i = -1;
    VALUE tmp;

    if (SPECIAL_CONST_P(obj)) {
	if (!SYMBOL_P(obj)) return -1;
	obj = rb_id2str(SYM2ID(obj));
    }
    switch (BUILTIN_TYPE(obj)) {
      as_default:
      default:
      case T_STRING:
      case T_REGEXP:
	i = ENCODING_GET_INLINED(obj);
	if (i == ENCODING_INLINE_MAX) {
	    VALUE iv;

	    iv = rb_ivar_get(obj, rb_id_encoding());
	    i = NUM2INT(iv);
	}
	break;
      case T_FILE:
	tmp = rb_funcall(obj, rb_intern("internal_encoding"), 0, 0);
	if (NIL_P(tmp)) obj = rb_funcall(obj, rb_intern("external_encoding"), 0, 0);
	else obj = tmp;
	if (NIL_P(obj)) break;
      case T_DATA:
	if (is_data_encoding(obj)) {
	    i = enc_check_encoding(obj);
	}
	else {
	    goto as_default;
	}
	break;
    }
    return i;
}