summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-11-03 09:35:55 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-11-03 09:35:55 +0900
commit12e38597c84f12e1064119d6b929c193eb1805e9 (patch)
tree1978f8c0e2052cee763c1bf12d80873d44295611 /src/vm.c
parentd489b41c31361844ee4715c1aac54f3f0b353995 (diff)
downloadmruby-12e38597c84f12e1064119d6b929c193eb1805e9.tar.gz
mruby-12e38597c84f12e1064119d6b929c193eb1805e9.zip
Always check division-by-zero to avoid undefined behavior; fix #3816
Also removed the code to normalize NaN value for `MRB_NAN_BOXING`. Tha code was added to fix #1712 but no longer required after 249f05e7d.
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c67
1 files changed, 18 insertions, 49 deletions
diff --git a/src/vm.c b/src/vm.c
index bb884f4a0..e5b7de0da 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -2331,70 +2331,39 @@ RETRY_TRY_BLOCK:
CASE(OP_DIV) {
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
int a = GETARG_A(i);
+ double x, y, f;
/* need to check if op is overridden */
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- double f;
- if (y == 0) {
- if (x > 0) f = INFINITY;
- else if (x < 0) f = -INFINITY;
- else /* if (x == 0) */ f = NAN;
- }
- else {
- f = (mrb_float)x / (mrb_float)y;
- }
- SET_FLOAT_VALUE(mrb, regs[a], f);
- }
+ x = (mrb_float)mrb_fixnum(regs[a]);
+ y = (mrb_float)mrb_fixnum(regs[a+1]);
break;
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y);
- }
+ x = (mrb_float)mrb_fixnum(regs[a]);
+ y = mrb_float(regs[a+1]);
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- double f;
- if (y == 0) {
- f = INFINITY;
- }
- else {
- f = x / y;
- }
- SET_FLOAT_VALUE(mrb, regs[a], f);
- }
-#else
- OP_MATH_BODY(/,mrb_float,mrb_fixnum);
-#endif
+ x = mrb_float(regs[a]);
+ y = (mrb_float)mrb_fixnum(regs[a+1]);
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x / y);
- }
-#else
- OP_MATH_BODY(/,mrb_float,mrb_float);
-#endif
+ x = mrb_float(regs[a]);
+ y = mrb_float(regs[a+1]);
break;
default:
goto L_SEND;
}
-#ifdef MRB_NAN_BOXING
- if (isnan(mrb_float(regs[a]))) {
- mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
- regs[a] = v;
+
+ if (y == 0) {
+ if (x > 0) f = INFINITY;
+ else if (x < 0) f = -INFINITY;
+ else /* if (x == 0) */ f = NAN;
}
-#endif
+ else {
+ f = x / y;
+ }
+ SET_FLOAT_VALUE(mrb, regs[a], f);
NEXT;
}