~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to variable.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
  variable.c -
4
4
 
5
5
  $Author: matz $
6
 
  $Date: 2007-08-25 12:29:39 +0900 (土, 25  8月 2007) $
 
6
  $Date: 2007-12-25 01:38:44 +0900 (Tue, 25 Dec 2007) $
7
7
  created at: Tue Apr 19 23:55:15 JST 1994
8
8
 
9
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
45
45
{
46
46
    VALUE path, tmp;
47
47
 
48
 
    path = rb_str_new2(rb_id2name(name));
 
48
    path = rb_str_dup(rb_id2str(name));
49
49
    while (fc) {
50
50
        if (fc->track == rb_cObject) break;
51
 
        if (ROBJECT(fc->track)->iv_tbl &&
52
 
            st_lookup(ROBJECT(fc->track)->iv_tbl, classpath, &tmp)) {
 
51
        if (RCLASS_IV_TBL(fc->track) &&
 
52
            st_lookup(RCLASS_IV_TBL(fc->track), classpath, &tmp)) {
53
53
            tmp = rb_str_dup(tmp);
54
54
            rb_str_cat2(tmp, "::");
55
55
            rb_str_append(tmp, path);
56
56
            path = tmp;
57
57
            break;
58
58
        }
59
 
        tmp = rb_str_new2(rb_id2name(fc->name));
 
59
        tmp = rb_str_dup(rb_id2str(fc->name));
60
60
        rb_str_cat2(tmp, "::");
61
61
        rb_str_append(tmp, path);
62
62
        path = tmp;
78
78
    switch (TYPE(value)) {
79
79
      case T_MODULE:
80
80
      case T_CLASS:
81
 
        if (!RCLASS(value)->iv_tbl) return ST_CONTINUE;
 
81
        if (!RCLASS_IV_TBL(value)) return ST_CONTINUE;
82
82
        else {
83
83
            struct fc_result arg;
84
84
            struct fc_result *list;
94
94
            arg.klass = res->klass;
95
95
            arg.track = value;
96
96
            arg.prev = res;
97
 
            st_foreach(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
 
97
            st_foreach(RCLASS_IV_TBL(value), fc_i, (st_data_t)&arg);
98
98
            if (arg.path) {
99
99
                res->path = arg.path;
100
100
                return ST_STOP;
118
118
    arg.klass = klass;
119
119
    arg.track = rb_cObject;
120
120
    arg.prev = 0;
121
 
    if (RCLASS(rb_cObject)->iv_tbl) {
122
 
        st_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
 
121
    if (RCLASS_IV_TBL(rb_cObject)) {
 
122
        st_foreach_safe(RCLASS_IV_TBL(rb_cObject), fc_i, (st_data_t)&arg);
123
123
    }
124
124
    if (arg.path == 0) {
125
125
        st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
126
126
    }
127
127
    if (arg.path) {
128
 
        if (!ROBJECT(klass)->iv_tbl) {
129
 
            ROBJECT(klass)->iv_tbl = st_init_numtable();
 
128
        if (!RCLASS_IV_TBL(klass)) {
 
129
            RCLASS_IV_TBL(klass) = st_init_numtable();
130
130
        }
131
 
        st_insert(ROBJECT(klass)->iv_tbl, classpath, arg.path);
132
 
        st_delete(RCLASS(klass)->iv_tbl, &tmp_classpath, 0);
 
131
        st_insert(RCLASS_IV_TBL(klass), classpath, arg.path);
 
132
        st_delete(RCLASS_IV_TBL(klass), &tmp_classpath, 0);
133
133
        return arg.path;
134
134
    }
135
135
    return Qnil;
141
141
    VALUE path = Qnil;
142
142
 
143
143
    if (!klass) klass = rb_cObject;
144
 
    if (ROBJECT(klass)->iv_tbl) {
145
 
        if (!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {
 
144
    if (RCLASS_IV_TBL(klass)) {
 
145
        if (!st_lookup(RCLASS_IV_TBL(klass), classpath, &path)) {
146
146
            ID classid = rb_intern("__classid__");
147
147
 
148
 
            if (!st_lookup(ROBJECT(klass)->iv_tbl, classid, &path)) {
 
148
            if (!st_lookup(RCLASS_IV_TBL(klass), classid, &path)) {
149
149
                return find_class_path(klass);
150
150
            }
151
 
            path = rb_str_new2(rb_id2name(SYM2ID(path)));
 
151
            path = rb_str_dup(rb_id2str(SYM2ID(path)));
152
152
            OBJ_FREEZE(path);
153
 
            st_insert(ROBJECT(klass)->iv_tbl, classpath, path);
154
 
            st_delete(RCLASS(klass)->iv_tbl, (st_data_t*)&classid, 0);
 
153
            st_insert(RCLASS_IV_TBL(klass), classpath, path);
 
154
            st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&classid, 0);
155
155
        }
156
156
        if (TYPE(path) != T_STRING) {
157
157
            rb_bug("class path is not set properly");
183
183
    VALUE path = classname(klass);
184
184
 
185
185
    if (!NIL_P(path)) return path;
186
 
    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,
 
186
    if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
187
187
                                           tmp_classpath, &path)) {
188
188
        return path;
189
189
    }
716
716
{
717
717
    VALUE ary = rb_ary_new();
718
718
    char buf[4];
719
 
    const char *s = "&`'+123456789";
 
719
    const char *s = "123456789";
720
720
 
721
721
    st_foreach_safe(rb_global_tbl, gvar_i, ary);
722
 
    if (!NIL_P(rb_backref_get())) {
723
 
        while (*s) {
724
 
            sprintf(buf, "$%c", *s++);
725
 
            rb_ary_push(ary, rb_str_new2(buf));
726
 
        }
 
722
    while (*s) {
 
723
        sprintf(buf, "$%c", *s++);
 
724
        rb_ary_push(ary, ID2SYM(rb_intern(buf)));
727
725
    }
728
726
    return ary;
729
727
}
806
804
    st_data_t data;
807
805
 
808
806
    if (rb_special_const_p(obj)) {
 
807
        if (rb_obj_frozen_p(obj)) rb_error_frozen("object");
809
808
        special_generic_ivar = 1;
810
809
    }
811
810
    if (!generic_iv_tbl) {
812
811
        generic_iv_tbl = st_init_numtable();
813
812
    }
814
 
 
815
813
    if (!st_lookup(generic_iv_tbl, obj, &data)) {
816
814
        FL_SET(obj, FL_EXIVAR);
817
815
        tbl = st_init_numtable();
907
905
    st_data_t data;
908
906
 
909
907
    if (!generic_iv_tbl) return;
910
 
    if (!FL_TEST(obj, FL_EXIVAR)) return;
 
908
    if (!FL_TEST(obj, FL_EXIVAR)) {
 
909
clear:
 
910
        if (FL_TEST(clone, FL_EXIVAR)) {
 
911
            rb_free_generic_ivar(clone);
 
912
            FL_UNSET(clone, FL_EXIVAR);
 
913
        }
 
914
        return;
 
915
    }
911
916
    if (st_lookup(generic_iv_tbl, obj, &data)) {
912
917
        st_table *tbl = (st_table *)data;
913
918
 
 
919
        if (tbl->num_entries == 0)
 
920
            goto clear;
 
921
 
914
922
        if (st_lookup(generic_iv_tbl, clone, &data)) {
915
923
            st_free_table((st_table *)data);
916
924
            st_insert(generic_iv_tbl, clone, (st_data_t)st_copy(tbl));
926
934
ivar_get(VALUE obj, ID id, int warn)
927
935
{
928
936
    VALUE val;
 
937
    VALUE klass;
 
938
    st_data_t index;
929
939
 
930
940
    switch (TYPE(obj)) {
931
941
      case T_OBJECT:
 
942
        klass = rb_obj_class(obj);
 
943
        if (!RCLASS_IV_INDEX_TBL(klass)) break; 
 
944
        if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
 
945
        if (ROBJECT_LEN(obj) <= index) break;
 
946
        val = ROBJECT_PTR(obj)[index];
 
947
        if (val != Qundef)
 
948
            return val;
 
949
        break;
932
950
      case T_CLASS:
933
951
      case T_MODULE:
934
 
        if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
 
952
        if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, &val))
935
953
            return val;
936
954
        break;
937
955
      default:
960
978
VALUE
961
979
rb_ivar_set(VALUE obj, ID id, VALUE val)
962
980
{
 
981
    VALUE klass;
 
982
    st_data_t index;
 
983
    long i, len;
 
984
    int ivar_extended;
 
985
 
963
986
    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
964
987
        rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
965
988
    if (OBJ_FROZEN(obj)) rb_error_frozen("object");
966
989
    switch (TYPE(obj)) {
967
990
      case T_OBJECT:
 
991
        klass = rb_obj_class(obj);
 
992
        if (!RCLASS_IV_INDEX_TBL(klass))
 
993
            RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
 
994
        ivar_extended = 0;
 
995
        if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) {
 
996
            index = RCLASS_IV_INDEX_TBL(klass)->num_entries;
 
997
            st_add_direct(RCLASS_IV_INDEX_TBL(klass), id, index);
 
998
            ivar_extended = 1;
 
999
        }
 
1000
        len = ROBJECT_LEN(obj);
 
1001
        if (len <= index) {
 
1002
            VALUE *ptr = ROBJECT_PTR(obj);
 
1003
            if (index < ROBJECT_EMBED_LEN_MAX) {
 
1004
                RBASIC(obj)->flags |= ROBJECT_EMBED;
 
1005
                ptr = ROBJECT(obj)->as.ary;
 
1006
                for (i = 0; i < ROBJECT_EMBED_LEN_MAX; i++) {
 
1007
                    ptr[i] = Qundef;
 
1008
                }
 
1009
            }
 
1010
            else {
 
1011
                VALUE *newptr;
 
1012
                long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */
 
1013
                if (!ivar_extended &&
 
1014
                    RCLASS_IV_INDEX_TBL(klass)->num_entries < newsize) {
 
1015
                    newsize = RCLASS_IV_INDEX_TBL(klass)->num_entries;
 
1016
                }
 
1017
                if (RBASIC(obj)->flags & ROBJECT_EMBED) {
 
1018
                    newptr = ALLOC_N(VALUE, newsize);
 
1019
                    MEMCPY(newptr, ptr, VALUE, len);
 
1020
                    RBASIC(obj)->flags &= ~ROBJECT_EMBED;
 
1021
                    ROBJECT(obj)->as.heap.ptr = newptr;
 
1022
                }
 
1023
                else {
 
1024
                    REALLOC_N(ROBJECT(obj)->as.heap.ptr, VALUE, newsize);
 
1025
                    newptr = ROBJECT(obj)->as.heap.ptr;
 
1026
                }
 
1027
                for (; len < newsize; len++)
 
1028
                    newptr[len] = Qundef;
 
1029
                ROBJECT(obj)->as.heap.len = newsize;
 
1030
            }
 
1031
        }
 
1032
        ROBJECT_PTR(obj)[index] = val;
 
1033
        break;
968
1034
      case T_CLASS:
969
1035
      case T_MODULE:
970
 
        if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
971
 
        st_insert(ROBJECT(obj)->iv_tbl, id, val);
972
 
        break;
 
1036
        if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
 
1037
        st_insert(RCLASS_IV_TBL(obj), id, val);
 
1038
        break;
973
1039
      default:
974
1040
        generic_ivar_set(obj, id, val);
975
1041
        break;
980
1046
VALUE
981
1047
rb_ivar_defined(VALUE obj, ID id)
982
1048
{
 
1049
    VALUE klass, val;
 
1050
    st_data_t index;
983
1051
    switch (TYPE(obj)) {
984
1052
      case T_OBJECT:
 
1053
        klass = rb_obj_class(obj);
 
1054
        if (!RCLASS_IV_INDEX_TBL(klass)) break; 
 
1055
        if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
 
1056
        if (ROBJECT_LEN(obj) <= index) break;
 
1057
        val = ROBJECT_PTR(obj)[index];
 
1058
        if (val != Qundef)
 
1059
            return Qtrue;
 
1060
        break;
985
1061
      case T_CLASS:
986
1062
      case T_MODULE:
987
 
        if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))
 
1063
        if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, 0))
988
1064
            return Qtrue;
989
1065
        break;
990
1066
      default:
995
1071
    return Qfalse;
996
1072
}
997
1073
 
998
 
static int
999
 
ivar_i(ID key, struct global_entry *entry, VALUE ary)
 
1074
struct obj_ivar_tag {
 
1075
    VALUE obj;
 
1076
    int (*func)(ID key, VALUE val, st_data_t arg);
 
1077
    st_data_t arg;
 
1078
};
 
1079
 
 
1080
static int
 
1081
obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data)
 
1082
{
 
1083
    if (index < ROBJECT_LEN(data->obj)) {
 
1084
        VALUE val = ROBJECT_PTR(data->obj)[index];
 
1085
        if (val != Qundef) {
 
1086
            return (data->func)(key, val, data->arg);
 
1087
        }
 
1088
    }
 
1089
    return ST_CONTINUE;
 
1090
}
 
1091
 
 
1092
static void
 
1093
obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 
1094
{
 
1095
    VALUE klass = rb_obj_class(obj);
 
1096
    st_table *tbl;
 
1097
    struct obj_ivar_tag data;
 
1098
 
 
1099
    tbl = RCLASS_IV_INDEX_TBL(klass);
 
1100
    if (!tbl)
 
1101
        return;
 
1102
 
 
1103
    data.obj = obj;
 
1104
    data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
 
1105
    data.arg = arg;
 
1106
 
 
1107
    st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
 
1108
}
 
1109
 
 
1110
void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 
1111
{
 
1112
    switch (TYPE(obj)) {
 
1113
      case T_OBJECT:
 
1114
        obj_ivar_each(obj, func, arg);
 
1115
        break;
 
1116
      case T_CLASS:
 
1117
      case T_MODULE:
 
1118
        if (RCLASS_IV_TBL(obj)) {
 
1119
            st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
 
1120
        }
 
1121
        break;
 
1122
      default:
 
1123
        if (!generic_iv_tbl) break;
 
1124
        if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
 
1125
            st_data_t tbl;
 
1126
 
 
1127
            if (st_lookup(generic_iv_tbl, obj, &tbl)) {
 
1128
                st_foreach_safe((st_table *)tbl, func, arg);
 
1129
            }
 
1130
        }
 
1131
        break;
 
1132
    }
 
1133
}
 
1134
 
 
1135
static int
 
1136
ivar_i(ID key, VALUE val, VALUE ary)
1000
1137
{
1001
1138
    if (rb_is_instance_id(key)) {
1002
1139
        rb_ary_push(ary, ID2SYM(key));
1027
1164
    VALUE ary;
1028
1165
 
1029
1166
    ary = rb_ary_new();
1030
 
    switch (TYPE(obj)) {
1031
 
      case T_OBJECT:
1032
 
      case T_CLASS:
1033
 
      case T_MODULE:
1034
 
        if (ROBJECT(obj)->iv_tbl) {
1035
 
            st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);
1036
 
        }
1037
 
        break;
1038
 
      default:
1039
 
        if (!generic_iv_tbl) break;
1040
 
        if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1041
 
            st_data_t tbl;
1042
 
 
1043
 
            if (st_lookup(generic_iv_tbl, obj, &tbl)) {
1044
 
                st_foreach_safe((st_table *)tbl, ivar_i, ary);
1045
 
            }
1046
 
        }
1047
 
        break;
1048
 
    }
 
1167
    rb_ivar_foreach(obj, ivar_i, ary);
1049
1168
    return ary;
1050
1169
}
1051
1170
 
1076
1195
{
1077
1196
    VALUE val = Qnil;
1078
1197
    ID id = rb_to_id(name);
 
1198
    VALUE klass;
 
1199
    st_data_t index;
1079
1200
 
1080
1201
    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
1081
1202
        rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
1086
1207
 
1087
1208
    switch (TYPE(obj)) {
1088
1209
      case T_OBJECT:
 
1210
        klass = rb_obj_class(obj);
 
1211
        if (!RCLASS_IV_INDEX_TBL(klass)) break; 
 
1212
        if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
 
1213
        if (ROBJECT_LEN(obj) <= index) break;
 
1214
        val = ROBJECT_PTR(obj)[index];
 
1215
        if (val != Qundef) {
 
1216
            ROBJECT_PTR(obj)[index] = Qundef;
 
1217
            return val;
 
1218
        }
 
1219
        break;
1089
1220
      case T_CLASS:
1090
1221
      case T_MODULE:
1091
 
        if (ROBJECT(obj)->iv_tbl && st_delete(ROBJECT(obj)->iv_tbl, (st_data_t*)&id, &val)) {
 
1222
        if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), (st_data_t*)&id, &val)) {
1092
1223
            return val;
1093
1224
        }
1094
1225
        break;
1166
1297
    Check_Type(av, T_DATA);
1167
1298
    if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
1168
1299
        RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {
1169
 
        rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(rb_inspect(av)));
 
1300
        VALUE desc = rb_inspect(av);
 
1301
        rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(desc));
1170
1302
    }
1171
1303
    return (struct st_table *)DATA_PTR(av);
1172
1304
}
1184
1316
        rb_raise(rb_eArgError, "empty file name");
1185
1317
    }
1186
1318
 
1187
 
    if ((tbl = RCLASS(mod)->iv_tbl) && st_lookup(tbl, id, &av) && av != Qundef)
 
1319
    if ((tbl = RCLASS_IV_TBL(mod)) && st_lookup(tbl, id, &av) && av != Qundef)
1188
1320
        return;
1189
1321
 
1190
1322
    rb_const_set(mod, id, Qundef);
1191
 
    tbl = RCLASS(mod)->iv_tbl;
 
1323
    tbl = RCLASS_IV_TBL(mod);
1192
1324
    if (st_lookup(tbl, autoload, &av)) {
1193
1325
        tbl = check_autoload_table(av);
1194
1326
    }
1209
1341
    VALUE val;
1210
1342
    st_data_t load = 0;
1211
1343
 
1212
 
    st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);
1213
 
    if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
 
1344
    st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, 0);
 
1345
    if (st_lookup(RCLASS_IV_TBL(mod), autoload, &val)) {
1214
1346
        struct st_table *tbl = check_autoload_table(val);
1215
1347
 
1216
1348
        st_delete(tbl, (st_data_t*)&id, &load);
1219
1351
            DATA_PTR(val) = 0;
1220
1352
            st_free_table(tbl);
1221
1353
            id = autoload;
1222
 
            if (st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val)) {
 
1354
            if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
1223
1355
                rb_gc_force_recycle(val);
1224
1356
            }
1225
1357
        }
1247
1379
    struct st_table *tbl;
1248
1380
    st_data_t load;
1249
1381
 
1250
 
    if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||
 
1382
    if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
1251
1383
        !(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &load)) {
1252
1384
        return Qnil;
1253
1385
    }
1266
1398
        DATA_PTR(val) = 0;
1267
1399
        st_free_table(tbl);
1268
1400
        id = autoload;
1269
 
        if (st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val)) {
 
1401
        if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
1270
1402
            rb_gc_force_recycle(val);
1271
1403
        }
1272
1404
    }
1276
1408
VALUE
1277
1409
rb_autoload_p(VALUE mod, ID id)
1278
1410
{
1279
 
    struct st_table *tbl = RCLASS(mod)->iv_tbl;
 
1411
    struct st_table *tbl = RCLASS_IV_TBL(mod);
1280
1412
    VALUE val;
1281
1413
 
1282
1414
    if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {
1294
1426
    tmp = klass;
1295
1427
  retry:
1296
1428
    while (tmp && !NIL_P(tmp)) {
1297
 
        while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
 
1429
        while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp),id,&value)) {
1298
1430
            if (value == Qundef) {
1299
1431
                if (!RTEST(rb_autoload_load(tmp, id))) break;
1300
1432
                continue;
1306
1438
            return value;
1307
1439
        }
1308
1440
        if (!recurse && klass != rb_cObject) break;
1309
 
        tmp = RCLASS(tmp)->super;
 
1441
        tmp = RCLASS_SUPER(tmp);
1310
1442
    }
1311
1443
    if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
1312
1444
        mod_retry = 1;
1359
1491
        rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
1360
1492
    if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
1361
1493
 
1362
 
    if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {
 
1494
    if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
1363
1495
        if (val == Qundef) {
1364
1496
            autoload_delete(mod, id);
1365
1497
            val = Qnil;
1393
1525
    if (!tbl) {
1394
1526
        tbl = st_init_numtable();
1395
1527
    }
1396
 
    if (RCLASS(mod)->iv_tbl) {
1397
 
        st_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
 
1528
    if (RCLASS_IV_TBL(mod)) {
 
1529
        st_foreach_safe(RCLASS_IV_TBL(mod), sv_i, (st_data_t)tbl);
1398
1530
    }
1399
1531
    return tbl;
1400
1532
}
1405
1537
    VALUE tmp = mod;
1406
1538
    for (;;) {
1407
1539
        data = rb_mod_const_at(tmp, data);
1408
 
        tmp = RCLASS(tmp)->super;
 
1540
        tmp = RCLASS_SUPER(tmp);
1409
1541
        if (!tmp) break;
1410
1542
        if (tmp == rb_cObject && mod != rb_cObject) break;
1411
1543
    }
1478
1610
    tmp = klass;
1479
1611
  retry:
1480
1612
    while (tmp) {
1481
 
        if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl, id, &value)) {
 
1613
        if (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), id, &value)) {
1482
1614
            if (value == Qundef && NIL_P(autoload_file(klass, id)))
1483
1615
                return Qfalse;
1484
1616
            return Qtrue;
1485
1617
        }
1486
1618
        if (!recurse && klass != rb_cObject) break;
1487
 
        tmp = RCLASS(tmp)->super;
 
1619
        tmp = RCLASS_SUPER(tmp);
1488
1620
    }
1489
1621
    if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
1490
1622
        mod_retry = 1;
1527
1659
            rb_error_frozen("class");
1528
1660
        }
1529
1661
    }
1530
 
    if (!RCLASS(klass)->iv_tbl) {
1531
 
        RCLASS(klass)->iv_tbl = st_init_numtable();
 
1662
    if (!RCLASS_IV_TBL(klass)) {
 
1663
        RCLASS_IV_TBL(klass) = st_init_numtable();
1532
1664
    }
1533
1665
    else if (isconst) {
1534
1666
        VALUE value = Qfalse;
1535
1667
 
1536
 
        if (st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
 
1668
        if (st_lookup(RCLASS_IV_TBL(klass), id, &value)) {
1537
1669
            if (value == Qundef)
1538
1670
              autoload_delete(klass, id);
1539
1671
            else
1544
1676
    if(isconst){
1545
1677
        rb_vm_change_state();
1546
1678
    }
1547
 
    st_insert(RCLASS(klass)->iv_tbl, id, val);
 
1679
    st_insert(RCLASS_IV_TBL(klass), id, val);
1548
1680
}
1549
1681
 
1550
1682
void
1577
1709
    rb_define_const(rb_cObject, name, val);
1578
1710
}
1579
1711
 
1580
 
void
1581
 
rb_cvar_set(VALUE klass, ID id, VALUE val)
 
1712
static VALUE
 
1713
original_module(VALUE c)
1582
1714
{
1583
 
    mod_av_set(klass, id, val, Qfalse);
 
1715
    if (TYPE(c) == T_ICLASS)
 
1716
        return RBASIC(c)->klass;
 
1717
    return c;
1584
1718
}
1585
1719
 
1586
1720
#define CVAR_LOOKUP(v,r) do {\
1587
 
    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
1588
 
        return (r);\
 
1721
    if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
 
1722
        r;\
1589
1723
    }\
1590
1724
    if (FL_TEST(klass, FL_SINGLETON) ) {\
1591
1725
        VALUE obj = rb_iv_get(klass, "__attached__");\
1595
1729
            klass = obj;\
1596
1730
            break;\
1597
1731
          default:\
1598
 
            klass = RCLASS(klass)->super;\
 
1732
            klass = RCLASS_SUPER(klass);\
1599
1733
            break;\
1600
1734
        }\
1601
1735
    }\
