Commit 20875263 authored by Masamitsu MURASE's avatar Masamitsu MURASE

Modify handling of integer literal.

Do not assume that significand of `double` is larger than `mrb_int`.
parent dfff7323
...@@ -959,6 +959,48 @@ readint_float(codegen_scope *s, const char *p, int base) ...@@ -959,6 +959,48 @@ readint_float(codegen_scope *s, const char *p, int base)
return f; return f;
} }
static mrb_int
readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflow)
{
const char *e = p + strlen(p);
mrb_int result = 0;
int n;
if (*p == '+') p++;
while (p < e) {
char c = *p;
c = tolower((unsigned char)c);
for (n=0; n<base; n++) {
if (mrb_digitmap[n] == c) {
break;
}
}
if (n == base) {
codegen_error(s, "malformed readint input");
}
if (neg) {
if ((MRB_INT_MIN + n)/base > result) {
*overflow = TRUE;
return 0;
}
result *= base;
result -= n;
}
else {
if ((MRB_INT_MAX - n)/base < result) {
*overflow = TRUE;
return 0;
}
result *= base;
result += n;
}
p++;
}
*overflow = FALSE;
return result;
}
static void static void
codegen(codegen_scope *s, node *tree, int val) codegen(codegen_scope *s, node *tree, int val)
{ {
...@@ -1733,18 +1775,18 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1733,18 +1775,18 @@ codegen(codegen_scope *s, node *tree, int val)
if (val) { if (val) {
char *p = (char*)tree->car; char *p = (char*)tree->car;
int base = (intptr_t)tree->cdr->car; int base = (intptr_t)tree->cdr->car;
double f;
mrb_int i; mrb_int i;
mrb_code co; mrb_code co;
int overflow;
f = readint_float(s, p, base); i = readint_mrb_int(s, p, base, FALSE, &overflow);
if (!FIXABLE(f)) { if (overflow) {
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(f)); int off = new_lit(s, mrb_float_value(f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
} }
else { else {
i = (mrb_int)f;
if (i < MAXARG_sBx && i > -MAXARG_sBx) { if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i); co = MKOP_AsBx(OP_LOADI, cursp(), i);
} }
...@@ -1789,18 +1831,18 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1789,18 +1831,18 @@ codegen(codegen_scope *s, node *tree, int val)
{ {
char *p = (char*)tree->car; char *p = (char*)tree->car;
int base = (intptr_t)tree->cdr->car; int base = (intptr_t)tree->cdr->car;
mrb_float f;
mrb_int i; mrb_int i;
mrb_code co; mrb_code co;
int overflow;
f = readint_float(s, p, base); i = readint_mrb_int(s, p, base, TRUE, &overflow);
if (!FIXABLE(f)) { if (overflow) {
double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(-f)); int off = new_lit(s, mrb_float_value(-f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
} }
else { else {
i = (mrb_int)-f;
if (i < MAXARG_sBx && i > -MAXARG_sBx) { if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i); co = MKOP_AsBx(OP_LOADI, cursp(), i);
} }
......
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