* 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
This commit is contained in:
matz 2002-09-03 05:20:14 +00:00
Родитель 20254d4e13
Коммит 6f484e4930
22 изменённых файлов: 276 добавлений и 238 удалений

Просмотреть файл

@ -14,10 +14,20 @@ Mon Sep 2 21:21:46 2002 Minero Aoki <aamine@loveruby.net>
* intern.h (ruby_parser_stack_on_heap): added.
Mon Sep 2 18:45:07 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (rb_copy_generic_ivar): remove old generic instance
variable table if it existes.
Sun Sep 1 15:54:33 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* config.guess: fixed for Linux/PPC.
Sat Aug 31 09:38:12 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_make_metaclass): metaclass of a metaclass is a
metaclass itself.
Fri Aug 30 22:45:16 2002 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb: Added.
@ -45,6 +55,37 @@ Fri Aug 30 19:40:28 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/tcltklib/tcltklib.c (ip_toUTF8, ip_fromUTF8): ditto.
Fri Aug 30 01:32:17 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_singleton_class): superclass of a metaclass
should be a metaclass of superclass.
* range.c (range_eq): two instances must belong to a same class to
be equal.
* range.c (range_eql): ditto.
* io.c (rb_io_taint_check): frozen check added.
* file.c (rb_stat_become): frozen check added.
* object.c (rb_obj_become): ditto.
* re.c (rb_reg_become): ditto.
* struct.c (rb_struct_become): ditto.
* time.c (time_become): ditto.
* array.c (rb_ary_become): should call rb_ary_modify().
* hash.c (rb_hash_become): should call rb_hash_modify().
* compar.c (cmp_equal): should not use NUM2LONG(), since <=> may
return bignum.
* compar.c (cmp_gt, cmp_ge, cmp_lt, cmp_le, cmp_between): ditto.
Thu Aug 29 23:34:42 2002 KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>
* bcc32/MakeFile.sub (sitearch): add.

38
array.c
Просмотреть файл

@ -795,22 +795,6 @@ rb_ary_empty_p(ary)
return Qfalse;
}
static VALUE
rb_ary_become(copy, orig)
VALUE copy, orig;
{
orig = to_ary(orig);
ary_make_shared(orig);
if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
free(RARRAY(copy)->ptr);
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
RARRAY(copy)->len = RARRAY(orig)->len;
RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared;
FL_SET(copy, ELTS_SHARED);
return copy;
}
VALUE
rb_ary_dup(ary)
VALUE ary;
@ -1316,13 +1300,21 @@ rb_ary_delete_if(ary)
}
static VALUE
rb_ary_replace(ary, ary2)
VALUE ary, ary2;
rb_ary_replace(copy, orig)
VALUE copy, orig;
{
if (ary == ary2) return ary;
ary2 = to_ary(ary2);
rb_ary_update(ary, 0, RARRAY(ary)->len, ary2);
return ary;
rb_ary_modify(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
ary_make_shared(orig);
if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
free(RARRAY(copy)->ptr);
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
RARRAY(copy)->len = RARRAY(orig)->len;
RARRAY(copy)->aux.shared = RARRAY(orig)->aux.shared;
FL_SET(copy, ELTS_SHARED);
return copy;
}
VALUE
@ -1857,7 +1849,7 @@ Init_Array()
rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1);
rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1);
rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1);
rb_define_method(rb_cArray, "become", rb_ary_become, 1);
rb_define_method(rb_cArray, "become", rb_ary_replace, 1);
rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);

56
class.c
Просмотреть файл

@ -94,25 +94,24 @@ rb_mod_dup(mod)
}
VALUE
rb_singleton_class_new(super)
VALUE super;
rb_singleton_class_clone(obj)
VALUE obj;
{
VALUE klass = rb_class_boot(super);
VALUE klass = RBASIC(obj)->klass;
FL_SET(klass, FL_SINGLETON);
return klass;
}
VALUE
rb_singleton_class_clone(klass)
VALUE klass;
{
if (!FL_TEST(klass, FL_SINGLETON))
return klass;
else {
/* copy singleton(unnamed) class */
NEWOBJ(clone, struct RClass);
CLONESETUP(clone, klass);
OBJSETUP(clone, 0, RBASIC(klass)->flags);
if (BUILTIN_TYPE(obj) == T_CLASS) {
RBASIC(clone)->klass = (VALUE)clone;
}
else {
RBASIC(clone)->klass = rb_singleton_class_clone(klass);
}
clone->super = RCLASS(klass)->super;
clone->iv_tbl = 0;
@ -122,6 +121,7 @@ rb_singleton_class_clone(klass)
}
clone->m_tbl = st_init_numtable();
st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
FL_SET(clone, FL_SINGLETON);
return (VALUE)clone;
}
@ -140,12 +140,17 @@ rb_singleton_class_attached(klass, obj)
}
VALUE
rb_make_metaclass(obj, klass)
VALUE obj, klass;
rb_make_metaclass(obj, super)
VALUE obj, super;
{
klass = rb_singleton_class_new(klass);
VALUE klass = rb_class_boot(super);
FL_SET(klass, FL_SINGLETON);
RBASIC(obj)->klass = klass;
rb_singleton_class_attached(klass, obj);
if (BUILTIN_TYPE(obj) == T_CLASS) {
RBASIC(klass)->klass = klass;
}
return klass;
}
@ -667,28 +672,12 @@ rb_undef_method(klass, name)
rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
}
#if 0
#define SPECIAL_SINGLETON(x,c) do {
if (obj == (x)) {\
if (!FL_TEST(c, FL_SINGLETON)) {\
c = rb_singleton_class_new(c);\
rb_singleton_class_attached(c,obj);\
}\
return c;\
}\
} while (0)
#else
#define SPECIAL_SINGLETON(x,c) do {\
if (obj == (x)) {\
return c;\
}\
} while (0)
#endif
VALUE
rb_singleton_class(obj)
VALUE obj;
@ -707,13 +696,12 @@ rb_singleton_class(obj)
DEFER_INTS;
if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
((BUILTIN_TYPE(obj) != T_CLASS && BUILTIN_TYPE(obj) != T_MODULE) ||
rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj)) {
(BUILTIN_TYPE(obj) == T_CLASS || /* metaclass (or metaclass of metaclass) */
rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj)) {
klass = RBASIC(obj)->klass;
}
else {
klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
RBASIC(klass)->klass = CLASS_OF(RCLASS(klass)->super);
}
if (OBJ_TAINTED(obj)) {
OBJ_TAINT(klass);

Просмотреть файл

@ -23,7 +23,10 @@ cmp_equal(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) == 0) return Qtrue;
if (c == INT2FIX(0)) return Qtrue;
if (TYPE(c) == T_BIGNUM) {
if (rb_big_norm(c) == INT2FIX(0)) return Qtrue;
}
return Qfalse;
}
@ -34,7 +37,11 @@ cmp_gt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) > 0) return Qtrue;
if (FIXNUM_P(c) && FIX2INT(c) > 0) return Qtrue;
if (TYPE(c) == T_BIGNUM) {
if (rb_big_norm(x) == INT2FIX(0)) return Qfalse;
if (RBIGNUM(c)->sign) return Qtrue;
}
return Qfalse;
}
@ -45,7 +52,11 @@ cmp_ge(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) >= 0) return Qtrue;
if (FIXNUM_P(c) && FIX2INT(c) >= 0) return Qtrue;
if (TYPE(c) == T_BIGNUM) {
if (rb_big_norm(x) == INT2FIX(0)) return Qtrue;
if (RBIGNUM(c)->sign) return Qtrue;
}
return Qfalse;
}
@ -55,8 +66,11 @@ cmp_lt(x, y)
{
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) < 0) return Qtrue;
if (FIXNUM_P(c) && FIX2INT(c) < 0) return Qtrue;
if (TYPE(c) == T_BIGNUM) {
if (rb_big_norm(x) == INT2FIX(0)) return Qfalse;
if (!RBIGNUM(c)->sign) return Qtrue;
}
return Qfalse;
}
@ -67,7 +81,11 @@ cmp_le(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) <= 0) return Qtrue;
if (FIXNUM_P(c) && FIX2INT(c) <= 0) return Qtrue;
if (TYPE(c) == T_BIGNUM) {
if (rb_big_norm(x) == INT2FIX(0)) return Qtrue;
if (!RBIGNUM(c)->sign) return Qtrue;
}
return Qfalse;
}
@ -75,14 +93,8 @@ static VALUE
cmp_between(x, min, max)
VALUE x, min, max;
{
VALUE c = rb_funcall(x, cmp, 1, min);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) < 0) return Qfalse;
c = rb_funcall(x, cmp, 1, max);
if (NIL_P(c)) return Qfalse;
if (NUM2LONG(c) > 0) return Qfalse;
if (cmp_lt(x, min)) return Qfalse;
if (cmp_gt(x, max)) return Qfalse;
return Qtrue;
}