1602
1736
    else {\
1603
 
        klass = RCLASS(klass)->super;\
 
1737
        klass = RCLASS_SUPER(klass);\
1604
1738
    }\
1605
1739
    while (klass) {\
1606
 
        if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
1607
 
            return (r);\
 
1740
        if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
 
1741
            r;\
1608
1742
        }\
1609
 
        klass = RCLASS(klass)->super;\
 
1743
        klass = RCLASS_SUPER(klass);\
1610
1744
    }\
1611
1745
} while(0)
1612
1746
 
 
1747
void
 
1748
rb_cvar_set(VALUE klass, ID id, VALUE val)
 
1749
{
 
1750
    VALUE tmp, front = 0, target = 0;
 
1751
 
 
1752
    tmp = klass;
 
1753
    CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
 
1754
    if (target) {
 
1755
        if (front && target != front) {
 
1756
            ID did = id;
 
1757
 
 
1758
            if (RTEST(ruby_verbose)) {
 
1759
                rb_warning("class variable %s of %s is overtaken by %s",
 
1760
                           rb_id2name(id), rb_class2name(original_module(front)),
 
1761
                           rb_class2name(original_module(target)));
 
1762
            }
 
1763
            if (BUILTIN_TYPE(front) == T_CLASS) {
 
1764
                st_delete(RCLASS_IV_TBL(front),&did,0);
 
1765
            }
 
1766
        }
 
1767
    }
 
1768
    else {
 
1769
        target = tmp;
 
1770
    }
 
1771
    mod_av_set(target, id, val, Qfalse);
 
1772
}
 
