# New Ticket Created by Matt Kennedy
# Please include the string: [perl #30630]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=30630 >
This patch was done against parrot_2004-07-07_070001.
bigint.patch affects classes/bigint.pmc
The BigInt PMC breaks parrot when building without GMP support because
a few GMP symbols are in code not protected in PARROT_HAS_GMP.
divide(), modulus(), and cmodulus() all do checks with
mpz_fits_slong_p() to see if the BigInt can morph to a PerlInt. The
attached bigint.patch moves this code into bigint_div_bigint() and
bigint_mod_bigint() where it's protected in PARROT_HAS_GMP. This patch
also removes a NULL return from the non GMP bigint_set_self() which
stops a returning from void function warning from gcc. I tested the
patched version against t/pmc/bigint.t on OS X with gcc 3.1 and linux
with gcc 3.2.2.
gmpconfig.patch affects config/auto/gmp.pl
Also attached a patch to fix build problem on Mac OS X. Configure.pl
couldn't find libgmp which was installed through Fink on my OS X 10.2
machine. The gmpconfig.patch tests for gmp.h in the standard Fink
install location and if found sets the include and link flags needed
to find GMP if the test case compile works.
--
Matt Kennedy
--- classes/bigint.pmc.orig Wed Jul 7 13:52:41 2004
+++ classes/bigint.pmc Wed Jul 7 13:57:05 2004
@@ -119,12 +119,22 @@
VTABLE_morph(interpreter, dest, enum_class_BigInt);
/* this is mpz_fdiv_q */
mpz_div(BN(dest), BN(self), BN(value));
+ if (mpz_fits_slong_p(BN(dest))) {
+ VTABLE_morph(interpreter, dest, enum_class_PerlInt);
+ VTABLE_set_integer_native(interpreter, dest,
+ mpz_get_si(BN(dest)));
+ }
}
static void
bigint_mod_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
{
VTABLE_morph(interpreter, dest, enum_class_BigInt);
mpz_mod(BN(dest), BN(self), BN(value));
+ if (mpz_fits_slong_p(BN(dest))) {
+ VTABLE_morph(interpreter, dest, enum_class_PerlInt);
+ VTABLE_set_integer_native(interpreter, dest,
+ mpz_get_si(BN(dest)));
+ }
}
static void
@@ -173,7 +183,6 @@
static void
bigint_set_self(Interp *interpreter, PMC *self, BIGNUM *value) {
internal_exception(1, "no bigint lib loaded");
- return NULL;
}
static BIGNUM*
bigint_get_self(Interp *interpreter, PMC *self) {
@@ -458,11 +467,6 @@
void divide(PMC* value, PMC* dest) {
MMD_BigInt: {
bigint_div_bigint(INTERP, SELF, value, dest);
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(INTERP, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(INTERP, dest,
- mpz_get_si(BN(dest)));
- }
}
MMD_DEFAULT: {
internal_exception(1, "unimp");
@@ -472,11 +476,6 @@
void modulus(PMC* value, PMC* dest) {
MMD_BigInt: {
bigint_mod_bigint(INTERP, SELF, value, dest);
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(INTERP, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(INTERP, dest,
- mpz_get_si(BN(dest)));
- }
}
MMD_DEFAULT: {
internal_exception(1, "unimp");
@@ -486,11 +485,6 @@
void cmodulus(PMC* value, PMC* dest) {
MMD_BigInt: {
bigint_mod_bigint(INTERP, SELF, value, dest);
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(INTERP, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(INTERP, dest,
- mpz_get_si(BN(dest)));
- }
}
MMD_DEFAULT: {
internal_exception(1, "unimp");
--- config/auto/gmp.pl.orig Wed Jul 7 11:58:00 2004
+++ config/auto/gmp.pl Wed Jul 7 13:05:58 2004
@@ -25,7 +25,25 @@
my $test;
my ($verbose) = @_;
my $libs = Configure::Data->get('libs');
+ my $linkflags = Configure::Data->get('linkflags');
+ my $ccflags = Configure::Data->get('ccflags');
Configure::Data->add(' ', 'libs', '-lgmp');
+
+ my $archname = $Config{archname};
+ my ($cpuarch, $osname) = split('-', $archname);
+ if(!defined $osname) {
+ ($osname, $cpuarch) = ($cpuarch, "");
+ }
+
+ # On OS X check the presence of the gmp header in the standard
+ # Fink location. TODO: Need a more generalized way for finding
+ # where Fink lives.
+ if($osname =~ /darwin/) {
+ if( -f "/sw/include/gmp.h") {
+ Configure::Data->add(' ', 'linkflags', '-L/sw/lib');
+ Configure::Data->add(' ', 'ccflags', '-I/sw/include');
+ }
+ }
cc_gen('config/auto/gmp/gmp.in');
eval { cc_build(); };
@@ -42,8 +60,10 @@
}
else {
- Configure::Data->set('libs', $libs);
- print " (no) " if $verbose;
+ Configure::Data->set('libs', $libs);
+ Configure::Data->set('ccflags', $ccflags);
+ Configure::Data->set('linkflags', $linkflags);
+ print " (no) " if $verbose;
}
}