mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Extract similar codes to macros for math opcode in mrb_vm_exec
This commit is contained in:
@@ -2214,128 +2214,67 @@ RETRY_TRY_BLOCK:
|
||||
}
|
||||
|
||||
#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
|
||||
#define OP_MATH_FLOAT_BODY(op,t1,t2) do { \
|
||||
RETURN_TYPE_OF_##t1 x = t1(regs[a]); \
|
||||
RETURN_TYPE_OF_##t2 y = t2(regs[a+1]); \
|
||||
SET_FLOAT_VALUE(mrb, regs[a], x op y); \
|
||||
} while (0)
|
||||
#define RETURN_TYPE_OF_mrb_fixnum mrb_int
|
||||
#define RETURN_TYPE_OF_mrb_float mrb_float
|
||||
#define OP_MATH(op_name) \
|
||||
/* need to check if op is overridden */ \
|
||||
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \
|
||||
OP_MATH_CASE_FIXNUM(op_name); \
|
||||
OP_MATH_CASE_FLOAT(op_name, fixnum, float); \
|
||||
OP_MATH_CASE_FLOAT(op_name, float, fixnum); \
|
||||
OP_MATH_CASE_FLOAT(op_name, float, float); \
|
||||
OP_MATH_CASE_STRING_##op_name(); \
|
||||
default: \
|
||||
c = 1; \
|
||||
mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \
|
||||
goto L_SEND_SYM; \
|
||||
} \
|
||||
NEXT;
|
||||
#define OP_MATH_CASE_FIXNUM(op_name) \
|
||||
case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \
|
||||
{ \
|
||||
mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \
|
||||
if (mrb_int_##op_name##_overflow(x, y, &z)) \
|
||||
OP_MATH_OVERFLOW_INT(op_name, x, y, z); \
|
||||
else \
|
||||
SET_INT_VALUE(regs[a], z); \
|
||||
} \
|
||||
break
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
|
||||
#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z)
|
||||
#else
|
||||
#define OP_MATH_CASE_FLOAT(op_name, t1, t2) \
|
||||
case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \
|
||||
{ \
|
||||
mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \
|
||||
SET_FLOAT_VALUE(mrb, regs[a], z); \
|
||||
} \
|
||||
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
|
||||
#define OP_MATH_CASE_STRING_add() \
|
||||
case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \
|
||||
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \
|
||||
mrb_gc_arena_restore(mrb, ai); \
|
||||
break
|
||||
#define OP_MATH_CASE_STRING_sub() (void)0
|
||||
#define OP_MATH_CASE_STRING_mul() (void)0
|
||||
#define OP_MATH_OP_add +
|
||||
#define OP_MATH_OP_sub -
|
||||
#define OP_MATH_OP_mul *
|
||||
#define OP_MATH_TT_fixnum MRB_TT_FIXNUM
|
||||
#define OP_MATH_TT_float MRB_TT_FLOAT
|
||||
|
||||
CASE(OP_ADD, B) {
|
||||
/* 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, y, z;
|
||||
mrb_value *regs_a = regs + a;
|
||||
|
||||
x = mrb_fixnum(regs_a[0]);
|
||||
y = mrb_fixnum(regs_a[1]);
|
||||
if (mrb_int_add_overflow(x, y, &z)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SET_INT_VALUE(regs[a], z);
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(+,mrb_fixnum,mrb_float);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
|
||||
OP_MATH_FLOAT_BODY(+,mrb_float,mrb_fixnum);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(+,mrb_float,mrb_float);
|
||||
break;
|
||||
#endif
|
||||
case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
|
||||
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
|
||||
break;
|
||||
default:
|
||||
c = 1;
|
||||
mid = mrb_intern_lit(mrb, "+");
|
||||
goto L_SEND_SYM;
|
||||
}
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
NEXT;
|
||||
OP_MATH(add);
|
||||
}
|
||||
|
||||
CASE(OP_SUB, B) {
|
||||
/* 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, y, z;
|
||||
|
||||
x = mrb_fixnum(regs[a]);
|
||||
y = mrb_fixnum(regs[a+1]);
|
||||
if (mrb_int_sub_overflow(x, y, &z)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SET_INT_VALUE(regs[a], z);
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(-,mrb_fixnum,mrb_float);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
|
||||
OP_MATH_FLOAT_BODY(-,mrb_float,mrb_fixnum);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(-,mrb_float,mrb_float);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
c = 1;
|
||||
mid = mrb_intern_lit(mrb, "-");
|
||||
goto L_SEND_SYM;
|
||||
}
|
||||
NEXT;
|
||||
OP_MATH(sub);
|
||||
}
|
||||
|
||||
CASE(OP_MUL, B) {
|
||||
/* 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, y, z;
|
||||
|
||||
x = mrb_fixnum(regs[a]);
|
||||
y = mrb_fixnum(regs[a+1]);
|
||||
if (mrb_int_mul_overflow(x, y, &z)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SET_INT_VALUE(regs[a], z);
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(*,mrb_fixnum,mrb_float);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
|
||||
OP_MATH_FLOAT_BODY(*,mrb_float,mrb_fixnum);
|
||||
break;
|
||||
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
|
||||
OP_MATH_FLOAT_BODY(*,mrb_float,mrb_float);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
c = 1;
|
||||
mid = mrb_intern_lit(mrb, "*");
|
||||
goto L_SEND_SYM;
|
||||
}
|
||||
NEXT;
|
||||
OP_MATH(mul);
|
||||
}
|
||||
|
||||
CASE(OP_DIV, B) {
|
||||
@@ -2390,76 +2329,46 @@ RETRY_TRY_BLOCK:
|
||||
NEXT;
|
||||
}
|
||||
|
||||
CASE(OP_ADDI, BB) {
|
||||
/* need to check if + is overridden */
|
||||
switch (mrb_type(regs[a])) {
|
||||
case MRB_TT_FIXNUM:
|
||||
{
|
||||
mrb_int x = mrb_fixnum(regs[a]);
|
||||
mrb_int y = (mrb_int)b;
|
||||
mrb_int z;
|
||||
#define OP_MATHI(op_name) \
|
||||
/* need to check if op is overridden */ \
|
||||
switch (mrb_type(regs[a])) { \
|
||||
OP_MATHI_CASE_FIXNUM(op_name); \
|
||||
OP_MATHI_CASE_FLOAT(op_name); \
|
||||
default: \
|
||||
SET_INT_VALUE(regs[a+1], b); \
|
||||
c = 1; \
|
||||
mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \
|
||||
goto L_SEND_SYM; \
|
||||
} \
|
||||
NEXT;
|
||||
#define OP_MATHI_CASE_FIXNUM(op_name) \
|
||||
case MRB_TT_FIXNUM: \
|
||||
{ \
|
||||
mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \
|
||||
if (mrb_int_##op_name##_overflow(x, y, &z)) \
|
||||
OP_MATH_OVERFLOW_INT(op_name, x, y, z); \
|
||||
else \
|
||||
SET_INT_VALUE(regs[a], z); \
|
||||
} \
|
||||
break
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
#define OP_MATHI_CASE_FLOAT(op_name) (void)0
|
||||
#else
|
||||
#define OP_MATHI_CASE_FLOAT(op_name) \
|
||||
case MRB_TT_FLOAT: \
|
||||
{ \
|
||||
mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \
|
||||
SET_FLOAT_VALUE(mrb, regs[a], z); \
|
||||
} \
|
||||
break
|
||||
#endif
|
||||
|
||||
if (mrb_int_add_overflow(x, y, &z)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SET_INT_VALUE(regs[a], z);
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
mrb_float x = mrb_float(regs[a]);
|
||||
SET_FLOAT_VALUE(mrb, regs[a], x + b);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SET_INT_VALUE(regs[a+1], b);
|
||||
c = 1;
|
||||
mid = mrb_intern_lit(mrb, "+");
|
||||
goto L_SEND_SYM;
|
||||
}
|
||||
NEXT;
|
||||
CASE(OP_ADDI, BB) {
|
||||
OP_MATHI(add);
|
||||
}
|
||||
|
||||
CASE(OP_SUBI, BB) {
|
||||
mrb_value *regs_a = regs + a;
|
||||
|
||||
/* need to check if + is overridden */
|
||||
switch (mrb_type(regs_a[0])) {
|
||||
case MRB_TT_FIXNUM:
|
||||
{
|
||||
mrb_int x = mrb_fixnum(regs_a[0]);
|
||||
mrb_int y = (mrb_int)b;
|
||||
mrb_int z;
|
||||
|
||||
if (mrb_int_sub_overflow(x, y, &z)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
SET_INT_VALUE(regs_a[0], z);
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
mrb_float x = mrb_float(regs[a]);
|
||||
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SET_INT_VALUE(regs_a[1], b);
|
||||
c = 1;
|
||||
mid = mrb_intern_lit(mrb, "-");
|
||||
goto L_SEND_SYM;
|
||||
}
|
||||
NEXT;
|
||||
OP_MATHI(sub);
|
||||
}
|
||||
|
||||
#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
|
||||
|
||||
Reference in New Issue
Block a user