Example #1
0
File: class.c Project: 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;
}
Example #2
0
/*
 * Returns system temporary directory; typically "/tmp".
 */
static VALUE
etc_systmpdir(void)
{
    VALUE tmpdir;
#ifdef _WIN32
    WCHAR path[_MAX_PATH];
    UINT len = rb_w32_system_tmpdir(path, numberof(path));
    if (!len) return Qnil;
    tmpdir = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
#else
    const char default_tmp[] = "/tmp";
    const char *tmpstr = default_tmp;
    size_t tmplen = strlen(default_tmp);
# if defined _CS_DARWIN_USER_TEMP_DIR
    #ifndef MAXPATHLEN
    #define MAXPATHLEN 1024
    #endif
    char path[MAXPATHLEN];
    size_t len;
    len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
    if (len > 0) {
	tmpstr = path;
	tmplen = len - 1;
    }
# endif
    tmpdir = rb_filesystem_str_new(tmpstr, tmplen);
#endif
    FL_UNSET(tmpdir, FL_TAINT);
    return tmpdir;
}
Example #3
0
/* call-seq:
 *   unfreeze -> self
 * 
 * Unfreezes the given object.  Will raise a +SecurityError+ if
 * <tt>$SAFE</tt> > 0.  Has no effect if the object is not yet frozen. */
static VALUE evilr_unfreeze(VALUE self) {
  if (rb_safe_level() > 0) {
    rb_raise(rb_eSecurityError, "can't unfreeze objects when $SAFE > 0");
  }
  FL_UNSET(self, FL_FREEZE);
  return self;
}
Example #4
0
static int
load_encoding(const char *name)
{
    VALUE enclib = rb_sprintf("enc/%s.so", name);
    VALUE verbose = ruby_verbose;
    VALUE debug = ruby_debug;
    VALUE errinfo;
    VALUE loaded;
    char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3;
    int idx;

    while (s < e) {
	if (!ISALNUM(*s)) *s = '_';
	else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
	++s;
    }
    FL_UNSET(enclib, FL_TAINT|FL_UNTRUSTED);
    OBJ_FREEZE(enclib);
    ruby_verbose = Qfalse;
    ruby_debug = Qfalse;
    errinfo = rb_errinfo();
    loaded = rb_protect(require_enc, enclib, 0);
    ruby_verbose = verbose;
    ruby_debug = debug;
    rb_set_errinfo(errinfo);
    if (NIL_P(loaded)) return -1;
    if ((idx = rb_enc_registered(name)) < 0) return -1;
    if (enc_autoload_p(enc_table.list[idx].enc)) return -1;
    return idx;
}
Example #5
0
static int
load_encoding(const char *name)
{
    VALUE enclib = rb_sprintf("enc/%s.so", name);
    VALUE verbose = ruby_verbose;
    VALUE debug = ruby_debug;
    VALUE errinfo;
    char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3;
    int loaded;
    int idx;

    while (s < e) {
	if (!ISALNUM(*s)) *s = '_';
	else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
	++s;
    }
    FL_UNSET(enclib, FL_TAINT);
    enclib = rb_fstring(enclib);
    ruby_verbose = Qfalse;
    ruby_debug = Qfalse;
    errinfo = rb_errinfo();
    loaded = rb_require_internal(enclib, rb_safe_level());
    ruby_verbose = verbose;
    ruby_debug = debug;
    rb_set_errinfo(errinfo);
    if (loaded < 0 || 1 < loaded) return -1;
    if ((idx = rb_enc_registered(name)) < 0) return -1;
    if (enc_autoload_p(enc_table.list[idx].enc)) return -1;
    return idx;
}
Example #6
0
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;
}
Example #7
0
/* call-seq:
 *   detach_singleton -> self
 *
 * If the receiver is a singleton class, it is transformed into a
 * regular class and it is detached from the instance.  Note that
 * this means it becomes the class of the object to which it was previous
 * attached.  If the receiver is not a singleton class, has no effect.
 * Returns the receiver. */
static VALUE evilr_detach_singleton(VALUE klass) {
  if (IS_SINGLETON_CLASS(klass)) {
    FL_UNSET(klass, FL_SINGLETON);
    if (RCLASS_IV_TBL(klass)) {
      st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&evilr__attached, 0);
    }
  }
  return klass;
}
Example #8
0
/* call-seq:
 *   to_class(klass=Object) -> Class
 * 
 * Makes a copy of the module, converts the copy to a class, and returns it. The
 * returned class can then have instances created from it. The +klass+ argument
 * sets the superclass of the returned class.  If +klass+ is not a Class,
 * raises +TypeError+. */
static VALUE evilr_to_class(int argc, VALUE *argv, VALUE self) {
  VALUE klass = evilr__optional_class(argc, argv);

  self = rb_obj_clone(self);
  RBASIC_SET_KLASS(self, rb_singleton_class(klass));
  RCLASS_SET_SUPER(self, klass);
  FL_UNSET(self, T_MASK);
  FL_SET(self, T_CLASS);
  return self;
}
Example #9
0
File: class.c Project: fi8on/ruby
/*!
 * \internal
 * Returns the singleton class of \a obj. Creates it if necessary.
 *
 * \note DO NOT expose the returned singleton class to
 *       outside of class.c.
 *       Use \ref rb_singleton_class instead for
 *       consistency of the metaclass hierarchy.
 */
static VALUE
singleton_class_of(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 %p", (void *)obj);
    }

    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
	rb_ivar_get(RBASIC(obj)->klass, id_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_UNTRUSTED(obj)) {
	OBJ_UNTRUST(klass);
    }
    else {
	FL_UNSET(klass, FL_UNTRUSTED);
    }
    if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);

    return klass;
}
Example #10
0
/* call-seq:
 *   dup_singleton_class(klass=Object) -> Class || nil
 * 
 * If the receiver has a singleton class, a copy of the class is returned,
 * and the superclass of that class is set to the given +klass+.  Any
 * modules that extend the object become modules included in the returned class.
 * If the receiver does not have a singleton class, +nil+ is returned and no
 * changes are made.  If the receiver is an immediate, a +TypeError+ is raised. */
static VALUE evilr_dup_singleton_class(int argc, VALUE *argv, VALUE self) {
  VALUE klass;
  evilr__check_immediate(self);
 
  if (!HAS_SINGLETON_CLASS(self)) {
    return Qnil;
  }
  klass = evilr__optional_class(argc, argv);
  self = rb_singleton_class_clone(self);
  evilr__reparent_class(self, klass);
  FL_UNSET(self, FL_SINGLETON);
  return self;
}
Example #11
0
static VALUE
undefine_final(VALUE os, SEL sel, VALUE obj)
{
    if (__os_finalizers != NULL)
	CFDictionaryRemoveValue(__os_finalizers, (const void *)obj);
    
    if (NATIVE(obj)) {
	rb_objc_flag_set((void *)obj, FL_FINALIZE, false);
    }
    else {
	FL_UNSET(obj, FL_FINALIZE);
    }
    return obj;
}
Example #12
0
File: etc.c Project: Shopify/ruby
/*
 * Returns system temporary directory; typically "/tmp".
 */
static VALUE
etc_systmpdir(void)
{
    VALUE tmpdir;
#ifdef _WIN32
    WCHAR path[_MAX_PATH];
    UINT len = rb_w32_system_tmpdir(path, numberof(path));
    if (!len) return Qnil;
    tmpdir = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
#else
    tmpdir = rb_filesystem_str_new_cstr("/tmp");
#endif
    FL_UNSET(tmpdir, FL_TAINT);
    return tmpdir;
}
Example #13
0
/*!
 * \internal
 * Returns the singleton class of \a obj. Creates it if necessary.
 *
 * \note DO NOT expose the returned singleton class to
 *       outside of class.c.
 *       Use \ref rb_singleton_class instead for
 *       consistency of the metaclass hierarchy.
 */
static VALUE
singleton_class_of(VALUE obj)
{
    VALUE klass;

    if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) {
	rb_raise(rb_eTypeError, "can't define singleton");
    }
    if (SPECIAL_CONST_P(obj)) {
	klass = special_singleton_class_of(obj);
	if (NIL_P(klass))
	    rb_bug("unknown immediate %p", (void *)obj);
	return klass;
    }
    else {
	enum ruby_value_type type = BUILTIN_TYPE(obj);
	if (type == T_FLOAT || type == T_BIGNUM) {
	    rb_raise(rb_eTypeError, "can't define singleton");
	}
    }

    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
	rb_ivar_get(RBASIC(obj)->klass, id_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);

    return klass;
}
Example #14
0
/* call-seq:
 *   to_module -> Module
 * 
 * Makes a copy of the class, converts the copy to a module, and returns it. The
 * returned module can be included in other classes. */
