From c45908e41f47c88674b73a754ecd0535449b667a Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 27 Aug 2002 08:31:08 +0000 Subject: * file.c (rb_find_file): $LOAD_PATH must not be empty. * file.c (rb_find_file_ext): ditto. * range.c (range_eq): class check should be based on range.class, instead of Range to work with Range.dup. * range.c (range_eql): ditto. * class.c (rb_mod_dup): need to preserve metaclass and flags. * object.c (rb_cstr_to_dbl): had a buffer overrun. * marshal.c (w_class): integrate singleton check into a funciton to follow DRY principle. * marshal.c (w_uclass): should check singleton method. * object.c (rb_obj_dup): dmark and dfree functions must be match for T_DATA type. * object.c (rb_obj_dup): class of the duped object must be match to the class of the original. * re.c (rb_reg_quote): do not escape \t, \f, \r, \n, for they are not regular expression metacharacters. * time.c (time_s_alloc): use time_free instead of free (null check, also serves for type mark). * time.c (time_s_at): check dfree function too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index c223c5861d..cbc37944f3 100644 --- a/object.c +++ b/object.c @@ -33,7 +33,7 @@ VALUE rb_cSymbol; static ID eq, eql; static ID inspect; -static ID clone; +static ID become; static ID alloc; VALUE @@ -95,15 +95,18 @@ 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); - if (TYPE(clone) == T_OBJECT && ROBJECT(obj)->iv_tbl) { - ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - } + CLONESETUP(clone, obj); + frozen = OBJ_FROZEN(obj); + FL_UNSET(clone, FL_FREEZE); /* temporarily remove frozen flag */ + rb_funcall(clone, become, 1, obj); + if (frozen) OBJ_FREEZE(clone); /* restore frozen status */ + OBJ_INFECT(clone, obj); return clone; } @@ -117,18 +120,31 @@ 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_funcall(obj, clone, 0, 0); - if (TYPE(dup) != TYPE(obj)) { - rb_raise(rb_eTypeError, "dupulicated object must be same type"); + dup = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); + DUPSETUP(dup, obj); + rb_funcall(dup, become, 1, obj); + OBJ_INFECT(dup, obj); + + return dup; +} + +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)) { + rb_raise(rb_eTypeError, "become should take same class object"); } - if (!SPECIAL_CONST_P(dup)) { - OBJSETUP(dup, rb_obj_class(obj), BUILTIN_TYPE(obj)); - OBJ_INFECT(dup, obj); - if (FL_TEST(obj, FL_EXIVAR)) { - FL_SET(dup, FL_EXIVAR); + 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 dup; + return obj; } static VALUE @@ -1009,7 +1025,7 @@ rb_cstr_to_dbl(p, badcheck) return d; } if (*end) { - char *buf = ALLOCA_N(char, strlen(p)); + char *buf = ALLOCA_N(char, strlen(p)+1); char *n = buf; while (p < end) *n++ = *p++; @@ -1267,6 +1283,7 @@ Init_Object() rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0); rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0); + rb_define_method(rb_mKernel, "become", rb_obj_become, 1); rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0); rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0); @@ -1402,5 +1419,5 @@ Init_Object() eq = rb_intern("=="); eql = rb_intern("eql?"); inspect = rb_intern("inspect"); - clone = rb_intern("clone"); + become = rb_intern("become"); } -- cgit v1.2.3