summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-08-10 08:47:18 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-08-10 08:47:18 +0000
commitb0faee9b9cd5a747e226a2c64f33588b2b8f4e6c (patch)
treee3dcd4c31ffa63ad1e8a0bf4a88c63162002c101
parent3f8dd52fe04789d5c001dc5566decf2679b58e90 (diff)
downloadruby-b0faee9b9cd5a747e226a2c64f33588b2b8f4e6c.tar.gz
clone
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@512 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--intern.h1
-rw-r--r--io.c2
-rw-r--r--ruby.h5
-rw-r--r--variable.c35
4 files changed, 28 insertions, 15 deletions
diff --git a/intern.h b/intern.h
index ccf6b9bad9..58a8b86f6a 100644
--- a/intern.h
+++ b/intern.h
@@ -309,6 +309,7 @@ VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_gvar_set2 _((const char*, VALUE));
VALUE rb_f_global_variables _((void));
void rb_alias_variable _((ID, ID));
+void rb_clone_generic_ivar _((VALUE,VALUE));
void rb_mark_generic_ivar _((VALUE));
void rb_mark_generic_ivar_tbl _((void));
void rb_free_generic_ivar _((VALUE));
diff --git a/io.c b/io.c
index 1344f9e5dc..1e689073d9 100644
--- a/io.c
+++ b/io.c
@@ -1772,7 +1772,7 @@ rb_io_clone(io)
char *mode;
NEWOBJ(obj, struct RFile);
- OBJSETUP(obj, CLASS_OF(io), T_FILE);
+ CLONESETUP(obj, io);
GetOpenFile(io, orig);
MakeOpenFile(obj, fptr);
diff --git a/ruby.h b/ruby.h
index 2dcf8cba80..d358be8347 100644
--- a/ruby.h
+++ b/ruby.h
@@ -209,10 +209,11 @@ VALUE rb_newobj _((void));
RBASIC(obj)->flags = (t);\
if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
}
-#define CLONESETUP(clone,obj) {\
+#define CLONESETUP(clone,obj) do {\
OBJSETUP(clone,rb_singleton_class_clone(RBASIC(obj)->klass),RBASIC(obj)->flags);\
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\
-}
+ if (FL_TEST(obj, FL_EXIVAR)) rb_clone_generic_ivar((VALUE)clone,(VALUE)obj);\
+} while (0)
struct RBasic {
unsigned long flags;
diff --git a/variable.c b/variable.c
index c8ad22f4b1..23ae945870 100644
--- a/variable.c
+++ b/variable.c
@@ -717,11 +717,9 @@ generic_ivar_set(obj, id, val)
VALUE val;
{
st_table *tbl;
- int special = Qfalse;
if (rb_special_const_p(obj)) {
special_generic_ivar = 1;
- special = Qtrue;
}
if (!generic_iv_tbl) {
generic_iv_tbl = st_init_numtable();
@@ -771,27 +769,28 @@ generic_ivar_remove(obj, id)
return val;
}
-static int
-givar_mark_i(key, value)
- ID key;
- VALUE value;
-{
- rb_gc_mark(value);
- return ST_CONTINUE;
-}
-
void
rb_mark_generic_ivar(obj)
VALUE obj;
{
st_table *tbl;
+ if (!generic_iv_tbl) return;
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
rb_mark_tbl(tbl);
}
}
static int
+givar_mark_i(key, value)
+ ID key;
+ VALUE value;
+{
+ rb_gc_mark(value);
+ return ST_CONTINUE;
+}
+
+static int
givar_i(obj, tbl)
VALUE obj;
st_table *tbl;
@@ -805,8 +804,8 @@ givar_i(obj, tbl)
void
rb_mark_generic_ivar_tbl()
{
- if (special_generic_ivar == 0) return;
if (!generic_iv_tbl) return;
+ if (special_generic_ivar == 0) return;
st_foreach(generic_iv_tbl, givar_i, 0);
}
@@ -820,6 +819,18 @@ rb_free_generic_ivar(obj)
st_free_table(tbl);
}
+void
+rb_clone_generic_ivar(clone, obj)
+ VALUE clone, obj;
+{
+ st_table *tbl;
+
+ if (!generic_iv_tbl) return;
+ if (st_lookup(generic_iv_tbl, obj, &tbl)) {
+ st_add_direct(generic_iv_tbl, clone, st_copy(tbl));
+ }
+}
+
VALUE
rb_ivar_get(obj, id)
VALUE obj;