* variable.c (generic_ivar_set): use st_update to insert object
  which does not have generic instance variables yet.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47849 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-10-08 14:49:49 +00:00
Родитель b61cb94e94
Коммит 26a29ffbed
1 изменённых файлов: 23 добавлений и 9 удалений

Просмотреть файл

@ -930,11 +930,27 @@ generic_ivar_get(VALUE obj, ID id, VALUE undef)
return undef;
}
static int
generic_ivar_update(st_data_t *k, st_data_t *v, st_data_t a, int existing)
{
VALUE obj = (VALUE)*k;
st_table **tbl = (st_table **)a;
if (!existing) {
FL_SET(obj, FL_EXIVAR);
*v = (st_data_t)(*tbl = st_init_numtable());
return ST_CONTINUE;
}
else {
*tbl = (st_table *)*v;
return ST_STOP;
}
}
static void
generic_ivar_set(VALUE obj, ID id, VALUE val)
{
st_table *tbl;
st_data_t data;
if (rb_special_const_p(obj)) {
if (rb_obj_frozen_p(obj)) rb_error_frozen("object");
@ -943,16 +959,14 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
if (!generic_iv_tbl) {
generic_iv_tbl = st_init_numtable();
}
if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) {
FL_SET(obj, FL_EXIVAR);
tbl = st_init_numtable();
st_add_direct(generic_iv_tbl, (st_data_t)obj, (st_data_t)tbl);
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);
if (FL_ABLE(obj)) RB_OBJ_WRITTEN(obj, Qundef, val);
return;
}
st_insert((st_table *)data, (st_data_t)id, (st_data_t)val);
if (FL_ABLE(obj)) RB_OBJ_WRITTEN(obj, data, val);
else {
st_insert(tbl, (st_data_t)id, (st_data_t)val);
}
if (FL_ABLE(obj)) RB_OBJ_WRITTEN(obj, Qundef, val);
}
static VALUE