Пример #1
0
mrb_value
mrb_f_kill(mrb_state *mrb, mrb_value klass)
{
  mrb_int pid;
  mrb_value *argv, sigo;
  int argc, sent, signo = 0;

  mrb_get_args(mrb, "oi*", &sigo, &pid, &argv, &argc);
  if (mrb_fixnum_p(sigo)) {
    signo = mrb_fixnum(sigo);
  } else {
    mrb_raisef(mrb, E_TYPE_ERROR, "bad signal type %s",
    	       mrb_obj_classname(mrb, sigo));
  }

  sent = 0;
  if (kill(pid, signo) == -1)
    mrb_sys_fail(mrb, "kill");
  sent++;

  while (argc-- > 0) {
    if (!mrb_fixnum_p(*argv)) {
      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected Fixnum)",
      	         mrb_obj_classname(mrb, *argv));
    }
    if (kill(mrb_fixnum(*argv), signo) == -1)
      mrb_sys_fail(mrb, "kill");
    sent++;
    argv++;
  }
  return mrb_fixnum_value(sent);
}
Пример #2
0
static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc)
{
    RString *str;
    mrb_value mesg = mrb_attr_get(exc, mrb->intern2("mesg", 4));
    mrb_value file = mrb_attr_get(exc, mrb->intern2("file", 4));
    mrb_value line = mrb_attr_get(exc, mrb->intern2("line", 4));
    RString *mesg_ptr = mesg.is_nil() ? nullptr : mesg.ptr<RString>();
    if (!file.is_nil() && !line.is_nil()) {
        assert(file.is_string());
        str = file.ptr<RString>()->dup();
        str->str_buf_cat(":",1);
        str->str_cat(mrb_obj_as_string(mrb,line));
        str->str_buf_cat(": ",2);
        if (mesg_ptr && mesg_ptr->len > 0) {
            str->str_cat(mesg_ptr);
            str->str_buf_cat(" (",2);
        }
        str->str_buf_cat(mrb_obj_classname(mrb, exc));
        if (mesg_ptr && mesg_ptr->len > 0) {
            str->str_buf_cat(")",1);
        }
    }
    else {
        str = RString::create(mrb,mrb_obj_classname(mrb, exc));
        str->str_buf_cat(": ",2);
        if (mesg_ptr && mesg_ptr->len > 0) {
            str->str_cat(mesg_ptr);
        } else {
            str->str_buf_cat(mrb_obj_classname(mrb, exc));
        }
    }
    return str->wrap();
}
Пример #3
0
static mrb_value
mrb_env_setenv(mrb_state *mrb, mrb_value name, mrb_value value)
{
  if (mrb_type(name) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, name));
    return mrb_nil_value();
  }

  if (mrb_nil_p(value)) {
    return mrb_env_unsetenv(mrb, name);
  }

  if (mrb_type(value) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, value));
    return mrb_nil_value();
  }

  char *nam = mrb_string_value_ptr(mrb, name);
  char *val = mrb_string_value_ptr(mrb, value);
  if (setenv(nam, val, 1) != 0) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "can't change environment variable");
    return mrb_nil_value();;
  }
  return value;
}
Пример #4
0
Файл: error.c Проект: koie/mruby
static mrb_value
exc_inspect(mrb_state *mrb, mrb_value exc)
{
  mrb_value str, mesg, file, line;

  mesg = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "mesg", 4));
  file = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "file", 4));
  line = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "line", 4));

  if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
    str = file;
    mrb_str_cat(mrb, str, ":", 1);
    mrb_str_append(mrb, str, line);
    mrb_str_cat(mrb, str, ": ", 2);
    if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
      mrb_str_append(mrb, str, mesg);
      mrb_str_cat(mrb, str, " (", 2);
    }
    mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
    if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
      mrb_str_cat(mrb, str, ")", 1);
    }
  }
  else {
    str = mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
    if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
      mrb_str_cat(mrb, str, ": ", 2);
      mrb_str_append(mrb, str, mesg);
    } else {
      mrb_str_cat(mrb, str, ": ", 2);
      mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
    }
  }
  return str;
}
Пример #5
0
static mrb_value
mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
{
    mrb_value v;

    if (mrb_fixnum_p(val)) return val;
    v = convert_type(mrb, val, "Integer", method, TRUE);
    if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
      const char *cname = mrb_obj_classname(mrb, val);
      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s to Integer (%s#%s gives %s)",
               cname, cname, method, mrb_obj_classname(mrb, v));
    }
    return v;
}
Пример #6
0
static mrb_value
method_to_s(mrb_state *mrb, mrb_value self)
{
  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
  mrb_value str = mrb_str_new_lit(mrb, "#<");
  struct RClass *rklass;

  mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, self));
  mrb_str_cat_lit(mrb, str, ": ");
  rklass = mrb_class_ptr(klass);
  if (mrb_class_ptr(owner) == rklass) {
    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0));
    mrb_str_cat_lit(mrb, str, "#");
    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0));
  }
  else {
    mrb_str_cat_cstr(mrb, str, mrb_class_name(mrb, rklass));
    mrb_str_cat_lit(mrb, str, "(");
    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, owner, "to_s", 0));
    mrb_str_cat_lit(mrb, str, ")#");
    mrb_str_cat_str(mrb, str, mrb_funcall(mrb, name, "to_s", 0));
  }
  mrb_str_cat_lit(mrb, str, ">");
  return str;
}
Пример #7
0
static mrb_value
mrb_ary_to_h(mrb_state *mrb, mrb_value ary)
{
  mrb_int i;
  mrb_value v, hash;

  hash = mrb_hash_new_capa(mrb, 0);

  for (i = 0; i < RARRAY_LEN(ary); ++i) {
    v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);

    if (mrb_nil_p(v)) {
      mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",
        mrb_str_new_cstr(mrb,  mrb_obj_classname(mrb, RARRAY_PTR(ary)[i])),
        mrb_fixnum_value(i)
      );
    }

    if (RARRAY_LEN(v) != 2) {
      mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)",
        mrb_fixnum_value(i),
        mrb_fixnum_value(RARRAY_LEN(v))
      );
    }

    mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
  }

  return hash;
}
Пример #8
0
static void
regexp_check(mrb_state *mrb, mrb_value obj)
{
  if (!memcmp(mrb_obj_classname(mrb, obj), REGEXP_CLASS, sizeof(REGEXP_CLASS) - 1)) {
    noregexp(mrb, obj);
  }
}
Пример #9
0
void
mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y)
{
  const char *classname;

  if (SPECIAL_CONST_P(y)) {
    y = mrb_inspect(mrb, y);
    //classname = StringValuePtr(y);
    classname = mrb_string_value_ptr(mrb, y);
  }
  else {
    classname = mrb_obj_classname(mrb, y);
  }
  mrb_raise(mrb, E_ARGUMENT_ERROR, "comparison of %s with %s failed",
	    mrb_obj_classname(mrb, x), classname);
}
Пример #10
0
/*!
 * Defines a class under the namespace of \a outer.
 * \param outer  a class which contains the new class.
 * \param id     name of the new class
 * \param super  a class from which the new class will derive.
 *               NULL means \c Object class.
 * \return the created class
 * \throw TypeError if the constant name \a name is already taken but
 *                  the constant is not a \c Class.
 * \throw NameError if the class is already defined but the class can not
 *                  be reopened because its superclass is not \a super.
 * \post top-level constant named \a name refers the returned class.
 *
 * \note if a class named \a name is already defined and its superclass is
 *       \a super, the function just returns the defined class.
 */
