ruby-changes:31901
From: nobu <ko1@a...>
Date: Tue, 3 Dec 2013 22:18:37 +0900 (JST)
Subject: [ruby-changes:31901] nobu:r43980 (trunk): hash.c: detect recursion for all
nobu 2013-12-03 22:18:30 +0900 (Tue, 03 Dec 2013) New Revision: 43980 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43980 Log: 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(). Modified files: trunk/ChangeLog trunk/array.c trunk/hash.c trunk/range.c trunk/struct.c trunk/test/ruby/test_array.rb Index: array.c =================================================================== --- array.c (revision 43979) +++ array.c (revision 43980) @@ -3774,27 +3774,6 @@ rb_ary_eql(VALUE ary1, VALUE ary2) https://github.com/ruby/ruby/blob/trunk/array.c#L3774 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, i https://github.com/ruby/ruby/blob/trunk/array.c#L3787 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); } /* Index: ChangeLog =================================================================== --- ChangeLog (revision 43979) +++ ChangeLog (revision 43980) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Dec 3 22:18:27 2013 Nobuyoshi Nakada <nobu@r...> + + * 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@r...> * vm_eval.c (rb_catch_protect): new function similar to Index: range.c =================================================================== --- range.c (revision 43979) +++ range.c (revision 43980) @@ -243,25 +243,6 @@ range_eql(VALUE range, VALUE obj) https://github.com/ruby/ruby/blob/trunk/range.c#L243 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, https://github.com/ruby/ruby/blob/trunk/range.c#L255 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 Index: struct.c =================================================================== --- struct.c (revision 43979) +++ struct.c (revision 43980) @@ -949,8 +949,15 @@ rb_struct_equal(VALUE s, VALUE s2) https://github.com/ruby/ruby/blob/trunk/struct.c#L949 return rb_exec_recursive_paired(recursive_equal, s, s2, s2); } +/* + * call-seq: + * struct.hash -> fixnum + * + * Returns a hash value based on this struct's contents (see Object#hash). + */ + static VALUE -recursive_hash(VALUE s, VALUE dummy, int recur) +rb_struct_hash(VALUE s) { long i, len; st_index_t h; @@ -958,31 +965,16 @@ recursive_hash(VALUE s, VALUE dummy, int https://github.com/ruby/ruby/blob/trunk/struct.c#L965 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)); - } + 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 - * - * Returns a hash value based on this struct's contents (see Object#hash). - */ - -static VALUE -rb_struct_hash(VALUE s) -{ - return rb_exec_recursive_paired(recursive_hash, s, s, 0); -} - static VALUE recursive_eql(VALUE s, VALUE s2, int recur) { Index: hash.c =================================================================== --- hash.c (revision 43979) +++ hash.c (revision 43980) @@ -79,14 +79,17 @@ rb_any_cmp(VALUE a, VALUE b) https://github.com/ruby/ruby/blob/trunk/hash.c#L79 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) https://github.com/ruby/ruby/blob/trunk/hash.c#L1962 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, https://github.com/ruby/ruby/blob/trunk/hash.c#L1973 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 Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 43979) +++ test/ruby/test_array.rb (revision 43980) @@ -2053,6 +2053,7 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L2053 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/