2#include "internal/gc.h" 
    3#include "internal/hash.h" 
    4#include "internal/proc.h" 
    5#include "internal/sanitizers.h" 
   51wmap_foreach_i(st_data_t key, st_data_t val, st_data_t arg)
 
   55    if (data->dead_entry != NULL) {
 
   56        ruby_sized_xfree(data->dead_entry, 
sizeof(
struct weakmap_entry));
 
   57        data->dead_entry = NULL;
 
   63    if (wmap_live_p(entry->key) && wmap_live_p(entry->val)) {
 
   67        int ret = data->func(entry, data->arg);
 
   79        data->dead_entry = entry;
 
   94    st_foreach(w->table, wmap_foreach_i, (st_data_t)&foreach_data);
 
   96    ruby_sized_xfree(foreach_data.dead_entry, 
sizeof(
struct weakmap_entry));
 
  102    rb_gc_mark_weak(&entry->key);
 
  103    rb_gc_mark_weak(&entry->val);
 
  113        wmap_foreach(w, wmap_mark_weak_table_i, (st_data_t)0);
 
  118wmap_free_table_i(st_data_t key, st_data_t val, st_data_t arg)
 
  132    st_foreach(w->table, wmap_free_table_i, 0);
 
  133    st_free_table(w->table);
 
  137wmap_memsize(
const void *ptr)
 
  142    size += st_memsize(w->table);
 
  144    size += st_table_size(w->table) * (2 * 
sizeof(
VALUE));
 
  155wmap_compact_table_i(st_data_t key, st_data_t val, st_data_t d)
 
  158    if (data->dead_entry != NULL) {
 
  159        ruby_sized_xfree(data->dead_entry, 
sizeof(
struct weakmap_entry));
 
  160        data->dead_entry = NULL;
 
  165    entry->val = rb_gc_location(entry->val);
 
  167    VALUE new_key = rb_gc_location(entry->key);
 
  171    if (entry->key != new_key) {
 
  172        DURING_GC_COULD_MALLOC_REGION_START();
 
  175            new_entry->key = new_key;
 
  176            new_entry->val = entry->val;
 
  177            st_insert(data->table, (st_data_t)&new_entry->key, (st_data_t)&new_entry->val);
 
  179        DURING_GC_COULD_MALLOC_REGION_END();
 
  185        data->dead_entry = entry;
 
  194wmap_compact(
void *ptr)
 
  204        st_foreach(w->table, wmap_compact_table_i, (st_data_t)&compact_data);
 
  206        ruby_sized_xfree(compact_data.dead_entry, 
sizeof(
struct weakmap_entry));
 
  218    0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
 
  222wmap_cmp(st_data_t x, st_data_t y)
 
  227    if (!wmap_live_p(x_obj) && !wmap_live_p(y_obj)) {
 
  231        return x_obj != y_obj;
 
  236wmap_hash(st_data_t n)
 
  238    return st_numhash(*(
VALUE *)n);
 
  247wmap_allocate(
VALUE klass)
 
  251    w->table = st_init_table(&wmap_hash_type);
 
  271    if (RSTRING_PTR(str)[0] == 
'#') {
 
  276        RSTRING_PTR(str)[0] = 
'#';
 
  279    wmap_inspect_append(str, entry->key);
 
  281    wmap_inspect_append(str, entry->val);
 
  287wmap_inspect(
VALUE self)
 
  293    VALUE str = rb_sprintf(
"-<%"PRIsVALUE
":%p", c, (
void *)self);
 
  295    wmap_foreach(w, wmap_inspect_i, (st_data_t)str);
 
  297    RSTRING_PTR(str)[0] = 
'#';
 
  325    wmap_foreach(w, wmap_each_i, (st_data_t)0);
 
  347wmap_each_key(
VALUE self)
 
  352    wmap_foreach(w, wmap_each_key_i, (st_data_t)0);
 
  358wmap_each_value_i(
struct weakmap_entry *entry, st_data_t _data)
 
  374wmap_each_value(
VALUE self)
 
  379    wmap_foreach(w, wmap_each_value_i, (st_data_t)0);
 
  408    wmap_foreach(w, wmap_keys_i, (st_data_t)ary);
 
  431wmap_values(
VALUE self)
 
  437    wmap_foreach(w, wmap_values_i, (st_data_t)ary);
 
  443wmap_aset_replace(st_data_t *key, st_data_t *val, st_data_t new_key_ptr, 
int existing)
 
  446    VALUE new_val = *(((
VALUE *)new_key_ptr) + 1);
 
  454        *key = (st_data_t)&entry->key;
 
  455        *val = (st_data_t)&entry->val;
 
  458    *(
VALUE *)*key = new_key;
 
  459    *(
VALUE *)*val = new_val;
 
  479    VALUE pair[2] = { key, val };
 
  481    st_update(w->table, (st_data_t)pair, wmap_aset_replace, (st_data_t)pair);
 
  499    if (!st_lookup(w->table, (st_data_t)&key, &data)) 
return Qundef;
 
  503    return *(
VALUE *)data;
 
  517    VALUE obj = wmap_lookup(self, key);
 
  518    return !UNDEF_P(obj) ? obj : 
Qnil;
 
  555    VALUE orig_key = key;
 
  556    st_data_t orig_key_data = (st_data_t)&orig_key;
 
  557    st_data_t orig_val_data;
 
  558    if (st_delete(w->table, &orig_key_data, &orig_val_data)) {
 
  561        rb_gc_remove_weak(self, (
VALUE *)orig_key_data);
 
  562        rb_gc_remove_weak(self, (
VALUE *)orig_val_data);
 
  567        if (wmap_live_p(orig_val)) {
 
  589    return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
 
  604    st_index_t n = st_table_size(w->table);
 
  606#if SIZEOF_ST_INDEX_T <= SIZEOF_LONG 
  636wkmap_mark_table_i(st_data_t key, st_data_t val_obj, st_data_t data)
 
  639    ruby_sized_xfree(*dead_entry, 
sizeof(
VALUE));
 
  644    if (wmap_live_p(*key_ptr)) {
 
  645        rb_gc_mark_weak(key_ptr);
 
  646        rb_gc_mark_movable((
VALUE)val_obj);
 
  651        *dead_entry = key_ptr;
 
  662        VALUE *dead_entry = NULL;
 
  663        st_foreach(w->table, wkmap_mark_table_i, (st_data_t)&dead_entry);
 
  664        if (dead_entry != NULL) {
 
  665            ruby_sized_xfree(dead_entry, 
sizeof(
VALUE));
 
  671wkmap_free_table_i(st_data_t key, st_data_t _val, st_data_t _arg)
 
  673    ruby_sized_xfree((
VALUE *)key, 
sizeof(
VALUE));
 
  682    st_foreach(w->table, wkmap_free_table_i, 0);
 
  683    st_free_table(w->table);
 
  687wkmap_memsize(
const void *ptr)
 
  692    size += st_memsize(w->table);
 
  694    size += st_table_size(w->table) * 
sizeof(
VALUE);
 
  700wkmap_compact_table_i(st_data_t key, st_data_t val_obj, st_data_t data, 
int _error)
 
  703    ruby_sized_xfree(*dead_entry, 
sizeof(
VALUE));
 
  708    if (wmap_live_p(*key_ptr)) {
 
  709        if (*key_ptr != rb_gc_location(*key_ptr) || val_obj != rb_gc_location(val_obj)) {
 
  716        *dead_entry = key_ptr;
 
  723wkmap_compact_table_replace(st_data_t *key_ptr, st_data_t *val_ptr, st_data_t _data, 
int existing)
 
  727    *(
VALUE *)*key_ptr = rb_gc_location(*(
VALUE *)*key_ptr);
 
  728    *val_ptr = (st_data_t)rb_gc_location((
VALUE)*val_ptr);
 
  734wkmap_compact(
void *ptr)
 
  739        VALUE *dead_entry = NULL;
 
  740        st_foreach_with_replace(w->table, wkmap_compact_table_i, wkmap_compact_table_replace, (st_data_t)&dead_entry);
 
  741        if (dead_entry != NULL) {
 
  742            ruby_sized_xfree(dead_entry, 
sizeof(
VALUE));
 
  755    0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
 
  759wkmap_cmp(st_data_t x, st_data_t y)
 
  764    if (wmap_live_p(x_obj) && wmap_live_p(y_obj)) {
 
  765        return rb_any_cmp(x_obj, y_obj);
 
  774wkmap_hash(st_data_t n)
 
  779    return rb_any_hash(obj);
 
  788wkmap_allocate(
VALUE klass)
 
  792    w->table = st_init_table(&wkmap_hash_type);
 
  803    if (!st_lookup(w->table, (st_data_t)&key, &data)) 
return Qundef;
 
  819    VALUE obj = wkmap_lookup(self, key);
 
  820    return !UNDEF_P(obj) ? obj : 
Qnil;
 
  829wkmap_aset_replace(st_data_t *key, st_data_t *val, st_data_t data_args, 
int existing)
 
  837    *(
VALUE *)*key = args->new_key;
 
  838    *val = (st_data_t)args->new_val;
 
  862        rb_raise(rb_eArgError, 
"WeakKeyMap keys must be garbage collectable");
 
  871    st_update(w->table, (st_data_t)&key, wkmap_aset_replace, (st_data_t)&args);
 
  914    VALUE orig_key = key;
 
  915    st_data_t orig_key_data = (st_data_t)&orig_key;
 
  916    st_data_t orig_val_data;
 
  917    if (st_delete(w->table, &orig_key_data, &orig_val_data)) {
 
  920        rb_gc_remove_weak(self, (
VALUE *)orig_key_data);
 
  922        ruby_sized_xfree((
VALUE *)orig_key_data, 
sizeof(
VALUE));
 
  961    if (!st_get_key(w->table, (st_data_t)&key, &orig_key)) 
return Qnil;
 
  963    return *(
VALUE *)orig_key;
 
  975    return RBOOL(!UNDEF_P(wkmap_lookup(self, key)));
 
  979wkmap_clear_i(st_data_t key, st_data_t val, st_data_t data)
 
  985    rb_gc_remove_weak(self, (
VALUE *)key);
 
  986    return wkmap_free_table_i(key, val, 0);
 
  996wkmap_clear(
VALUE self)
 
 1001    st_foreach(w->table, wkmap_clear_i, (st_data_t)self);
 
 1019wkmap_inspect(
VALUE self)
 
 1024    st_index_t n = st_table_size(w->table);
 
 1026#if SIZEOF_ST_INDEX_T <= SIZEOF_LONG 
 1027    const char * format = 
"#<%"PRIsVALUE
":%p size=%lu>";
 
 1029    const char * format = 
"#<%"PRIsVALUE
":%p size=%llu>";
 
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *name)
Defines a top-level module.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define Qundef
Old name of RUBY_Qundef.
#define rb_str_cat2
Old name of rb_str_cat_cstr.
#define T_FLOAT
Old name of RUBY_T_FLOAT.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define ULONG2NUM
Old name of RB_ULONG2NUM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define CLASS_OF
Old name of rb_class_of.
#define xmalloc
Old name of ruby_xmalloc.
#define FL_ABLE
Old name of RB_FL_ABLE.
#define ULL2NUM
Old name of RB_ULL2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
VALUE rb_any_to_s(VALUE obj)
Generates a textual representation of the given object.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_class_name(VALUE obj)
Queries the name of the given object's class.
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
VALUE rb_yield_values(int n,...)
Identical to rb_yield(), except it takes variadic number of parameters and pass them to the block.
VALUE rb_yield(VALUE val)
Yields the block.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
#define _(args)
This was a transition path from K&R to ANSI.
This is the struct that holds necessary info for a struct.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.