Permalink
Browse files

fix regressions in module #dup/#clone, minor coding style cleanups

  • Loading branch information...
Laurent Sansonetti
Laurent Sansonetti committed Jun 27, 2011
1 parent 39b9c3b commit 97de43e5592b329c4f635fb2517524ec5551385d
Showing with 107 additions and 130 deletions.
  1. +51 −48 class.c
  2. +1 −1 class.h
  3. +3 −31 object.c
  4. +52 −50 variable.c
View
99 class.c
@@ -265,56 +265,62 @@ rb_class_new(VALUE super)
}
/* :nodoc: */
+
+extern ID id_classid, id_classpath;
+
VALUE
rb_mod_init_copy(VALUE clone, SEL sel, VALUE orig)
{
- static ID classpath = 0;
- static ID classid = 0;
-
rb_obj_init_copy(clone, 0, orig);
- {
- VALUE super;
- unsigned long version_flag;
-
- if (!RCLASS_RUBY(orig)) {
- super = orig;
- rb_warn("cloning class `%s' is not supported, creating a " \
- "subclass instead", rb_class2name(orig));
- }
- else {
- super = RCLASS_SUPER(orig);
- }
- RCLASS_SET_SUPER(clone, super);
- version_flag = RCLASS_IS_RUBY_CLASS;
- if ((RCLASS_VERSION(super) & RCLASS_IS_OBJECT_SUBCLASS) == RCLASS_IS_OBJECT_SUBCLASS) {
- version_flag |= RCLASS_IS_OBJECT_SUBCLASS;
- }
+ VALUE super;
+ if (!RCLASS_RUBY(orig)) {
+ super = orig;
+ rb_warn("cloning class `%s' is not supported, creating a " \
+ "subclass instead", rb_class2name(orig));
+ }
+ else {
+ super = RCLASS_SUPER(orig);
+ }
+ RCLASS_SET_SUPER(clone, super);
- RCLASS_SET_VERSION(clone, version_flag);
+ // Copy flags.
+ unsigned long version_flag = RCLASS_IS_RUBY_CLASS;
+ if ((RCLASS_VERSION(super) & RCLASS_IS_OBJECT_SUBCLASS)
+ == RCLASS_IS_OBJECT_SUBCLASS) {
+ version_flag |= RCLASS_IS_OBJECT_SUBCLASS;
+ }
+ if (RCLASS_MODULE(orig)) {
+ version_flag |= RCLASS_IS_MODULE;
+ }
+ RCLASS_SET_VERSION(clone, version_flag);
+ if (!class_isMetaClass((Class)clone)) {
+ // Clear type info.
+ RCLASS_SET_VERSION(*(Class *)clone, RCLASS_VERSION(*(Class *)clone));
+ }
- rb_vm_copy_methods((Class)orig, (Class)clone);
- CFMutableDictionaryRef ivar_dict = rb_class_ivar_dict(orig);
- if (ivar_dict != NULL) {
- CFMutableDictionaryRef cloned_ivar_dict;
+ // Copy methods.
+ rb_vm_copy_methods((Class)orig, (Class)clone);
+ if (!class_isMetaClass((Class)orig)) {
+ rb_vm_copy_methods(*(Class *)orig, *(Class *)clone);
+ }
- if (classpath == 0) {
- classpath = rb_intern("__classpath__");
- }
- if (classid == 0) {
- classid = rb_intern("__classid__");
- }
- cloned_ivar_dict = CFDictionaryCreateMutableCopy(NULL, 0,
- (CFDictionaryRef)ivar_dict);
- // Remove the classpath & classid (name) so that they are not
- // copied over the new module / class
- CFDictionaryRemoveValue(cloned_ivar_dict, (const void *)classpath);
- CFDictionaryRemoveValue(cloned_ivar_dict, (const void *)classid);
- CFMakeCollectable(cloned_ivar_dict);
- rb_class_ivar_set_dict(clone, cloned_ivar_dict);
- }
+ // Copy ivars.
+ CFMutableDictionaryRef orig_dict = rb_class_ivar_dict(orig);
+ CFMutableDictionaryRef clone_dict;
+ if (orig_dict != NULL) {
+ clone_dict = CFDictionaryCreateMutableCopy(NULL, 0, orig_dict);
+ rb_class_ivar_set_dict(clone, clone_dict);
+ CFMakeCollectable(clone_dict);
+ }
+ else {
+ clone_dict = rb_class_ivar_dict_or_create(clone);
}
+ // Remove the classpath & classid (name) so that they are not
+ // copied over the new module / class.
+ CFDictionaryRemoveValue(clone_dict, (const void *)id_classpath);
+ CFDictionaryRemoveValue(clone_dict, (const void *)id_classid);
return clone;
}
@@ -595,21 +601,18 @@ rb_define_module(const char *name)
VALUE
rb_define_module_under(VALUE outer, const char *name)
{
- VALUE module;
- ID id;
-
- id = rb_intern(name);
+ ID id = rb_intern(name);
if (rb_const_defined_at(outer, id)) {
- module = rb_const_get_at(outer, id);
- if (TYPE(module) == T_MODULE)
+ VALUE module = rb_const_get_at(outer, id);
+ if (TYPE(module) == T_MODULE) {
return module;
+ }
rb_raise(rb_eTypeError, "%s::%s:%s is not a module",
rb_class2name(outer), name, rb_obj_classname(module));
}
- module = rb_define_module_id(id);
+ VALUE module = rb_define_module_id(id);
rb_const_set(outer, id, module);
rb_set_class_path(module, outer, name);
-
return module;
}
View
@@ -116,7 +116,7 @@ rb_class_get_flags(Class k)
static inline void
rb_class_set_flags(Class k, unsigned long flags)
{
- rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT);
+ rb_class_set_mask(k, (flags << RCLASS_MASK_TYPE_SHIFT) | 0);
}
#define RCLASS_VERSION(m) (rb_class_get_flags((Class)m))
View
@@ -216,28 +216,6 @@ init_copy(VALUE dest, VALUE obj)
}
ROBJECT(dest)->num_slots = ROBJECT(obj)->num_slots;
break;
-
- case T_CLASS:
- case T_MODULE:
- {
- CFMutableDictionaryRef dest_dict = rb_class_ivar_dict(dest);
- if (dest_dict != NULL) {
- CFDictionaryRemoveAllValues(dest_dict);
- }
- CFMutableDictionaryRef obj_dict = rb_class_ivar_dict(obj);
- if (obj_dict != NULL) {
- dest_dict = CFDictionaryCreateMutableCopy(NULL, 0,
- (CFDictionaryRef)obj_dict);
- CFMakeCollectable(dest_dict);
- rb_class_ivar_set_dict(dest, dest_dict);
- }
- else {
- if (dest_dict) {
- rb_class_ivar_set_dict(dest, NULL);
- }
- }
- }
- break;
}
rb_vm_call(dest, selInitializeCopy, 1, &obj);
@@ -379,14 +357,7 @@ rb_obj_init_copy(VALUE obj, SEL sel, VALUE orig)
static VALUE
rb_nsobj_dup(VALUE obj, VALUE sel)
{
- VALUE klass = rb_class_real(CLASS_OF(obj), true);
- if (class_respondsToSelector((Class)klass, selCopyWithZone)) {
- return (VALUE)objc_msgSend((id)obj, selCopy);
- }
-
- VALUE copy = rb_vm_new_rb_object(klass);
- rb_obj_init_copy(copy, 0, (VALUE)obj);
- return copy;
+ return rb_obj_dup(obj);
}
/*
@@ -1989,7 +1960,8 @@ rb_obj_alloc0(VALUE klass)
rb_raise(rb_eTypeError, "can't create instance of singleton class");
}
- if ((RCLASS_VERSION(*(void **)klass) & RCLASS_HAS_ROBJECT_ALLOC) == RCLASS_HAS_ROBJECT_ALLOC) {
+ if ((RCLASS_VERSION(*(void **)klass) & RCLASS_HAS_ROBJECT_ALLOC)
+ == RCLASS_HAS_ROBJECT_ALLOC) {
// Fast path!
return rb_vm_new_rb_object(klass);
}
Oops, something went wrong.

0 comments on commit 97de43e

Please sign in to comment.