struct RClass *
mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
{
  struct RClass * c;
  mrb_sym id = mrb_intern(mrb, name);

  if (mrb_const_defined_at(mrb, outer, id)) {
    c = mrb_class_from_sym(mrb, outer, id);
    if (c->tt != MRB_TT_CLASS) {
        mrb_raise(mrb, E_TYPE_ERROR, "%s is not a class", mrb_sym2name(mrb, id));
    }
    if (mrb_class_real(c->super) != super) {
        mrb_name_error(mrb, id, "%s is already defined", mrb_sym2name(mrb, id));
    }
    return c;
  }
  if (!super) {
    mrb_warn("no super class for `%s::%s', Object assumed",
             mrb_obj_classname(mrb, mrb_obj_value(outer)), mrb_sym2name(mrb, id));
  }
  c = mrb_class_new(mrb, super);
  setup_class(mrb, mrb_obj_value(outer), c, id);
  mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));

  return c;
}
Пример #11
0
static mrb_value
exc_to_s(mrb_state *mrb, mrb_value exc)
{
  mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg"));

  if (mrb_nil_p(mesg)) return mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
  return mesg;
}
Пример #12
0
static mrb_value exc_to_s(mrb_state *mrb, mrb_value exc)
{
    mrb_value mesg = mrb_attr_get(exc, mrb_intern(mrb, "mesg", 4));

    if (mesg.is_nil())
        return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc))->wrap();
    return mesg;
}
Пример #13
0
static mrb_value
inspect_type(mrb_state *mrb, mrb_value val)
{
  if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {
    return mrb_inspect(mrb, val);
  }
  else {
    return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));
  }
}
Пример #14
0
static mrb_value
exc_inspect(mrb_state *mrb, mrb_value exc)
{
  mrb_value str, mesg, file, line;
  mrb_bool append_mesg;

  mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
  file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
  line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));

  append_mesg = !mrb_nil_p(mesg);
  if (append_mesg) {
    mesg = mrb_obj_as_string(mrb, mesg);
    append_mesg = RSTRING_LEN(mesg) > 0;
  }

  if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
    str = mrb_str_dup(mrb, file);
    mrb_str_cat_lit(mrb, str, ":");
    mrb_str_append(mrb, str, line);
    mrb_str_cat_lit(mrb, str, ": ");
    if (append_mesg) {
      mrb_str_cat_str(mrb, str, mesg);
      mrb_str_cat_lit(mrb, str, " (");
    }
    mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
    if (append_mesg) {
      mrb_str_cat_lit(mrb, str, ")");
    }
  }
  else {
    const char *cname = mrb_obj_classname(mrb, exc);
    str = mrb_str_new_cstr(mrb, cname);
    mrb_str_cat_lit(mrb, str, ": ");
    if (append_mesg) {
      mrb_str_cat_str(mrb, str, mesg);
    }
    else {
      mrb_str_cat_cstr(mrb, str, cname);
    }
  }
  return str;
}
Пример #15
0
static int
must_encoding(mrb_state *mrb, mrb_value enc)
{
  int index = enc_check_encoding(mrb, enc);
  if (index < 0) {
    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type %s (expected Encoding)",
         mrb_obj_classname(mrb, enc));
  }
  return index;
}
Пример #16
0
static mrb_value
color_inspect(mrb_state *mrb, mrb_value self)
{
  char buf[128];
  ALLEGRO_COLOR *c;
  char const *s;
  int len;
  c = mrb_data_get_ptr(mrb, self, &mrbal_color_data_type);
  s = mrb_obj_classname(mrb, self);
  len = snprintf(buf, sizeof(buf), "#<%s: r=%f, g=%f, b=%f, a=%f>", s, c->r, c->g, c->b, c->a);
  return mrb_str_new(mrb, buf, len);
}
Пример #17
0
mrb_value
mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
{
  mrb_value v;

  if (mrb_type(val) == type) return val;
  v = convert_type(mrb, val, tname, method, 1/*Qtrue*/);
  if (mrb_type(v) != type) {
    mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
     mrb_obj_classname(mrb, val), method, tname);
  }
  return v;
}
Пример #18
0
struct RClass*
mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
{
  struct RClass *c, *s;

  if (mrb_const_defined(mrb, outer, id)) {
    mrb_value v = mrb_const_get(mrb, outer, id);

    mrb_check_type(mrb, v, MRB_TT_CLASS);
    c = mrb_class_ptr(v);
    if (!mrb_nil_p(super)) {
      if (mrb_type(super) != MRB_TT_CLASS) {
        mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
      }

      if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) {
        mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id));
      }
    }

    return c;
  }

  if (!mrb_nil_p(super)) {
    if (mrb_type(super) != MRB_TT_CLASS) {
      mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
    }
    s = mrb_class_ptr(super);
  }
  else {
    s = mrb->object_class;
  }

  c = mrb_class_new(mrb, s);
  setup_class(mrb, outer, c, id);
  mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));

  return c;
}
Пример #19
0
/*!
 * Ensures a class can be derived from super.
 *
 * \param super a reference to an object.
 * \exception TypeError if \a super is not a Class or \a super is a singleton class.
 */
