On Thursday 25 September 2008 00:09:37 Moritz Lenz wrote:

> As of today (and r31404) Rakudo's 'make spectest_regression' produces
> compile time errors in three files, all of which are related to integer
> overflow.
>
> To reproduce:
> $ cd languages/perl6
> $ make spectest_regression
> $ ../../parrot perl6.pbc t/spec/S03-operators/arith.rakudo
> add_1_const:Integer overflow '2147483648'
> current instr.: 'parrot;PCT::HLLCompiler;evalpmc' pc 744
> (src/PCT/HLLCompiler.pir:448)
> called from Sub 'parrot;PCT::HLLCompiler;compile' pc 438
> (src/PCT/HLLCompiler.pir:303)
> [...]
>
> I suspect it might be this commit:
>
> r31402 | chromatic | 2008-09-25 07:30:31 +0200 (Thu, 25 Sep 2008) | 7 lines
>
> [src] Expanded float precision to 15 digits from 6.  One side effect is
> that float output no longer always has six digits after the dot; this drops
> trailing
> zeroes.  Most of the changes are to tests which expected specific output
> formats.
>
> The sprintf format %.15g should be portable, but watch the smokes.  See RT
> #59006, reported by Patrick Michaud.

I suspect it is too.  I can't figure out what in PCT is the culprit (something 
related to printing floats), but here's an IMCC patch which avoids overflow 
by autopromoting I regs which would overflow to N regs.

There's a further refactoring opportunity in here, but I'd like to see if this 
works first.

-- c

=== compilers/imcc/pbc.c
==================================================================
--- compilers/imcc/pbc.c	(revision 31446)
+++ compilers/imcc/pbc.c	(local)
@@ -1478,8 +1478,9 @@
     if (r->type & VT_CONSTP)
         r = r->reg;
 
-    if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X'))
+    if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) {
         i = strtoul(r->name+2, 0, 16);
+    }
 
     else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o'))
         i = strtoul(r->name+2, 0, 8);
@@ -1501,6 +1502,32 @@
     return i;
 }
 
+INTVAL
+int_reg_does_not_overflow(PARROT_INTERP, ARGIN(const SymReg *r))
+{
+    INTVAL i;
+
+    errno = 0;
+
+    if (r->type & VT_CONSTP)
+        r = r->reg;
+
+    if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) {
+        i = strtoul(r->name + 2, 0, 16);
+    }
+
+    else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o'))
+        i = strtoul(r->name + 2, 0, 8);
+
+    else if (r->name[0] == '0' && (r->name[1] == 'b' || r->name[1] == 'B'))
+        i = strtoul(r->name + 2, 0, 2);
+
+    else
+        i = strtol(r->name, 0, 10);
+
+    return errno ? 0 : 1;
+}
+
 /*
 
 =item C<static void make_pmc_const>
@@ -1557,7 +1584,13 @@
 
     switch (r->set) {
         case 'I':
-            r->color = IMCC_int_from_reg(interp, r);
+            if (int_reg_does_not_overflow(interp, r)) {
+                r->color = IMCC_int_from_reg(interp, r);
+            }
+            else {
+                r->set   = 'N';
+                r->color = add_const_num(interp, r->name);
+            }
             break;
         case 'S':
             if (r->type & VT_CONSTP)
=== compilers/imcc/pbc.h
==================================================================
--- compilers/imcc/pbc.h	(revision 31446)
+++ compilers/imcc/pbc.h	(local)
@@ -34,6 +34,10 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+INTVAL int_reg_does_not_overflow(PARROT_INTERP, ARGIN(const SymReg *r))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 STRING * IMCC_string_from_reg(PARROT_INTERP, ARGIN(const SymReg *r))

Reply via email to