summaryrefslogtreecommitdiffstats
path: root/random.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-02 05:20:51 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-02 05:20:51 +0000
commitd9876a53b51d56257982821789e05a41d03f0bc5 (patch)
tree69e41da5fe299d192654898b1b44b7e6e4535e2a /random.c
parent3d6a864d52c8d28827d036d5fe6dcacfb23f14c1 (diff)
downloadruby-d9876a53b51d56257982821789e05a41d03f0bc5.tar.gz
ruby-d9876a53b51d56257982821789e05a41d03f0bc5.tar.xz
ruby-d9876a53b51d56257982821789e05a41d03f0bc5.zip
* random.c (rand_int): prevent from GC.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@24353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'random.c')
-rw-r--r--random.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/random.c b/random.c
index 4a6299386..0855a1bc7 100644
--- a/random.c
+++ b/random.c
@@ -855,27 +855,32 @@ add_to_begin(VALUE beg, VALUE offset)
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;
}
}