diff --git a/include/mruby/internal.h b/include/mruby/internal.h index d60675f61..86883f821 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -74,7 +74,8 @@ mrb_irep_catch_handler_table(const struct mrb_irep *irep) #endif /* numeric */ -mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_int mrb_div_int(mrb_int x, mrb_int y); mrb_value mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y); diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8d9a96ba9..f61b68536 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -867,7 +867,7 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) else { /* OP_DIV */ if (n == 0) goto normal; if (n0 == MRB_INT_MIN && n == -1) goto normal; - n = mrb_div_int(s->mrb, n0, n); + n = mrb_div_int(n0, n); } s->pc = addr_pc(s, data0.addr); gen_int(s, dst, n); diff --git a/src/numeric.c b/src/numeric.c index d1b7b6597..90fb58c2d 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -107,7 +107,18 @@ mrb_int_pow(mrb_state *mrb, mrb_value x) #define int_pow mrb_int_pow mrb_int -mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y) +mrb_div_int(mrb_int x, mrb_int y) +{ + mrb_int div = x / y; + + if ((x ^ y) < 0 && x != div * y) { + div -= 1; + } + return div; +} + +mrb_value +mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y) { if (y == 0) { mrb_int_zerodiv(mrb); @@ -115,16 +126,7 @@ mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y) else if(x == MRB_INT_MIN && y == -1) { mrb_int_overflow(mrb, "division"); } - else { - mrb_int div = x / y; - - if ((x ^ y) < 0 && x != div * y) { - div -= 1; - } - return div; - } - /* not reached */ - return 0; + return mrb_int_value(mrb, mrb_div_int(x, y)); } /* 15.2.8.3.4 */ @@ -156,8 +158,7 @@ int_div(mrb_state *mrb, mrb_value x) return mrb_bint_mul_ii(mrb, a, b); } #endif - mrb_int div = mrb_div_int(mrb, a, b); - return mrb_int_value(mrb, div); + return mrb_div_int_value(mrb, a, b); } switch (mrb_type(y)) { #ifdef MRB_USE_BIGINT @@ -207,7 +208,7 @@ int_idiv(mrb_state *mrb, mrb_value x) mrb_int y; mrb_get_args(mrb, "i", &y); - return mrb_int_value(mrb, mrb_div_int(mrb, mrb_integer(x), y)); + return mrb_div_int_value(mrb, mrb_integer(x), y); } static mrb_value @@ -288,11 +289,10 @@ flo_pow(mrb_state *mrb, mrb_value x) static mrb_value flo_idiv(mrb_state *mrb, mrb_value xv) { - mrb_int y, div; + mrb_int y; mrb_get_args(mrb, "i", &y); - div = mrb_div_int(mrb, (mrb_int)mrb_float(xv), y); - return mrb_int_value(mrb, (mrb_int)div); + return mrb_div_int_value(mrb, (mrb_int)mrb_float(xv), y); } mrb_float diff --git a/src/vm.c b/src/vm.c index 3c3a5237f..424567a18 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2553,8 +2553,7 @@ RETRY_TRY_BLOCK: { mrb_int x = mrb_integer(regs[a]); mrb_int y = mrb_integer(regs[a+1]); - mrb_int div = mrb_div_int(mrb, x, y); - SET_INT_VALUE(mrb, regs[a], div); + regs[a] = mrb_div_int_value(mrb, x, y); } NEXT; #ifndef MRB_NO_FLOAT