48
path = rb_str_new2(rb_id2name(name));
48
path = rb_str_dup(rb_id2str(name));
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);
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);
118
118
arg.klass = klass;
119
119
arg.track = rb_cObject;
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);
124
124
if (arg.path == 0) {
125
125
st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
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();
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);
141
141
VALUE path = Qnil;
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__");
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);
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);
156
156
if (TYPE(path) != T_STRING) {
157
157
rb_bug("class path is not set properly");
717
717
VALUE ary = rb_ary_new();
719
const char *s = "&`'+123456789";
719
const char *s = "123456789";
721
721
st_foreach_safe(rb_global_tbl, gvar_i, ary);
722
if (!NIL_P(rb_backref_get())) {
724
sprintf(buf, "$%c", *s++);
725
rb_ary_push(ary, rb_str_new2(buf));
723
sprintf(buf, "$%c", *s++);
724
rb_ary_push(ary, ID2SYM(rb_intern(buf)));
909
907
if (!generic_iv_tbl) return;
910
if (!FL_TEST(obj, FL_EXIVAR)) return;
908
if (!FL_TEST(obj, FL_EXIVAR)) {
910
if (FL_TEST(clone, FL_EXIVAR)) {
911
rb_free_generic_ivar(clone);
912
FL_UNSET(clone, FL_EXIVAR);
911
916
if (st_lookup(generic_iv_tbl, obj, &data)) {
912
917
st_table *tbl = (st_table *)data;
919
if (tbl->num_entries == 0)
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)
930
940
switch (TYPE(obj)) {
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];
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))
961
979
rb_ivar_set(VALUE obj, ID id, VALUE val)
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)) {
991
klass = rb_obj_class(obj);
992
if (!RCLASS_IV_INDEX_TBL(klass))
993
RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
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);
1000
len = ROBJECT_LEN(obj);
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++) {
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;
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;
1024
REALLOC_N(ROBJECT(obj)->as.heap.ptr, VALUE, newsize);
1025
newptr = ROBJECT(obj)->as.heap.ptr;
1027
for (; len < newsize; len++)
1028
newptr[len] = Qundef;
1029
ROBJECT(obj)->as.heap.len = newsize;
1032
ROBJECT_PTR(obj)[index] = val;
970
if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
971
st_insert(ROBJECT(obj)->iv_tbl, id, val);
1036
if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
1037
st_insert(RCLASS_IV_TBL(obj), id, val);
974
1040
generic_ivar_set(obj, id, val);
981
1047
rb_ivar_defined(VALUE obj, ID id)
983
1051
switch (TYPE(obj)) {
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];
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))
999
ivar_i(ID key, struct global_entry *entry, VALUE ary)
1074
struct obj_ivar_tag {
1076
int (*func)(ID key, VALUE val, st_data_t arg);
1081
obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data)
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);
1093
obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
1095
VALUE klass = rb_obj_class(obj);
1097
struct obj_ivar_tag data;
1099
tbl = RCLASS_IV_INDEX_TBL(klass);
1104
data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
1107
st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
1110
void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
1112
switch (TYPE(obj)) {
1114
obj_ivar_each(obj, func, arg);
1118
if (RCLASS_IV_TBL(obj)) {
1119
st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
1123
if (!generic_iv_tbl) break;
1124
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1127
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
1128
st_foreach_safe((st_table *)tbl, func, arg);
1136
ivar_i(ID key, VALUE val, VALUE ary)
1001
1138
if (rb_is_instance_id(key)) {
1002
1139
rb_ary_push(ary, ID2SYM(key));
1029
1166
ary = rb_ary_new();
1030
switch (TYPE(obj)) {
1034
if (ROBJECT(obj)->iv_tbl) {
1035
st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);
1039
if (!generic_iv_tbl) break;
1040
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1043
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
1044
st_foreach_safe((st_table *)tbl, ivar_i, ary);
1167
rb_ivar_foreach(obj, ivar_i, ary);
1087
1208
switch (TYPE(obj)) {
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;
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)) {
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));
1171
1303
return (struct st_table *)DATA_PTR(av);
1184
1316
rb_raise(rb_eArgError, "empty file name");
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)
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);
1210
1342
st_data_t load = 0;
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);
1216
1348
st_delete(tbl, (st_data_t*)&id, &load);
1359
1491
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
1360
1492
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
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);
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)))
1486
1618
if (!recurse && klass != rb_cObject) break;
1487
tmp = RCLASS(tmp)->super;
1619
tmp = RCLASS_SUPER(tmp);
1489
1621
if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
1527
1659
rb_error_frozen("class");
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();
1533
1665
else if (isconst) {
1534
1666
VALUE value = Qfalse;
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);
1577
1709
rb_define_const(rb_cObject, name, val);
1581
rb_cvar_set(VALUE klass, ID id, VALUE val)
1713
original_module(VALUE c)
1583
mod_av_set(klass, id, val, Qfalse);
1715
if (TYPE(c) == T_ICLASS)
1716
return RBASIC(c)->klass;
1586
1720
#define CVAR_LOOKUP(v,r) do {\
1587
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
1721
if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
1590
1724
if (FL_TEST(klass, FL_SINGLETON) ) {\
1591
1725
VALUE obj = rb_iv_get(klass, "__attached__");\
1598
klass = RCLASS(klass)->super;\
1732
klass = RCLASS_SUPER(klass);\
1603
klass = RCLASS(klass)->super;\
1737
klass = RCLASS_SUPER(klass);\
1605
1739
while (klass) {\
1606
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
1740
if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
1609
klass = RCLASS(klass)->super;\
1743
klass = RCLASS_SUPER(klass);\
1748
rb_cvar_set(VALUE klass, ID id, VALUE val)
1750
VALUE tmp, front = 0, target = 0;
1753
CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
1755
if (front && target != front) {
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)));
1763
if (BUILTIN_TYPE(front) == T_CLASS) {
1764
st_delete(RCLASS_IV_TBL(front),&did,0);
1771
mod_av_set(target, id, val, Qfalse);
1614
1775
rb_cvar_get(VALUE klass, ID id)
1777
VALUE value, tmp, front = 0, target = 0;
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;});
1782
rb_name_error(id,"uninitialized class variable %s in %s",
1783
rb_id2name(id), rb_class2name(tmp));
1785
if (front && target != front) {
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)));
1793
if (BUILTIN_TYPE(front) == T_CLASS) {
1794
st_delete(RCLASS_IV_TBL(front),&did,0);
1626
1801
rb_cvar_defined(VALUE klass, ID id)
1628
1803
if (!klass) return Qfalse;
1629
CVAR_LOOKUP(0,Qtrue);
1804
CVAR_LOOKUP(0,return Qtrue);
1733
1908
rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
1734
1909
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
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)) {
1739
1914
if (rb_cvar_defined(mod, id)) {