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