Commit 261e4d3f authored by Yukihiro Matsumoto's avatar Yukihiro Matsumoto

handle number literal overflow

parent 38d2b7f8
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include "node.h" #include "node.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
typedef mrb_ast_node node; typedef mrb_ast_node node;
typedef struct mrb_parser_state parser_state; typedef struct mrb_parser_state parser_state;
...@@ -800,6 +803,27 @@ raise_error(codegen_scope *s, const char *msg) ...@@ -800,6 +803,27 @@ raise_error(codegen_scope *s, const char *msg)
genop(s, MKOP_ABx(OP_ERR, 0, idx)); genop(s, MKOP_ABx(OP_ERR, 0, idx));
} }
static mrb_float
readint_float(codegen_scope *s, const char *p, int base)
{
const char *e = p + strlen(p);
mrb_float f = 0;
int n;
while (p <= e) {
char c = tolower(*p);
for (n=0; n<base; n++) {
if (mrb_digitmap[n] == c) {
f *= base;
f += n;
break;
}
}
p++;
}
return f;
}
static void static void
codegen(codegen_scope *s, node *tree, int val) codegen(codegen_scope *s, node *tree, int val)
{ {
...@@ -1553,14 +1577,22 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1553,14 +1577,22 @@ codegen(codegen_scope *s, node *tree, int val)
int i = readint(p, base); int i = readint(p, base);
mrb_code co; mrb_code co;
if (i < MAXARG_sBx && i > -MAXARG_sBx) { if (i == LONG_MAX && errno == ERANGE) {
co = MKOP_AsBx(OP_LOADI, cursp(), i); mrb_float f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(f));
genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
} }
else { else {
int off = new_lit(s, mrb_fixnum_value(i)); if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_ABx(OP_LOADL, cursp(), off); co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
} }
genop(s, co);
push(); push();
} }
break; break;
...@@ -1599,15 +1631,23 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1599,15 +1631,23 @@ codegen(codegen_scope *s, node *tree, int val)
int i = readint(p, base); int i = readint(p, base);
mrb_code co; mrb_code co;
i = -i; if (i == LONG_MAX && errno == ERANGE) {
if (i < MAXARG_sBx && i > -MAXARG_sBx) { mrb_float f = readint_float(s, p, base);
co = MKOP_AsBx(OP_LOADI, cursp(), i); int off = new_lit(s, mrb_float_value(-f));
}
else { genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
int off = new_lit(s, mrb_fixnum_value(i)); }
co = MKOP_ABx(OP_LOADL, cursp(), off); else {
} i = -i;
genop(s, co); if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
co = MKOP_ABx(OP_LOADL, cursp(), off);
}
genop(s, co);
}
push(); push();
} }
break; break;
......
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