develooper Front page | perl.perl5.porters | Postings from March 2003

[PATCH] glibc _moddi3

Thread Next
From:
Jarkko Hietaniemi
Date:
March 1, 2003 12:57
Subject:
[PATCH] glibc _moddi3
Message ID:
20030301205751.GB7547@kosh.hut.fi
Here's an attempt to squash the glibc _moddi3 negative quad bug that's
been around for aeons.  An aeon.  Almost a year.  (The bug is also
known as [perl #9402] or "Abigail's faithfully failing int.t".)
I didn't feel like writing a Configure test for such a precise bug
but instead went for runtime.  Now pp_i_modulo is basically a switchboard
that rewires the opcode dispatch table as required (thus effectively
rewiring itself out of the way).  The patch works for me-- I've got
the same buggy glibc in the Debian box I run my smokes in.

--- pp.c.orig	2003-03-01 22:51:50.000000000 +0200
+++ pp.c	2003-03-01 22:51:55.000000000 +0200
@@ -2457,6 +2457,40 @@
     }
 }
 
+STATIC
+PP(pp_i_modulo_0)
+{
+    /* This is the vanilla old i_modulo. */
+    dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
+    {
+      dPOPTOPiirl;
+      if (!right)
+	DIE(aTHX_ "Illegal modulus zero");
+      SETi( left % right );
+      RETURN;
+    }
+}
+
+STATIC
+PP(pp_i_modulo_1)
+{
+#ifdef __GLIBC__
+    /* This is the i_modulo with the workaround for the _moddi3
+     * bug in (at least) glibc 2.2.5 (the "right = -right" part
+     * is the workaround).  See below for pp_i_modulo. */
+    dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
+    {
+      dPOPTOPiirl;
+      if (!right)
+	DIE(aTHX_ "Illegal modulus zero");
+      if (right < 0)
+	right = -right;
+      SETi( left % right );
+      RETURN;
+    }
+#endif
+}
+
 PP(pp_i_modulo)
 {
     dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
@@ -2464,6 +2498,28 @@
       dPOPTOPiirl;
       if (!right)
 	DIE(aTHX_ "Illegal modulus zero");
+      /* The assumption is to use hereafter the old vanilla version... */
+      PL_ppaddr[OP_I_MODULO] = &Perl_pp_i_modulo_0;
+      /* .. but if we have glibc, we might have a buggy _moddi3
+       * (at least glicb 2.2.5 is known to have this bug), in other
+       * words our integer modulus with negative quad as the second
+       * argument might be broken.  Test for this and re-patch the
+       * opcode dispatch table if that is the case, remembering to
+       * also apply the workaround so that this first round works
+       * right, too.
+       *
+       * See [perl #9402] for more information. */
+#if defined(__GLIBC__) && IVSIZE == 8
+      {
+	IV l =   3;
+	IV r = -10;
+	if (l % r == -3) {
+	  PL_ppaddr[OP_I_MODULO] = &Perl_pp_i_modulo_1;
+	  if (right < 0)
+	    right = -right;
+	}
+      }
+#endif
       SETi( left % right );
       RETURN;
     }

-- 
Jarkko Hietaniemi <jhi@iki.fi> http://www.iki.fi/jhi/ "There is this special
biologist word we use for 'stable'.  It is 'dead'." -- Jack Cohen

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About