Annotation of OpenXM/src/ox_pari/ox_pari.c, Revision 1.18
1.18 ! noro 1: /* $OpenXM: OpenXM/src/ox_pari/ox_pari.c,v 1.17 2018/06/04 06:39:26 ohara 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: mp_set_memory_functions(GC_malloc,gc_realloc,gc_free);
31: }
32:
1.1 noro 33: void init_pari()
34: {
1.2 noro 35: pari_init(paristack,2);
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.15 noro 160: int status;
161: char *err;
1.2 noro 162:
1.15 noro 163: if ( (status = setjmp(GP_DATA->env)) != 0 ) {
164: err = errmessage[status];
165: if ( status == errpile ) {
166: sprintf(buf,"%s\nIncrease PARI stack by pari(allocatemem,size).",err);
167: init_pari();
168: } else if ( strlen(err) != 0 )
169: sprintf(buf,"An error occured in PARI :%s",err);
170: else
171: sprintf(buf,"An error occured in PARI.");
1.8 noro 172: push((cmo*)make_error2(buf));
1.4 noro 173: return -1;
174: }
175: cmo_string *func = (cmo_string *)pop();
176: if(func->tag != CMO_STRING) {
1.8 noro 177: sprintf(buf,"sm_executeFunction : func->tag=%d is not CMO_STRING",func->tag);
178: push((cmo*)make_error2(buf));
1.4 noro 179: return -1;
180: }
1.1 noro 181:
1.4 noro 182: c = (cmo_int32 *)pop();
1.2 noro 183: ac = c->i;
184: if ( ac > PARI_MAX_AC ) {
1.8 noro 185: push((cmo*)make_error2("sm_executeFunction : too many arguments"));
1.4 noro 186: return -1;
1.2 noro 187: }
188: for ( i = 0; i < ac; i++ ) {
189: av[i] = (cmo *)pop();
1.8 noro 190: // fprintf(stderr,"arg%d:",i);
191: // print_cmo(av[i]);
192: // fprintf(stderr,"\n");
1.2 noro 193: }
1.4 noro 194: if( strcmp( func->s, "exit" ) == 0 )
195: exit(0);
1.3 noro 196:
197: parif =search_parif(func->s);
198: if ( !parif ) {
1.8 noro 199: sprintf(buf,"%s : not implemented",func->s);
200: push((cmo*)make_error2(buf));
1.4 noro 201: return -1;
1.3 noro 202: } else if ( parif->type == 0 ) {
203: /* one long int variable */
204: int a = cmo_to_int(av[0]);
1.4 noro 205: a = (int)(parif->f)(a);
1.3 noro 206: ret = (cmo *)new_cmo_int32(a);
1.2 noro 207: push(ret);
1.4 noro 208: return 0;
1.12 noro 209: } else if ( parif->type == 1 ) {
1.7 noro 210: /* one number/poly/matrix argument possibly with prec */
1.5 noro 211: av0 = avma;
1.2 noro 212: z = cmo_to_GEN(av[0]);
1.7 noro 213: prec = ac==2 ? cmo_to_int(av[1])*3.32193/32+3 : precreal;
1.8 noro 214: if ( ismatrix(z) ) {
1.7 noro 215: int i,len;
216: len = lg(z);
217: for ( i = 1; i < len; i++ )
218: settyp(z[i],t_COL);
219: settyp(z,t_MAT);
220: z = shallowtrans(z);
221: }
222: printf("input : "); output(z);
1.3 noro 223: m = (*parif->f)(z,prec);
1.2 noro 224: ret = GEN_to_cmo(m);
1.5 noro 225: avma = av0;
1.2 noro 226: push(ret);
1.4 noro 227: return 0;
1.13 noro 228: } else if ( parif->type == 2 ) {
229: /* one number/poly/matrix argument with flag=0 */
230: av0 = avma;
231: z = cmo_to_GEN(av[0]);
232: if ( ismatrix(z) ) {
233: int i,len;
234: len = lg(z);
235: for ( i = 1; i < len; i++ )
236: settyp(z[i],t_COL);
237: settyp(z,t_MAT);
238: z = shallowtrans(z);
239: }
240: printf("input : "); output(z);
241: m = (*parif->f)(z,0);
242: ret = GEN_to_cmo(m);
243: avma = av0;
244: push(ret);
245: return 0;
1.3 noro 246: } else {
1.8 noro 247: sprintf(buf,"%s : not implemented",func->s);
248: push((cmo*)make_error2(buf));
1.4 noro 249: return -1;
1.3 noro 250: }
1.1 noro 251: }
252:
253: int receive_and_execute_sm_command()
254: {
1.4 noro 255: int code = receive_int32(fd_rw);
256: switch(code) {
257: case SM_popCMO:
258: sm_popCMO();
259: break;
260: case SM_executeFunction:
261: sm_executeFunction();
262: break;
263: case SM_mathcap:
264: sm_mathcap();
265: break;
266: case SM_setMathCap:
267: pop();
268: break;
1.11 noro 269: case SM_shutdown:
270: exit(0);
271: break;
1.4 noro 272: default:
273: printf("receive_and_execute_sm_command : code=%d\n",code);fflush(stdout);
274: break;
275: }
276: return 0;
1.1 noro 277: }
278:
279: int receive()
280: {
1.4 noro 281: int tag;
1.1 noro 282:
1.4 noro 283: tag = receive_ox_tag(fd_rw);
284: switch(tag) {
285: case OX_DATA:
286: printf("receive : ox_data %d\n",tag);fflush(stdout);
287: push(receive_cmo(fd_rw));
288: break;
289: case OX_COMMAND:
290: printf("receive : ox_command %d\n",tag);fflush(stdout);
291: receive_and_execute_sm_command();
292: break;
293: default:
294: printf("receive : tag=%d\n",tag);fflush(stdout);
295: }
296: return 0;
1.1 noro 297: }
298:
1.18 ! noro 299: sigjmp_buf ox_env;
1.16 noro 300:
301: void usr1_handler(int sig)
302: {
1.18 ! noro 303: siglongjmp(ox_env,1);
1.16 noro 304: }
305:
1.1 noro 306: int main()
307: {
1.18 ! noro 308: if ( sigsetjmp(ox_env,~0) ) {
1.16 noro 309: fprintf(stderr,"resetting libpari and sending OX_SYNC_BALL...");
310: initialize_stack();
311: init_pari();
312: send_ox_tag(fd_rw,OX_SYNC_BALL);
313: fprintf(stderr,"done\n");
314: } else {
315: init_gc();
316: ox_stderr_init(stderr);
317: initialize_stack();
318: init_pari();
319:
320: fprintf(stderr,"ox_pari\n");
1.4 noro 321:
1.16 noro 322: fd_rw = oxf_open(3);
323: oxf_determine_byteorder_server(fd_rw);
324: }
1.17 ohara 325:
326: #if defined(__CYGWIN__)
327: void *mysignal(int sig,void (*handler)(int m));
328: mysignal(SIGUSR1,usr1_handler);
329: #else
1.16 noro 330: signal(SIGUSR1,usr1_handler);
1.17 ohara 331: #endif
1.4 noro 332:
333: while(1){
334: receive();
335: }
1.1 noro 336: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>