diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-26 07:00:04 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-26 07:00:04 +0000 |
commit | cb0a4c0f6231639dab11d50b21614cbea019e5d4 (patch) | |
tree | f624d00849c92461652879b065649a0693bc575d /bignum.c | |
parent | 6f3ad9bd3d1c0fd53539d55743b445d67360e911 (diff) |
* bignum.c (bigdivrem): restart calculation when bigdivrem1 was
interrupted by signal. Otherwise, ruby script may see a garbage
value.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37850 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 15 |
1 files changed, 13 insertions, 2 deletions
@@ -2713,16 +2713,22 @@ rb_big_stop(void *ptr) } static VALUE -bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) +bigdivrem(VALUE x, VALUE y_, volatile VALUE *divp, volatile VALUE *modp) { + VALUE y; struct big_div_struct bds; - long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y); + long nx, ny; long i, j; VALUE z, yy, zz; BDIGIT *xds, *yds, *zds, *tds; BDIGIT_DBL t2; BDIGIT dd, q; + retry: + y = y_; + nx = RBIGNUM_LEN(x); + ny = RBIGNUM_LEN(y); + if (BIGZEROP(y)) rb_num_zerodiv(); xds = BDIGITS(x); yds = BDIGITS(y); @@ -2795,6 +2801,11 @@ bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp) bds.stop = Qfalse; if (nx > 10000 || ny > 10000) { rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds); + + if (bds.stop == Qtrue) { + /* execute trap handler, but exception was not raised. */ + goto retry; + } } else { bigdivrem1(&bds); |