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:
nobu 2013-12-03 13:18:30 +00:00
Родитель c7159e81fc
Коммит 6f2efe84fb
6 изменённых файлов: 54 добавлений и 81 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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

Просмотреть файл

@ -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