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
-
[PATCH] glibc _moddi3
by Jarkko Hietaniemi