[libmath-prime-util-perl] 74/181: more XS tweaks

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:51:08 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.

commit 9ed115df4c6e23e220170d6bfc220446313f2600
Author: bulk88 <bulk88 at hotmail.com>
Date:   Tue Dec 31 04:28:52 2013 -0500

    more XS tweaks
    
    in _validate_int, croak and warn use perl's printf implementation which is
    Perl_sv_vcatpvfn_flags. You can pass a SV*. This is more compact machine
    code for the rare error braches, also by making the croaks identical, they
    optimize to 1 asm branch
    
    in XSUB prime_memfree, my VC 2003 32 bit CC didn't realize ix on 0 and 1
    didn't return anything, also 0 was stored in a non-vol register ret even
    though in some cases it will never be used. Just make things explicit with
    gotos. Since its a PPCODE, a jump to the end does a PUTBACK which leaves
    0 ret SVs.
    
    in prime_precalc, make tailcall/"jmp" friendly
    
    in _XS_factor_exp, remove multiple stack extends
    
    in _XS_lucas_sequence, we take in 4 args or xsubpp's croak execs, but
    return 3, no EXTEND needed
    
    in factor, don't call GIMME_V, which contains function calls, more than
    once
---
 XS.xs | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/XS.xs b/XS.xs
index 7b5578d..3072b6f 100644
--- a/XS.xs
+++ b/XS.xs
@@ -89,19 +89,20 @@ static int _validate_int(pTHX_ SV* n, int negok)
   int ret, isneg = 0;
 
   /* TODO: magic, grok_number, etc. */
+  /* fix multiple magic aware Sv*V getters */
   if (SvGAMAGIC(n)) return 0;          /* Leave while we still can */
   if (!SvOK(n))  croak("Parameter must be defined");
   if (SvIOK(n)) {                      /* If defined as number, use that */
     if (SvIsUV(n) || SvIV(n) >= 0)  return 1;
     if (negok)  return -1;
-    else      croak("Parameter '%s' must be a positive integer", SvPV_nolen(n));
+    else      croak("Parameter '" SVf "' must be a positive integer", n);
   }
   if (SvROK(n) && !sv_isa(n, "Math::BigInt"))  return 0;
   ptr = SvPV(n, len);                  /* Includes stringifying bigints */
-  if (len == 0 || ptr == 0)  croak("Parameter '' must be a positive integer");
+  if (len == 0 || ptr == 0)  croak("Parameter '" SVf "' must be a positive integer", n);
   if (ptr[0] == '-') {                 /* Read negative sign */
     if (negok) { isneg = 1; ptr++; len--; }
-    else       croak("Parameter '%s' must be a positive integer", ptr);
+    else       croak("Parameter '" SVf "' must be a positive integer", n);
   }
   if (ptr[0] == '+') { ptr++; len--; } /* Allow a single plus sign */
   while (len > 0 && *ptr == '0')       /* Strip all leading zeros */
@@ -110,7 +111,7 @@ static int _validate_int(pTHX_ SV* n, int negok)
     return 0;
   for (i = 0; i < len; i++)            /* Ensure all characters are digits */
     if (!isDIGIT(ptr[i]))
-      croak("Parameter '%s' must be a positive integer", ptr);
+      croak("Parameter '" SVf "' must be a positive integer", n);
   if (isneg == 1)                      /* Negative number (ignore overflow) */
     return -1;
   ret    = isneg ? -1           : 1;
@@ -161,15 +162,17 @@ prime_memfree()
     _XS_get_callgmp = 3
     _get_prime_cache_size = 4
   PPCODE:
-    UV ret = 0;
+    UV ret;
     switch (ix) {
-      case 0:  prime_memfree();     break;
-      case 1:  _prime_memfreeall(); break;
+      case 0:  prime_memfree(); goto return_nothing;
+      case 1:  _prime_memfreeall(); goto return_nothing;
       case 2:  ret = _XS_get_verbose(); break;
       case 3:  ret = _XS_get_callgmp(); break;
-      case 4:  ret = get_prime_cache(0,0); break;
+      case 4:
+      default:  ret = get_prime_cache(0,0); break;
     }
-    if (ix > 1) XSRETURN_UV(ret);
+    XSRETURN_UV(ret);
+    return_nothing:
 
 void
 prime_precalc(IN UV n)
@@ -177,12 +180,15 @@ prime_precalc(IN UV n)
     _XS_set_verbose = 1
     _XS_set_callgmp = 2
   PPCODE:
+    PUTBACK; /* SP is never used again, the 3 next func calls are
+    tailcall friendly since this XSUB has nothing to do after the 3 calls
+    return */
     switch (ix) {
       case 0:  prime_precalc(n);    break;
       case 1:  _XS_set_verbose(n);  break;
       default: _XS_set_callgmp(n);  break;
     }
-
+    return; /* skip implicit PUTBACK */
 
 void
 _XS_prime_count(IN UV low, IN UV high = 0)
@@ -302,11 +308,12 @@ _XS_factor_exp(IN UV n)
     } else {
       /* Return ( [p1,e1], [p2,e2], [p3,e3], ... ) */
       if (n == 1)  XSRETURN_EMPTY;
+      EXTEND(SP, nfactors);
       for (i = 0; i < nfactors; i++) {
         AV* av = newAV();
         av_push(av, newSVuv(factors[i]));
         av_push(av, newSVuv(exponents[i]));
-        XPUSHs( sv_2mortal(newRV_noinc( (SV*) av )) );
+        PUSHs( sv_2mortal(newRV_noinc( (SV*) av )) );
       }
     }
 
@@ -410,9 +417,9 @@ _XS_lucas_sequence(IN UV n, IN IV P, IN IV Q, IN UV k)
     UV U, V, Qk;
   PPCODE:
     lucas_seq(&U, &V, &Qk,  n, P, Q, k);
-    XPUSHs(sv_2mortal(newSVuv( U )));
-    XPUSHs(sv_2mortal(newSVuv( V )));
-    XPUSHs(sv_2mortal(newSVuv( Qk )));
+    PUSHs(sv_2mortal(newSVuv( U )));
+    PUSHs(sv_2mortal(newSVuv( V )));
+    PUSHs(sv_2mortal(newSVuv( Qk )));
 
 int
 _XS_is_prime(IN UV n)
@@ -494,21 +501,22 @@ next_prime(IN SV* svn)
 void
 factor(IN SV* svn)
   PPCODE:
+    U32 gimme_v =  GIMME_V;
     int status = _validate_int(aTHX_ svn, 0);
     if (status == 1) {
       UV factors[MPU_MAX_FACTORS+1];
       UV n = my_svuv(svn);
       int i, nfactors = factor(n, factors);
-      if (GIMME_V == G_SCALAR) {
+      if (gimme_v == G_SCALAR) {
         PUSHs(sv_2mortal(newSVuv(nfactors)));
-      } else if (GIMME_V == G_ARRAY) {
+      } else if (gimme_v == G_ARRAY) {
         EXTEND(SP, nfactors);
         for (i = 0; i < nfactors; i++) {
           PUSHs(sv_2mortal(newSVuv( factors[i] )));
         }
       }
     } else {
-      _vcallsubn(aTHX_ GIMME_V, "Math::Prime::Util::_generic_factor", 1);
+      _vcallsubn(aTHX_ gimme_v, "Math::Prime::Util::_generic_factor", 1);
       return; /* skip implicit PUTBACK */
     }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list