Math-Pari

 view release on metacpan or  search on metacpan

Pari.xs  view on Meta::CPAN

	   CASE_INTERFACE(73);
	   CASE_INTERFACE(86);
	   CASE_INTERFACE(87);
	   CASE_INTERFACE(9900);

	 default: 
	     if (!ep)
		 croak("Unsupported interface %ld for \"direct-link\" Pari function %s",
		       valence, olds);
	     if (!ep->code)
		 croak("Unsupported interface %ld and no code for a Pari function %s",
		       valence, olds);
	   flexible:
	     s1 = s = ep->code;
	     if (*s1 == 'x')
		 s1++;
	     if (*s1 == 'v') {
		 pbuf = "_flexible_void";
		 DO_INTERFACE(_flexible_void);
	     }
	     else if (*s1 == 'l') {
		 pbuf = "_flexible_long";
		 DO_INTERFACE(_flexible_long);
	     }
	     else if (*s1 == 'i') {
		 pbuf = "_flexible_int";
		 DO_INTERFACE(_flexible_int);
	     }
	     else {
		 pbuf = "_flexible_gen";
		 DO_INTERFACE(_flexible_gen);
	     }
	     
	     flexible = 1;
	 }
	 strcpy(subname+12,"interface");
	 strcpy(subname+12+9,pbuf);
	 protocv = perl_get_cv(subname, FALSE);
	 if (protocv) {
	     proto = SvPV((SV*)protocv,na);
	 }
	 
	 strcpy(subname+12,olds);
	 RETVAL = newXS(subname,math_pari_subaddr,file);
	 if (proto)
	     sv_setpv((SV*)RETVAL, proto);
	 XSINTERFACE_FUNC_SET(RETVAL, flexible ? (void*)ep : (void*)func);
       } else {
	 croak( "Cannot load a Pari macro `%s': macros are unsupported; VALENCE=%#04x, code=<%s>, isFunction=%d, EpVAR=%d",
		olds, (ep ? (int)EpVALENCE(ep) : 0x666), (ep->code ? ep->code : "<null>"), isPariFunction(ep), (int)EpVAR);
       }
     }
   OUTPUT:
     RETVAL

# Tag is menu entry, or -1 for all.

void
_listPari(tag)
     int tag
   PPCODE:
     {
       long valence;
       entree *ep, *table = functions_basic;
       int i=-1;

       while (++i <= 1) {
	   if (i==1)
#if defined(NO_HIGHLEVEL_PARI) || PARI_VERSION_EXP >= 2009000		/* Probably disappered earlier */
	       break;
#else
	       table = functions_highlevel;
#endif
	   
	   for(ep = table; ep->name; ep++)  {
	       valence = EpVALENCE(ep);
	       if ((tag == -1 && !_is_internal(ep->menu)) || ep->menu == tag) {
		   switch (valence) {
		   default:
		   case 0:
		       if (ep->code == 0)
			   break;
		       /* FALL THROUGH */
	           case 1:
		   case 10:
		   case 199:
		   case 109:
		   case 11:
		   case 15:
		   case 2:
		   case 20:
		   case 299:
		   case 209:
		   case 2099:
		   case 2199:
		   case 3:
		   case 30:
		   case 4:
		   case 5:
		   case 21:
		   case 23:
		   case 24:
		   case 25:
		   case 29:
		   case 32:
		   case 33:
		   case 35:
		   case 12:
		   case 13:
		   case 14:
		   case 26:
		   case 28:
		   case 31:
		   case 34:
		   case 22:
		   case 27:
		   case 37:
		   case 47:
		   case 48:
		   case 49:
		   case 83:

Pari.xs  view on Meta::CPAN

#  endif
   }
#endif  /* PARI_VERSION_EXP >= 2003000 */
   PariStack = (SV *) GENfirstOnStack;
   if (!worksv)
     worksv =    NEWSV(910,0);
   if (workErrsv)
     sv_setpvn(workErrsv, "", 0);		/* Just in case, on restart */
   else
     workErrsv = newSVpvn("",0);
   pariErr = &perlErr;
#if PARI_VERSION_EXP >= 2003000
   pari_set_last_newline(1);			/* Bug in PARI: at the start, we do not need extra newlines */
#endif
#if PARI_VERSION_EXP >= 2004000			/* Undocumented when it appeared; present in 2.5.0 */
   cb_pari_err_recover = _svErrdie;		/*  XXXX  Not enough for our needs! */
   cb_pari_handle_exception = math_pari_handle_exception;
# ifdef CB_EXCEPTION_FLAGS
   cb_exception_resets_avma = 1;
   cb_exception_flushes_err = 1;
# endif
   av = avma;
				/* Init the rest ourselves */
#if PARI_VERSION_EXP >= 2009000
   if (!GP_DATA->colormap)				/* init_defaults() leaves them NULL */
     sd_graphcolormap("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]",0);
   if (!GP_DATA->graphcolors)
     sd_graphcolors("[4,5]",0);
   avma = av;
#else /* !(PARI_VERSION_EXP >= 2009000) */
   if (!pari_colormap)				/* init_defaults() leaves them NULL */
     pari_colormap = gclone(readseq("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]"));
   if (!pari_graphcolors)
     pari_graphcolors = gclone(readseq("[4,5]"));
   avma = av;
#endif /* !(PARI_VERSION_EXP >= 2009000) */
#endif
#if PARI_VERSION_EXP < 2005000			/* Undocumented when it disappeared; missing in 2.5.0 */
   foreignHandler = (void*)&callPerlFunction;
   foreignExprSwitch = (char)SVt_PVCV;
   foreignExprHandler = &exprHandler_Perl;
#endif
   foreignAutoload = &autoloadPerlFunction;
   foreignFuncFree = &freePerlFunction;
   pariStash = gv_stashpv("Math::Pari", TRUE);
   pariEpStash = gv_stashpv("Math::Pari::Ep", TRUE);
   perlavma = sentinel = avma;
   fmt_nbPset(def_fmt_nb);
   global_top = myPARI_top;
#if PARI_VERSION_EXP >= 2004002			/* Undocumented when it appeared; present in 2.5.0 */
   if (!   code_return_1) {
      code_return_1 = gclone(compile_str("x->1"));
      code2_return_1 = gclone(compile_str("(x,y)->1"));
      avma = sentinel;
   }
#endif
}

void
memUsage()
PPCODE:
#ifdef DEBUG_PARI
  EXTEND(sp, 4);		/* Got cv + 0, - but on newer Perls, this does not count.  Return 4. */
  PUSHs(sv_2mortal(newSViv(SVnumtotal)));
  PUSHs(sv_2mortal(newSViv(SVnum)));
  PUSHs(sv_2mortal(newSViv(onStack)));
  PUSHs(sv_2mortal(newSViv(offStack)));
#endif  
  

void
dumpStack()
PPCODE:
	long i = 0, ssize, oursize = 0;
	SV *ret, *sv1, *nextsv;
        const char *pref = "";

	switch(GIMME_V) {
	case G_VOID:
            pref = "# ";
	case G_SCALAR:
	    ssize = getstack();
	    ret = newSVpvf("%sstack size is %ld bytes (%ld x %ld longs)\n",
			   pref, ssize, (long)sizeof(long), ssize/sizeof(long));
            for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
		GEN x = (GEN) SV_myvoidp_get(sv1);
		SV* tmp = pari_print(x);
		sv_catpvf(ret,"%s %2ld: %s\n", pref, i, SvPV_nolen(tmp));
		SvREFCNT_dec(tmp);
		i++;
		oursize += gsizeword(x);
		nextsv = SV_Stack_find_next(sv1);
	    }
	    sv_catpvf(ret,"%sour data takes %ld words out of %ld words on stack\n", pref, oursize, ssize/sizeof(long));
	    if(GIMME_V == G_VOID) {
		PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
		SvREFCNT_dec(ret);
		XSRETURN(0);
	    } else {
		ST(0) = sv_2mortal(ret);
		XSRETURN(1);
	    }
	case G_ARRAY:
            for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
		GEN x = (GEN) SV_myvoidp_get(sv1);
		XPUSHs(sv_2mortal(pari_print(x)));
		nextsv = SV_Stack_find_next(sv1);
	    }
	}

void
__dumpStack()
PPCODE:
	GEN x = (GEN)avma;	/* If this works, it is accidental only: it assumes the entry point to “the region on stack” is at its smallest address. */
	long ssize, i = 0;
	SV* ret;

	switch(GIMME_V) {
	case G_VOID:
	case G_SCALAR:
	    ssize = getstack();
	    ret = newSVpvf("stack size is %ld bytes (%ld x %ld longs)\n",
			   ssize,(long)sizeof(long),ssize/sizeof(long));
	    for(; x < (GEN)myPARI_top; x += gsizeword(x), i++) {
		SV* tmp = pari_print(x);
		sv_catpvf(ret," %2ld: %s\n",i,SvPV_nolen(tmp));
		SvREFCNT_dec(tmp);
	    }
	    if(GIMME_V == G_VOID) {
		PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
		SvREFCNT_dec(ret);
		XSRETURN(0);
	    } else {
		ST(0) = sv_2mortal(ret);
		XSRETURN(1);
	    }
	case G_ARRAY:
	    for(; x < (GEN)myPARI_top; x += gsizeword(x), i++)
		XPUSHs(sv_2mortal(pari_print(x)));
	}

void
dumpHeap()
PPCODE:
    heap_dumper_t hd;
    int context = GIMME_V, m;

    SV* ret = Nullsv;			/* Avoid unit warning */

    switch(context) {
    case G_VOID:
    case G_SCALAR: ret = newSVpvn("",0); break;
    case G_ARRAY:  ret = (SV*)newAV();	 break;
    }

    hd.words = hd.items = 0;
    hd.acc = ret;
    hd.context = context;

    heap_dumper(&hd);

    switch(context) {
    case G_VOID:
    case G_SCALAR: {
	SV* tmp = newSVpvf("heap had %ld bytes (%ld items)\n",
			   (hd.words + BL_HEAD * hd.items) * sizeof(long),
			   hd.items);
	sv_catsv(tmp,ret);
	SvREFCNT_dec(ret);
	if(GIMME_V == G_VOID) {
	    PerlIO_puts(PerlIO_stdout(), SvPV_nolen(tmp));
	    SvREFCNT_dec(tmp);
	    XSRETURN(0);
	} else {
	    ST(0) = sv_2mortal(tmp);
	    XSRETURN(1);
	}
    }
    case G_ARRAY:
	for(m = 0; m <= av_len((AV*)ret); m++)
	    XPUSHs(sv_2mortal(SvREFCNT_inc(*av_fetch((AV*)ret,m,0))));
	SvREFCNT_dec(ret);
    }

MODULE = Math::Pari PACKAGE = Math::Pari

void
DESTROY(rv)
     SV *	rv
   CODE:
     {
	 /* PariStack keeps the latest SV that keeps a GEN on stack. */
	 SV* sv = SvRV(rv);
	 char* ostack;			/* The value of PariStack when the
					 * variable was created, thus the
					 * previous SV that keeps a GEN from
					 * stack, or some atoms. */
	 long oldavma;			 /* The value of avma on the entry
					  * to function having the SV as
					  * argument. */
	 long howmany;
	 SV_OAVMA_PARISTACK_get(sv, oldavma, ostack);
	 oldavma += myPARI_bot;
#if 1



( run in 1.538 second using v1.01-cache-2.11-cpan-71847e10f99 )