# 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;
     }
 }
 

Reply via email to