diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-11-01 05:54:53 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-11-01 05:54:53 +0900 |
| commit | 9b85ffa5a760e53536762bf6cdf402c90ae9ceb7 (patch) | |
| tree | 233c39ed97abc4703ede75fd16b5b97ff337adb2 | |
| parent | 604e39bdfbc97666671c2b638c1cd2cdc068be3e (diff) | |
| download | mruby-9b85ffa5a760e53536762bf6cdf402c90ae9ceb7.tar.gz mruby-9b85ffa5a760e53536762bf6cdf402c90ae9ceb7.zip | |
OP_ADDI/OP_SUBI should handle integer overflow; close #518
| -rw-r--r-- | src/vm.c | 26 |
1 files changed, 24 insertions, 2 deletions
@@ -1444,7 +1444,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* need to check if + is overridden */ switch (mrb_type(regs[a])) { case MRB_TT_FIXNUM: - regs[a].attr_i += GETARG_C(i); + { + mrb_int x = regs[a].attr_i; + mrb_int y = GETARG_C(i); + mrb_int z = x + y; + + if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { + /* integer overflow */ + SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y); + break; + } + regs[a].attr_i = z; + } break; case MRB_TT_FLOAT: regs[a].attr_f += GETARG_C(i); @@ -1464,7 +1475,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* need to check if + is overridden */ switch (mrb_type(regs[a])) { case MRB_TT_FIXNUM: - regs[a].attr_i -= GETARG_C(i); + { + mrb_int x = regs[a].attr_i; + mrb_int y = GETARG_C(i); + mrb_int z = x - y; + + if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { + /* integer overflow */ + SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); + break; + } + regs[a].attr_i = z; + } break; case MRB_TT_FLOAT: regs[a].attr_f -= GETARG_C(i); |
