From 6f484e4930be69c58462dd11c97663e6c8488b8e Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 3 Sep 2002 05:20:14 +0000 Subject: * variable.c (rb_copy_generic_ivar): remove old generic instance variable table if it existes. * class.c (rb_make_metaclass): metaclass of a metaclass is a metaclass itself. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2784 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index cbc37944f3..d26efe1837 100644 --- a/object.c +++ b/object.c @@ -90,23 +90,43 @@ rb_obj_class(obj) return rb_class_real(CLASS_OF(obj)); } +static void +copy_object(dest, obj) + VALUE dest, obj; +{ + RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR|FL_TAINT); + RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT); + if (FL_TEST(obj, FL_EXIVAR)) { + rb_copy_generic_ivar(dest, obj); + } + switch (TYPE(obj)) { + case T_OBJECT: + case T_CLASS: + case T_MODULE: + if (ROBJECT(dest)->iv_tbl) { + st_free_table(ROBJECT(dest)->iv_tbl); + ROBJECT(dest)->iv_tbl = 0; + } + if (ROBJECT(obj)->iv_tbl) { + ROBJECT(dest)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); + } + } +} + VALUE rb_obj_clone(obj) VALUE obj; { VALUE clone; - int frozen; if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(obj))); } - clone = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); - CLONESETUP(clone, obj); - frozen = OBJ_FROZEN(obj); - FL_UNSET(clone, FL_FREEZE); /* temporarily remove frozen flag */ + clone = rb_obj_alloc(rb_obj_class(obj)); + RBASIC(clone)->klass = rb_singleton_class_clone(obj); + copy_object(clone, obj); rb_funcall(clone, become, 1, obj); - if (frozen) OBJ_FREEZE(clone); /* restore frozen status */ - OBJ_INFECT(clone, obj); + RBASIC(clone)->flags = RBASIC(obj)->flags; return clone; } @@ -120,10 +140,9 @@ rb_obj_dup(obj) if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't dup %s", rb_class2name(CLASS_OF(obj))); } - dup = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); - DUPSETUP(dup, obj); + dup = rb_obj_alloc(rb_obj_class(obj)); + copy_object(dup, obj); rb_funcall(dup, become, 1, obj); - OBJ_INFECT(dup, obj); return dup; } @@ -132,18 +151,11 @@ VALUE rb_obj_become(obj, orig) VALUE obj, orig; { - long type; - - if ((type = TYPE(obj)) != TYPE(orig) || - rb_obj_class(obj) != rb_obj_class(orig)) { + if (obj == orig) return obj; + rb_check_frozen(obj); + if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) { rb_raise(rb_eTypeError, "become should take same class object"); } - if (type == T_OBJECT) { - if (ROBJECT(obj)->iv_tbl) st_free_table(ROBJECT(obj)->iv_tbl); - if (ROBJECT(orig)->iv_tbl) { - ROBJECT(obj)->iv_tbl = st_copy(ROBJECT(orig)->iv_tbl); - } - } return obj; } -- cgit v1.2.3