ruby-changes:53462
From: shyouhei <ko1@a...>
Date: Mon, 12 Nov 2018 12:26:46 +0900 (JST)
Subject: [ruby-changes:53462] shyouhei:r65678 (trunk): vm_insnhelper.c: avoid division by zero
shyouhei 2018-11-12 12:26:39 +0900 (Mon, 12 Nov 2018) New Revision: 65678 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65678 Log: vm_insnhelper.c: avoid division by zero same as r65642. Modified files: trunk/internal.h trunk/numeric.c trunk/vm_insnhelper.c Index: numeric.c =================================================================== --- numeric.c (revision 65677) +++ numeric.c (revision 65678) @@ -1089,6 +1089,30 @@ flo_iszero(VALUE f) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1089 return RFLOAT_VALUE(f) == 0.0; } +static double +double_div_double(double x, double y) +{ + if (LIKELY(y != 0.0)) { + return x / y; + } + else if (x == 0.0) { + return nan(""); + } + else { + double z = signbit(y) ? -1.0 : 1.0; + return x * z * HUGE_VAL; + } +} + +VALUE +rb_flo_div_flo(VALUE x, VALUE y) +{ + double num = RFLOAT_VALUE(x); + double den = RFLOAT_VALUE(y); + double ret = double_div_double(x, y); + return DBL2NUM(ret); +} + /* * call-seq: * float / other -> float @@ -1099,52 +1123,25 @@ flo_iszero(VALUE f) https://github.com/ruby/ruby/blob/trunk/numeric.c#L1123 static VALUE flo_div(VALUE x, VALUE y) { - double den; double num = RFLOAT_VALUE(x); - double sign = 1.0; + double den; + double ret; if (RB_TYPE_P(y, T_FIXNUM)) { - if (FIXNUM_ZERO_P(y)) { - goto zerodiv; - } - else { - den = FIX2LONG(y); - goto nonzero; - } + den = FIX2LONG(y); } else if (RB_TYPE_P(y, T_BIGNUM)) { - if (rb_bigzero_p(y)) { - goto zerodiv; - } - else { - den = rb_big2dbl(y); - goto nonzero; - } + den = rb_big2dbl(y); } else if (RB_TYPE_P(y, T_FLOAT)) { - if (flo_iszero(y)) { - sign = signbit(RFLOAT_VALUE(y)) ? -1.0 : 1.0; - goto zerodiv; - } - else { - den = RFLOAT_VALUE(y); - goto nonzero; - } + den = RFLOAT_VALUE(y); } else { return rb_num_coerce_bin(x, y, '/'); } -nonzero: - return DBL2NUM(num / den); - -zerodiv: - if (num == 0.0) { - return DBL2NUM(nan("")); - } - else { - return DBL2NUM(num * sign * HUGE_VAL); - } + ret = double_div_double(num, den); + return DBL2NUM(ret); } /* Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 65677) +++ vm_insnhelper.c (revision 65678) @@ -3450,7 +3450,7 @@ vm_opt_div(VALUE recv, VALUE obj) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3450 } else if (FLONUM_2_P(recv, obj) && BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) { - return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj)); + return rb_flo_div_flo(recv, obj); } else if (SPECIAL_CONST_P(recv) || SPECIAL_CONST_P(obj)) { return Qundef; @@ -3458,7 +3458,7 @@ vm_opt_div(VALUE recv, VALUE obj) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3458 else if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat && BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) { - return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj)); + return rb_flo_div_flo(recv, obj); } else { return Qundef; Index: internal.h =================================================================== --- internal.h (revision 65677) +++ internal.h (revision 65678) @@ -1755,6 +1755,7 @@ rb_num_negative_int_p(VALUE num) https://github.com/ruby/ruby/blob/trunk/internal.h#L1755 VALUE rb_float_abs(VALUE flt); VALUE rb_float_equal(VALUE x, VALUE y); VALUE rb_float_eql(VALUE x, VALUE y); +VALUE rb_flo_div_flo(VALUE x, VALUE y); #if USE_FLONUM #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n))) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/