1773
 
1613
1774
VALUE
1614
1775
rb_cvar_get(VALUE klass, ID id)
1615
1776
{
1616
 
    VALUE value, tmp;
 
1777
    VALUE value, tmp, front = 0, target = 0;
1617
1778
 
1618
1779
    tmp = klass;
1619
 
    CVAR_LOOKUP(&value, value);
1620
 
    rb_name_error(id,"uninitialized class variable %s in %s",
1621
 
                  rb_id2name(id), rb_class2name(tmp));
1622
 
    return Qnil;                /* not reached */
 
1780
    CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
 
1781
    if (!target) {
 
1782
        rb_name_error(id,"uninitialized class variable %s in %s",
 
1783
                      rb_id2name(id), rb_class2name(tmp));
 
1784
    }
 
1785
    if (front && target != front) {
 
1786
        ID did = id;
 
1787
 
 
1788
        if (RTEST(ruby_verbose)) {
 
1789
            rb_warning("class variable %s of %s is overtaken by %s",
 
1790
                       rb_id2name(id), rb_class2name(original_module(front)),
 
1791
                       rb_class2name(original_module(target)));
 
1792
        }
 
1793
        if (BUILTIN_TYPE(front) == T_CLASS) {
 
1794
            st_delete(RCLASS_IV_TBL(front),&did,0);
 
1795
        }
 
1796
    }
 
1797
    return value;
1623
1798
}
1624
1799
 
1625
1800
VALUE
1626
1801
rb_cvar_defined(VALUE klass, ID id)
1627
1802
{
1628
1803
    if (!klass) return Qfalse;
1629
 
    CVAR_LOOKUP(0,Qtrue);
 
1804
    CVAR_LOOKUP(0,return Qtrue);
1630
1805
    return Qfalse;
1631
1806
}
1632
1807
 
1694
1869
{
1695
1870
    VALUE ary = rb_ary_new();
1696
1871
 
1697
 
    if (RCLASS(obj)->iv_tbl) {
1698
 
        st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary);
 
1872
    if (RCLASS_IV_TBL(obj)) {
 
1873
        st_foreach_safe(RCLASS_IV_TBL(obj), cv_i, ary);
1699
1874
    }
1700
1875
    return ary;
1701
1876
}
1733
1908
        rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
1734
1909
    if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
1735
1910
 
1736
 
    if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {
 
1911
    if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
1737
1912
        return val;
1738
1913
    }
1739
1914
    if (rb_cvar_defined(mod, id)) {