From 12e38597c84f12e1064119d6b929c193eb1805e9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 3 Nov 2017 09:35:55 +0900 Subject: 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. --- mrbgems/mruby-struct/src/struct.c | 2 +- src/vm.c | 67 +++++++++++---------------------------- 2 files changed, 19 insertions(+), 50 deletions(-) diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 019f99f22..1d2e62583 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -200,7 +200,7 @@ make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c } static mrb_value -make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass) +make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *klass) { mrb_value nstr; mrb_sym id; 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; } -- cgit v1.2.3