Annotation of OpenXM/src/ox_pari/ox_pari.c, Revision 1.20
1.20 ! noro 1: /* $OpenXM: OpenXM/src/ox_pari/ox_pari.c,v 1.19 2019/12/19 08:34:41 fujimoto Exp $ */
1.12 noro 2:
1.17 ohara 3: #include <signal.h>
1.12 noro 4: #include "ox_pari.h"
1.1 noro 5:
6: OXFILE *fd_rw;
7:
8: static int stack_size = 0;
9: static int stack_pointer = 0;
10: static cmo **stack = NULL;
11: extern int debug_print;
1.2 noro 12: long paristack=10000000;
1.1 noro 13:
14: #define INIT_S_SIZE 2048
15: #define EXT_S_SIZE 2048
16:
1.3 noro 17: void *gc_realloc(void *p,size_t osize,size_t nsize)
18: {
19: return (void *)GC_realloc(p,nsize);
20: }
21:
22: void gc_free(void *p,size_t size)
23: {
24: GC_free(p);
25: }
26:
27: void init_gc()
28: {
1.4 noro 29: GC_INIT();
1.3 noro 30: }
31:
1.1 noro 32: void init_pari()
33: {
1.2 noro 34: pari_init(paristack,2);
1.20 ! noro 35: mp_set_memory_functions(GC_malloc,gc_realloc,gc_free);
1.1 noro 36: }
37:
38: int initialize_stack()
39: {
1.4 noro 40: stack_pointer = 0;
41: stack_size = INIT_S_SIZE;
42: stack = MALLOC(stack_size*sizeof(cmo*));
43: return 0;
1.1 noro 44: }
45:
46: static int extend_stack()
47: {
1.4 noro 48: int size2 = stack_size + EXT_S_SIZE;
49: cmo **stack2 = MALLOC(size2*sizeof(cmo*));
50: memcpy(stack2, stack, stack_size*sizeof(cmo *));
51: free(stack);
52: stack = stack2;
53: stack_size = size2;
54: return 0;
1.1 noro 55: }
56:
57: int push(cmo* m)
58: {
1.4 noro 59: stack[stack_pointer] = m;
60: stack_pointer++;
61: if(stack_pointer >= stack_size) {
62: extend_stack();
63: }
64: return 0;
1.1 noro 65: }
66:
67: cmo* pop()
68: {
1.4 noro 69: if(stack_pointer > 0) {
70: stack_pointer--;
71: return stack[stack_pointer];
72: }
73: return new_cmo_null();
1.1 noro 74: }
75:
76: void pops(int n)
77: {
1.4 noro 78: stack_pointer -= n;
79: if(stack_pointer < 0) {
80: stack_pointer = 0;
81: }
1.1 noro 82: }
83:
84: #define OX_PARI_VERSION 20150731
85: #define ID_STRING "2015/07/31 15:00:00"
86:
87: int sm_mathcap()
88: {
1.16 noro 89: #if 0
1.14 ohara 90: char *opts[] = {"no_ox_reset", NULL};
91: mathcap_init2(OX_PARI_VERSION, ID_STRING, "ox_pari", NULL, NULL, opts);
1.16 noro 92: #else
93: mathcap_init2(OX_PARI_VERSION, ID_STRING, "ox_pari", NULL, NULL, NULL);
94: #endif
1.4 noro 95: push((cmo*)oxf_cmo_mathcap(fd_rw));
96: return 0;
1.1 noro 97: }
98:
99: int sm_popCMO()
100: {
1.4 noro 101: cmo* m = pop();
1.1 noro 102:
1.4 noro 103: if(m != NULL) {
104: send_ox_cmo(fd_rw, m);
105: return 0;
106: }
107: return SM_popCMO;
1.1 noro 108: }
109:
1.8 noro 110: cmo_error2 *make_error2(char *message)
1.1 noro 111: {
1.9 noro 112: return new_cmo_error2((cmo *)new_cmo_string(message));
1.1 noro 113: }
114:
115: int get_i()
116: {
1.4 noro 117: cmo *c = pop();
118: if(c->tag == CMO_INT32) {
119: return ((cmo_int32 *)c)->i;
120: }else if(c->tag == CMO_ZZ) {
121: return mpz_get_si(((cmo_zz *)c)->mpz);
122: }
1.8 noro 123: make_error2("get_i : invalid object");
1.4 noro 124: return 0;
1.1 noro 125: }
126:
127: char *get_str()
128: {
1.4 noro 129: cmo *c = pop();
130: if(c->tag == CMO_STRING) {
131: return ((cmo_string *)c)->s;
132: }
1.8 noro 133: make_error2("get_str : invalid object");
1.4 noro 134: return "";
1.1 noro 135: }
136:
1.8 noro 137: int ismatrix(GEN z)
138: {
139: int len,col,i;
140:
141: if ( typ(z) != t_VEC ) return 0;
142: if ( typ((GEN)z[1]) != t_VEC ) return 0;
143: len = lg(z); col = lg((GEN)z[1]);
144: for ( i = 2; i < len; i++ )
145: if ( lg((GEN)z[i]) != col ) return 0;
146: return 1;
147: }
148:
1.1 noro 149: int sm_executeFunction()
150: {
1.5 noro 151: pari_sp av0;
1.2 noro 152: int ac,i;
153: cmo_int32 *c;
154: cmo *av[PARI_MAX_AC];
155: cmo *ret;
156: GEN z,m;
1.3 noro 157: struct parif *parif;
1.7 noro 158: unsigned long prec;
1.8 noro 159: char buf[BUFSIZ];
1.20 ! noro 160: extern unsigned long precreal;
! 161:
1.4 noro 162: cmo_string *func = (cmo_string *)pop();
163: if(func->tag != CMO_STRING) {
1.8 noro 164: sprintf(buf,"sm_executeFunction : func->tag=%d is not CMO_STRING",func->tag);
165: push((cmo*)make_error2(buf));
1.4 noro 166: return -1;
167: }
1.1 noro 168:
1.4 noro 169: c = (cmo_int32 *)pop();
1.2 noro 170: ac = c->i;
171: if ( ac > PARI_MAX_AC ) {
1.8 noro 172: push((cmo*)make_error2("sm_executeFunction : too many arguments"));
1.4 noro 173: return -1;
1.2 noro 174: }
175: for ( i = 0; i < ac; i++ ) {
176: av[i] = (cmo *)pop();
177: }
1.4 noro 178: if( strcmp( func->s, "exit" ) == 0 )
179: exit(0);
1.3 noro 180:
1.20 ! noro 181: if ( !strcmp(func->s,"allocatemem") ) {
! 182: paristack = cmo_to_int(av[0]);
! 183: pari_close();
! 184: init_pari();
! 185: return 0;
! 186: }
1.3 noro 187: parif =search_parif(func->s);
188: if ( !parif ) {
1.8 noro 189: sprintf(buf,"%s : not implemented",func->s);
190: push((cmo*)make_error2(buf));
1.4 noro 191: return -1;
1.20 ! noro 192: } else if ( parif->type <= 2 ) {
! 193: /* type=1 => one GEN argument possibly with prec */
! 194: /* type=2 => one GEN argument with optarg */
! 195: /* type=3 => one GEN, return ulong */
! 196:
1.5 noro 197: av0 = avma;
1.2 noro 198: z = cmo_to_GEN(av[0]);
1.7 noro 199: prec = ac==2 ? cmo_to_int(av[1])*3.32193/32+3 : precreal;
1.8 noro 200: if ( ismatrix(z) ) {
1.7 noro 201: int i,len;
202: len = lg(z);
203: for ( i = 1; i < len; i++ )
204: settyp(z[i],t_COL);
205: settyp(z,t_MAT);
206: z = shallowtrans(z);
207: }
1.20 ! noro 208: pari_CATCH(CATCH_ALL) {
! 209: GEN E = pari_err_last();
! 210: long code = err_get_num(E);
! 211: char *err = pari_err2str(E);
! 212: if ( code == e_MEM || code == e_STACK ) {
! 213: sprintf(buf,"%s\nIncrease PARI stack by pari(allocatemem,size).",err);
! 214: } else
! 215: sprintf(buf,"An error occured in PARI :%s",err);
! 216: push((cmo*)make_error2(buf));
! 217: pari_CATCH_reset();
! 218: avma = av0;
! 219: return -1;
! 220: }
! 221: pari_TRY {
! 222: ret = 0;
! 223: if ( parif->type == 0 ) {
! 224: gp_allocatemem(z);
! 225: ret = av[0];
! 226: /* allocatemem */
! 227: } else if ( parif->type == 1 ) {
! 228: m = (*parif->f)(z,prec);
! 229: ret = GEN_to_cmo(m);
! 230: } else if ( parif->type == 2 ) {
! 231: m = (*parif->f)(z,parif->opt);
! 232: ret = GEN_to_cmo(m);
! 233: } else if ( parif->type == 3 ) {
! 234: /* XXX */
! 235: unsigned long a;
! 236: a = (unsigned long)(*parif->f)(z);
! 237: ret = (cmo *)new_cmo_int32((int)a);
! 238: }
! 239: avma = av0;
! 240: push(ret);
! 241: return 0;
1.13 noro 242: }
1.20 ! noro 243: pari_ENDCATCH
1.3 noro 244: } else {
1.8 noro 245: sprintf(buf,"%s : not implemented",func->s);
246: push((cmo*)make_error2(buf));
1.4 noro 247: return -1;
1.3 noro 248: }
1.1 noro 249: }
250:
251: int receive_and_execute_sm_command()
252: {
1.4 noro 253: int code = receive_int32(fd_rw);
254: switch(code) {
255: case SM_popCMO:
256: sm_popCMO();
257: break;
258: case SM_executeFunction:
259: sm_executeFunction();
260: break;
261: case SM_mathcap:
262: sm_mathcap();
263: break;
264: case SM_setMathCap:
265: pop();
266: break;
1.11 noro 267: case SM_shutdown:
268: exit(0);
269: break;
1.4 noro 270: default:
271: printf("receive_and_execute_sm_command : code=%d\n",code);fflush(stdout);
272: break;
273: }
274: return 0;
1.1 noro 275: }
276:
277: int receive()
278: {
1.4 noro 279: int tag;
1.1 noro 280:
1.4 noro 281: tag = receive_ox_tag(fd_rw);
282: switch(tag) {
283: case OX_DATA:
284: printf("receive : ox_data %d\n",tag);fflush(stdout);
285: push(receive_cmo(fd_rw));
286: break;
287: case OX_COMMAND:
288: printf("receive : ox_command %d\n",tag);fflush(stdout);
289: receive_and_execute_sm_command();
290: break;
291: default:
292: printf("receive : tag=%d\n",tag);fflush(stdout);
293: }
294: return 0;
1.1 noro 295: }
296:
1.19 fujimoto 297: #if defined(ANDROID)
298: jmp_buf ox_env;
299: #else
1.18 noro 300: sigjmp_buf ox_env;
1.19 fujimoto 301: #endif
1.16 noro 302:
303: void usr1_handler(int sig)
304: {
1.19 fujimoto 305: #if defined(ANDROID)
306: _longjmp(ox_env,1);
307: #else
1.18 noro 308: siglongjmp(ox_env,1);
1.19 fujimoto 309: #endif
1.16 noro 310: }
311:
1.1 noro 312: int main()
313: {
1.19 fujimoto 314: #if defined(ANDROID)
315: if ( _setjmp(ox_env) ) {
316: #else
1.18 noro 317: if ( sigsetjmp(ox_env,~0) ) {
1.19 fujimoto 318: #endif
1.16 noro 319: fprintf(stderr,"resetting libpari and sending OX_SYNC_BALL...");
1.20 ! noro 320: init_pari();
1.16 noro 321: initialize_stack();
322: send_ox_tag(fd_rw,OX_SYNC_BALL);
323: fprintf(stderr,"done\n");
324: } else {
325: init_gc();
326: ox_stderr_init(stderr);
1.20 ! noro 327: init_pari();
1.16 noro 328: initialize_stack();
329:
330: fprintf(stderr,"ox_pari\n");
1.4 noro 331:
1.16 noro 332: fd_rw = oxf_open(3);
333: oxf_determine_byteorder_server(fd_rw);
334: }
1.17 ohara 335:
336: #if defined(__CYGWIN__)
337: void *mysignal(int sig,void (*handler)(int m));
338: mysignal(SIGUSR1,usr1_handler);
339: #else
1.16 noro 340: signal(SIGUSR1,usr1_handler);
1.17 ohara 341: #endif
1.4 noro 342:
343: while(1){
344: receive();
345: }
1.1 noro 346: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>