summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'class.c')
-rw-r--r--class.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/class.c b/class.c
index 2eedb262dc..b5caf3082a 100644
--- a/class.c
+++ b/class.c
@@ -33,16 +33,6 @@ rb_class_new(super)
return (VALUE)klass;
}
-VALUE
-rb_singleton_class_new(super)
- VALUE super;
-{
- VALUE klass = rb_class_new(super);
-
- FL_SET(klass, FL_SINGLETON);
- return klass;
-}
-
static int
clone_method(mid, body, tbl)
ID mid;
@@ -54,6 +44,47 @@ clone_method(mid, body, tbl)
}
VALUE
+rb_mod_clone(module)
+ VALUE module;
+{
+ NEWOBJ(clone, struct RClass);
+ CLONESETUP(clone, module);
+
+ clone->super = RCLASS(module)->super;
+ if (RCLASS(module)->iv_tbl) {
+ clone->iv_tbl = st_copy(RCLASS(module)->iv_tbl);
+ }
+ if (RCLASS(module)->m_tbl) {
+ clone->m_tbl = st_init_numtable();
+ st_foreach(RCLASS(module)->m_tbl, clone_method, clone->m_tbl);
+ }
+
+ return (VALUE)clone;
+}
+
+VALUE
+rb_mod_dup(mod)
+ VALUE mod;
+{
+ VALUE dup = rb_mod_clone(mod);
+ OBJSETUP(dup, RBASIC(mod)->klass, BUILTIN_TYPE(mod));
+ if (FL_TEST(mod, FL_SINGLETON)) {
+ FL_SET(dup, FL_SINGLETON);
+ }
+ return dup;
+}
+
+VALUE
+rb_singleton_class_new(super)
+ VALUE super;
+{
+ VALUE klass = rb_class_new(super);
+
+ FL_SET(klass, FL_SINGLETON);
+ return klass;
+}
+
+VALUE
rb_singleton_class_clone(klass)
VALUE klass;
{
@@ -67,6 +98,9 @@ rb_singleton_class_clone(klass)
clone->super = RCLASS(klass)->super;
clone->iv_tbl = 0;
clone->m_tbl = 0;
+ if (RCLASS(klass)->iv_tbl) {
+ clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
+ }
clone->m_tbl = st_init_numtable();
st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
FL_SET(clone, FL_SINGLETON);
@@ -78,8 +112,12 @@ void
rb_singleton_class_attached(klass, obj)
VALUE klass, obj;
{
- if (FL_TEST(klass, FL_SINGLETON))
- rb_iv_set(klass, "__attached__", obj);
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ if (!RCLASS(klass)->iv_tbl) {
+ RCLASS(klass)->iv_tbl = st_init_numtable();
+ }
+ st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
+ }
}
VALUE
@@ -217,7 +255,12 @@ rb_include_module(klass, module)
VALUE klass, module;
{
VALUE p;
+ int changed = 0;
+ rb_frozen_class_p(klass);
+ if (!OBJ_TAINTED(klass)) {
+ rb_secure(4);
+ }
if (NIL_P(module)) return;
if (klass == module) return;
@@ -238,16 +281,16 @@ rb_include_module(klass, module)
if (RCLASS(module)->super) {
rb_include_module(p, RCLASS(module)->super);
}
+ if (changed) rb_clear_cache();
return;
}
}
- rb_frozen_class_p(klass);
- RCLASS(klass)->super =
- include_class_new(module, RCLASS(klass)->super);
+ RCLASS(klass)->super = include_class_new(module, RCLASS(klass)->super);
klass = RCLASS(klass)->super;
module = RCLASS(module)->super;
+ changed = 1;
}
- rb_clear_cache();
+ if (changed) rb_clear_cache();
}
VALUE