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

ruby-changes:12640

From: nobu <ko1@a...>
Date: Sun, 2 Aug 2009 14:21:10 +0900 (JST)
Subject: [ruby-changes:12640] Ruby:r24353 (trunk): * random.c (rand_int): prevent from GC.

nobu	2009-08-02 14:20:51 +0900 (Sun, 02 Aug 2009)

  New Revision: 24353

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24353

  Log:
    * random.c (rand_int): prevent from GC.

  Modified files:
    trunk/ChangeLog
    trunk/random.c
    trunk/test/ruby/test_rand.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 24352)
+++ ChangeLog	(revision 24353)
@@ -1,3 +1,7 @@
+Sun Aug  2 14:20:43 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* random.c (rand_int): prevent from GC.
+
 Sat Aug  1 19:23:27 2009  NARUSE, Yui  <naruse@r...>
 
 	* string.c (tr_trans): change condition of singlebyte
Index: test/ruby/test_rand.rb
===================================================================
--- test/ruby/test_rand.rb	(revision 24352)
+++ test/ruby/test_rand.rb	(revision 24353)
@@ -4,13 +4,24 @@
   def assert_random_int(ws, m, init = 0)
     srand(init)
     rnds = [Random.new(init)]
-    ws.each do |w|
+    rnds2 = [rnds[0].dup]
+    rnds3 = [rnds[0].dup]
+    ws.each_with_index do |w, i|
       w = w.to_i
       assert_equal(w, rand(m))
       rnds.each do |rnd|
         assert_equal(w, rnd.int(m))
       end
+      rnds2.each do |rnd|
+        r=rnd.int(i...(m+i))
+        assert_equal(w+i, r)
+      end
+      rnds3.each do |rnd|
+        r=rnd.int(i..(m+i-1))
+        assert_equal(w+i, r)
+      end
       rnds << Marshal.load(Marshal.dump(rnds[-1]))
+      rnds2 << Marshal.load(Marshal.dump(rnds2[-1]))
     end
   end
 
Index: random.c
===================================================================
--- random.c	(revision 24352)
+++ random.c	(revision 24353)
@@ -855,27 +855,32 @@
 static VALUE
 rand_int(struct MT *mt, VALUE vmax)
 {
+    long max;
+    unsigned long r;
+
     if (FIXNUM_P(vmax)) {
-	long max = FIX2LONG(vmax);
-	unsigned long r;
+	max = FIX2LONG(vmax);
 	if (!max) return Qnil;
 	r = limited_rand(mt, (unsigned long)(max < 0 ? -max : max) - 1);
 	return ULONG2NUM(r);
     }
     else {
-	struct RBignum *limit = (struct RBignum *)vmax;
+	VALUE ret;
 	if (rb_bigzero_p(vmax)) return Qnil;
-	if (!RBIGNUM_SIGN(limit)) {
-	    limit = (struct RBignum *)rb_big_clone(vmax);
-	    RBIGNUM_SET_SIGN(limit, 1);
+	if (!RBIGNUM_SIGN(vmax)) {
+	    vmax = rb_big_clone(vmax);
+	    RBIGNUM_SET_SIGN(vmax, 1);
 	}
-	limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1));
-	if (FIXNUM_P((VALUE)limit)) {
-	    if (FIX2LONG((VALUE)limit) == -1)
-		return Qnil;
-	    return LONG2NUM(limited_rand(mt, FIX2LONG((VALUE)limit)));
+	vmax = rb_big_minus(vmax, INT2FIX(1));
+	if (FIXNUM_P(vmax)) {
+	    max = FIX2LONG(vmax);
+	    if (max == -1) return Qnil;
+	    r = limited_rand(mt, max);
+	    return LONG2NUM(r);
 	}
-	return limited_big_rand(mt, limit);
+	ret = limited_big_rand(mt, RBIGNUM(vmax));
+	RB_GC_GUARD(vmax);
+	return ret;
     }
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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