Use wmap_foreach for wmap_mark

This commit is contained in:
Peter Zhu 2024-08-20 11:03:12 -04:00
Родитель e375fa078f
Коммит 9c372f872d
1 изменённых файлов: 38 добавлений и 50 удалений

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

@ -50,23 +50,53 @@ wmap_free_entry(VALUE *key, VALUE *val)
ruby_sized_xfree(key, sizeof(struct weakmap_entry)); ruby_sized_xfree(key, sizeof(struct weakmap_entry));
} }
struct wmap_foreach_data {
void (*func)(struct weakmap_entry *, st_data_t);
st_data_t arg;
};
static int static int
wmap_mark_weak_table_i(st_data_t key, st_data_t val, st_data_t _) wmap_foreach_i(st_data_t key, st_data_t val, st_data_t arg)
{ {
VALUE key_obj = *(VALUE *)key; struct wmap_foreach_data *data = (struct wmap_foreach_data *)arg;
VALUE val_obj = *(VALUE *)val;
if (wmap_live_p(key_obj) && wmap_live_p(val_obj)) { struct weakmap_entry *entry = (struct weakmap_entry *)key;
rb_gc_mark_weak((VALUE *)key); RUBY_ASSERT(&entry->val == (VALUE *)val);
rb_gc_mark_weak((VALUE *)val);
return ST_CONTINUE; if (wmap_live_p(entry->key) && wmap_live_p(entry->val)) {
VALUE k = entry->key;
VALUE v = entry->val;
data->func(entry, data->arg);
RB_GC_GUARD(k);
RB_GC_GUARD(v);
} }
else { else {
wmap_free_entry((VALUE *)key, (VALUE *)val); wmap_free_entry((VALUE *)key, (VALUE *)val);
return ST_DELETE; return ST_DELETE;
} }
return ST_CONTINUE;
}
static void
wmap_foreach(struct weakmap *w, void (*func)(struct weakmap_entry *, st_data_t), st_data_t arg)
{
struct wmap_foreach_data foreach_data = {
.func = func,
.arg = arg,
};
st_foreach(w->table, wmap_foreach_i, (st_data_t)&foreach_data);
}
static void
wmap_mark_weak_table_i(struct weakmap_entry *entry, st_data_t _)
{
rb_gc_mark_weak(&entry->key);
rb_gc_mark_weak(&entry->val);
} }
static void static void
@ -74,7 +104,7 @@ wmap_mark(void *ptr)
{ {
struct weakmap *w = ptr; struct weakmap *w = ptr;
if (w->table) { if (w->table) {
st_foreach(w->table, wmap_mark_weak_table_i, (st_data_t)0); wmap_foreach(w, wmap_mark_weak_table_i, (st_data_t)0);
} }
} }
@ -190,48 +220,6 @@ wmap_allocate(VALUE klass)
return obj; return obj;
} }
struct wmap_foreach_data {
void (*func)(struct weakmap_entry *, st_data_t);
st_data_t arg;
};
static int
wmap_foreach_i(st_data_t key, st_data_t val, st_data_t arg)
{
struct wmap_foreach_data *data = (struct wmap_foreach_data *)arg;
struct weakmap_entry *entry = (struct weakmap_entry *)key;
RUBY_ASSERT(&entry->val == (VALUE *)val);
if (wmap_live_p(entry->key) && wmap_live_p(entry->val)) {
VALUE k = entry->key;
VALUE v = entry->val;
data->func(entry, data->arg);
RB_GC_GUARD(k);
RB_GC_GUARD(v);
}
else {
wmap_free_entry((VALUE *)key, (VALUE *)val);
return ST_DELETE;
}
return ST_CONTINUE;
}
static void
wmap_foreach(struct weakmap *w, void (*func)(struct weakmap_entry *, st_data_t), st_data_t arg)
{
struct wmap_foreach_data foreach_data = {
.func = func,
.arg = arg,
};
st_foreach(w->table, wmap_foreach_i, (st_data_t)&foreach_data);
}
static VALUE static VALUE
wmap_inspect_append(VALUE str, VALUE obj) wmap_inspect_append(VALUE str, VALUE obj)
{ {