Created
April 23, 2011 23:48
-
-
Save lrz/939092 to your computer and use it in GitHub Desktop.
Fix for #1238 and #1240 (work in progress)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/class.c b/class.c | |
index 8b18f71..e411aeb 100644 | |
--- a/class.c | |
+++ b/class.c | |
@@ -23,6 +23,27 @@ | |
extern st_table *rb_class_tbl; | |
extern VALUE rb_cRubyObject; | |
+VALUE | |
+rb_class_super(VALUE klass) | |
+{ | |
+ if (klass == 0 || RCLASS_MODULE(klass)) { | |
+ return 0; | |
+ } | |
+ return (VALUE)class_getSuperclass((Class)klass); | |
+} | |
+ | |
+void | |
+rb_class_set_super(VALUE klass, VALUE super) | |
+{ | |
+ class_setSuperclass((Class)klass, (Class)super); | |
+} | |
+ | |
+int | |
+rb_class_ismeta(VALUE klass) | |
+{ | |
+ return class_isMetaClass((Class)klass); | |
+} | |
+ | |
void | |
rb_objc_class_sync_version(Class ocklass, Class ocsuper) | |
{ | |
@@ -153,11 +174,7 @@ rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass) | |
goto no_more_classes; | |
} | |
- if (super == 0) { | |
- super = rb_cObject; | |
- } | |
- | |
- Class ocklass = objc_allocateClassPair((Class)super, ocname, sizeof(id)); | |
+ Class ocklass = objc_allocateClassPair((Class)super, ocname, 0); | |
if (ocklass == NULL) { | |
goto no_more_classes; | |
} | |
@@ -170,7 +187,7 @@ rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass) | |
objc_registerClassPair(ocklass); | |
- if (klass != 0) { | |
+ if (klass != 0 && super != 0) { | |
rb_objc_class_sync_version(ocklass, (Class)super); | |
} | |
@@ -183,6 +200,9 @@ no_more_classes: | |
VALUE | |
rb_objc_create_class(const char *name, VALUE super) | |
{ | |
+ if (super == 0) { | |
+ super = rb_cObject; | |
+ } | |
VALUE klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass); | |
if (super != rb_cNSObject && super != 0 | |
@@ -503,12 +523,11 @@ rb_define_module_id(ID id) | |
{ | |
VALUE mdl = rb_objc_alloc_class(id == 0 ? NULL : rb_id2name(id), | |
rb_cObject, T_MODULE, rb_cModule); | |
- | |
- if ((rb_mKernel != 0) && (id == 0)) { | |
- /* because Module#initialize can accept a block */ | |
- rb_objc_define_method(*(VALUE *)mdl, "initialize", rb_mod_initialize, 0); | |
+ if (rb_mKernel != 0 && id == 0) { | |
+ // Because Module#initialize can accept a block. | |
+ rb_objc_define_method(*(VALUE *)mdl, "initialize", | |
+ rb_mod_initialize, 0); | |
} | |
- | |
return mdl; | |
} | |
@@ -825,7 +844,7 @@ class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (VALUE, | |
if (recur == Qfalse) { | |
break; | |
} | |
- mod = (VALUE)class_getSuperclass((Class)mod); | |
+ mod = RCLASS_SUPER(mod); | |
} | |
return ary; | |
diff --git a/eval.c b/eval.c | |
index 28bcd79..481589f 100644 | |
--- a/eval.c | |
+++ b/eval.c | |
@@ -588,7 +588,7 @@ rb_mod_append_features(VALUE module, SEL sel, VALUE include) | |
} | |
m = RCLASS_SUPER(m); | |
} | |
- while (m == 0 || RCLASS_SINGLETON(m)); | |
+ while (m != 0 && RCLASS_SINGLETON(m)); | |
return module; | |
} | |
@@ -647,7 +647,7 @@ rb_extend_object(VALUE obj, VALUE module) | |
} | |
m = RCLASS_SUPER(m); | |
} | |
- while (m == 0 || RCLASS_SINGLETON(m)); | |
+ while (m != 0 && RCLASS_SINGLETON(m)); | |
} | |
/* | |
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h | |
index ad7b1cb..8ca9f4b 100644 | |
--- a/include/ruby/ruby.h | |
+++ b/include/ruby/ruby.h | |
@@ -428,9 +428,12 @@ struct RBasic { | |
VALUE flags; | |
}; | |
-#define RCLASS_SUPER(m) ((VALUE)class_getSuperclass((Class)m)) | |
-#define RCLASS_SET_SUPER(m, s) (class_setSuperclass((Class)m, (Class)s)) | |
-#define RCLASS_META(m) (class_isMetaClass((Class)m)) | |
+VALUE rb_class_super(VALUE klass); | |
+void rb_class_set_super(VALUE klass, VALUE super); | |
+int rb_class_ismeta(VALUE klass); | |
+#define RCLASS_SUPER(m) (rb_class_super((VALUE)m)) | |
+#define RCLASS_SET_SUPER(m, s) (rb_class_set_super((VALUE)m, (VALUE)s)) | |
+#define RCLASS_META(m) (rb_class_ismeta((VALUE)m)) | |
#define RFLOAT_VALUE(v) FIXFLOAT2DBL(v) | |
#define DOUBLE2NUM(dbl) rb_float_new(dbl) | |
diff --git a/variable.c b/variable.c | |
index 3f1dac5..62f9780 100644 | |
--- a/variable.c | |
+++ b/variable.c | |
@@ -933,43 +933,16 @@ rb_copy_generic_ivar(VALUE clone, VALUE obj) | |
} | |
} | |
-static inline bool | |
-rb_class_has_ivar_dict(VALUE mod) | |
-{ | |
- const long v = RCLASS_VERSION(mod); | |
- return (v & RCLASS_IS_RUBY_CLASS) == RCLASS_IS_RUBY_CLASS | |
- && (v & RCLASS_KVO_CHECK_DONE) != RCLASS_KVO_CHECK_DONE; | |
-} | |
- | |
-#define RCLASS_RUBY_IVAR_DICT(mod) \ | |
- (*(CFMutableDictionaryRef *) \ | |
- ((void *)mod + class_getInstanceSize(*(Class *)RCLASS_SUPER(mod)))) | |
- | |
CFMutableDictionaryRef | |
rb_class_ivar_dict(VALUE mod) | |
{ | |
- if (rb_class_has_ivar_dict(mod)) { | |
- return RCLASS_RUBY_IVAR_DICT(mod); | |
- } | |
return generic_ivar_dict(mod, false); | |
} | |
void | |
rb_class_ivar_set_dict(VALUE mod, CFMutableDictionaryRef dict) | |
{ | |
- if (rb_class_has_ivar_dict(mod)) { | |
- CFMutableDictionaryRef old_dict = RCLASS_RUBY_IVAR_DICT(mod); | |
- if (old_dict != dict) { | |
- if (old_dict != NULL) { | |
- GC_RELEASE(old_dict); | |
- } | |
- GC_RETAIN(dict); | |
- RCLASS_RUBY_IVAR_DICT(mod) = dict; | |
- } | |
- } | |
- else { | |
- generic_ivar_dict_set(mod, dict); | |
- } | |
+ generic_ivar_dict_set(mod, dict); | |
} | |
CFMutableDictionaryRef | |
@@ -1508,7 +1481,7 @@ retry: | |
} | |
tmp = RCLASS_SUPER(tmp); | |
} | |
- if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) { | |
+ if (!exclude && !mod_retry && RCLASS_MODULE(klass)) { | |
mod_retry = 1; | |
tmp = rb_cObject; | |
goto retry; | |
@@ -1713,7 +1686,7 @@ rb_const_defined_0(VALUE klass, ID id, int exclude, int recurse) | |
} | |
tmp = RCLASS_SUPER(tmp); | |
} | |
- if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) { | |
+ if (!exclude && !mod_retry && RCLASS_MODULE(klass)) { | |
mod_retry = 1; | |
tmp = rb_cObject; | |
goto retry; | |
@@ -1752,7 +1725,7 @@ mod_av_set(VALUE klass, ID id, VALUE val, int isconst) | |
rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest); | |
} | |
if (OBJ_FROZEN(klass)) { | |
- if (BUILTIN_TYPE(klass) == T_MODULE) { | |
+ if (TYPE(klass) == T_MODULE) { | |
rb_error_frozen("module"); | |
} | |
else { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment