Commit f639da0f authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

Fix broken NaN with `MRB_NAN_BOXING`

Example:

  $ bin/mruby -e '(Float::INFINITY - Float::INFINITY).nan?'
  zsh: segmentation fault

Cause:

  `SET_FLOAT_VALUE` is not used. It is needed for normalizing NaN.

Treatment:

  In my environment, this issue could be reproduced only when
  `infinity - infinity`, however `SET_FLOAT_VALUE` should be used in all
  arithmetic operations (regardless of boxing setting), I think.

  So I fixed all similar codes by extracting to macro.
parent 79fd986b
...@@ -2214,9 +2214,13 @@ RETRY_TRY_BLOCK: ...@@ -2214,9 +2214,13 @@ RETRY_TRY_BLOCK:
} }
#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_BODY(op,v1,v2) do {\ #define OP_MATH_FLOAT_BODY(op,t1,t2) do { \
v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ RETURN_TYPE_OF_##t1 x = t1(regs[a]); \
} while(0) 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
CASE(OP_ADD, B) { CASE(OP_ADD, B) {
/* need to check if op is overridden */ /* need to check if op is overridden */
...@@ -2239,33 +2243,13 @@ RETRY_TRY_BLOCK: ...@@ -2239,33 +2243,13 @@ RETRY_TRY_BLOCK:
break; break;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ OP_MATH_FLOAT_BODY(+,mrb_fixnum,mrb_float);
mrb_int x = mrb_fixnum(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
}
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(+,mrb_float,mrb_fixnum);
{
mrb_float x = mrb_float(regs[a]);
mrb_int y = mrb_fixnum(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x + y);
}
#else
OP_MATH_BODY(+,mrb_float,mrb_fixnum);
#endif
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(+,mrb_float,mrb_float);
{
mrb_float x = mrb_float(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x + y);
}
#else
OP_MATH_BODY(+,mrb_float,mrb_float);
#endif
break; break;
#endif #endif
case TYPES2(MRB_TT_STRING,MRB_TT_STRING): case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
...@@ -2300,33 +2284,13 @@ RETRY_TRY_BLOCK: ...@@ -2300,33 +2284,13 @@ RETRY_TRY_BLOCK:
break; break;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ OP_MATH_FLOAT_BODY(-,mrb_fixnum,mrb_float);
mrb_int x = mrb_fixnum(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
}
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(-,mrb_float,mrb_fixnum);
{
mrb_float x = mrb_float(regs[a]);
mrb_int y = mrb_fixnum(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x - y);
}
#else
OP_MATH_BODY(-,mrb_float,mrb_fixnum);
#endif
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(-,mrb_float,mrb_float);
{
mrb_float x = mrb_float(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x - y);
}
#else
OP_MATH_BODY(-,mrb_float,mrb_float);
#endif
break; break;
#endif #endif
default: default:
...@@ -2357,33 +2321,13 @@ RETRY_TRY_BLOCK: ...@@ -2357,33 +2321,13 @@ RETRY_TRY_BLOCK:
break; break;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ OP_MATH_FLOAT_BODY(*,mrb_fixnum,mrb_float);
mrb_int x = mrb_fixnum(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
}
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(*,mrb_float,mrb_fixnum);
{
mrb_float x = mrb_float(regs[a]);
mrb_int y = mrb_fixnum(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x * y);
}
#else
OP_MATH_BODY(*,mrb_float,mrb_fixnum);
#endif
break; break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
#ifdef MRB_WORD_BOXING OP_MATH_FLOAT_BODY(*,mrb_float,mrb_float);
{
mrb_float x = mrb_float(regs[a]);
mrb_float y = mrb_float(regs[a+1]);
SET_FLOAT_VALUE(mrb, regs[a], x * y);
}
#else
OP_MATH_BODY(*,mrb_float,mrb_float);
#endif
break; break;
#endif #endif
default: default:
...@@ -2466,14 +2410,10 @@ RETRY_TRY_BLOCK: ...@@ -2466,14 +2410,10 @@ RETRY_TRY_BLOCK:
break; break;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING
{ {
mrb_float x = mrb_float(regs[a]); mrb_float x = mrb_float(regs[a]);
SET_FLOAT_VALUE(mrb, regs[a], x + b); SET_FLOAT_VALUE(mrb, regs[a], x + b);
} }
#else
mrb_float(regs[a]) += b;
#endif
break; break;
#endif #endif
default: default:
...@@ -2507,14 +2447,10 @@ RETRY_TRY_BLOCK: ...@@ -2507,14 +2447,10 @@ RETRY_TRY_BLOCK:
break; break;
#ifndef MRB_WITHOUT_FLOAT #ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING
{ {
mrb_float x = mrb_float(regs[a]); mrb_float x = mrb_float(regs[a]);
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b); SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b);
} }
#else
mrb_float(regs_a[0]) -= b;
#endif
break; break;
#endif #endif
default: default:
......
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