зеркало из 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>
|
Tue Dec 3 21:53:15 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* vm_eval.c (rb_catch_protect): new function similar to
|
* 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);
|
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:
|
* call-seq:
|
||||||
* ary.hash -> fixnum
|
* ary.hash -> fixnum
|
||||||
|
@ -3808,7 +3787,17 @@ recursive_hash(VALUE ary, VALUE dummy, int recur)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_hash(VALUE ary)
|
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
|
static VALUE
|
||||||
hash_recursive(VALUE obj, VALUE arg, int recurse)
|
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);
|
return rb_funcallv(obj, id_hash, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_hash(VALUE obj)
|
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:
|
retry:
|
||||||
switch (TYPE(hval)) {
|
switch (TYPE(hval)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
|
@ -1959,20 +1962,6 @@ hash_i(VALUE key, VALUE val, VALUE arg)
|
||||||
return ST_CONTINUE;
|
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:
|
* call-seq:
|
||||||
* hsh.hash -> fixnum
|
* hsh.hash -> fixnum
|
||||||
|
@ -1984,7 +1973,12 @@ recursive_hash(VALUE hash, VALUE dummy, int recur)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_hash_hash(VALUE hash)
|
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
|
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);
|
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:
|
* call-seq:
|
||||||
* rng.hash -> fixnum
|
* rng.hash -> fixnum
|
||||||
|
@ -274,7 +255,18 @@ recursive_hash(VALUE range, VALUE dummy, int recur)
|
||||||
static VALUE
|
static VALUE
|
||||||
range_hash(VALUE range)
|
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
|
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);
|
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:
|
* call-seq:
|
||||||
* struct.hash -> fixnum
|
* struct.hash -> fixnum
|
||||||
|
@ -980,7 +959,20 @@ recursive_hash(VALUE s, VALUE dummy, int recur)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_struct_hash(VALUE s)
|
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
|
static VALUE
|
||||||
|
|
|
@ -2053,6 +2053,7 @@ class TestArray < Test::Unit::TestCase
|
||||||
assert_not_equal([[1]].hash, [[2]].hash)
|
assert_not_equal([[1]].hash, [[2]].hash)
|
||||||
a = []
|
a = []
|
||||||
a << a
|
a << a
|
||||||
|
assert_not_equal([a, 1].hash, [a, 2].hash)
|
||||||
assert_not_equal([a, a].hash, a.hash) # Implementation dependent
|
assert_not_equal([a, a].hash, a.hash) # Implementation dependent
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче