=================================================================== RCS file: /home/cvs/OpenXM/src/ox_pari/ox_pari.c,v retrieving revision 1.14 retrieving revision 1.22 diff -u -p -r1.14 -r1.22 --- OpenXM/src/ox_pari/ox_pari.c 2016/08/23 03:03:26 1.14 +++ OpenXM/src/ox_pari/ox_pari.c 2020/11/10 04:48:49 1.22 @@ -1,5 +1,6 @@ -/* $OpenXM: OpenXM/src/ox_pari/ox_pari.c,v 1.13 2016/08/01 01:35:01 noro Exp $ */ +/* $OpenXM: OpenXM/src/ox_pari/ox_pari.c,v 1.21 2020/11/10 01:11:38 noro Exp $ */ +#include #include "ox_pari.h" OXFILE *fd_rw; @@ -8,6 +9,7 @@ static int stack_size = 0; static int stack_pointer = 0; static cmo **stack = NULL; extern int debug_print; +extern unsigned long precreal; long paristack=10000000; #define INIT_S_SIZE 2048 @@ -26,12 +28,12 @@ void gc_free(void *p,size_t size) void init_gc() { GC_INIT(); - mp_set_memory_functions(GC_malloc,gc_realloc,gc_free); } void init_pari() { pari_init(paristack,2); + mp_set_memory_functions(GC_malloc,gc_realloc,gc_free); } int initialize_stack() @@ -85,8 +87,12 @@ void pops(int n) int sm_mathcap() { +#if 0 char *opts[] = {"no_ox_reset", NULL}; mathcap_init2(OX_PARI_VERSION, ID_STRING, "ox_pari", NULL, NULL, opts); +#else + mathcap_init2(OX_PARI_VERSION, ID_STRING, "ox_pari", NULL, NULL, NULL); +#endif push((cmo*)oxf_cmo_mathcap(fd_rw)); return 0; } @@ -152,12 +158,7 @@ int sm_executeFunction() struct parif *parif; unsigned long prec; char buf[BUFSIZ]; - - if ( setjmp(GP_DATA->env) ) { - sprintf(buf,"sm_executeFunction : an error occured in PARI."); - push((cmo*)make_error2(buf)); - return -1; - } + cmo_string *func = (cmo_string *)pop(); if(func->tag != CMO_STRING) { sprintf(buf,"sm_executeFunction : func->tag=%d is not CMO_STRING",func->tag); @@ -173,30 +174,36 @@ int sm_executeFunction() } for ( i = 0; i < ac; i++ ) { av[i] = (cmo *)pop(); -// fprintf(stderr,"arg%d:",i); -// print_cmo(av[i]); -// fprintf(stderr,"\n"); } if( strcmp( func->s, "exit" ) == 0 ) exit(0); + if ( !strcmp(func->s,"allocatemem") ) { + paristack = cmo_to_int(av[0]); + pari_close(); + init_pari(); + return 0; + } + if ( !strcmp(func->s,"pari_setprec") ) { + long n,prec; + + n = cmo_to_int(av[0]); + setrealprecision(n,&prec); + return 0; + } parif =search_parif(func->s); if ( !parif ) { sprintf(buf,"%s : not implemented",func->s); push((cmo*)make_error2(buf)); return -1; - } else if ( parif->type == 0 ) { - /* one long int variable */ - int a = cmo_to_int(av[0]); - a = (int)(parif->f)(a); - ret = (cmo *)new_cmo_int32(a); - push(ret); - return 0; - } else if ( parif->type == 1 ) { - /* one number/poly/matrix argument possibly with prec */ + } else if ( parif->type <= 2 ) { + /* type=1 => one GEN argument possibly with prec */ + /* type=2 => one GEN argument with optarg */ + /* type=3 => one GEN, return ulong */ + av0 = avma; z = cmo_to_GEN(av[0]); - prec = ac==2 ? cmo_to_int(av[1])*3.32193/32+3 : precreal; + prec = ac==2 ? ndec2prec(cmo_to_int(av[1])) : nbits2prec(precreal); if ( ismatrix(z) ) { int i,len; len = lg(z); @@ -205,30 +212,42 @@ int sm_executeFunction() settyp(z,t_MAT); z = shallowtrans(z); } - printf("input : "); output(z); - m = (*parif->f)(z,prec); - ret = GEN_to_cmo(m); - avma = av0; - push(ret); - return 0; - } else if ( parif->type == 2 ) { - /* one number/poly/matrix argument with flag=0 */ - av0 = avma; - z = cmo_to_GEN(av[0]); - if ( ismatrix(z) ) { - int i,len; - len = lg(z); - for ( i = 1; i < len; i++ ) - settyp(z[i],t_COL); - settyp(z,t_MAT); - z = shallowtrans(z); + pari_CATCH(CATCH_ALL) { + GEN E = pari_err_last(); + long code = err_get_num(E); + char *err = pari_err2str(E); + if ( code == e_MEM || code == e_STACK ) { + sprintf(buf,"%s\nIncrease PARI stack by pari(allocatemem,size).",err); + } else + sprintf(buf,"An error occured in PARI :%s",err); + push((cmo*)make_error2(buf)); + pari_CATCH_reset(); + avma = av0; + return -1; } - printf("input : "); output(z); - m = (*parif->f)(z,0); - ret = GEN_to_cmo(m); - avma = av0; - push(ret); - return 0; + pari_TRY { + ret = 0; + if ( parif->type == 0 ) { + gp_allocatemem(z); + ret = av[0]; + /* allocatemem */ + } else if ( parif->type == 1 ) { + m = (*parif->f)(z,prec); + ret = GEN_to_cmo(m); + } else if ( parif->type == 2 ) { + m = (*parif->f)(z,parif->opt); + ret = GEN_to_cmo(m); + } else if ( parif->type == 3 ) { + /* XXX */ + unsigned long a; + a = (unsigned long)(*parif->f)(z); + ret = (cmo *)new_cmo_int32((int)a); + } + avma = av0; + push(ret); + return 0; + } + pari_ENDCATCH } else { sprintf(buf,"%s : not implemented",func->s); push((cmo*)make_error2(buf)); @@ -282,17 +301,51 @@ int receive() return 0; } +#if defined(ANDROID) +jmp_buf ox_env; +#else +sigjmp_buf ox_env; +#endif + +void usr1_handler(int sig) +{ +#if defined(ANDROID) + _longjmp(ox_env,1); +#else + siglongjmp(ox_env,1); +#endif +} + int main() { - init_gc(); - ox_stderr_init(stderr); - initialize_stack(); - init_pari(); +#if defined(ANDROID) + if ( _setjmp(ox_env) ) { +#else + if ( sigsetjmp(ox_env,~0) ) { +#endif + fprintf(stderr,"resetting libpari and sending OX_SYNC_BALL..."); + init_pari(); + initialize_stack(); + send_ox_tag(fd_rw,OX_SYNC_BALL); + fprintf(stderr,"done\n"); + } else { + init_gc(); + ox_stderr_init(stderr); + init_pari(); + initialize_stack(); + + fprintf(stderr,"ox_pari\n"); - fprintf(stderr,"ox_pari\n"); + fd_rw = oxf_open(3); + oxf_determine_byteorder_server(fd_rw); + } - fd_rw = oxf_open(3); - oxf_determine_byteorder_server(fd_rw); +#if defined(__CYGWIN__) + void *mysignal(int sig,void (*handler)(int m)); + mysignal(SIGUSR1,usr1_handler); +#else + signal(SIGUSR1,usr1_handler); +#endif while(1){ receive();