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

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/

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