[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]