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