зеркало из https://github.com/github/ruby.git
* 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
This commit is contained in:
Родитель
3d7f8c2320
Коммит
2a4c4f7b0c
32
ChangeLog
32
ChangeLog
|
@ -1,3 +1,35 @@
|
|||
Thu Aug 30 08:00:12 2007 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* 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 <akr@fsij.org>
|
||||
|
||||
* lib/open-uri.rb: add :ftp_active_mode option.
|
||||
|
|
15
array.c
15
array.c
|
@ -2525,7 +2525,7 @@ rb_ary_diff(VALUE ary1, VALUE ary2)
|
|||
ary3 = rb_ary_new();
|
||||
|
||||
for (i=0; i<RARRAY_LEN(ary1); i++) {
|
||||
if (st_lookup(RHASH(hash)->tbl, 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; i<RARRAY_LEN(ary1); i++) {
|
||||
v = vv = rb_ary_elt(ary1, i);
|
||||
if (st_delete(RHASH(hash)->tbl, (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; i<RARRAY_LEN(ary1); i++) {
|
||||
v = vv = rb_ary_elt(ary1, i);
|
||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
|
||||
if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) {
|
||||
rb_ary_push(ary3, v);
|
||||
}
|
||||
}
|
||||
for (i=0; i<RARRAY_LEN(ary2); i++) {
|
||||
v = vv = rb_ary_elt(ary2, i);
|
||||
if (st_delete(RHASH(hash)->tbl, (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; i<RARRAY_LEN(ary); i++) {
|
||||
v = vv = rb_ary_elt(ary, i);
|
||||
if (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {
|
||||
if (st_delete(RHASH_TBL(hash), (st_data_t*)&vv, 0)) {
|
||||
rb_ary_store(ary, j++, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
6
gc.c
6
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:
|
||||
|
|
108
hash.c
108
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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче