mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
optimized OP_{ADD,SUB,MUL,DIV} to use numeric function for fixnums to handle overflow
This commit is contained in:
@@ -22,6 +22,11 @@ mrb_value mrb_flt2big(mrb_state *mrb, mrb_float d);
|
||||
void mrb_num_zerodiv(mrb_state *mrb);
|
||||
mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base);
|
||||
|
||||
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
+119
-79
@@ -118,6 +118,12 @@ num_pow(mrb_state *mrb, mrb_value x)
|
||||
* result.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_float_value(mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
|
||||
}
|
||||
|
||||
/* 15.2.9.3.19(x) */
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -404,7 +410,7 @@ flo_to_f(mrb_state *mrb, mrb_value num)
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
flo_is_infinite_p(mrb_state *mrb, mrb_value num)
|
||||
flo_infinite_p(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
mrb_float value = mrb_float(num);
|
||||
|
||||
@@ -426,7 +432,7 @@ flo_is_infinite_p(mrb_state *mrb, mrb_value num)
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
flo_is_finite_p(mrb_state *mrb, mrb_value num)
|
||||
flo_finite_p(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
mrb_float value = mrb_float(num);
|
||||
|
||||
@@ -691,9 +697,31 @@ int_succ(mrb_state *mrb, mrb_value num)
|
||||
return mrb_funcall(mrb, num, "+", 1, mrb_fixnum_value(1));
|
||||
}
|
||||
|
||||
#define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
|
||||
#define SQRT_INT_MAX ((SIGNED_VALUE)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
|
||||
/*tests if N*N would overflow*/
|
||||
#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
|
||||
#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
|
||||
|
||||
mrb_value
|
||||
mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_int a;
|
||||
|
||||
a = mrb_fixnum(x);
|
||||
if (a == 0) return x;
|
||||
if (FIXNUM_P(y)) {
|
||||
mrb_int b, c;
|
||||
|
||||
b = mrb_fixnum(y);
|
||||
if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
|
||||
return mrb_fixnum_value(a*b);
|
||||
c = a * b;
|
||||
if (c/a != b) {
|
||||
return mrb_float_value((mrb_float)a*(mrb_float)b);
|
||||
}
|
||||
return mrb_fixnum_value(c);;
|
||||
}
|
||||
return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y));
|
||||
}
|
||||
|
||||
/* 15.2.8.3.3 */
|
||||
/*
|
||||
@@ -709,27 +737,8 @@ static mrb_value
|
||||
fix_mul(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
mrb_int a;
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
|
||||
a = mrb_fixnum(x);
|
||||
if (FIXNUM_P(y)) {
|
||||
mrb_int b, c;
|
||||
mrb_value r;
|
||||
|
||||
b = mrb_fixnum(y);
|
||||
if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
|
||||
return mrb_fixnum_value(a*b);
|
||||
c = a * b;
|
||||
r = mrb_fixnum_value(c);
|
||||
|
||||
if (a == 0) return x;
|
||||
if (mrb_fixnum(r) != c || c/a != b) {
|
||||
r = mrb_float_value((mrb_float)a*(mrb_float)b);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return mrb_float_value((mrb_float)a * mrb_to_flo(mrb, y));
|
||||
return mrb_fixnum_mul(mrb, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -942,8 +951,28 @@ fix_xor(mrb_state *mrb, mrb_value x)
|
||||
return mrb_fixnum_value(val);
|
||||
}
|
||||
|
||||
static mrb_value fix_lshift(mrb_state *mrb, mrb_int, unsigned long);
|
||||
static mrb_value fix_rshift(mrb_int, unsigned long);
|
||||
static mrb_value
|
||||
lshift(mrb_state *mrb, mrb_int val, unsigned long width)
|
||||
{
|
||||
if (width > (sizeof(mrb_int)*CHAR_BIT-1)
|
||||
|| ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width,
|
||||
sizeof(mrb_int)*CHAR_BIT-1);
|
||||
}
|
||||
val = val << width;
|
||||
return mrb_fixnum_value(val);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
rshift(mrb_int val, unsigned long i)
|
||||
{
|
||||
if (i >= sizeof(mrb_int)*CHAR_BIT-1) {
|
||||
if (val < 0) return mrb_fixnum_value(-1);
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
val = RSHIFT(val, i);
|
||||
return mrb_fixnum_value(val);
|
||||
}
|
||||
|
||||
/* 15.2.8.3.12 */
|
||||
/*
|
||||
@@ -954,7 +983,7 @@ static mrb_value fix_rshift(mrb_int, unsigned long);
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_fix_lshift(mrb_state *mrb, mrb_value x)
|
||||
fix_lshift(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
mrb_int val, width;
|
||||
@@ -964,20 +993,8 @@ mrb_fix_lshift(mrb_state *mrb, mrb_value x)
|
||||
y = bit_coerce(mrb, y);
|
||||
width = mrb_fixnum(y);
|
||||
if (width < 0)
|
||||
return fix_rshift(val, (unsigned long)-width);
|
||||
return fix_lshift(mrb, val, width);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
fix_lshift(mrb_state *mrb, mrb_int val, unsigned long width)
|
||||
{
|
||||
if (width > (sizeof(mrb_int)*CHAR_BIT-1)
|
||||
|| ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width,
|
||||
sizeof(mrb_int)*CHAR_BIT-1);
|
||||
}
|
||||
val = val << width;
|
||||
return mrb_fixnum_value(val);
|
||||
return rshift(val, (unsigned long)-width);
|
||||
return lshift(mrb, val, width);
|
||||
}
|
||||
|
||||
/* 15.2.8.3.13 */
|
||||
@@ -989,7 +1006,7 @@ fix_lshift(mrb_state *mrb, mrb_int val, unsigned long width)
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_fix_rshift(mrb_state *mrb, mrb_value x)
|
||||
fix_rshift(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
mrb_int i, val;
|
||||
@@ -1000,19 +1017,8 @@ mrb_fix_rshift(mrb_state *mrb, mrb_value x)
|
||||
i = mrb_fixnum(y);
|
||||
if (i == 0) return x;
|
||||
if (i < 0)
|
||||
return fix_lshift(mrb, val, (unsigned long)-i);
|
||||
return fix_rshift(val, i);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
fix_rshift(mrb_int val, unsigned long i)
|
||||
{
|
||||
if (i >= sizeof(mrb_int)*CHAR_BIT-1) {
|
||||
if (val < 0) return mrb_fixnum_value(-1);
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
val = RSHIFT(val, i);
|
||||
return mrb_fixnum_value(val);
|
||||
return lshift(mrb, val, (unsigned long)-i);
|
||||
return rshift(val, i);
|
||||
}
|
||||
|
||||
/* 15.2.8.3.23 */
|
||||
@@ -1066,7 +1072,27 @@ flt2big(mrb_state *mrb, mrb_float d)
|
||||
mrb_value
|
||||
mrb_flt2big(mrb_state *mrb, mrb_float d)
|
||||
{
|
||||
return mrb_fixnum_value(flt2big(mrb, d));
|
||||
return mrb_fixnum_value(flt2big(mrb, d));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_int a;
|
||||
|
||||
a = mrb_fixnum(x);
|
||||
if (a == 0) return y;
|
||||
if (FIXNUM_P(y)) {
|
||||
mrb_int b, c;
|
||||
|
||||
b = mrb_fixnum(y);
|
||||
c = a + b;
|
||||
if (c - b != a) {
|
||||
return mrb_float_value((mrb_float)a + (mrb_float)b);
|
||||
}
|
||||
return mrb_fixnum_value(c);
|
||||
}
|
||||
return mrb_float_value((mrb_float)a + mrb_to_flo(mrb, y));
|
||||
}
|
||||
|
||||
/* 15.2.8.3.1 */
|
||||
@@ -1079,15 +1105,32 @@ mrb_flt2big(mrb_state *mrb, mrb_float d)
|
||||
* result.
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_fixnum_plus(mrb_state *mrb, mrb_value self)
|
||||
fix_plus(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int x, y;
|
||||
mrb_value other;
|
||||
|
||||
x = mrb_fixnum(self);
|
||||
mrb_get_args(mrb, "i", &y);
|
||||
mrb_get_args(mrb, "o", &other);
|
||||
return mrb_fixnum_plus(mrb, self, other);
|
||||
}
|
||||
|
||||
DEBUG(printf("%d + %d = %d\n", x, y, x+y));
|
||||
return mrb_fixnum_value(x + y);
|
||||
mrb_value
|
||||
mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_int a;
|
||||
|
||||
a = mrb_fixnum(x);
|
||||
if (a == 0) return y;
|
||||
if (FIXNUM_P(y)) {
|
||||
mrb_int b, c;
|
||||
|
||||
b = mrb_fixnum(y);
|
||||
c = a - b;
|
||||
if (c + b != a) {
|
||||
return mrb_float_value((mrb_float)a - (mrb_float)b);
|
||||
}
|
||||
return mrb_fixnum_value(c);
|
||||
}
|
||||
return mrb_float_value((mrb_float)a - mrb_to_flo(mrb, y));
|
||||
}
|
||||
|
||||
/* 15.2.8.3.2 */
|
||||
@@ -1101,15 +1144,12 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value self)
|
||||
* result.
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_fixnum_minus(mrb_state *mrb, mrb_value self)
|
||||
fix_minus(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int x, y;
|
||||
mrb_value other;
|
||||
|
||||
x = mrb_fixnum(self);
|
||||
mrb_get_args(mrb, "i", &y);
|
||||
|
||||
DEBUG(printf("%d - %d = %d\n", x, y, x-y));
|
||||
return mrb_fixnum_value(x - y);
|
||||
mrb_get_args(mrb, "o", &other);
|
||||
return mrb_fixnum_minus(mrb, self, other);
|
||||
}
|
||||
|
||||
/* 15.2.8.3.29 (x) */
|
||||
@@ -1179,7 +1219,7 @@ mrb_fix_to_s(mrb_state *mrb, mrb_value self, int argc, mrb_value *argv)
|
||||
*
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_fixnum_to_s(mrb_state *mrb, mrb_value self) /* fix_to_s */
|
||||
fix_to_s(mrb_state *mrb, mrb_value self) /* fix_to_s */
|
||||
{
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
@@ -1236,7 +1276,7 @@ num_cmp(mrb_state *mrb, mrb_value self)
|
||||
* and <code>other</code>.
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_float_plus(mrb_state *mrb, mrb_value self)
|
||||
flo_plus(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_float x, y;
|
||||
|
||||
@@ -1267,8 +1307,8 @@ mrb_init_numeric(mrb_state *mrb)
|
||||
fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer);
|
||||
|
||||
mrb_undef_method(mrb, fixnum, "new");
|
||||
mrb_define_method(mrb, fixnum, "+", mrb_fixnum_plus, ARGS_REQ(1)); /* 15.2.8.3.1 */
|
||||
mrb_define_method(mrb, fixnum, "-", mrb_fixnum_minus, ARGS_REQ(1)); /* 15.2.8.3.2 */
|
||||
mrb_define_method(mrb, fixnum, "+", fix_plus, ARGS_REQ(1)); /* 15.2.8.3.1 */
|
||||
mrb_define_method(mrb, fixnum, "-", fix_minus, ARGS_REQ(1)); /* 15.2.8.3.2 */
|
||||
mrb_define_method(mrb, fixnum, "-@", fix_uminus, ARGS_REQ(1)); /* 15.2.7.4.2 */
|
||||
mrb_define_method(mrb, fixnum, "*", fix_mul, ARGS_REQ(1)); /* 15.2.8.3.3 */
|
||||
mrb_define_method(mrb, fixnum, "%", fix_mod, ARGS_REQ(1)); /* 15.2.8.3.5 */
|
||||
@@ -1277,8 +1317,8 @@ mrb_init_numeric(mrb_state *mrb)
|
||||
mrb_define_method(mrb, fixnum, "&", fix_and, ARGS_REQ(1)); /* 15.2.8.3.9 */
|
||||
mrb_define_method(mrb, fixnum, "|", fix_or, ARGS_REQ(1)); /* 15.2.8.3.10 */
|
||||
mrb_define_method(mrb, fixnum, "^", fix_xor, ARGS_REQ(1)); /* 15.2.8.3.11 */
|
||||
mrb_define_method(mrb, fixnum, "<<", mrb_fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */
|
||||
mrb_define_method(mrb, fixnum, ">>", mrb_fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */
|
||||
mrb_define_method(mrb, fixnum, "<<", fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */
|
||||
mrb_define_method(mrb, fixnum, ">>", fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */
|
||||
mrb_define_method(mrb, fixnum, "ceil", int_to_i, ARGS_NONE()); /* 15.2.8.3.14 */
|
||||
mrb_define_method(mrb, fixnum, "eql?", num_eql, ARGS_REQ(1)); /* 15.2.8.3.16 */
|
||||
mrb_define_method(mrb, fixnum, "floor", num_floor, ARGS_NONE()); /* 15.2.8.3.17 */
|
||||
@@ -1288,22 +1328,22 @@ mrb_init_numeric(mrb_state *mrb)
|
||||
mrb_define_method(mrb, fixnum, "succ", fix_succ, ARGS_NONE()); /* 15.2.8.3.21 */
|
||||
mrb_define_method(mrb, fixnum, "to_f", fix_to_f, ARGS_NONE()); /* 15.2.8.3.23 */
|
||||
mrb_define_method(mrb, fixnum, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */
|
||||
mrb_define_method(mrb, fixnum, "to_s", mrb_fixnum_to_s, ARGS_NONE()); /* 15.2.8.3.25 */
|
||||
mrb_define_method(mrb, fixnum, "to_s", fix_to_s, ARGS_NONE()); /* 15.2.8.3.25 */
|
||||
mrb_define_method(mrb, fixnum, "truncate", int_to_i, ARGS_NONE()); /* 15.2.8.3.26 */
|
||||
mrb_define_method(mrb, fixnum, "divmod", fix_divmod, ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
|
||||
|
||||
/* Float Class */
|
||||
fl = mrb->float_class = mrb_define_class(mrb, "Float", numeric);
|
||||
mrb_undef_method(mrb, fl, "new");
|
||||
mrb_define_method(mrb, fl, "+", mrb_float_plus, ARGS_REQ(1)); /* 15.2.9.3.1 */
|
||||
mrb_define_method(mrb, fl, "+", flo_plus, ARGS_REQ(1)); /* 15.2.9.3.1 */
|
||||
mrb_define_method(mrb, fl, "-", flo_minus, ARGS_REQ(1)); /* 15.2.9.3.2 */
|
||||
mrb_define_method(mrb, fl, "*", flo_mul, ARGS_REQ(1)); /* 15.2.9.3.3 */
|
||||
mrb_define_method(mrb, fl, "%", flo_mod, ARGS_REQ(1)); /* 15.2.9.3.5 */
|
||||
mrb_define_method(mrb, fl, "==", flo_eq, ARGS_REQ(1)); /* 15.2.9.3.7 */
|
||||
mrb_define_method(mrb, fl, "ceil", flo_ceil, ARGS_NONE()); /* 15.2.9.3.8 */
|
||||
mrb_define_method(mrb, fl, "finite?", flo_is_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */
|
||||
mrb_define_method(mrb, fl, "finite?", flo_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */
|
||||
mrb_define_method(mrb, fl, "floor", flo_floor, ARGS_NONE()); /* 15.2.9.3.10 */
|
||||
mrb_define_method(mrb, fl, "infinite?", flo_is_infinite_p,ARGS_NONE()); /* 15.2.9.3.11 */
|
||||
mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, ARGS_NONE()); /* 15.2.9.3.11 */
|
||||
mrb_define_method(mrb, fl, "round", flo_round, ARGS_ANY()); /* 15.2.9.3.12 */
|
||||
mrb_define_method(mrb, fl, "to_f", flo_to_f, ARGS_NONE()); /* 15.2.9.3.13 */
|
||||
mrb_define_method(mrb, fl, "to_i", flo_truncate, ARGS_NONE()); /* 15.2.9.3.14 */
|
||||
|
||||
@@ -1162,12 +1162,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
regs[a].value.v1 = regs[a].value.v1 op regs[a+1].value.v2;\
|
||||
} while(0)
|
||||
|
||||
#define OP_MATH(op) do {\
|
||||
#define OP_MATH(op,iop,s) do {\
|
||||
int a = GETARG_A(i);\
|
||||
/* need to check if - is overridden */\
|
||||
/* 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):\
|
||||
OP_MATH_BODY(op,i,i); \
|
||||
regs[a] = iop(mrb, regs[a], regs[a+1]);\
|
||||
break;\
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\
|
||||
{\
|
||||
@@ -1182,6 +1182,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\
|
||||
OP_MATH_BODY(op,f,f);\
|
||||
break;\
|
||||
s\
|
||||
default:\
|
||||
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));\
|
||||
goto L_SEND;\
|
||||
@@ -1190,50 +1191,28 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
|
||||
CASE(OP_ADD) {
|
||||
/* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/
|
||||
int a = GETARG_A(i);
|
||||
|
||||
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
|
||||
OP_MATH_BODY(+,i,i);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
|
||||
{
|
||||
mrb_int x = regs[a].value.i;
|
||||
mrb_float y = regs[a+1].value.f;
|
||||
SET_FLOAT_VALUE(regs[a], (mrb_float)x + y);
|
||||
}
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
|
||||
OP_MATH_BODY(+,f,i);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
|
||||
OP_MATH_BODY(+,f,f);
|
||||
break;
|
||||
OP_MATH(+,mrb_fixnum_plus,
|
||||
case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
|
||||
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
|
||||
break;
|
||||
default:
|
||||
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
|
||||
goto L_SEND;
|
||||
}
|
||||
break;);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_SUB) {
|
||||
/* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/
|
||||
OP_MATH(-);
|
||||
OP_MATH(-,mrb_fixnum_minus,;);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_MUL) {
|
||||
/* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/
|
||||
OP_MATH(*);
|
||||
OP_MATH(*,mrb_fixnum_mul,;);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_DIV) {
|
||||
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
|
||||
OP_MATH(/);
|
||||
OP_MATH(/,mrb_num_div,;);
|
||||
NEXT;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user