Feature #11146 ยป 0001-variable.c-generic_iv_tbl-is-unavoidable.patch
| variable.c | ||
|---|---|---|
|
static void check_before_mod_set(VALUE, ID, VALUE, const char *);
|
||
|
static void setup_const_entry(rb_const_entry_t *, VALUE, VALUE, rb_const_flag_t);
|
||
|
static int const_update(st_data_t *, st_data_t *, st_data_t, int);
|
||
|
static st_table *generic_iv_tbl;
|
||
|
void
|
||
|
Init_var_tables(void)
|
||
|
{
|
||
|
rb_global_tbl = st_init_numtable();
|
||
|
generic_iv_tbl = st_init_numtable();
|
||
|
autoload = rb_intern_const("__autoload__");
|
||
|
/* __classpath__: fully qualified class path */
|
||
|
classpath = rb_intern_const("__classpath__");
|
||
| ... | ... | |
|
}
|
||
|
static int special_generic_ivar = 0;
|
||
|
static st_table *generic_iv_tbl;
|
||
|
st_table*
|
||
|
rb_generic_ivar_table(VALUE obj)
|
||
| ... | ... | |
|
st_data_t tbl;
|
||
|
if (!FL_TEST(obj, FL_EXIVAR)) return 0;
|
||
|
if (!generic_iv_tbl) return 0;
|
||
|
if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) return 0;
|
||
|
return (st_table *)tbl;
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
st_data_t tbl, val;
|
||
|
if (generic_iv_tbl) {
|
||
|
if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
|
||
|
if (st_lookup((st_table *)tbl, (st_data_t)id, &val)) {
|
||
|
return (VALUE)val;
|
||
|
}
|
||
|
if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
|
||
|
if (st_lookup((st_table *)tbl, (st_data_t)id, &val)) {
|
||
|
return (VALUE)val;
|
||
|
}
|
||
|
}
|
||
|
return undef;
|
||
| ... | ... | |
|
if (rb_obj_frozen_p(obj)) rb_error_frozen("object");
|
||
|
special_generic_ivar = 1;
|
||
|
}
|
||
|
if (!generic_iv_tbl) {
|
||
|
generic_iv_tbl = st_init_numtable();
|
||
|
}
|
||
|
if (!st_update(generic_iv_tbl, (st_data_t)obj,
|
||
|
generic_ivar_update, (st_data_t)&tbl)) {
|
||
|
st_add_direct(tbl, (st_data_t)id, (st_data_t)val);
|
||
| ... | ... | |
|
st_table *tbl;
|
||
|
st_data_t data;
|
||
|
if (!generic_iv_tbl) return Qfalse;
|
||
|
if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) return Qfalse;
|
||
|
tbl = (st_table *)data;
|
||
|
if (st_lookup(tbl, (st_data_t)id, &data)) {
|
||
| ... | ... | |
|
st_data_t data, key = (st_data_t)id;
|
||
|
int status;
|
||
|
if (!generic_iv_tbl) return 0;
|
||
|
if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) return 0;
|
||
|
tbl = (st_table *)data;
|
||
|
status = st_delete(tbl, &key, valp);
|
||
| ... | ... | |
|
{
|
||
|
st_data_t tbl;
|
||
|
if (!generic_iv_tbl) return;
|
||
|
if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
|
||
|
rb_mark_tbl((st_table *)tbl);
|
||
|
}
|
||
| ... | ... | |
|
void
|
||
|
rb_mark_generic_ivar_tbl(void)
|
||
|
{
|
||
|
if (!generic_iv_tbl) return;
|
||
|
if (special_generic_ivar == 0) return;
|
||
|
st_foreach_safe(generic_iv_tbl, givar_i, 0);
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
st_data_t key = (st_data_t)obj, tbl;
|
||
|
if (!generic_iv_tbl) return;
|
||
|
if (st_delete(generic_iv_tbl, &key, &tbl))
|
||
|
st_free_table((st_table *)tbl);
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
st_data_t data;
|
||
|
if (!generic_iv_tbl) return;
|
||
|
if (!FL_TEST(obj, FL_EXIVAR)) {
|
||
|
clear:
|
||
|
if (FL_TEST(clone, FL_EXIVAR)) {
|
||
| ... | ... | |
|
break;
|
||
|
default:
|
||
|
generic:
|
||
|
if (!generic_iv_tbl) break;
|
||
|
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
|
||
|
st_data_t tbl;
|
||
| ... | ... | |
|
break;
|
||
|
default:
|
||
|
generic:
|
||
|
if (!generic_iv_tbl) break;
|
||
|
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
|
||
|
st_data_t data;
|
||
|
-
|
||