void
mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
{
  if (super->tt != MRB_TT_CLASS) {
    mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)",
           mrb_obj_classname(mrb, mrb_obj_value(super)));
  }
  if (super->tt == MRB_TT_SCLASS) {
    mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
  }
  if (super == mrb->class_class) {
    mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
  }
}
Пример #20
0
static mrb_value
exc_inspect(mrb_state *mrb, mrb_value exc)
{
  mrb_value str;

  str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
  exc = mrb_obj_as_string(mrb, exc);

  if (RSTRING_LEN(exc) > 0) {
    mrb_str_cat2(mrb, str, ": ");
    mrb_str_append(mrb, str, exc);
  }
  return str;
}
Пример #21
0
/*
 *  call-seq:
 *     obj.clone -> an_object
 *
 *  Produces a shallow copy of <i>obj</i>---the instance variables of
 *  <i>obj</i> are copied, but not the objects they reference. Copies
 *  the frozen state of <i>obj</i>. See also the discussion
 *  under <code>Object#dup</code>.
 *
 *     class Klass
 *        attr_accessor :str
 *     end
 *     s1 = Klass.new      #=> #<Klass:0x401b3a38>
 *     s1.str = "Hello"    #=> "Hello"
 *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
 *     s2.str[1,4] = "i"   #=> "i"
 *     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
 *     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
 *
 *  This method may have class-specific behavior.  If so, that
 *  behavior will be documented under the #+initialize_copy+ method of
 *  the class.
 *
 *  Some Class(True False Nil Symbol Fixnum Float) Object  cannot clone.
 */
