[macruby-changes] [3002] MacRuby/trunk/variable.c
source_changes at macosforge.org
source_changes at macosforge.org
Fri Nov 13 00:08:24 PST 2009
Revision: 3002
http://trac.macosforge.org/projects/ruby/changeset/3002
Author: lsansonetti at apple.com
Date: 2009-11-13 00:08:20 -0800 (Fri, 13 Nov 2009)
Log Message:
-----------
fixed a const lookup bug where autoload variables in included modules wouldn't be taken into account + cleanup class variables
Modified Paths:
--------------
MacRuby/trunk/variable.c
Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c 2009-11-13 08:02:09 UTC (rev 3001)
+++ MacRuby/trunk/variable.c 2009-11-13 08:08:20 UTC (rev 3002)
@@ -841,25 +841,26 @@
static CFMutableDictionaryRef generic_iv_dict = NULL;
static VALUE
-generic_ivar_get(VALUE obj, ID id, int warn)
+generic_ivar_get(VALUE obj, ID id, bool warn, bool undef)
{
if (generic_iv_dict != NULL) {
CFDictionaryRef obj_dict;
if (CFDictionaryGetValueIfPresent(generic_iv_dict,
- (const void *)obj, (const void **)&obj_dict)
- && obj_dict != NULL) {
- VALUE val;
+ (const void *)obj, (const void **)&obj_dict)
+ && obj_dict != NULL) {
+ VALUE val;
if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id,
- (const void **)&val))
+ (const void **)&val)) {
return val;
+ }
}
}
if (warn) {
rb_warning("instance variable %s not initialized", rb_id2name(id));
}
- return Qnil;
+ return undef ? Qundef : Qnil;
}
static void
@@ -872,18 +873,20 @@
rb_error_frozen("object");
}
if (generic_iv_dict == NULL) {
- generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL, &rb_cfdictionary_value_cb);
+ generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &rb_cfdictionary_value_cb);
rb_objc_retain(generic_iv_dict);
obj_dict = NULL;
}
else {
obj_dict = (CFMutableDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)generic_iv_dict, (const void *)obj);
+ (CFDictionaryRef)generic_iv_dict, (const void *)obj);
}
if (obj_dict == NULL) {
- obj_dict = CFDictionaryCreateMutable(NULL, 0, NULL, &rb_cfdictionary_value_cb);
+ obj_dict = CFDictionaryCreateMutable(NULL, 0, NULL,
+ &rb_cfdictionary_value_cb);
CFDictionarySetValue(generic_iv_dict, (const void *)obj,
- (const void *)obj_dict);
+ (const void *)obj_dict);
CFMakeCollectable(obj_dict);
}
CFDictionarySetValue(obj_dict, (const void *)id, (const void *)val);
@@ -895,10 +898,12 @@
CFMutableDictionaryRef obj_dict;
if (generic_iv_dict != NULL
- && CFDictionaryGetValueIfPresent((CFDictionaryRef)generic_iv_dict,
- (const void *)obj, (const void **)&obj_dict) && obj_dict != NULL) {
- if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id, NULL))
+ && CFDictionaryGetValueIfPresent((CFDictionaryRef)generic_iv_dict,
+ (const void *)obj, (const void **)&obj_dict)
+ && obj_dict != NULL) {
+ if (CFDictionaryGetValueIfPresent(obj_dict, (const void *)id, NULL)) {
return Qtrue;
+ }
}
return Qfalse;
}
@@ -1027,7 +1032,7 @@
}
static VALUE
-ivar_get(VALUE obj, ID id, int warn)
+ivar_get(VALUE obj, ID id, bool warn, bool undef)
{
VALUE val;
@@ -1072,27 +1077,25 @@
break;
case T_NATIVE:
- return generic_ivar_get(obj, id, warn);
-
default:
- return generic_ivar_get(obj, id, warn);
+ return generic_ivar_get(obj, id, warn, undef);
}
if (warn) {
rb_warning("instance variable %s not initialized", rb_id2name(id));
}
- return Qnil;
+ return undef ? Qundef : Qnil;
}
VALUE
rb_ivar_get(VALUE obj, ID id)
{
- return ivar_get(obj, id, Qtrue);
+ return ivar_get(obj, id, true, false);
}
VALUE
rb_attr_get(VALUE obj, ID id)
{
- return ivar_get(obj, id, Qfalse);
+ return ivar_get(obj, id, false, false);
}
VALUE
@@ -1138,9 +1141,6 @@
break;
case T_NATIVE:
- generic_ivar_set(obj, id, val);
- break;
-
default:
generic_ivar_set(obj, id, val);
break;
@@ -1443,7 +1443,9 @@
fn = rb_str_new2(file);
rb_obj_untaint(fn);
OBJ_FREEZE(fn);
- st_insert(tbl, id, (st_data_t)rb_node_newnode(NODE_MEMO, fn, rb_safe_level(), 0));
+ NODE *n = rb_node_newnode(NODE_MEMO, fn, rb_safe_level(), 0);
+ GC_RELEASE(n);
+ st_insert(tbl, id, (st_data_t)n);
}
static NODE*
@@ -1557,13 +1559,16 @@
int mod_retry = 0;
tmp = klass;
- retry:
+retry:
while (RTEST(tmp)) {
CFDictionaryRef iv_dict;
while ((iv_dict = rb_class_ivar_dict(tmp)) != NULL
- && CFDictionaryGetValueIfPresent(iv_dict, (const void *)id, (const void **)&value)) {
+ && CFDictionaryGetValueIfPresent(iv_dict, (const void *)id,
+ (const void **)&value)) {
if (value == Qundef) {
- if (!RTEST(rb_autoload_load(tmp, id))) break;
+ if (!RTEST(rb_autoload_load(tmp, id))) {
+ break;
+ }
continue;
}
if (exclude && tmp == rb_cObject && klass != rb_cObject) {
@@ -1573,14 +1578,25 @@
value = rb_vm_resolve_const_value(value, klass, id);
return value;
}
- if (!recurse && klass != rb_cObject) break;
+ if (!recurse && klass != rb_cObject) {
+ break;
+ }
VALUE inc_mods = rb_attr_get(tmp, idIncludedModules);
if (inc_mods != Qnil) {
int i, count = RARRAY_LEN(inc_mods);
for (i = 0; i < count; i++) {
- iv_dict = rb_class_ivar_dict(RARRAY_AT(inc_mods, i));
- if (CFDictionaryGetValueIfPresent(iv_dict, (const void *)id, (const void **)&value))
+ VALUE mod = RARRAY_AT(inc_mods, i);
+ iv_dict = rb_class_ivar_dict(mod);
+ if (CFDictionaryGetValueIfPresent(iv_dict, (const void *)id,
+ (const void **)&value)) {
+ if (value == Qundef) {
+ if (!RTEST(rb_autoload_load(mod, id))) {
+ break;
+ }
+ continue;
+ }
return rb_vm_resolve_const_value(value, klass, id);
+ }
}
}
tmp = RCLASS_SUPER(tmp);
@@ -1886,106 +1902,39 @@
rb_define_const(rb_cObject, name, val);
}
-static VALUE
-original_module(VALUE c)
+static inline VALUE
+unmeta_class(VALUE klass)
{
- if (TYPE(c) == T_ICLASS)
- return RBASIC(c)->klass;
- return c;
+ if (RCLASS_META(klass)) {
+ klass = (VALUE)objc_getClass(class_getName((Class)klass));
+ }
+ return klass;
}
-#define IV_LOOKUP(k,i,v) ((iv_dict = rb_class_ivar_dict(k)) != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)i, (const void **)(v)))
-
-#define CVAR_LOOKUP(v,r) do {\
- if (IV_LOOKUP(klass, id, v)) {\
- r;\
- }\
- if (RCLASS_SINGLETON(klass)) {\
- VALUE obj = rb_iv_get(klass, "__attached__");\
- switch (TYPE(obj)) {\
- case T_MODULE:\
- case T_CLASS:\
- klass = obj;\
- break;\
- default:\
- klass = RCLASS_SUPER(klass);\
- break;\
- }\
- }\
- else {\
- klass = RCLASS_SUPER(klass);\
- }\
- while (klass) {\
- if (IV_LOOKUP(klass, id, v)) {\
- r;\
- }\
- klass = RCLASS_SUPER(klass);\
- }\
-} while(0)
-
void
rb_cvar_set(VALUE klass, ID id, VALUE val)
{
- VALUE tmp, front = 0, target = 0;
- CFMutableDictionaryRef iv_dict;
-
- tmp = klass;
- if (!RCLASS_META(klass)) {
- tmp = klass = *(VALUE *)klass;
+ if (RCLASS_META(klass)) {
+ klass = (VALUE)objc_getClass(class_getName((Class)klass));
}
- CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
- if (target) {
- if (front && target != front) {
- ID did = id;
-
- if (RTEST(ruby_verbose)) {
- rb_warning("class variable %s of %s is overtaken by %s",
- rb_id2name(id), rb_class2name(original_module(front)),
- rb_class2name(original_module(target)));
- }
- if (TYPE(front) == T_CLASS) {
- CFDictionaryRemoveValue(rb_class_ivar_dict(front), (const void *)did);
- }
- }
- }
- else {
- target = tmp;
- }
- mod_av_set(target, id, val, Qfalse);
+ rb_ivar_set(klass, id, val);
}
VALUE
rb_cvar_get2(VALUE klass, ID id, bool check)
{
- VALUE value, tmp, front = 0, target = 0;
- CFMutableDictionaryRef iv_dict;
-
- tmp = klass;
- if (!RCLASS_META(klass)) {
- tmp = klass = *(VALUE *)klass;
- }
- CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
- if (!target) {
+ VALUE orig = klass;
+ klass = unmeta_class(klass);
+ VALUE value = ivar_get(klass, id, false, true);
+ if (value == Qundef) {
if (check) {
rb_name_error(id,"uninitialized class variable %s in %s",
- rb_id2name(id), rb_class2name(tmp));
+ rb_id2name(id), rb_class2name(orig));
}
else {
return Qnil;
}
}
- if (front && target != front) {
- ID did = id;
-
- if (RTEST(ruby_verbose)) {
- rb_warning("class variable %s of %s is overtaken by %s",
- rb_id2name(id), rb_class2name(original_module(front)),
- rb_class2name(original_module(target)));
- }
- if (BUILTIN_TYPE(front) == T_CLASS) {
- CFDictionaryRemoveValue(rb_class_ivar_dict(front), (const void *)did);
- }
- }
return value;
}
@@ -1998,15 +1947,8 @@
VALUE
rb_cvar_defined(VALUE klass, ID id)
{
- CFMutableDictionaryRef iv_dict;
- if (!klass) {
- return Qfalse;
- }
- if (!RCLASS_META(klass)) {
- klass = *(VALUE *)klass;
- }
- CVAR_LOOKUP(0,return Qtrue);
- return Qfalse;
+ klass = unmeta_class(klass);
+ return ivar_get(klass, id, false, true) == Qundef ? Qfalse : Qtrue;
}
void
@@ -2069,13 +2011,11 @@
*/
VALUE
-rb_mod_class_variables(VALUE obj, SEL sel)
+rb_mod_class_variables(VALUE klass, SEL sel)
{
- if (!RCLASS_META(obj)) {
- obj = *(VALUE *)obj;
- }
+ klass = unmeta_class(klass);
VALUE ary = rb_ary_new();
- CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+ CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(klass);
if (iv_dict != NULL) {
ivar_dict_foreach((VALUE)iv_dict, cv_i, (VALUE)ary);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091113/b1bf0793/attachment-0001.html>
More information about the macruby-changes
mailing list