static VALUE evilr_to_module(VALUE klass) {
  VALUE mod, iclass;

  if (IS_SINGLETON_CLASS(klass)) {
    if((mod = evilr_singleton_class_instance(klass))) {
      mod = rb_singleton_class_clone(mod);
      (void)evilr_detach_singleton(mod);
    } else {
      rb_raise(rb_eTypeError, "singleton class without attached instance");
    }
  } else {
    mod = rb_obj_clone(klass);
  }

  RBASIC_SET_KLASS(mod, rb_cModule);
  iclass = RCLASS_SUPER(mod);
  RCLASS_SET_SUPER(mod, NULL);
  FL_UNSET(mod, T_MASK);
  FL_SET(mod, T_MODULE);
  evilr__include_iclasses(mod, iclass);

  return mod;
}
Example #15
0
VALUE rb_object_free(VALUE obj)
{
  ID id_destructor = rb_intern("__destruct__");

  /* value returned by destructor */
  VALUE destruct_value = Qnil;
  
  /* prevent freeing of immediates */
  switch (TYPE(obj)) {
  case T_NIL:
  case T_FIXNUM:
  case T_TRUE:
  case T_FALSE:
  case T_SYMBOL:
    rb_raise(rb_eTypeError, "obj_free() called for immediate value");
    break;
  }

  /* prevent freeing of *some* critical objects */
  if ((obj == rb_cObject) ||
      (obj == rb_cClass) ||
      (obj == rb_cModule) ||
      (obj == rb_cSymbol) ||
      (obj == rb_cFixnum) ||
      (obj == rb_cFloat) ||
      (obj == rb_cString) ||
      (obj == rb_cRegexp) ||
      (obj == rb_cInteger) ||
      (obj == rb_cArray) ||
      (obj == rb_cNilClass) ||
      (obj == rb_cFalseClass) ||
      (obj == rb_cTrueClass) ||
      (obj == rb_cNumeric) ||
      (obj == rb_cBignum) ||
      (obj == rb_cStruct)) 
    rb_raise(rb_eTypeError, "obj_free() called for critical object");
   
  /* run destructor (if one is defined) */
  if (rb_respond_to(obj, id_destructor))
    destruct_value = rb_funcall(obj, id_destructor, 0);

#ifdef RUBY_19
      switch (BUILTIN_TYPE(obj)) {
      case T_NIL:
      case T_FIXNUM:
      case T_TRUE:
      case T_FALSE:
        rb_bug("obj_free() called for broken object");
        break;
      }

  if (FL_TEST(obj, FL_EXIVAR)) {
    rb_free_generic_ivar((VALUE)obj);
    FL_UNSET(obj, FL_EXIVAR);
  }

  switch (BUILTIN_TYPE(obj)) {
  case T_OBJECT:
    if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
        RANY(obj)->as.object.as.heap.ivptr) {
      xfree(RANY(obj)->as.object.as.heap.ivptr);
    }
    break;
  case T_MODULE:
  case T_CLASS:
    rb_clear_cache_by_class((VALUE)obj);
    rb_free_m_table(RCLASS_M_TBL(obj));
    if (RCLASS_IV_TBL(obj)) {
      st_free_table(RCLASS_IV_TBL(obj));
    }
    if (RCLASS_IV_INDEX_TBL(obj)) {
      st_free_table(RCLASS_IV_INDEX_TBL(obj));
    }
    xfree(RANY(obj)->as.klass.ptr);
    break;
  case T_STRING:
    rb_str_free(obj);
    break;
  case T_ARRAY:
    rb_ary_free(obj);
    break;
  case T_HASH:
    if (RANY(obj)->as.hash.ntbl) {
      st_free_table(RANY(obj)->as.hash.ntbl);
    }
    break;
  case T_REGEXP:
    if (RANY(obj)->as.regexp.ptr) {
      onig_free(RANY(obj)->as.regexp.ptr);
    }
    break;
  case T_DATA:
    if (DATA_PTR(obj)) {
      if (RTYPEDDATA_P(obj)) {
        RDATA(obj)->dfree = RANY(obj)->as.typeddata.type->dfree;
      }
      if ((long)RANY(obj)->as.data.dfree == -1) {
        xfree(DATA_PTR(obj));
      }
      else if (RANY(obj)->as.data.dfree) {
        make_deferred(RANY(obj));
        return 1;
      }
    }
    break;
  case T_MATCH:
    if (RANY(obj)->as.match.rmatch) {
      struct rmatch *rm = RANY(obj)->as.match.rmatch;
      onig_region_free(&rm->regs, 0);
      if (rm->char_offset)
        xfree(rm->char_offset);
      xfree(rm);
    }
    break;
  case T_FILE:
    if (RANY(obj)->as.file.fptr) {
      make_io_deferred(RANY(obj));
      return 1;
    }
    break;
  case T_RATIONAL:
  case T_COMPLEX:
    break;
  case T_ICLASS:
    /* iClass shares table with the module */
    xfree(RANY(obj)->as.klass.ptr);
    break;

  case T_FLOAT:
    break;

  case T_BIGNUM:
    if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
      xfree(RBIGNUM_DIGITS(obj));
    }
    break;
  case T_NODE:
    switch (nd_type(obj)) {
    case NODE_SCOPE:
      if (RANY(obj)->as.node.u1.tbl) {
        xfree(RANY(obj)->as.node.u1.tbl);
      }
      break;
    case NODE_ALLOCA:
      xfree(RANY(obj)->as.node.u1.node);
      break;
    }
    break;			/* no need to free iv_tbl */

  case T_STRUCT:
    if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
        RANY(obj)->as.rstruct.as.heap.ptr) {
      xfree(RANY(obj)->as.rstruct.as.heap.ptr);
    }
    break;

  default:
    rb_bug("gc_sweep(): unknown data type 0x%x(%p)",
           BUILTIN_TYPE(obj), (void*)obj);
  }

#else
  switch (BUILTIN_TYPE(obj)) {
  case T_NIL:
  case T_FIXNUM:
  case T_TRUE:
  case T_FALSE:
    rb_bug("obj_free() called for broken object");
    break;
  }

  if (FL_TEST(obj, FL_EXIVAR)) {
    rb_free_generic_ivar((VALUE)obj);
  }

  switch (BUILTIN_TYPE(obj)) {
  case T_OBJECT:
    if (RANY(obj)->as.object.iv_tbl) {
      st_free_table(RANY(obj)->as.object.iv_tbl);
    }
    break;
  case T_MODULE:
  case T_CLASS:
    rb_clear_cache_by_class((VALUE)obj);
    st_free_table(RANY(obj)->as.klass.m_tbl);
    if (RANY(obj)->as.object.iv_tbl) {
      st_free_table(RANY(obj)->as.object.iv_tbl);
    }
    break;
  case T_STRING:
    if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) {
      RUBY_CRITICAL(free(RANY(obj)->as.string.ptr));
    }
    break;
  case T_ARRAY:
    if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) {
      RUBY_CRITICAL(free(RANY(obj)->as.array.ptr));
    }
    break;
  case T_HASH:
    if (RANY(obj)->as.hash.tbl) {
      st_free_table(RANY(obj)->as.hash.tbl);
    }
    break;
  case T_REGEXP:
    if (RANY(obj)->as.regexp.ptr) {
      re_free_pattern(RANY(obj)->as.regexp.ptr);
    }
    if (RANY(obj)->as.regexp.str) {
      RUBY_CRITICAL(free(RANY(obj)->as.regexp.str));
    }
    break;
  case T_DATA:
    if (DATA_PTR(obj)) {
      if ((long)RANY(obj)->as.data.dfree == -1) {
        RUBY_CRITICAL(free(DATA_PTR(obj)));
      }
      else if (RANY(obj)->as.data.dfree) {
        make_deferred(RANY(obj));
        return 1;
      }
    }
    break;
  case T_MATCH:
    if (RANY(obj)->as.match.regs) {
      re_free_registers(RANY(obj)->as.match.regs);
      RUBY_CRITICAL(free(RANY(obj)->as.match.regs));
    }
    break;
  case T_FILE:
    if (RANY(obj)->as.file.fptr) {
      struct rb_io_t *fptr = RANY(obj)->as.file.fptr;
      make_deferred(RANY(obj));
      RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;
      RDATA(obj)->data = fptr;
      return 1;
    }
    break;
  case T_ICLASS:
    /* iClass shares table with the module */
    break;

  case T_FLOAT:
  case T_VARMAP:
  case T_BLKTAG:
    break;

  case T_BIGNUM:
    if (RANY(obj)->as.bignum.digits) {
      RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits));
    }
    break;
  case T_NODE:
    switch (nd_type(obj)) {
    case NODE_SCOPE:
      if (RANY(obj)->as.node.u1.tbl) {
        RUBY_CRITICAL(free(RANY(obj)->as.node.u1.tbl));
      }
      break;
    case NODE_ALLOCA:
      RUBY_CRITICAL(free(RANY(obj)->as.node.u1.node));
      break;
    }
    break;			/* no need to free iv_tbl */

  case T_SCOPE:
    if (RANY(obj)->as.scope.local_vars &&
        RANY(obj)->as.scope.flags != SCOPE_ALLOCA) {
      VALUE *vars = RANY(obj)->as.scope.local_vars-1;
      if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0)
        RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl));
      if ((RANY(obj)->as.scope.flags & (SCOPE_MALLOC|SCOPE_CLONE)) == SCOPE_MALLOC)
        RUBY_CRITICAL(free(vars));
    }
    break;

  case T_STRUCT:
    if (RANY(obj)->as.rstruct.ptr) {
      RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr));
    }
    break;

  default:
    rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)",
           RANY(obj)->as.basic.flags & T_MASK, obj);
  }
#endif  

  rb_gc_force_recycle(obj);

  return destruct_value;
}