Annotation of OpenXM/src/ox_pari/ox_pari.c, Revision 1.21
1.21 ! noro 1: /* $OpenXM: OpenXM/src/ox_pari/ox_pari.c,v 1.20 2020/08/26 06:03:31 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.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.21 ! noro 199: prec = ac==2 ? ndec2prec(cmo_to_int(av[1])) : nbits2prec(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>