mrb_value
mrb_obj_clone(mrb_state *mrb, mrb_value self)
{
  struct RObject *clone;

  if (mrb_special_const_p(self)) {
      mrb_raise(mrb, E_TYPE_ERROR, "can't clone %s", mrb_obj_classname(mrb, self));
  }
  clone = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
  clone->c = mrb_singleton_class_clone(mrb, self);
  init_copy(mrb, mrb_obj_value(clone), self);

  return mrb_obj_value(clone);
}
Пример #22
0
mrb_value
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
{
  mrb_value str = mrb_str_buf_new(mrb, 20);
  const char *cname = mrb_obj_classname(mrb, obj);

  mrb_str_buf_cat(mrb, str, "#<", 2);
  mrb_str_cat2(mrb, str, cname);
  mrb_str_cat(mrb, str, ":", 1);
  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj)));
  mrb_str_buf_cat(mrb, str, ">", 1);

  return str;
}
Пример #23
0
static mrb_value
mrb_env_getenv(mrb_state *mrb, mrb_value name)
{
  if (mrb_type(name) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, name));
    return mrb_nil_value();
  }

  char *nam = mrb_string_value_ptr(mrb, name);
  char *env = getenv(nam);
  if (env == NULL) {
    return mrb_nil_value();
  }
  return mrb_str_new2(mrb, env);
}
Пример #24
0
static mrb_value
exc_to_s(mrb_state *mrb, mrb_value exc)
{
  mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
  struct RObject *p;

  if (!mrb_string_p(mesg)) {
    return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
  }
  p = mrb_obj_ptr(mesg);
  if (!p->c) {
    p->c = mrb->string_class;
  }
  return mesg;
}
Пример #25
0
mrb_value
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
{
  const char *cname = mrb_obj_classname(mrb, obj);
  size_t len;
  mrb_value str;
  struct RString *s;

  len = strlen(cname)+6+16;
  str = mrb_str_new(mrb, 0, len); /* 6:tags 16:addr */
  s = mrb_str_ptr(str);
  s->len = sprintf(s->ptr, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));

  return str;
}
Пример #26
0
mrb_value
mat4_transform(mrb_state* mrb, mrb_value self)
{
  mrb_value vector;
  mrb_get_args(mrb, "o", &vector);

  const char* vector_class = mrb_obj_classname(mrb, vector);
  mat4* selfValue = mat4_get_ptr(mrb, self);

  if (strcmp(vector_class, "Vec2") == 0) {
    return mat4_transform_vec2(mrb, selfValue, vec2_get_ptr(mrb, vector));
  }
  
  return mrb_nil_value();
}
Пример #27
0
mrb_value
mrb_obj_dup(mrb_state *mrb, mrb_value obj)
{
    struct RBasic *p;
    mrb_value dup;

    if (mrb_special_const_p(obj)) {
        mrb_raise(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj));
    }
    p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
    dup = mrb_obj_value(p);
    init_copy(mrb, dup, obj);

    return dup;
}
Пример #28
0
mrb_value
mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
{
  iv_tbl *t = obj->iv;
  int len = iv_size(mrb, t);

  if (len > 0) {
    const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
    mrb_value str = mrb_sprintf(mrb, "-<%s:%p", cn, (void*)obj);

    iv_foreach(mrb, t, inspect_i, &str);
    return str;
  }
  return mrb_any_to_s(mrb, mrb_obj_value(obj));
}
Пример #29
0
mrb_value
mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
{
  mrb_value v;

  /* always convert T_DATA */
  if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
  v = convert_type(mrb, val, tname, method, 0/*Qfalse*/);
  if (mrb_nil_p(v)) return mrb_nil_value();
  if (mrb_type(v) != type) {
    mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
     mrb_obj_classname(mrb, val), method, tname);
  }
  return v;
}
Пример #30
0
/*
 *  call-seq:
 *     obj.clone -> an_object
 *
 *  Produces a shallow copy of <i>obj</i>---the instance variables of
 *  <i>obj</i> are copied, but not the objects they reference. Copies
 *  the frozen state of <i>obj</i>. See also the discussion
 *  under <code>Object#dup</code>.
 *
 *     class Klass
 *        attr_accessor :str
 *     end
 *     s1 = Klass.new      #=> #<Klass:0x401b3a38>
 *     s1.str = "Hello"    #=> "Hello"
 *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
 *     s2.str[1,4] = "i"   #=> "i"
 *     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
 *     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
 *
 *  This method may have class-specific behavior.  If so, that
 *  behavior will be documented under the #+initialize_copy+ method of
 *  the class.
 *
 *  Some Class(True False Nil Symbol Fixnum Float) Object  cannot clone.
 */
mrb_value
mrb_obj_clone(mrb_state *mrb, mrb_value self)
{
  struct RObject *clone;

  if (mrb_special_const_p(self)) {
      mrb_raise(mrb, E_TYPE_ERROR, "can't clone %s", mrb_obj_classname(mrb, self));
  }
  clone = (struct RObject*)mrb_obj_alloc(mrb, self.tt, mrb_obj_class(mrb, self));
  clone->c = mrb_singleton_class_clone(mrb, self);
  init_copy(mrb, mrb_obj_value(clone), self);
  //1-9-2 no bug mrb_funcall(mrb, clone, "initialize_clone", 1, self);
  //RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;

  return mrb_obj_value(clone);
}