зеркало из https://github.com/github/ruby.git
hash.c: detect recursion for all
* hash.c (rb_hash): detect recursion for all `hash' methods. each `hash' methods no longer need to use rb_exec_recursive(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43980 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
c7159e81fc
Коммит
6f2efe84fb
|
@ -1,3 +1,8 @@
|
|||
Tue Dec 3 22:18:27 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* hash.c (rb_hash): detect recursion for all `hash' methods. each
|
||||
`hash' methods no longer need to use rb_exec_recursive().
|
||||
|
||||
Tue Dec 3 21:53:15 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* vm_eval.c (rb_catch_protect): new function similar to
|
||||
|
|
33
array.c
33
array.c
|
@ -3774,27 +3774,6 @@ rb_ary_eql(VALUE ary1, VALUE ary2)
|
|||
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
recursive_hash(VALUE ary, VALUE dummy, int recur)
|
||||
{
|
||||
long i;
|
||||
st_index_t h;
|
||||
VALUE n;
|
||||
|
||||
h = rb_hash_start(RARRAY_LEN(ary));
|
||||
if (recur) {
|
||||
h = rb_hash_uint(h, NUM2LONG(rb_hash(rb_cArray)));
|
||||
}
|
||||
else {
|
||||
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||
n = rb_hash(RARRAY_AREF(ary, i));
|
||||
h = rb_hash_uint(h, NUM2LONG(n));
|
||||
}
|
||||
}
|
||||
h = rb_hash_end(h);
|
||||
return LONG2FIX(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ary.hash -> fixnum
|
||||
|
@ -3808,7 +3787,17 @@ recursive_hash(VALUE ary, VALUE dummy, int recur)
|
|||
static VALUE
|
||||
rb_ary_hash(VALUE ary)
|
||||
{
|
||||
return rb_exec_recursive_paired(recursive_hash, ary, ary, 0);
|
||||
long i;
|
||||
st_index_t h;
|
||||
VALUE n;
|
||||
|
||||
h = rb_hash_start(RARRAY_LEN(ary));
|
||||
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||
n = rb_hash(RARRAY_AREF(ary, i));
|
||||
h = rb_hash_uint(h, NUM2LONG(n));
|
||||
}
|
||||
h = rb_hash_end(h);
|
||||
return LONG2FIX(h);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
28
hash.c
28
hash.c
|
@ -79,14 +79,17 @@ rb_any_cmp(VALUE a, VALUE b)
|
|||
static VALUE
|
||||
hash_recursive(VALUE obj, VALUE arg, int recurse)
|
||||
{
|
||||
if (recurse) return INT2FIX(0);
|
||||
if (recurse) {
|
||||
/* TODO: break to call with the object which eql? to obj */
|
||||
return INT2FIX(0);
|
||||
}
|
||||
return rb_funcallv(obj, id_hash, 0, 0);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_hash(VALUE obj)
|
||||
{
|
||||
VALUE hval = rb_exec_recursive(hash_recursive, obj, 0);
|
||||
VALUE hval = rb_exec_recursive_paired(hash_recursive, obj, obj, 0);
|
||||
retry:
|
||||
switch (TYPE(hval)) {
|
||||
case T_FIXNUM:
|
||||
|
@ -1959,20 +1962,6 @@ hash_i(VALUE key, VALUE val, VALUE arg)
|
|||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
recursive_hash(VALUE hash, VALUE dummy, int recur)
|
||||
{
|
||||
st_index_t hval = RHASH_SIZE(hash);
|
||||
|
||||
if (!hval) return INT2FIX(0);
|
||||
if (recur)
|
||||
hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval);
|
||||
else
|
||||
rb_hash_foreach(hash, hash_i, (VALUE)&hval);
|
||||
hval = rb_hash_end(hval);
|
||||
return INT2FIX(hval);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* hsh.hash -> fixnum
|
||||
|
@ -1984,7 +1973,12 @@ recursive_hash(VALUE hash, VALUE dummy, int recur)
|
|||
static VALUE
|
||||
rb_hash_hash(VALUE hash)
|
||||
{
|
||||
return rb_exec_recursive_paired(recursive_hash, hash, hash, 0);
|
||||
st_index_t hval = RHASH_SIZE(hash);
|
||||
|
||||
if (!hval) return INT2FIX(0);
|
||||
rb_hash_foreach(hash, hash_i, (VALUE)&hval);
|
||||
hval = rb_hash_end(hval);
|
||||
return INT2FIX(hval);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
32
range.c
32
range.c
|
@ -243,25 +243,6 @@ range_eql(VALUE range, VALUE obj)
|
|||
return rb_exec_recursive_paired(recursive_eql, range, obj, obj);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
recursive_hash(VALUE range, VALUE dummy, int recur)
|
||||
{
|
||||
st_index_t hash = EXCL(range);
|
||||
VALUE v;
|
||||
|
||||
hash = rb_hash_start(hash);
|
||||
if (!recur) {
|
||||
v = rb_hash(RANGE_BEG(range));
|
||||
hash = rb_hash_uint(hash, NUM2LONG(v));
|
||||
v = rb_hash(RANGE_END(range));
|
||||
hash = rb_hash_uint(hash, NUM2LONG(v));
|
||||
}
|
||||
hash = rb_hash_uint(hash, EXCL(range) << 24);
|
||||
hash = rb_hash_end(hash);
|
||||
|
||||
return LONG2FIX(hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.hash -> fixnum
|
||||
|
@ -274,7 +255,18 @@ recursive_hash(VALUE range, VALUE dummy, int recur)
|
|||
static VALUE
|
||||
range_hash(VALUE range)
|
||||
{
|
||||
return rb_exec_recursive_paired(recursive_hash, range, range, 0);
|
||||
st_index_t hash = EXCL(range);
|
||||
VALUE v;
|
||||
|
||||
hash = rb_hash_start(hash);
|
||||
v = rb_hash(RANGE_BEG(range));
|
||||
hash = rb_hash_uint(hash, NUM2LONG(v));
|
||||
v = rb_hash(RANGE_END(range));
|
||||
hash = rb_hash_uint(hash, NUM2LONG(v));
|
||||
hash = rb_hash_uint(hash, EXCL(range) << 24);
|
||||
hash = rb_hash_end(hash);
|
||||
|
||||
return LONG2FIX(hash);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
36
struct.c
36
struct.c
|
@ -949,27 +949,6 @@ rb_struct_equal(VALUE s, VALUE s2)
|
|||
return rb_exec_recursive_paired(recursive_equal, s, s2, s2);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
recursive_hash(VALUE s, VALUE dummy, int recur)
|
||||
{
|
||||
long i, len;
|
||||
st_index_t h;
|
||||
VALUE n;
|
||||
const VALUE *ptr;
|
||||
|
||||
h = rb_hash_start(rb_hash(rb_obj_class(s)));
|
||||
if (!recur) {
|
||||
ptr = RSTRUCT_CONST_PTR(s);
|
||||
len = RSTRUCT_LEN(s);
|
||||
for (i = 0; i < len; i++) {
|
||||
n = rb_hash(ptr[i]);
|
||||
h = rb_hash_uint(h, NUM2LONG(n));
|
||||
}
|
||||
}
|
||||
h = rb_hash_end(h);
|
||||
return INT2FIX(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* struct.hash -> fixnum
|
||||
|
@ -980,7 +959,20 @@ recursive_hash(VALUE s, VALUE dummy, int recur)
|
|||
static VALUE
|
||||
rb_struct_hash(VALUE s)
|
||||
{
|
||||
return rb_exec_recursive_paired(recursive_hash, s, s, 0);
|
||||
long i, len;
|
||||
st_index_t h;
|
||||
VALUE n;
|
||||
const VALUE *ptr;
|
||||
|
||||
h = rb_hash_start(rb_hash(rb_obj_class(s)));
|
||||
ptr = RSTRUCT_CONST_PTR(s);
|
||||
len = RSTRUCT_LEN(s);
|
||||
for (i = 0; i < len; i++) {
|
||||
n = rb_hash(ptr[i]);
|
||||
h = rb_hash_uint(h, NUM2LONG(n));
|
||||
}
|
||||
h = rb_hash_end(h);
|
||||
return INT2FIX(h);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
|
|
@ -2053,6 +2053,7 @@ class TestArray < Test::Unit::TestCase
|
|||
assert_not_equal([[1]].hash, [[2]].hash)
|
||||
a = []
|
||||
a << a
|
||||
assert_not_equal([a, 1].hash, [a, 2].hash)
|
||||
assert_not_equal([a, a].hash, a.hash) # Implementation dependent
|
||||
end
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче