mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Modify handling of integer literal.
Do not assume that significand of `double` is larger than `mrb_int`.
This commit is contained in:
+51
-9
@@ -959,6 +959,48 @@ readint_float(codegen_scope *s, const char *p, int base)
|
||||
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
|
||||
codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
@@ -1733,18 +1775,18 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (val) {
|
||||
char *p = (char*)tree->car;
|
||||
int base = (intptr_t)tree->cdr->car;
|
||||
double f;
|
||||
mrb_int i;
|
||||
mrb_code co;
|
||||
int overflow;
|
||||
|
||||
f = readint_float(s, p, base);
|
||||
if (!FIXABLE(f)) {
|
||||
i = readint_mrb_int(s, p, base, FALSE, &overflow);
|
||||
if (overflow) {
|
||||
double f = readint_float(s, p, base);
|
||||
int off = new_lit(s, mrb_float_value(f));
|
||||
|
||||
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
|
||||
}
|
||||
else {
|
||||
i = (mrb_int)f;
|
||||
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
|
||||
co = MKOP_AsBx(OP_LOADI, cursp(), i);
|
||||
}
|
||||
@@ -1789,18 +1831,18 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
char *p = (char*)tree->car;
|
||||
int base = (intptr_t)tree->cdr->car;
|
||||
mrb_float f;
|
||||
mrb_int i;
|
||||
mrb_code co;
|
||||
int overflow;
|
||||
|
||||
f = readint_float(s, p, base);
|
||||
if (!FIXABLE(f)) {
|
||||
i = readint_mrb_int(s, p, base, TRUE, &overflow);
|
||||
if (overflow) {
|
||||
double f = readint_float(s, p, base);
|
||||
int off = new_lit(s, mrb_float_value(-f));
|
||||
|
||||
|
||||
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
|
||||
}
|
||||
else {
|
||||
i = (mrb_int)-f;
|
||||
if (i < MAXARG_sBx && i > -MAXARG_sBx) {
|
||||
co = MKOP_AsBx(OP_LOADI, cursp(), i);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user