From 2a4c4f7b0c147585119036c43c1d04f73621e510 Mon Sep 17 00:00:00 2001 From: akr Date: Wed, 29 Aug 2007 23:12:21 +0000 Subject: * include/ruby/intern.h: declare rb_hash_tbl. * include/ruby/ruby.h (RHash): delay st_table allocation. rename tbl field to ntbl to detect direct reference to the st_table as a compile error. (RHASH_TBL): abstract accessor defined. (RHASH_ITER_LEV): ditto. (RHASH_IFNONE): ditto. (RHASH_SIZE): ditto. (RHASH_EMPTY_P): ditto. * hash.c: delay st_table allocation. * gc.c: replace tbl by ntbl. * array.c: replace direct field accessor by abstract field accessor such as RHASH(hash)->tbl to RHASH_TBL(hash). * marshal.c: ditto. * insns.def: ditto. * ext/iconv/iconv.c: ditto. * ext/json/ext/generator/generator.c: ditto. * ext/json/ext/parser/parser.c: ditto. * ext/syck/rubyext.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13309 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 32 +++++++++++ array.c | 15 +++--- ext/iconv/iconv.c | 4 +- ext/json/ext/generator/generator.c | 8 +-- ext/json/ext/parser/parser.c | 4 +- ext/syck/rubyext.c | 2 +- gc.c | 6 +-- hash.c | 108 ++++++++++++++++++++++++------------- include/ruby/intern.h | 1 + include/ruby/ruby.h | 7 ++- insns.def | 4 +- marshal.c | 4 +- 12 files changed, 136 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 475ff0395c..c75125134d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +Thu Aug 30 08:00:12 2007 Tanaka Akira + + * include/ruby/intern.h: declare rb_hash_tbl. + + * include/ruby/ruby.h (RHash): delay st_table allocation. + rename tbl field to ntbl to detect direct reference to the st_table + as a compile error. + (RHASH_TBL): abstract accessor defined. + (RHASH_ITER_LEV): ditto. + (RHASH_IFNONE): ditto. + (RHASH_SIZE): ditto. + (RHASH_EMPTY_P): ditto. + + * hash.c: delay st_table allocation. + + * gc.c: replace tbl by ntbl. + + * array.c: replace direct field accessor by abstract field accessor + such as RHASH(hash)->tbl to RHASH_TBL(hash). + + * marshal.c: ditto. + + * insns.def: ditto. + + * ext/iconv/iconv.c: ditto. + + * ext/json/ext/generator/generator.c: ditto. + + * ext/json/ext/parser/parser.c: ditto. + + * ext/syck/rubyext.c: ditto. + Wed Aug 29 18:36:06 2007 Tanaka Akira * lib/open-uri.rb: add :ftp_active_mode option. diff --git a/array.c b/array.c index 0b4ffa14d7..7718305d5a 100644 --- a/array.c +++ b/array.c @@ -2525,7 +2525,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2) ary3 = rb_ary_new(); for (i=0; itbl, RARRAY_PTR(ary1)[i], 0)) continue; + if (st_lookup(RHASH_TBL(hash), RARRAY_PTR(ary1)[i], 0)) continue; rb_ary_push(ary3, rb_ary_elt(ary1, i)); } return ary3; @@ -2553,9 +2553,12 @@ rb_ary_and(VALUE ary1, VALUE ary2) RARRAY_LEN(ary1) : RARRAY_LEN(ary2)); hash = ary_make_hash(ary2, 0); + if (RHASH_EMPTY_P(hash)) + return ary3; + for (i=0; itbl, (st_data_t*)&vv, 0)) { + if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { rb_ary_push(ary3, v); } } @@ -2587,13 +2590,13 @@ rb_ary_or(VALUE ary1, VALUE ary2) for (i=0; itbl, (st_data_t*)&vv, 0)) { + if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { rb_ary_push(ary3, v); } } for (i=0; itbl, (st_data_t*)&vv, 0)) { + if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { rb_ary_push(ary3, v); } } @@ -2623,12 +2626,12 @@ rb_ary_uniq_bang(VALUE ary) ary_iter_check(ary); hash = ary_make_hash(ary, 0); - if (RARRAY_LEN(ary) == RHASH(hash)->tbl->num_entries) { + if (RARRAY_LEN(ary) == RHASH_SIZE(hash)) { return Qnil; } for (i=j=0; itbl, (st_data_t*)&vv, 0)) { + if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) { rb_ary_store(ary, j++, v); } } diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index b6bc0a11a5..ccedd0c66d 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -138,10 +138,10 @@ map_charset(VALUE *code) { VALUE val = *code; - if (RHASH(charset_map)->tbl && RHASH(charset_map)->tbl->num_entries) { + if (RHASH_SIZE(charset_map)) { VALUE key = rb_funcall2(val, rb_intern("downcase"), 0, 0); StringValuePtr(key); - if (st_lookup(RHASH(charset_map)->tbl, key, &val)) { + if (st_lookup(RHASH_TBL(charset_map), key, &val)) { *code = val; } } diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index b08455f223..616832c992 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -86,7 +86,7 @@ static int hash_to_json_state_i(VALUE key, VALUE value, VALUE Vstate) } inline static VALUE mHash_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) { - long depth, len = RHASH(self)->tbl->num_entries; + long depth, len = RHASH_SIZE(self); VALUE result; GET_STATE(Vstate); @@ -140,7 +140,7 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "02", &Vstate, &Vdepth); depth = NIL_P(Vdepth) ? 0 : FIX2LONG(Vdepth); if (NIL_P(Vstate)) { - long len = RHASH(self)->tbl->num_entries; + long len = RHASH_SIZE(self); result = rb_str_buf_new(len); rb_str_buf_cat2(result, "{"); rb_hash_foreach(self, hash_to_json_i, result); @@ -480,7 +480,7 @@ static inline VALUE cState_configure(VALUE self, VALUE opts) state->object_nl = tmp; } tmp = ID2SYM(i_check_circular); - if (st_lookup(RHASH(opts)->tbl, tmp, 0)) { + if (st_lookup(RHASH_TBL(opts), tmp, 0)) { tmp = rb_hash_aref(opts, ID2SYM(i_check_circular)); state->check_circular = RTEST(tmp); } else { @@ -488,7 +488,7 @@ static inline VALUE cState_configure(VALUE self, VALUE opts) } tmp = ID2SYM(i_max_nesting); state->max_nesting = 19; - if (st_lookup(RHASH(opts)->tbl, tmp, 0)) { + if (st_lookup(RHASH_TBL(opts), tmp, 0)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { Check_Type(max_nesting, T_FIXNUM); diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index a1950b067a..a6b7021f7e 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1470,7 +1470,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) rb_raise(rb_eArgError, "opts needs to be like a hash"); } else { VALUE tmp = ID2SYM(i_max_nesting); - if (st_lookup(RHASH(opts)->tbl, tmp, 0)) { + if (st_lookup(RHASH_TBL(opts), tmp, 0)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { Check_Type(max_nesting, T_FIXNUM); @@ -1480,7 +1480,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } } tmp = ID2SYM(i_allow_nan); - if (st_lookup(RHASH(opts)->tbl, tmp, 0)) { + if (st_lookup(RHASH_TBL(opts), tmp, 0)) { VALUE allow_nan = rb_hash_aref(opts, tmp); if (RTEST(allow_nan)) json->allow_nan = 1; } diff --git a/ext/syck/rubyext.c b/ext/syck/rubyext.c index 9a41c18e8f..53625c91de 100644 --- a/ext/syck/rubyext.c +++ b/ext/syck/rubyext.c @@ -621,7 +621,7 @@ rb_syck_load_handler(SyckParser *p, SyckNode *n) if ( bonus->taint) OBJ_TAINT( obj ); if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj); - rb_hash_aset(bonus->data, INT2FIX(RHASH(bonus->data)->tbl->num_entries), obj); + rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj); return obj; } diff --git a/gc.c b/gc.c index 8054d9acb3..7d521eb07a 100644 --- a/gc.c +++ b/gc.c @@ -1032,7 +1032,7 @@ gc_mark_children(VALUE ptr, int lev) break; case T_HASH: - mark_hash(obj->as.hash.tbl, lev); + mark_hash(obj->as.hash.ntbl, lev); ptr = obj->as.hash.ifnone; goto again; @@ -1267,8 +1267,8 @@ obj_free(VALUE obj) rb_ary_free(obj); break; case T_HASH: - if (RANY(obj)->as.hash.tbl) { - st_free_table(RANY(obj)->as.hash.tbl); + if (RANY(obj)->as.hash.ntbl) { + st_free_table(RANY(obj)->as.hash.ntbl); } break; case T_REGEXP: diff --git a/hash.c b/hash.c index 27c0c5bdfc..8fbc7b9416 100644 --- a/hash.c +++ b/hash.c @@ -147,10 +147,10 @@ hash_foreach_iter(VALUE key, VALUE value, struct hash_foreach_arg *arg) int status; st_table *tbl; - tbl = RHASH(arg->hash)->tbl; + tbl = RHASH(arg->hash)->ntbl; if (key == Qundef) return ST_CONTINUE; status = (*arg->func)(key, value, arg->arg); - if (RHASH(arg->hash)->tbl != tbl) { + if (RHASH(arg->hash)->ntbl != tbl) { rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); } switch (status) { @@ -172,7 +172,7 @@ hash_foreach_ensure(VALUE hash) if (RHASH(hash)->iter_lev == 0) { if (FL_TEST(hash, HASH_DELETED)) { - st_cleanup_safe(RHASH(hash)->tbl, Qundef); + st_cleanup_safe(RHASH(hash)->ntbl, Qundef); FL_UNSET(hash, HASH_DELETED); } } @@ -182,7 +182,7 @@ hash_foreach_ensure(VALUE hash) static VALUE hash_foreach_call(struct hash_foreach_arg *arg) { - if (st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, (st_data_t)arg)) { + if (st_foreach(RHASH(arg->hash)->ntbl, hash_foreach_iter, (st_data_t)arg)) { rb_raise(rb_eRuntimeError, "hash modified during iteration"); } return Qnil; @@ -193,6 +193,8 @@ rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg) { struct hash_foreach_arg arg; + if (!RHASH(hash)->ntbl) + return; RHASH(hash)->iter_lev++; arg.hash = hash; arg.func = (rb_foreach_func *)func; @@ -216,7 +218,7 @@ hash_alloc(VALUE klass) { VALUE hash = hash_alloc0(klass); - RHASH(hash)->tbl = st_init_table(&objhash); + RHASH(hash)->ntbl = 0; return hash; } @@ -228,14 +230,29 @@ rb_hash_new(void) } static void -rb_hash_modify(VALUE hash) +rb_hash_modify_check(VALUE hash) { - if (!RHASH(hash)->tbl) rb_raise(rb_eTypeError, "uninitialized Hash"); if (OBJ_FROZEN(hash)) rb_error_frozen("hash"); if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify hash"); } +struct st_table * +rb_hash_tbl(VALUE hash) +{ + if (!RHASH(hash)->ntbl) { + RHASH(hash)->ntbl = st_init_table(&objhash); + } + return RHASH(hash)->ntbl; +} + +static void +rb_hash_modify(VALUE hash) +{ + rb_hash_modify_check(hash); + rb_hash_tbl(hash); +} + /* * call-seq: * Hash.new => hash @@ -313,7 +330,9 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass) if (argc == 1 && TYPE(argv[0]) == T_HASH) { hash = hash_alloc0(klass); - RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl); + if (RHASH(argv[0])->ntbl) { + RHASH(hash)->ntbl = st_copy(RHASH(argv[0])->ntbl); + } return hash; } @@ -388,11 +407,13 @@ rb_hash_rehash(VALUE hash) if (RHASH(hash)->iter_lev > 0) { rb_raise(rb_eRuntimeError, "rehash during iteration"); } - rb_hash_modify(hash); - tbl = st_init_table_with_size(RHASH(hash)->tbl->type, RHASH(hash)->tbl->num_entries); + rb_hash_modify_check(hash); + if (!RHASH(hash)->ntbl) + return hash; + tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries); rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl); - st_free_table(RHASH(hash)->tbl); - RHASH(hash)->tbl = tbl; + st_free_table(RHASH(hash)->ntbl); + RHASH(hash)->ntbl = tbl; return hash; } @@ -416,7 +437,7 @@ rb_hash_aref(VALUE hash, VALUE key) { VALUE val; - if (!st_lookup(RHASH(hash)->tbl, key, &val)) { + if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { return rb_funcall(hash, id_default, 1, key); } return val; @@ -427,7 +448,7 @@ rb_hash_lookup(VALUE hash, VALUE key) { VALUE val; - if (!st_lookup(RHASH(hash)->tbl, key, &val)) { + if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { return Qnil; /* without Hash#default */ } return val; @@ -475,7 +496,7 @@ rb_hash_fetch(int argc, VALUE *argv, VALUE hash) if (block_given && argc == 2) { rb_warn("block supersedes default value argument"); } - if (!st_lookup(RHASH(hash)->tbl, key, &val)) { + if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { if (block_given) return rb_yield(key); if (argc == 1) { rb_raise(rb_eKeyError, "key not found"); @@ -620,13 +641,15 @@ rb_hash_delete_key(VALUE hash, VALUE key) { st_data_t ktmp = (st_data_t)key, val; + if (!RHASH(hash)->ntbl) + return Qundef; if (RHASH(hash)->iter_lev > 0) { - if (st_delete_safe(RHASH(hash)->tbl, &ktmp, &val, Qundef)) { + if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, Qundef)) { FL_SET(hash, HASH_DELETED); return (VALUE)val; } } - else if (st_delete(RHASH(hash)->tbl, &ktmp, &val)) + else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val)) return (VALUE)val; return Qundef; } @@ -765,9 +788,12 @@ rb_hash_delete_if(VALUE hash) VALUE rb_hash_reject_bang(VALUE hash) { - int n = RHASH(hash)->tbl->num_entries; + int n; + if (!RHASH(hash)->ntbl) + return Qnil; + n = RHASH(hash)->ntbl->num_entries; rb_hash_delete_if(hash); - if (n == RHASH(hash)->tbl->num_entries) return Qnil; + if (n == RHASH(hash)->ntbl->num_entries) return Qnil; return hash; } @@ -861,12 +887,14 @@ clear_i(VALUE key, VALUE value, VALUE dummy) static VALUE rb_hash_clear(VALUE hash) { - rb_hash_modify(hash); - if (RHASH(hash)->tbl->num_entries > 0) { + rb_hash_modify_check(hash); + if (!RHASH(hash)->ntbl) + return hash; + if (RHASH(hash)->ntbl->num_entries > 0) { if (RHASH(hash)->iter_lev > 0) rb_hash_foreach(hash, clear_i, 0); else - st_clear(RHASH(hash)->tbl); + st_clear(RHASH(hash)->ntbl); } return hash; @@ -894,11 +922,11 @@ VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val) { rb_hash_modify(hash); - if (TYPE(key) != T_STRING || st_lookup(RHASH(hash)->tbl, key, 0)) { - st_insert(RHASH(hash)->tbl, key, val); + if (TYPE(key) != T_STRING || st_lookup(RHASH(hash)->ntbl, key, 0)) { + st_insert(RHASH(hash)->ntbl, key, val); } else { - st_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val); + st_add_direct(RHASH(hash)->ntbl, rb_str_new4(key), val); } return val; } @@ -959,7 +987,9 @@ rb_hash_replace(VALUE hash, VALUE hash2) static VALUE rb_hash_size(VALUE hash) { - return INT2FIX(RHASH(hash)->tbl->num_entries); + if (!RHASH(hash)->ntbl) + return INT2FIX(0); + return INT2FIX(RHASH(hash)->ntbl->num_entries); } @@ -976,9 +1006,7 @@ rb_hash_size(VALUE hash) static VALUE rb_hash_empty_p(VALUE hash) { - if (RHASH(hash)->tbl->num_entries == 0) - return Qtrue; - return Qfalse; + return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse; } static int @@ -1190,7 +1218,7 @@ inspect_hash(VALUE hash, VALUE dummy, int recur) static VALUE rb_hash_inspect(VALUE hash) { - if (RHASH(hash)->tbl == 0 || RHASH(hash)->tbl->num_entries == 0) + if (RHASH_EMPTY_P(hash)) return rb_str_new2("{}"); return rb_exec_recursive(inspect_hash, hash, 0); } @@ -1288,7 +1316,9 @@ rb_hash_values(VALUE hash) static VALUE rb_hash_has_key(VALUE hash, VALUE key) { - if (st_lookup(RHASH(hash)->tbl, key, 0)) { + if (!RHASH(hash)->ntbl) + return Qfalse; + if (st_lookup(RHASH(hash)->ntbl, key, 0)) { return Qtrue; } return Qfalse; @@ -1380,15 +1410,17 @@ hash_equal(VALUE hash1, VALUE hash2, int eql) } return rb_equal(hash2, hash1); } - if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries) + if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return Qfalse; + if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl) + return Qtrue; #if 0 if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) && FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) return Qfalse; #endif - data.tbl = RHASH(hash2)->tbl; + data.tbl = RHASH(hash2)->ntbl; data.result = Qtrue; rb_hash_foreach(hash1, eql ? eql_i : equal_i, (st_data_t)&data); @@ -1451,7 +1483,9 @@ recursive_hash(VALUE hash, VALUE dummy, int recur) if (recur) { return LONG2FIX(0); } - hval = RHASH(hash)->tbl->num_entries; + if (!RHASH(hash)->ntbl) + return LONG2FIX(0); + hval = RHASH(hash)->ntbl->num_entries; rb_hash_foreach(hash, hash_i, (st_data_t)&hval); return INT2FIX(hval); } @@ -1695,7 +1729,7 @@ static VALUE rb_hash_compare_by_id(VALUE hash) { rb_hash_modify(hash); - RHASH(hash)->tbl->type = &identhash; + RHASH(hash)->ntbl->type = &identhash; rb_hash_rehash(hash); return hash; } @@ -1712,7 +1746,9 @@ rb_hash_compare_by_id(VALUE hash) static VALUE rb_hash_compare_by_id_p(VALUE hash) { - if (RHASH(hash)->tbl->type == &identhash) { + if (!RHASH(hash)->ntbl) + return Qfalse; + if (RHASH(hash)->ntbl->type == &identhash) { return Qtrue; } return Qfalse; diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 78ac3f9d00..829d732893 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -326,6 +326,7 @@ VALUE rb_hash_lookup(VALUE, VALUE); VALUE rb_hash_aset(VALUE, VALUE, VALUE); VALUE rb_hash_delete_if(VALUE); VALUE rb_hash_delete(VALUE,VALUE); +struct st_table *rb_hash_tbl(VALUE); int rb_path_check(const char*); int rb_env_path_tainted(void); /* io.c */ diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 2dbf29956e..63cb7b417e 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -478,10 +478,15 @@ struct RRegexp { struct RHash { struct RBasic basic; - struct st_table *tbl; + struct st_table *ntbl; /* maybe 0 */ int iter_lev; VALUE ifnone; }; +#define RHASH_TBL(h) rb_hash_tbl(h) +#define RHASH_ITER_LEV(h) RHASH(h)->iter_lev +#define RHASH_IFNONE(h) RHASH(h)->ifnone +#define RHASH_SIZE(h) (RHASH(h)->ntbl ? RHASH(h)->ntbl->num_entries : 0) +#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0) struct RFile { struct RBasic basic; diff --git a/insns.def b/insns.def index 4a12a5b930..1d9ef3d6f2 100644 --- a/insns.def +++ b/insns.def @@ -1312,7 +1312,7 @@ opt_case_dispatch } else { VALUE val; - if (st_lookup(RHASH(hash)->tbl, key, &val)) { + if (st_lookup(RHASH_TBL(hash), key, &val)) { JUMP(FIX2INT(val)); } else { @@ -1958,7 +1958,7 @@ opt_length val = LONG2NUM(RARRAY_LEN(recv)); } else if (HEAP_CLASS_OF(recv) == rb_cHash) { - val = INT2FIX(RHASH(recv)->tbl->num_entries); + val = INT2FIX(RHASH_SIZE(recv)); } else { goto INSN_LABEL(normal_dispatch); diff --git a/marshal.c b/marshal.c index b4ba9b6140..79e559d7f3 100644 --- a/marshal.c +++ b/marshal.c @@ -578,7 +578,7 @@ w_object(VALUE obj, struct dump_arg *arg, int limit) else { w_byte(TYPE_HASH_DEF, arg); } - w_long(RHASH(obj)->tbl->num_entries, arg); + w_long(RHASH_SIZE(obj), arg); rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg); if (!NIL_P(RHASH(obj)->ifnone)) { w_object(RHASH(obj)->ifnone, arg, limit); @@ -899,7 +899,7 @@ r_string(struct load_arg *arg) static VALUE r_entry(VALUE v, struct load_arg *arg) { - rb_hash_aset(arg->data, INT2FIX(RHASH(arg->data)->tbl->num_entries), v); + rb_hash_aset(arg->data, INT2FIX(RHASH_SIZE(arg->data)), v); if (arg->taint) OBJ_TAINT(v); if (arg->proc) { v = rb_funcall(arg->proc, rb_intern("call"), 1, v); -- cgit v1.2.3