Просмотреть файл

@ -813,6 +813,13 @@ rb_error_frozen(what)
rb_raise(rb_eTypeError, "can't modify frozen %s", what);
}
void
rb_check_frozen(obj)
VALUE obj;
{
if (OBJ_FROZEN(obj)) rb_error_frozen(rb_class2name(CLASS_OF(obj)));
}
static void
init_syserr()
{

Просмотреть файл

@ -41,16 +41,17 @@ static ID id_metadata;
*/
static algo_t *
get_digest_base_metadata(class)
VALUE class;
get_digest_base_metadata(klass)
VALUE klass;
{
VALUE obj;
algo_t *algo;
if (rb_cvar_defined(class, id_metadata) == Qfalse)
if (rb_cvar_defined(klass, id_metadata) == Qfalse) {
rb_notimplement();
}
obj = rb_cvar_get(class, id_metadata);
obj = rb_cvar_get(klass, id_metadata);
Data_Get_Struct(obj, algo_t, algo);
@ -58,54 +59,42 @@ get_digest_base_metadata(class)
}
static VALUE
rb_digest_base_s_new(argc, argv, class)
int argc;
VALUE* argv;
VALUE class;
rb_digest_base_alloc(klass)
VALUE klass;
{
algo_t *algo;
VALUE obj;
void *pctx;
if (class == cDigest_Base)
if (klass == cDigest_Base) {
rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
}
algo = get_digest_base_metadata(class);
algo = get_digest_base_metadata(klass);
pctx = xmalloc(algo->ctx_size);
algo->init_func(pctx);
obj = Data_Wrap_Struct(class, 0, free, pctx);
rb_obj_call_init(obj, argc, argv);
obj = Data_Wrap_Struct(klass, 0, free, pctx);
return obj;
}
static VALUE
rb_digest_base_s_digest(class, str)
VALUE class;
rb_digest_base_s_digest(klass, str)
VALUE klass;
VALUE str;
{
algo_t *algo;
void *pctx;
size_t len;
unsigned char *digest;
VALUE obj;
VALUE obj = rb_digest_base_alloc(klass);
if (class == cDigest_Base)
rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
algo = get_digest_base_metadata(klass);
Data_Get_Struct(obj, void, pctx);
#ifdef StringValue
StringValue(str);
#else
Check_Type(str, T_STRING);
#endif
algo = get_digest_base_metadata(class);
pctx = xmalloc(algo->ctx_size);
algo->init_func(pctx);
algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len);
len = algo->digest_len;
@ -122,26 +111,18 @@ rb_digest_base_s_digest(class, str)
}
static VALUE
rb_digest_base_s_hexdigest(class, str)
VALUE class;
rb_digest_base_s_hexdigest(klass, str)
VALUE klass;
VALUE str;
{
algo_t *algo;
void *pctx;
size_t len;
unsigned char *hexdigest;
VALUE obj;
VALUE obj = rb_digest_base_alloc(klass);
if (class == cDigest_Base)
rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
#ifdef StringValue
StringValue(str);
#else
Check_Type(str, T_STRING);
#endif
algo = get_digest_base_metadata(class);
algo = get_digest_base_metadata(klass);
pctx = xmalloc(algo->ctx_size);
algo->init_func(pctx);
@ -161,21 +142,25 @@ rb_digest_base_s_hexdigest(class, str)
}
static VALUE
rb_digest_base_clone(self)
VALUE self;
rb_digest_base_become(copy, obj)
VALUE copy, obj;
{
algo_t *algo;
void *pctx1, *pctx2;
VALUE class;
VALUE klass;
class = CLASS_OF(self);
algo = get_digest_base_metadata(class);
Data_Get_Struct(self, void, pctx1);
pctx2 = xmalloc(algo->ctx_size);
printf("Digest::Base::bacome\n");
if (copy = obj) return copy;
rb_check_frozen(copy);
algo = get_digest_base_metadata(CLASS_OF(klass));
if (algo != get_digest_base_metadata(CLASS_OF(obj))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
Data_Get_Struct(copy, void, pctx1);
Data_Get_Struct(copy, void, pctx2);
memcpy(pctx2, pctx1, algo->ctx_size);
return Data_Wrap_Struct(class, 0, free, pctx2);
return copy;
}
static VALUE
@ -185,12 +170,7 @@ rb_digest_base_update(self, str)
algo_t *algo;
void *pctx;
#ifdef StringValue
StringValue(str);
#else
Check_Type(str, T_STRING);
#endif
algo = get_digest_base_metadata(CLASS_OF(self));
Data_Get_Struct(self, void, pctx);
@ -281,13 +261,13 @@ rb_digest_base_equal(self, other)
VALUE self, other;
{
algo_t *algo;
VALUE class;
VALUE klass;
VALUE str1, str2;
class = CLASS_OF(self);
algo = get_digest_base_metadata(class);
klass = CLASS_OF(self);
algo = get_digest_base_metadata(klass);
if (CLASS_OF(other) == class) {
if (CLASS_OF(other) == klass) {
void *pctx1, *pctx2;
Data_Get_Struct(self, void, pctx1);
@ -296,11 +276,7 @@ rb_digest_base_equal(self, other)
return algo->equal_func(pctx1, pctx2) ? Qtrue : Qfalse;
}
#ifdef StringValue
StringValue(other);
#else
Check_Type(other, T_STRING);
#endif
str2 = other;
if (RSTRING(str2)->len == algo->digest_len)
@ -326,12 +302,13 @@ Init_digest()
cDigest_Base = rb_define_class_under(mDigest, "Base", rb_cObject);
rb_define_singleton_method(cDigest_Base, "new", rb_digest_base_s_new, -1);
printf("Init_digest\n");
rb_define_singleton_method(cDigest_Base, "allocate", rb_digest_base_alloc, 0);
rb_define_singleton_method(cDigest_Base, "digest", rb_digest_base_s_digest, 1);
rb_define_singleton_method(cDigest_Base, "hexdigest", rb_digest_base_s_hexdigest, 1);
rb_define_method(cDigest_Base, "initialize", rb_digest_base_init, -1);
rb_define_method(cDigest_Base, "clone", rb_digest_base_clone, 0);
rb_define_method(cDigest_Base, "become", rb_digest_base_become, 1);
rb_define_method(cDigest_Base, "update", rb_digest_base_update, 1);
rb_define_method(cDigest_Base, "<<", rb_digest_base_update, 1);
rb_define_method(cDigest_Base, "digest", rb_digest_base_digest, 0);

Просмотреть файл

@ -18,7 +18,6 @@ void
Init_md5()
{
VALUE mDigest, cDigest_Base, cDigest_MD5;
ID id_metadata;
rb_require("digest.so");
@ -27,8 +26,6 @@ Init_md5()
cDigest_MD5 = rb_define_class_under(mDigest, "MD5", cDigest_Base);
id_metadata = rb_intern("metadata");
rb_cvar_set(cDigest_MD5, id_metadata,
Data_Wrap_Struct(rb_cObject, 0, 0, &md5), Qtrue);
rb_cvar_declare(cDigest_MD5, rb_intern("metadata"),
Data_Wrap_Struct(rb_cObject, 0, 0, &md5));
}

Просмотреть файл

@ -822,7 +822,7 @@ if $extlist.size > 0
if File.exist?(f)
$extinit += format("\
\tInit_%s();\n\
\trb_provide(\"%s\");\n\
\trb_provide(\"%s.so\");\n\
", i, t)
$extobjs += "ext/"
$extobjs += f

Просмотреть файл

@ -148,7 +148,7 @@ static VALUE strio_closed _((VALUE));
static VALUE strio_closed_read _((VALUE));
static VALUE strio_closed_write _((VALUE));
static VALUE strio_eof _((VALUE));
static VALUE strio_clone _((VALUE));
static VALUE strio_become _((VALUE, VALUE));
static VALUE strio_get_lineno _((VALUE));
static VALUE strio_set_lineno _((VALUE, VALUE));
static VALUE strio_get_pos _((VALUE));
@ -405,14 +405,17 @@ strio_eof(self)
}
static VALUE
strio_clone(self)
VALUE self;
strio_become(copy, orig)
VALUE copy, orig;
{
struct StringIO *ptr = StringIO(self);
VALUE clone = rb_call_super(0, 0);
DATA_PTR(clone) = ptr;
struct StringIO *ptr = StringIO(orig);
if (DATA_PTR(copy)) {
strio_free(DATA_PTR(ptr));
}
DATA_PTR(copy) = ptr;
++ptr->count;
return self;
return copy;
}
static VALUE
@ -883,8 +886,7 @@ Init_stringio()
rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
rb_define_method(StringIO, "initialize", strio_initialize, -1);
rb_enable_super(StringIO, "initialize");
rb_define_method(StringIO, "clone", strio_clone, 0);
rb_enable_super(StringIO, "clone");
rb_define_method(StringIO, "become", strio_become, 1);
rb_define_method(StringIO, "reopen", strio_reopen, -1);
rb_define_method(StringIO, "string", strio_get_string, 0);

18
file.c
Просмотреть файл

@ -2024,26 +2024,28 @@ rb_stat_init(obj, fname)
}
static VALUE
rb_stat_become(obj, orig)
VALUE obj, orig;
rb_stat_become(copy, orig)
VALUE copy, orig;
{
struct stat *nst;
if (copy == orig) return orig;
rb_check_frozen(copy);
/* need better argument type check */
if (!rb_obj_is_instance_of(orig, rb_obj_class(obj))) {
if (!rb_obj_is_instance_of(orig, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
if (DATA_PTR(obj)) {
free(DATA_PTR(obj));
DATA_PTR(obj) = 0;
if (DATA_PTR(copy)) {
free(DATA_PTR(copy));
DATA_PTR(copy) = 0;
}
if (DATA_PTR(orig)) {
nst = ALLOC(struct stat);
*nst = *(struct stat*)DATA_PTR(orig);
DATA_PTR(obj) = nst;
DATA_PTR(copy) = nst;
}
return obj;
return copy;
}
static VALUE

28
hash.c
Просмотреть файл

@ -254,30 +254,6 @@ to_hash(hash)
return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
}
static VALUE
rb_hash_become(copy, orig)
VALUE copy, orig;
{
orig = to_hash(orig);
if (RHASH(copy)->tbl) st_free_table(RHASH(copy)->tbl);
RHASH(copy)->tbl = (st_table*)st_copy(RHASH(orig)->tbl);
RHASH(copy)->ifnone = RHASH(orig)->ifnone;
if (FL_TEST(orig, HASH_PROC_DEFAULT)) {
FL_SET(copy, HASH_PROC_DEFAULT);
}
else {
FL_UNSET(copy, HASH_PROC_DEFAULT);
}
if (FL_TEST(orig, HASH_DELETED)) {
FL_SET(copy, HASH_DELETED);
}
else {
FL_UNSET(copy, HASH_DELETED);
}
return copy;
}
static int
rb_hash_rehash_i(key, value, tbl)
VALUE key, value;
@ -596,7 +572,7 @@ replace_i(key, val, hash)
}
static VALUE
rb_hash_replace(hash, hash2)
rb_hash_become(hash, hash2)
VALUE hash, hash2;
{
hash2 = to_hash(hash2);
@ -1654,7 +1630,7 @@ Init_Hash()
rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
rb_define_method(rb_cHash,"update", rb_hash_update, 1);
rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
rb_define_method(rb_cHash,"replace", rb_hash_become, 1);
rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);

Просмотреть файл

@ -95,7 +95,6 @@ VALUE rb_class_boot _((VALUE));
VALUE rb_class_new _((VALUE));
VALUE rb_mod_clone _((VALUE));
VALUE rb_mod_dup _((VALUE));
VALUE rb_singleton_class_new _((VALUE));
VALUE rb_singleton_class_clone _((VALUE));
void rb_singleton_class_attached _((VALUE,VALUE));
VALUE rb_make_metaclass _((VALUE, VALUE));

2
io.c
Просмотреть файл

@ -177,6 +177,7 @@ rb_io_taint_check(io)
{
if (!OBJ_TAINTED(io) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
rb_check_frozen(io);
return io;
}
@ -2270,6 +2271,7 @@ rb_io_become(clone, io)
char *mode;
io = rb_io_get_io(io);
if (clone == io) return clone;
GetOpenFile(io, orig);
MakeOpenFile(clone, fptr);

Просмотреть файл

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

Просмотреть файл

@ -95,7 +95,8 @@ range_eq(range, obj)
VALUE range, obj;
{
if (range == obj) return Qtrue;
if (!rb_obj_is_kind_of(obj, rb_obj_class(range))) return Qfalse;
if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))
return Qfalse;
if (!rb_equal(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))
return Qfalse;
@ -153,7 +154,8 @@ range_eql(range, obj)
VALUE range, obj;
{
if (range == obj) return Qtrue;
if (!rb_obj_is_kind_of(obj, rb_obj_class(obj))) return Qfalse;
if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))
return Qfalse;
if (!rb_eql(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))
return Qfalse;

37
re.c
Просмотреть файл

@ -526,6 +526,23 @@ match_alloc(klass)
return (VALUE)match;
}
static VALUE
match_clone(match)
VALUE match;
{
NEWOBJ(clone, struct RMatch);
CLONESETUP(clone, match);
clone->str = RMATCH(match)->str;
clone->regs = 0;
clone->regs = ALLOC(struct re_registers);
clone->regs->allocated = 0;
re_copy_registers(clone->regs, RMATCH(match)->regs);
return (VALUE)clone;
}
static VALUE
match_become(obj, orig)
VALUE obj, orig;
@ -1158,9 +1175,7 @@ rb_reg_initialize_m(argc, argv, self)
}
}
if (OBJ_FROZEN(self)) {
rb_error_frozen("Regexp");
}
rb_check_frozen(self);
src = argv[0];
if (TYPE(src) == T_REGEXP) {
rb_reg_check(src);
@ -1311,20 +1326,22 @@ rb_reg_options(re)
}
static VALUE
rb_reg_become(clone, re)
rb_reg_become(copy, re)
VALUE re;
{
if (copy == re) return copy;
rb_check_frozen(copy);
/* need better argument type check */
if (!rb_obj_is_instance_of(re, rb_obj_class(clone))) {
if (!rb_obj_is_instance_of(re, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument type");
}
RREGEXP(clone)->ptr = 0;
RREGEXP(clone)->len = 0;
RREGEXP(clone)->str = 0;
RREGEXP(copy)->ptr = 0;
RREGEXP(copy)->len = 0;
RREGEXP(copy)->str = 0;
rb_reg_check(re);
rb_reg_initialize(clone, RREGEXP(re)->str, RREGEXP(re)->len,
rb_reg_initialize(copy, RREGEXP(re)->str, RREGEXP(re)->len,
rb_reg_options(re));
return clone;
return copy;
}
VALUE

2
ruby.h
Просмотреть файл

@ -278,7 +278,7 @@ VALUE rb_newobj _((void));
if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
} while (0)
#define CLONESETUP(clone,obj) do {\
OBJSETUP(clone,rb_singleton_class_clone(RBASIC(obj)->klass),RBASIC(obj)->flags);\
OBJSETUP(clone,rb_singleton_class_clone((VALUE)obj),RBASIC(obj)->flags);\
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\
if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\
} while (0)

Просмотреть файл

@ -213,7 +213,7 @@ rb_str_to_str(str)
}
static void
rb_str_become(str, str2)
rb_str_shared_replace(str, str2)
VALUE str, str2;
{
if (str == str2) return;
@ -1071,7 +1071,7 @@ rb_str_succ_bang(str)
VALUE str;
{
rb_str_modify(str);
rb_str_become(str, rb_str_succ(str));
rb_str_shared_replace(str, rb_str_succ(str));
return str;
}

Просмотреть файл

@ -421,17 +421,19 @@ rb_struct_to_a(s)
}
static VALUE
rb_struct_become(clone, s)
VALUE clone, s;
rb_struct_become(copy, s)
VALUE copy, s;
{
if (!rb_obj_is_instance_of(s, rb_obj_class(clone))) {
if (copy == s) return copy;
rb_check_frozen(copy);
if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
RSTRUCT(clone)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
RSTRUCT(clone)->len = RSTRUCT(s)->len;
MEMCPY(RSTRUCT(clone)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(clone)->len);
RSTRUCT(copy)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
RSTRUCT(copy)->len = RSTRUCT(s)->len;
MEMCPY(RSTRUCT(copy)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(copy)->len);
return clone;
return copy;
}
static VALUE

20
time.c
Просмотреть файл

@ -793,12 +793,23 @@ time_hash(time)
return LONG2FIX(hash);
}
static void
time_modify(time)
VALUE time;
{
rb_check_frozen(time);
if (!OBJ_TAINTED(time) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify Time");
}
static VALUE
time_become(copy, time)
VALUE copy, time;
{
struct time_object *tobj, *tcopy;
if (copy == time) return copy;
time_modify(copy);
if (TYPE(time) != T_DATA || RDATA(time)->dfree != time_free) {
rb_raise(rb_eTypeError, "wrong argument type");
}
@ -818,15 +829,6 @@ time_dup(time)
return dup;
}
static void
time_modify(time)
VALUE time;
{
if (OBJ_FROZEN(time)) rb_error_frozen("Time");
if (!OBJ_TAINTED(time) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify Time");
}
static VALUE
time_localtime(time)
VALUE time;

Просмотреть файл

@ -924,7 +924,15 @@ rb_copy_generic_ivar(clone, obj)
if (!generic_iv_tbl) return;
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
st_add_direct(generic_iv_tbl, clone, st_copy(tbl));
st_table *old;
if (st_lookup(generic_iv_tbl, clone, &old)) {
st_free_table(old);
st_insert(generic_iv_tbl, clone, st_copy(tbl));
}
else {
st_add_direct(generic_iv_tbl, clone, st_copy(tbl));
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.3"
#define RUBY_RELEASE_DATE "2002-09-02"
#define RUBY_RELEASE_DATE "2002-09-03"
#define RUBY_VERSION_CODE 173
#define RUBY_RELEASE_CODE 20020902
#define RUBY_RELEASE_CODE 20020903