Integer overflow in operations should cause `RangeError`.

parent dd3ed8d9
...@@ -1090,11 +1090,7 @@ RETRY_TRY_BLOCK: ...@@ -1090,11 +1090,7 @@ RETRY_TRY_BLOCK:
break; break;
} }
#endif #endif
{ goto L_INT_OVERFLOW;
mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "integer overflow");
mrb_exc_set(mrb, exc);
}
goto L_RAISE;
#endif #endif
#ifndef MRB_NO_FLOAT #ifndef MRB_NO_FLOAT
case IREP_TT_FLOAT: case IREP_TT_FLOAT:
...@@ -2250,34 +2246,40 @@ RETRY_TRY_BLOCK: ...@@ -2250,34 +2246,40 @@ RETRY_TRY_BLOCK:
NEXT; NEXT;
} }
L_INT_OVERFLOW:
{
mrb_value exc = mrb_exc_new_lit(mrb, E_RANGE_ERROR, "integer overflow");
mrb_exc_set(mrb, exc);
}
goto L_RAISE;
#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
#define OP_MATH(op_name) \ #define OP_MATH(op_name) \
/* need to check if op is overridden */ \ /* need to check if op is overridden */ \
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \
OP_MATH_CASE_FIXNUM(op_name); \ OP_MATH_CASE_INTEGER(op_name); \
OP_MATH_CASE_FLOAT(op_name, fixnum, float); \ OP_MATH_CASE_FLOAT(op_name, integer, float); \
OP_MATH_CASE_FLOAT(op_name, float, fixnum); \ OP_MATH_CASE_FLOAT(op_name, float, integer); \
OP_MATH_CASE_FLOAT(op_name, float, float); \ OP_MATH_CASE_FLOAT(op_name, float, float); \
OP_MATH_CASE_STRING_##op_name(); \ OP_MATH_CASE_STRING_##op_name(); \
default: \ default: \
c = 1; \ c = 1; \
mid = MRB_OPSYM(op_name); \ mid = MRB_OPSYM(op_name); \
goto L_SEND_SYM; \ goto L_SEND_SYM; \
} \ } \
NEXT; NEXT;
#define OP_MATH_CASE_FIXNUM(op_name) \ #define OP_MATH_CASE_INTEGER(op_name) \
case TYPES2(MRB_TT_INTEGER, MRB_TT_INTEGER): \ case TYPES2(MRB_TT_INTEGER, MRB_TT_INTEGER): \
{ \ { \
mrb_int x = mrb_integer(regs[a]), y = mrb_integer(regs[a+1]), z; \ mrb_int x = mrb_integer(regs[a]), y = mrb_integer(regs[a+1]), z; \
if (mrb_int_##op_name##_overflow(x, y, &z)) \ if (mrb_int_##op_name##_overflow(x, y, &z)) \
OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ OP_MATH_OVERFLOW_INT(); \
else \ else \
SET_INT_VALUE(mrb,regs[a], z); \ SET_INT_VALUE(mrb,regs[a], z); \
} \ } \
break break
#ifdef MRB_NO_FLOAT #ifdef MRB_NO_FLOAT
#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0 #define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(mrb,regs[a], z)
#else #else
#define OP_MATH_CASE_FLOAT(op_name, t1, t2) \ #define OP_MATH_CASE_FLOAT(op_name, t1, t2) \
case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \ case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \
...@@ -2286,9 +2288,8 @@ RETRY_TRY_BLOCK: ...@@ -2286,9 +2288,8 @@ RETRY_TRY_BLOCK:
SET_FLOAT_VALUE(mrb, regs[a], z); \ SET_FLOAT_VALUE(mrb, regs[a], z); \
} \ } \
break break
#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y)
#endif #endif
#define OP_MATH_OVERFLOW_INT() goto L_INT_OVERFLOW
#define OP_MATH_CASE_STRING_add() \ #define OP_MATH_CASE_STRING_add() \
case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \
...@@ -2299,8 +2300,8 @@ RETRY_TRY_BLOCK: ...@@ -2299,8 +2300,8 @@ RETRY_TRY_BLOCK:
#define OP_MATH_OP_add + #define OP_MATH_OP_add +
#define OP_MATH_OP_sub - #define OP_MATH_OP_sub -
#define OP_MATH_OP_mul * #define OP_MATH_OP_mul *
#define OP_MATH_TT_fixnum MRB_TT_INTEGER #define OP_MATH_TT_integer MRB_TT_INTEGER
#define OP_MATH_TT_float MRB_TT_FLOAT #define OP_MATH_TT_float MRB_TT_FLOAT
CASE(OP_ADD, B) { CASE(OP_ADD, B) {
OP_MATH(add); OP_MATH(add);
...@@ -2361,21 +2362,21 @@ RETRY_TRY_BLOCK: ...@@ -2361,21 +2362,21 @@ RETRY_TRY_BLOCK:
#define OP_MATHI(op_name) \ #define OP_MATHI(op_name) \
/* need to check if op is overridden */ \ /* need to check if op is overridden */ \
switch (mrb_type(regs[a])) { \ switch (mrb_type(regs[a])) { \
OP_MATHI_CASE_FIXNUM(op_name); \ OP_MATHI_CASE_INTEGER(op_name); \
OP_MATHI_CASE_FLOAT(op_name); \ OP_MATHI_CASE_FLOAT(op_name); \
default: \ default: \
SET_INT_VALUE(mrb,regs[a+1], b); \ SET_INT_VALUE(mrb,regs[a+1], b); \
c = 1; \ c = 1; \
mid = MRB_OPSYM(op_name); \ mid = MRB_OPSYM(op_name); \
goto L_SEND_SYM; \ goto L_SEND_SYM; \
} \ } \
NEXT; NEXT;
#define OP_MATHI_CASE_FIXNUM(op_name) \ #define OP_MATHI_CASE_INTEGER(op_name) \
case MRB_TT_INTEGER: \ case MRB_TT_INTEGER: \
{ \ { \
mrb_int x = mrb_integer(regs[a]), y = (mrb_int)b, z; \ mrb_int x = mrb_integer(regs[a]), y = (mrb_int)b, z; \
if (mrb_int_##op_name##_overflow(x, y, &z)) \ if (mrb_int_##op_name##_overflow(x, y, &z)) \
OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ OP_MATH_OVERFLOW_INT(); \
else \ else \
SET_INT_VALUE(mrb,regs[a], z); \ SET_INT_VALUE(mrb,regs[a], z); \
} \ } \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment