00001
00002
00003
00004
00005
00006
00007
00008 static char *rcsid="@(#)$Id$";
00009
00010 #include "eus.h"
00011 #define FALSE 0
00012 #define TRUE 1
00013
00014 extern pointer ALLOWOTHERKEYS,K_ALLOWOTHERKEYS;
00015 extern pointer OPTIONAL,REST,KEY,AUX,MACRO,LAMBDA,LAMCLOSURE;
00016 extern char *maxmemory;
00017
00018 #ifdef EVAL_DEBUG
00019 int evaldebug;
00020 #endif
00021
00022 pointer *getobjv(sym,varvec,obj)
00023 register pointer sym;
00024 pointer varvec,obj;
00025 { register pointer *vv=varvec->c.vec.v;
00026 register int i=0,n;
00027 n=intval(varvec->c.vec.size);
00028 while (i<n)
00029 if (vv[i]==sym) return(&(obj->c.obj.iv[i]));
00030 else i++;
00031 return(NULL);}
00032
00033 pointer getval(ctx,sym)
00034 register context *ctx;
00035 register pointer sym;
00036 { register struct bindframe *bf=ctx->bindfp;
00037 register pointer var,val;
00038 pointer *vaddr;
00039 int vt;
00040 if (sym->c.sym.vtype>=V_SPECIAL) {
00041 vt=intval(sym->c.sym.vtype);
00042 val=ctx->specials->c.vec.v[vt];
00043 if (val==UNBOUND) {
00044 val=sym->c.sym.speval;
00045 if (val==UNBOUND) error(E_UNBOUND,sym);
00046 else return(val); }
00047 else return(val);}
00048 if (sym->c.sym.vtype==V_CONSTANT) return(sym->c.sym.speval);
00049 GC_POINT;
00050 while (bf!=NULL) {
00051 var=bf->sym;
00052 val=bf->val;
00053 if (sym==var) {
00054 if (val==UNBOUND) goto getspecial;
00055 return(val);}
00056 else if (var->cix==vectorcp.cix) {
00057 vaddr=getobjv(sym,var,val);
00058 if (vaddr) return(*vaddr);}
00059 if (bf==bf->lexblink) break;
00060 bf=bf->lexblink;}
00061
00062
00063 getspecial:
00064 val=sym->c.sym.speval;
00065 if (val==UNBOUND) error(E_UNBOUND,sym);
00066 else return(val);}
00067
00068 pointer setval(ctx,sym,val)
00069 register context *ctx;
00070 register pointer sym,val;
00071 { register struct bindframe *bf=ctx->bindfp;
00072 register pointer var;
00073 pointer *vaddr;
00074 int vt;
00075 if (sym->c.sym.vtype>=V_SPECIAL) {
00076 vt=intval(sym->c.sym.vtype);
00077 pointer_update(ctx->specials->c.vec.v[vt],val);
00078 return(val);}
00079 while (bf!=NULL) {
00080 var=bf->sym;
00081 if (sym==var) {
00082 if (bf->val==UNBOUND) goto setspecial;
00083 pointer_update(bf->val,val); return(val);}
00084 else if (var->cix==vectorcp.cix) {
00085 vaddr=getobjv(sym,var,bf->val);
00086 if (vaddr) {pointer_update(*vaddr,val); return(val);}}
00087 bf=bf->lexblink; GC_POINT;}
00088
00089 if (sym->c.sym.vtype==V_CONSTANT) error(E_SETCONST,sym);
00090 if (sym->c.sym.vtype==V_GLOBAL) goto setspecial;
00091 setspecial:
00092 pointer_update(sym->c.sym.speval,val);
00093 return(val);
00094 }
00095
00096
00097 pointer getfunc(ctx,f)
00098 register context *ctx;
00099 register pointer f;
00100 { register struct fletframe *ffp=ctx->fletfp;
00101 while (ffp!=NULL) {
00102 if (ffp->name==f) { return(ffp->fclosure);}
00103 else ffp=ffp->lexlink;}
00104 if (f->c.sym.spefunc==UNBOUND) error(E_UNDEF,f);
00105 else {
00106 return(f->c.sym.spefunc);}}
00107
00108
00109 pointer get_sym_func(s)
00110 pointer s;
00111 { register pointer f;
00112 if ((f=s->c.sym.spefunc)==UNBOUND) error(E_UNDEF,s);
00113 else return(f);}
00114
00115
00116 void setfunc(sym,func)
00117 register pointer sym,func;
00118 { pointer_update(sym->c.sym.spefunc,func);}
00119
00120 pointer *ovafptr(o,v)
00121 register pointer o,v;
00122 { register pointer c,*vaddr;
00123 if (!ispointer(o)) error(E_NOOBJ,o,v);
00124 c=classof(o);
00125 vaddr=getobjv(v,c->c.cls.vars,o);
00126 if (vaddr) return(vaddr);
00127 else error(E_NOOBJVAR,o,v);}
00128
00129
00130
00131 void bindspecial(ctx,sym,newval)
00132 register context *ctx;
00133 pointer sym,newval;
00134 { register struct specialbindframe *sbf=(struct specialbindframe *)(ctx->vsp);
00135 int vt;
00136 GC_POINT;
00137 vt=intval(sym->c.sym.vtype);
00138 ctx->vsp += (sizeof(struct specialbindframe)/sizeof(pointer));
00139 sbf->sblink=ctx->sbindfp;
00140 sbf->sym=sym;
00141
00142 if (sym->c.sym.vtype==V_GLOBAL){
00143 sbf->oldval=speval(sym); speval(sym)=newval;}
00144 else { sbf->oldval=spevalof(sym,vt); spevalof(sym,vt)=newval;}
00145
00146 ctx->sbindfp=sbf;
00147 ctx->special_bind_count++;}
00148
00149
00150 void unbindx(ctx,count)
00151 register context *ctx;
00152 register int count;
00153 { register pointer s;
00154 register struct specialbindframe *sbfp=ctx->sbindfp;
00155 if (ctx->special_bind_count<count) error(E_USER,(pointer)"inconsistent special binding");
00156 ctx->special_bind_count -= count;
00157 while (count-- >0) {
00158 s=sbfp->sym;
00159
00160 if (s->c.sym.vtype==V_GLOBAL) {pointer_update(speval(s),sbfp->oldval);}
00161 else pointer_update(Spevalof(s),sbfp->oldval);
00162 sbfp=sbfp->sblink;}
00163 ctx->sbindfp=sbfp;}
00164
00165 void unbindspecial(ctx,limit)
00166 register context *ctx;
00167 register struct specialbindframe *limit;
00168 { register pointer s;
00169 register struct specialbindframe *sbfp=ctx->sbindfp;
00170 if (sbfp) {
00171 while (limit<=sbfp) {
00172 s=sbfp->sym;
00173
00174 if (s->c.sym.vtype==V_GLOBAL) {pointer_update(speval(s),sbfp->oldval);}
00175 else pointer_update(Spevalof(s),sbfp->oldval);
00176 sbfp=sbfp->sblink;
00177 ctx->special_bind_count--;}
00178 ctx->sbindfp=sbfp;}}
00179
00180 struct bindframe *fastbind(ctx,var,val,lex)
00181 register context *ctx;
00182 register pointer var,val;
00183 struct bindframe *lex;
00184 { register struct bindframe *bf;
00185 bf=(struct bindframe *)(ctx->vsp);
00186 ctx->vsp += sizeof(struct bindframe)/sizeof(eusinteger_t);
00187 bf->lexblink=lex;
00188 bf->dynblink=ctx->bindfp;
00189 bf->sym=var;
00190 bf->val=val;
00191 ctx->bindfp=bf;
00192 return(bf); }
00193
00194 struct bindframe *vbind(ctx,var,val,lex,declscope)
00195 register context *ctx;
00196 register pointer var,val;
00197 struct bindframe *lex,*declscope;
00198 { register struct bindframe *p;
00199 if (!issymbol(var)) error(E_NOSYMBOL);
00200 if (var->c.sym.vtype==V_CONSTANT) error(E_NOVARIABLE,var);
00201 p=ctx->bindfp;
00202 while (p>declscope) {
00203 if (p->sym==var)
00204 if (p->val==UNBOUND) { bindspecial(ctx,var,val); return(ctx->bindfp);}
00205 else error(E_MULTIDECL);
00206 if (p==p->lexblink) break;
00207 p=p->lexblink;}
00208
00209 if (var->c.sym.vtype>= V_GLOBAL ) {
00210
00211
00212
00213
00214
00215
00216 bindspecial(ctx,var,val);
00217 return(ctx->bindfp);}
00218 return(fastbind(ctx,var,val,lex));}
00219
00220 struct bindframe *declare(ctx,decllist,env)
00221 register context *ctx;
00222 pointer decllist;
00223 struct bindframe *env;
00224 { register pointer decl,var;
00225
00226 while (iscons(decllist)) {
00227 decl=ccar(decllist); decllist=ccdr(decllist);
00228 if (!iscons(decl)) error(E_DECLARE);
00229 if (ccar(decl)==QSPECIAL) {
00230 decl=ccdr(decl);
00231 while (iscons(decl)) {
00232 var=ccar(decl);
00233 if (var->c.sym.vtype < V_SPECIAL) env=vbind(ctx,var,UNBOUND,env,ctx->bindfp);
00234 decl=ccdr(decl); } } }
00235 return(env);}
00236
00237 int parsekeyparams(keyvec,actuals,noarg,results,allowotherkeys)
00238
00239 register pointer keyvec, *actuals, *results;
00240 int noarg,allowotherkeys;
00241 { register int i=0,n=0,suppliedbits=0,keysize, bitpos;
00242 register pointer akeyvar, *keys;
00243
00244 if (noarg<=0) return(suppliedbits);
00245 if (noarg & 1) error(E_KEYPARAM);
00246 keysize=vecsize(keyvec);
00247 for (i=0; i<keysize; i++) {
00248 #ifdef SAFETY
00249 take_care(results[i]);
00250 #endif
00251 results[i]=NIL;
00252 }
00253 while (n<noarg) {
00254 akeyvar=actuals[n++];
00255 if (!issymbol(akeyvar)) error(E_KEYPARAM);
00256 if (akeyvar->c.sym.homepkg!=keywordpkg) error(E_KEYPARAM);
00257 i=0;
00258 keys=keyvec->c.vec.v;
00259 if (akeyvar==K_ALLOWOTHERKEYS) allowotherkeys=(actuals[n]!=NIL);
00260 while (i<keysize && keys[i]!=akeyvar) i++;
00261 if (i<keysize) {
00262 bitpos = 1<<i;
00263 if ((suppliedbits & bitpos) ==0) {
00264 pointer_update(results[i],actuals[n]);
00265 suppliedbits |= bitpos;} }
00266 else if (!allowotherkeys) error(E_NOKEYPARAM,akeyvar);
00267 n++;}
00268 return(suppliedbits);}
00269
00270 struct bindframe *bindkeyparams(ctx,formal,argp,noarg,env,bf)
00271 register context *ctx;
00272 pointer formal;
00273 pointer *argp;
00274 int noarg;
00275 struct bindframe *env,*bf;
00276 { pointer fvar,initform;
00277 register pointer fkeyvar,akeyvar;
00278 pointer keys[KEYWORDPARAMETERLIMIT],
00279 vars[KEYWORDPARAMETERLIMIT],
00280 inits[KEYWORDPARAMETERLIMIT];
00281 register int nokeys=0,i,n,allowotherkeys=0;
00282
00283
00284 while (iscons(formal)) {
00285 fkeyvar=ccar(formal); formal=ccdr(formal);
00286 if (iscons(fkeyvar)) {
00287 fvar=ccar(fkeyvar);
00288 initform=ccdr(fkeyvar);
00289 if (iscons(initform)) initform=ccar(initform); else initform=NIL;
00290 if (iscons(fvar)) {
00291 fkeyvar=ccar(fvar); fvar=ccdr(fvar);
00292 if (!iscons(fvar)) error(E_KEYPARAM);
00293 fvar=ccar(fvar);
00294 if (!issymbol(fkeyvar)) error(E_NOSYMBOL);
00295 if (fkeyvar->c.sym.homepkg!=keywordpkg) error(E_KEYPARAM);}
00296 else {
00297 if (!issymbol(fvar)) error(E_NOSYMBOL);
00298 fkeyvar=fvar->c.sym.pname;
00299 fkeyvar=intern(ctx,(char *)fkeyvar->c.str.chars,
00300 vecsize(fkeyvar),keywordpkg);}}
00301 else if (fkeyvar==ALLOWOTHERKEYS) {
00302 allowotherkeys=1;
00303 if (islist(formal)) {
00304 fkeyvar=ccar(formal); formal=ccdr(formal);
00305 if (fkeyvar==AUX) break;
00306 else error(E_USER,(pointer)"something after &allow-other-keys"); }
00307 break;}
00308 else if (fkeyvar==AUX) break;
00309 else {
00310 initform=NIL;
00311 fvar=fkeyvar;
00312 if (!issymbol(fvar)) error(E_NOSYMBOL);
00313 fkeyvar=fvar->c.sym.pname;
00314 fkeyvar=intern(ctx,(char *)fkeyvar->c.str.chars,
00315 vecsize(fkeyvar),keywordpkg);}
00316
00317 keys[nokeys]=fkeyvar;
00318 vars[nokeys]=fvar;
00319 inits[nokeys]=initform;
00320 nokeys++;
00321 if (nokeys>=KEYWORDPARAMETERLIMIT) {
00322 error(E_USER, "Too many keyword parameters >32");
00323 }
00324 }
00325 n=0;
00326 while (n<noarg) {
00327 akeyvar=argp[n++];
00328 if (!issymbol(akeyvar)) error(E_KEYPARAM);
00329 if (akeyvar->c.sym.homepkg!=keywordpkg) error(E_KEYPARAM);
00330 if (akeyvar==K_ALLOWOTHERKEYS) allowotherkeys=(argp[n]!=NIL);
00331 i=0;
00332 while (i<nokeys && keys[i]!=akeyvar) i++;
00333 if (n>=noarg) error(E_KEYPARAM);
00334 if (i<nokeys) {
00335 if (inits[i]!=UNBOUND) {
00336 env=vbind(ctx,vars[i],argp[n],env,bf);
00337 inits[i]=UNBOUND;} }
00338 else if (!allowotherkeys) error(E_NOKEYPARAM,akeyvar);
00339 n++; }
00340 i=0;
00341 while (i<nokeys) {
00342 if (inits[i]!=UNBOUND) env=vbind(ctx,vars[i],eval(ctx,inits[i]),env,bf);
00343 i++;}
00344 return(env);}
00345
00346 pointer funlambda(ctx,fn,formal,body,argp,env,noarg)
00347 register context *ctx;
00348 pointer fn,formal,body,*argp;
00349 struct bindframe *env;
00350 int noarg;
00351 { pointer ftype,fvar,result,decl,aval,initform,fkeyvar,akeyvar;
00352 pointer *vspsave= ctx->vsp;
00353 struct specialbindframe *sbfps=ctx->sbindfp;
00354 struct bindframe *bf=ctx->bindfp;
00355 struct blockframe *myblock;
00356 int n=0,keyno=0,i;
00357 jmp_buf funjmp;
00358
00359 ctx->bindfp=env;
00360
00361
00362 while (iscons(body)) {
00363 decl=ccar(body);
00364 if (!iscons(decl) || (ccar(decl)!=QDECLARE)) break;
00365 env=declare(ctx,ccdr(decl),env);
00366 body=ccdr(body); GC_POINT;}
00367
00368
00369 while (iscons(formal)) {
00370 fvar=ccar(formal); formal=ccdr(formal);
00371 if (fvar==OPTIONAL) goto bindopt;
00372 if (fvar==REST) goto bindrest;
00373 if (fvar==KEY) { keyno=n; goto bindkey;}
00374 if (fvar==AUX) goto bindaux;
00375 if (n>=noarg) error(E_MISMATCHARG);
00376 env=vbind(ctx,fvar,argp[n],env,bf);
00377 n++;}
00378 if (n!=noarg) error(E_MISMATCHARG);
00379 goto evbody;
00380 bindopt:
00381 while (iscons(formal)) {
00382 fvar=ccar(formal); formal=ccdr(formal);
00383 if (fvar==REST) goto bindrest;
00384 if (fvar==KEY) { keyno=n; goto bindkey;}
00385 if (fvar==AUX) goto bindaux;
00386 if (n<noarg) {
00387 aval=argp[n];
00388 if (iscons(fvar)) fvar=ccar(fvar);}
00389 else if (iscons(fvar)) {
00390 initform=ccdr(fvar);
00391 fvar=ccar(fvar);
00392 if (iscons(initform)) {GC_POINT;aval=eval(ctx,ccar(initform));}
00393 else aval=NIL;}
00394 else aval=NIL;
00395 env=vbind(ctx,fvar,aval,env,bf);
00396 n++;}
00397 if (n<noarg) error(E_MISMATCHARG);
00398 goto evbody;
00399 bindrest:
00400 keyno=n;
00401 fvar=carof(formal,E_PARAMETER);
00402 formal=ccdr(formal);
00403
00404 result=NIL;
00405 i=noarg;
00406 while (n<i) result=cons(ctx,argp[--i],result);
00407 env=vbind(ctx,fvar,result,env,bf);
00408 n++;
00409 if (!iscons(formal)) goto evbody;
00410 fvar=ccar(formal); formal=ccdr(formal);
00411 if (fvar==KEY) goto bindkey;
00412 else if (fvar==AUX) goto bindaux;
00413 else error(E_PARAMETER);
00414 bindkey:
00415 env=bindkeyparams(ctx,formal,&argp[keyno],noarg-keyno,env,bf);
00416 while (iscons(formal)) {
00417 fvar=ccar(formal); formal=ccdr(formal);
00418 if (fvar==AUX) goto bindaux;}
00419 goto evbody;
00420 bindaux:
00421 while (iscons(formal)) {
00422 fvar=ccar(formal); formal=ccdr(formal);
00423 if (iscons(fvar)) {
00424 initform=ccdr(fvar);
00425 fvar=ccar(fvar);
00426 if (iscons(initform)) {GC_POINT;aval=eval(ctx,ccar(initform));}
00427 else aval=NIL;}
00428 else aval=NIL;
00429 env=vbind(ctx,fvar,aval,env,bf); }
00430 evbody:
00431 GC_POINT;
00432
00433 myblock=(struct blockframe *)makeblock(ctx,BLOCKFRAME,fn,(jmp_buf *)funjmp,NULL);
00434
00435 if ((result=(pointer)eussetjmp(funjmp))==0) {GC_POINT;result=progn(ctx,body);}
00436 else if (result==(pointer)1) result=makeint(0);
00437
00438 ctx->blkfp=myblock->dynklink;
00439 ctx->bindfp=bf;
00440 ctx->vsp=vspsave;
00441
00442 #ifdef __RETURN_BARRIER
00443 check_return_barrier(ctx);
00444
00445 #endif
00446
00447 unbindspecial(ctx,sbfps+1);
00448 return(result);}
00449
00450 #if IRIX6
00451
00452 #include <alloca.h>
00453
00454 extern long i_call_foreign(eusinteger_t (*)(),int,numunion *);
00455 extern double f_call_foreign(eusinteger_t (*)(),int,numunion *);
00456
00457 pointer call_foreign(func,code,n,args)
00458 eusinteger_t (*func)();
00459 pointer code;
00460 int n;
00461 pointer args[];
00462 { pointer paramtypes=code->c.fcode.paramtypes;
00463 pointer resulttype=code->c.fcode.resulttype;
00464 pointer p,lisparg;
00465 numunion nu,*cargv;
00466 eusinteger_t i=0;
00467 double f;
00468
00469 cargv=(numunion *)alloca(n*sizeof(numunion));
00470 while (iscons(paramtypes)) {
00471 p=ccar(paramtypes); paramtypes=ccdr(paramtypes);
00472 lisparg=args[i];
00473 if (p==K_INTEGER)
00474 cargv[i++].ival=isint(lisparg)?intval(lisparg):bigintval(lisparg);
00475 else if (p==K_FLOAT) cargv[i++].fval=ckfltval(lisparg);
00476 else if (p==K_STRING)
00477 if (elmtypeof(lisparg)==ELM_FOREIGN)
00478 cargv[i++].ival=lisparg->c.ivec.iv[0];
00479 else cargv[i++].ival=(eusinteger_t)(lisparg->c.str.chars);
00480 else error(E_USER,(pointer)"unknown type specifier");}
00481
00482 while (i<n) {
00483 lisparg=args[i];
00484 if (isint(lisparg)) cargv[i++].ival=intval(lisparg);
00485 else if (isflt(lisparg)) cargv[i++].fval=ckfltval(lisparg);
00486 else if (isvector(lisparg)) {
00487 if (elmtypeof(lisparg)==ELM_FOREIGN)
00488 cargv[i++].ival=lisparg->c.ivec.iv[0];
00489 else cargv[i++].ival=(eusinteger_t)(lisparg->c.str.chars);}
00490 else cargv[i++].ival=(eusinteger_t)(lisparg->c.obj.iv);}
00491
00492 if (resulttype==K_FLOAT) return(makeflt(f_call_foreign(func,n,cargv)));
00493 else {
00494 i=i_call_foreign(func,n,cargv);
00495 if (resulttype==K_INTEGER) return(mkbigint(i));
00496 else if (resulttype==K_STRING) {
00497 p=makepointer(i-2*sizeof(pointer));
00498 if (isvector(p)) return(p);
00499 else error(E_USER,(pointer)"illegal foreign string"); }
00500 else if (iscons(resulttype)) {
00501
00502 if (ccar(resulttype)==K_STRING) {
00503 resulttype=ccdr(resulttype);
00504 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00505 else j=strlen((char *)i);
00506 return(makestring((char *)i, j)); }
00507 else if (ccar(resulttype)==K_FOREIGN_STRING) {
00508 resulttype=ccdr(resulttype);
00509 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00510 else j=strlen((char *)i);
00511 return(make_foreign_string(i, j)); }
00512 error(E_USER,(pointer)"unknown result type"); }
00513 else error(E_USER,(pointer)"result type?");
00514 }}
00515
00516 #else
00517
00518 #if IRIX
00519
00520 #include <alloca.h>
00521
00522 extern int i_call_foreign(eusinteger_t (*)(),int,int *);
00523 extern double f_call_foreign(eusinteger_t (*)(),int,int *);
00524
00525 pointer call_foreign(func,code,n,args)
00526 eusinteger_t (*func)();
00527 pointer code;
00528 int n;
00529 pointer args[];
00530 { pointer paramtypes=code->c.fcode.paramtypes;
00531 pointer resulttype=code->c.fcode.resulttype;
00532 pointer p,lisparg;
00533 numunion nu,*cargs;
00534 eusinteger_t i=0;
00535 unsigned int *offset,*isfloat,m=0;
00536 int *cargv;
00537 union {
00538 double d;
00539 struct {
00540 int i1,i2;} i;
00541 } numbox;
00542 double f;
00543
00544 cargs=(numunion *)alloca(n*sizeof(numunion));
00545 offset=(unsigned int *)alloca(n*sizeof(unsigned int));
00546 isfloat=(unsigned int *)alloca(n*sizeof(unsigned int));
00547 while (iscons(paramtypes)) {
00548 p=ccar(paramtypes); paramtypes=ccdr(paramtypes);
00549 lisparg=args[i];
00550 if (isfloat[i]=(p==K_FLOAT)) {
00551 cargs[i].fval=ckfltval(lisparg);
00552 offset[i]=(m+1)&~1; m=offset[i++]+2;}
00553 else if (p==K_INTEGER) {
00554 cargs[i++].ival=isint(lisparg)?intval(lisparg):bigintval(lisparg);
00555 offset[i++]=m++;}
00556 else if (p==K_STRING) {
00557 if (elmtypeof(lisparg)==ELM_FOREIGN)
00558 cargs[i].ival=lisparg->c.ivec.iv[0];
00559 else cargs[i].ival=(eusinteger_t)(lisparg->c.str.chars);
00560 offset[i++]=m++;}
00561 else error(E_USER,(pointer)"unknown type specifier");}
00562
00563 while (i<n) {
00564 lisparg=args[i];
00565 if (isfloat[i]=isflt(lisparg)) {
00566 cargs[i].fval=ckfltval(lisparg);
00567 offset[i]=(m+1)&~1; m=offset[i++]+2;}
00568 else if (isint(lisparg)) {
00569 cargs[i].ival=intval(lisparg);
00570 offset[i++]=m++;}
00571 else if (isvector(lisparg)) {
00572 if (elmtypeof(lisparg)==ELM_FOREIGN)
00573 cargs[i].ival=lisparg->c.ivec.iv[0];
00574 else cargs[i].ival=(eusinteger_t)(lisparg->c.str.chars);
00575 offset[i++]=m++;}
00576 else {
00577 cargs[i++].ival=(eusinteger_t)(lisparg->c.obj.iv);
00578 offset[i++]=m++;}}
00579 cargv=(int *)alloca(m*sizeof(int));
00580 for (i=0; i<n; ++i) {
00581 if (isfloat[i]) {
00582 numbox.d=(double)cargs[i].fval;
00583 cargv[offset[i]]=numbox.i.i1; cargv[offset[i]+1]=numbox.i.i2;}
00584 else cargv[offset[i]]=cargs[i].ival;}
00585
00586 if (resulttype==K_FLOAT) return(makeflt(f_call_foreign(func,m,cargv)));
00587 else {
00588 i=i_call_foreign(func,m,cargv);
00589 if (resulttype==K_INTEGER) return(mkbigint(i));
00590 else if (resulttype==K_STRING) {
00591 p=makepointer(i-2*sizeof(pointer));
00592 if (isvector(p)) return(p);
00593 else error(E_USER,(pointer)"illegal foreign string"); }
00594 else if (iscons(resulttype)) {
00595
00596 if (ccar(resulttype)=K_STRING) {
00597 resulttype=ccdr(resulttype);
00598 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00599 else j=strlen((char *)i);
00600 return(makestring((char *)i, j)); }
00601 else if (ccar(resulttype)=K_FOREIGN_STRING) {
00602 resulttype=ccdr(resulttype);
00603 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00604 else j=strlen((char *)i);
00605 return(make_foreign_string(i, j)); }
00606 error(E_USER,(pointer)"unknown result type"); }
00607 else error(E_USER,(pointer)"result type?");
00608 }}
00609
00610 #else
00611
00612
00613 #if x86_64
00614 extern long exec_function_i(void (*)(), long *, long *, long, long *);
00615 extern long exec_function_f(void (*)(), long *, long *, long, long *);
00616
00617
00618
00619
00620
00621 __asm__ (".align 8\n"
00622 #if Darwin
00623 "_exec_function_i:\n\t"
00624 #else
00625 "exec_function_i:\n\t"
00626 #endif
00627 "push %rbx\n\t"
00628 "sub $0x120, %rsp\n\t"
00629 "mov %rdx, %rax\n\t"
00630 "movsd 0x00(%rax), %xmm0\n\t"
00631 "movsd 0x08(%rax), %xmm1\n\t"
00632 "movsd 0x10(%rax), %xmm2\n\t"
00633 "movsd 0x18(%rax), %xmm3\n\t"
00634 "movsd 0x20(%rax), %xmm4\n\t"
00635 "movsd 0x28(%rax), %xmm5\n\t"
00636 "movsd 0x30(%rax), %xmm6\n\t"
00637 "movsd 0x38(%rax), %xmm7\n\t"
00638 "mov %rsp, %rax\n\t"
00639 "mov $0, %r10\n\t"
00640 "cmpl %ecx, %r10d\n\t"
00641 "jge .LENDLP\n"
00642 ".LNEXTLP:\n\t"
00643 "mov (%r8), %rbx\n\t"
00644 "mov %rbx, (%rax)\n\t"
00645 "add $8, %rax\n\t"
00646 "add $8, %r8\n\t"
00647 "add $1, %r10d\n\t"
00648 "cmpl %r10d, %ecx\n\t"
00649 "jg .LNEXTLP\n"
00650 ".LENDLP:\n\t"
00651 "mov %rdi, %rbx\n\t"
00652 "mov %rsi, %rax\n\t"
00653 "mov 0x00(%rax), %rdi\n\t"
00654 "mov 0x08(%rax), %rsi\n\t"
00655 "mov 0x10(%rax), %rdx\n\t"
00656 "mov 0x18(%rax), %rcx\n\t"
00657 "mov 0x20(%rax), %r8\n\t"
00658 "mov 0x28(%rax), %r9\n\t"
00659 "mov $0x00, %eax\n\t"
00660 "call *%rbx\n\t"
00661 "add $0x120, %rsp\n\t"
00662 "pop %rbx\n\t"
00663 "retq"
00664 );
00665 __asm__ (".align 8\n"
00666 #if Darwin
00667 "_exec_function_f:\n\t"
00668 #else
00669 "exec_function_f:\n\t"
00670 #endif
00671 "push %rbx\n\t"
00672 "sub $0x120, %rsp\n\t"
00673 "mov %rdx, %rax\n\t"
00674 "movsd 0x00(%rax), %xmm0\n\t"
00675 "movsd 0x08(%rax), %xmm1\n\t"
00676 "movsd 0x10(%rax), %xmm2\n\t"
00677 "movsd 0x18(%rax), %xmm3\n\t"
00678 "movsd 0x20(%rax), %xmm4\n\t"
00679 "movsd 0x28(%rax), %xmm5\n\t"
00680 "movsd 0x30(%rax), %xmm6\n\t"
00681 "movsd 0x38(%rax), %xmm7\n\t"
00682 "mov %rsp, %rax\n\t"
00683 "mov $0, %r10\n\t"
00684 "cmpl %ecx, %r10d\n\t"
00685 "jge .LENDLPF\n"
00686 ".LNEXTLPF:\n\t"
00687 "mov (%r8), %rbx\n\t"
00688 "mov %rbx, (%rax)\n\t"
00689 "add $8, %rax\n\t"
00690 "add $8, %r8\n\t"
00691 "add $1, %r10d\n\t"
00692 "cmpl %r10d, %ecx\n\t"
00693 "jg .LNEXTLPF\n"
00694 ".LENDLPF:\n\t"
00695 "mov %rdi, %rbx\n\t"
00696 "mov %rsi, %rax\n\t"
00697 "mov 0x00(%rax), %rdi\n\t"
00698 "mov 0x08(%rax), %rsi\n\t"
00699 "mov 0x10(%rax), %rdx\n\t"
00700 "mov 0x18(%rax), %rcx\n\t"
00701 "mov 0x20(%rax), %r8\n\t"
00702 "mov 0x28(%rax), %r9\n\t"
00703 "mov $0x00, %eax\n\t"
00704 "call *%rbx\n\t"
00705 "movsd %xmm0, (%rsp)\n\t"
00706 "mov (%rsp), %rax\n\t"
00707 "add $0x120, %rsp\n\t"
00708 "pop %rbx\n\t"
00709 "retq"
00710 );
00711
00712 pointer call_foreign(ifunc,code,n,args)
00713 eusinteger_t (*ifunc)();
00714 pointer code;
00715 int n;
00716 pointer args[];
00717 {
00718 pointer paramtypes=code->c.fcode.paramtypes;
00719 pointer resulttype=code->c.fcode.resulttype;
00720 pointer p,lisparg;
00721 eusinteger_t iargv[6];
00722 eusinteger_t fargv[8];
00723 eusinteger_t vargv[16];
00724 int icntr = 0, fcntr = 0, vcntr = 0;
00725
00726 numunion nu;
00727 eusinteger_t j=0;
00728 eusinteger_t c=0;
00729 union {
00730 double d;
00731 float f;
00732 long l;
00733 struct {
00734 int i1,i2;} i;
00735 } numbox;
00736 double f;
00737
00738 if (code->c.fcode.entry2 != NIL) {
00739 ifunc = (((eusinteger_t)ifunc)&0xffffffff00000000)
00740 | (intval(code->c.fcode.entry2)&0x00000000ffffffff);
00741
00742 }
00743
00744 while (iscons(paramtypes)) {
00745 p=ccar(paramtypes); paramtypes=ccdr(paramtypes);
00746 lisparg=args[j++];
00747 if (p==K_INTEGER) {
00748 c = isint(lisparg)?intval(lisparg):bigintval(lisparg);
00749 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00750 } else if (p==K_STRING) {
00751 if (elmtypeof(lisparg)==ELM_FOREIGN) c=lisparg->c.ivec.iv[0];
00752 else c=(eusinteger_t)(lisparg->c.str.chars);
00753 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00754 } else if (p==K_FLOAT32) {
00755 numbox.f=(float)ckfltval(lisparg);
00756 c=((eusinteger_t)numbox.i.i1) & 0x00000000FFFFFFFF;
00757 if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
00758 } else if (p==K_DOUBLE || p==K_FLOAT) {
00759 numbox.d=ckfltval(lisparg);
00760 c=numbox.l;
00761 if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
00762 } else error(E_USER,(pointer)"unknown type specifier");
00763 }
00764
00765 while (j<n) {
00766 lisparg=args[j++];
00767 if (isint(lisparg)) {
00768 c=intval(lisparg);
00769 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00770 } else if (isflt(lisparg)) {
00771 numbox.d=ckfltval(lisparg);
00772 c=numbox.l;
00773 if(fcntr < 8) fargv[fcntr++] = c; else vargv[vcntr++] = c;
00774 } else if (isvector(lisparg)) {
00775 if (elmtypeof(lisparg)==ELM_FOREIGN) c=lisparg->c.ivec.iv[0];
00776 else c=(eusinteger_t)(lisparg->c.str.chars);
00777 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00778 } else if (isbignum(lisparg)){
00779 if (bigsize(lisparg)==1){
00780 eusinteger_t *xv = bigvec(lisparg);
00781 c=(eusinteger_t)xv[0];
00782 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00783 }else{
00784 fprintf(stderr, "bignum size!=1\n");
00785 }
00786 } else {
00787 c=(eusinteger_t)(lisparg->c.obj.iv);
00788 if(icntr < 6) iargv[icntr++] = c; else vargv[vcntr++] = c;
00789 }
00790 }
00791
00792 if (resulttype==K_FLOAT) {
00793 numbox.l = exec_function_f((void (*)())ifunc, iargv, fargv, vcntr, vargv);
00794 f = numbox.d;
00795 return(makeflt(f));
00796 } else if (resulttype==K_FLOAT32) {
00797 numbox.l = exec_function_f((void (*)())ifunc, iargv, fargv, vcntr, vargv);
00798 f = (double)numbox.f;
00799 return(makeflt(f));
00800 } else {
00801 c = exec_function_i((void (*)())ifunc, iargv, fargv, vcntr, vargv);
00802 if (resulttype==K_INTEGER) {
00803 return(mkbigint(c));
00804 } else if (resulttype==K_STRING) {
00805 p=makepointer(c-2*sizeof(pointer));
00806 if (isvector(p)) return(p);
00807 else error(E_USER,(pointer)"illegal foreign string");
00808 } else if (iscons(resulttype)) {
00809
00810 if (ccar(resulttype)==K_STRING) {
00811 resulttype=ccdr(resulttype);
00812 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00813 else j=strlen((char *)c);
00814 return(makestring((char *)c, j));
00815 } else if (ccar(resulttype)==K_FOREIGN_STRING) {
00816 resulttype=ccdr(resulttype);
00817 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00818 else j=strlen((char *)c);
00819 return(make_foreign_string(c, j)); }
00820 error(E_USER,(pointer)"unknown result type");
00821 } else error(E_USER,(pointer)"result type?");
00822 }
00823 }
00824 #else
00825 pointer call_foreign(ifunc,code,n,args)
00826 eusinteger_t (*ifunc)();
00827 pointer code;
00828 int n;
00829 pointer args[];
00830 { double (*ffunc)();
00831 pointer paramtypes=code->c.fcode.paramtypes;
00832 pointer resulttype=code->c.fcode.resulttype;
00833 pointer p,lisparg;
00834 eusinteger_t cargv[100];
00835 numunion nu;
00836 eusinteger_t i=0;
00837 eusinteger_t j=0;
00838 union {
00839 double d;
00840 float f;
00841 struct {
00842 int i1,i2;} i;
00843 } numbox;
00844 double f;
00845
00846 if (code->c.fcode.entry2 != NIL) {
00847 ifunc = (((int)ifunc)&0xffff0000) | (intval(code->c.fcode.entry2)&0x0000ffff);
00848 }
00849 ffunc=(double (*)())ifunc;
00850 while (iscons(paramtypes)) {
00851 p=ccar(paramtypes); paramtypes=ccdr(paramtypes);
00852 lisparg=args[j++];
00853 if (p==K_INTEGER)
00854 cargv[i++]=isint(lisparg)?intval(lisparg):bigintval(lisparg);
00855 else if (p==K_STRING) {
00856 if (elmtypeof(lisparg)==ELM_FOREIGN) cargv[i++]=lisparg->c.ivec.iv[0];
00857 else cargv[i++]=(eusinteger_t)(lisparg->c.str.chars);}
00858 else if (p==K_FLOAT32) {
00859 numbox.f=ckfltval(lisparg);
00860 cargv[i++]=(int)numbox.i.i1;}
00861 else if (p==K_DOUBLE || p==K_FLOAT) {
00862 numbox.d=ckfltval(lisparg);
00863 cargv[i++]=numbox.i.i1; cargv[i++]=numbox.i.i2;}
00864 else error(E_USER,(pointer)"unknown type specifier");}
00865
00866 while (j<n) {
00867 lisparg=args[j++];
00868 if (isint(lisparg)) cargv[i++]=intval(lisparg);
00869 else if (isflt(lisparg)) {
00870 numbox.d=ckfltval(lisparg);
00871 numbox.f=ckfltval(lisparg);
00872 cargv[i++]=numbox.i.i1; cargv[i++]=numbox.i.i2;}
00873 else if (isvector(lisparg)) {
00874 if (elmtypeof(lisparg)==ELM_FOREIGN)
00875 cargv[i++]=lisparg->c.ivec.iv[0];
00876 else cargv[i++]=(eusinteger_t)(lisparg->c.str.chars);}
00877 #if 1
00878 else if (isbignum(lisparg)){
00879 if (bigsize(lisparg)==1){
00880 eusinteger_t *xv = bigvec(lisparg);
00881 cargv[i++]=(eusinteger_t)xv[0];
00882 }else{
00883 fprintf(stderr, "bignum size!=1\n");
00884 }
00885 }
00886 #endif
00887 else cargv[i++]=(eusinteger_t)(lisparg->c.obj.iv);}
00888
00889 if (resulttype==K_FLOAT) {
00890 if (i<=8)
00891 f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00892 cargv[4],cargv[5],cargv[6],cargv[7]);
00893 else if (i<=32)
00894 f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00895 cargv[4],cargv[5],cargv[6],cargv[7],
00896 cargv[8],cargv[9],cargv[10],cargv[11],
00897 cargv[12],cargv[13],cargv[14],cargv[15],
00898 cargv[16],cargv[17],cargv[18],cargv[19],
00899 cargv[20],cargv[21],cargv[22],cargv[23],
00900 cargv[24],cargv[25],cargv[26],cargv[27],
00901 cargv[28],cargv[29],cargv[30],cargv[31]);
00902 #if (sun3 || sun4 || mips || alpha)
00903 else if (i>32)
00904 f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00905 cargv[4],cargv[5],cargv[6],cargv[7],
00906 cargv[8],cargv[9],cargv[10],cargv[11],
00907 cargv[12],cargv[13],cargv[14],cargv[15],
00908 cargv[16],cargv[17],cargv[18],cargv[19],
00909 cargv[20],cargv[21],cargv[22],cargv[23],
00910 cargv[24],cargv[25],cargv[26],cargv[27],
00911 cargv[28],cargv[29],cargv[30],cargv[31],
00912 cargv[32],cargv[33],cargv[34],cargv[35],
00913 cargv[36],cargv[37],cargv[38],cargv[39],
00914 cargv[40],cargv[41],cargv[42],cargv[43],
00915 cargv[44],cargv[45],cargv[46],cargv[47],
00916 cargv[48],cargv[49],cargv[50],cargv[51],
00917 cargv[52],cargv[53],cargv[54],cargv[55],
00918 cargv[56],cargv[57],cargv[58],cargv[59],
00919 cargv[60],cargv[61],cargv[62],cargv[63],
00920 cargv[64],cargv[65],cargv[66],cargv[67],
00921 cargv[68],cargv[69],cargv[70],cargv[71],
00922 cargv[72],cargv[73],cargv[74],cargv[75],
00923 cargv[76],cargv[77],cargv[78],cargv[79]);
00924 #endif
00925 return(makeflt(f));}
00926 else {
00927 if (i<8)
00928 i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00929 cargv[4],cargv[5],cargv[6],cargv[7]);
00930 else if (i<=32)
00931 i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00932 cargv[4],cargv[5],cargv[6],cargv[7],
00933 cargv[8],cargv[9],cargv[10],cargv[11],
00934 cargv[12],cargv[13],cargv[14],cargv[15],
00935 cargv[16],cargv[17],cargv[18],cargv[19],
00936 cargv[20],cargv[21],cargv[22],cargv[23],
00937 cargv[24],cargv[25],cargv[26],cargv[27],
00938 cargv[28],cargv[29],cargv[30],cargv[31]);
00939 #if (sun3 || sun4 || mips || alpha)
00940 else if (i>32)
00941 i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00942 cargv[4],cargv[5],cargv[6],cargv[7],
00943 cargv[8],cargv[9],cargv[10],cargv[11],
00944 cargv[12],cargv[13],cargv[14],cargv[15],
00945 cargv[16],cargv[17],cargv[18],cargv[19],
00946 cargv[20],cargv[21],cargv[22],cargv[23],
00947 cargv[24],cargv[25],cargv[26],cargv[27],
00948 cargv[28],cargv[29],cargv[30],cargv[31],
00949 cargv[32],cargv[33],cargv[34],cargv[35],
00950 cargv[36],cargv[37],cargv[38],cargv[39],
00951 cargv[40],cargv[41],cargv[42],cargv[43],
00952 cargv[44],cargv[45],cargv[46],cargv[47],
00953 cargv[48],cargv[49],cargv[50],cargv[51],
00954 cargv[52],cargv[53],cargv[54],cargv[55],
00955 cargv[56],cargv[57],cargv[58],cargv[59],
00956 cargv[60],cargv[61],cargv[62],cargv[63],
00957 cargv[64],cargv[65],cargv[66],cargv[67],
00958 cargv[68],cargv[69],cargv[70],cargv[71],
00959 cargv[72],cargv[73],cargv[74],cargv[75],
00960 cargv[76],cargv[77],cargv[78],cargv[79]);
00961 #endif
00962 if (resulttype==K_INTEGER) return(mkbigint(i));
00963 else if (resulttype==K_STRING) {
00964 p=makepointer(i-2*sizeof(pointer));
00965 if (isvector(p)) return(p);
00966 else error(E_USER,(pointer)"illegal foreign string"); }
00967 else if (iscons(resulttype)) {
00968
00969 if (ccar(resulttype)=K_STRING) {
00970 resulttype=ccdr(resulttype);
00971 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00972 else j=strlen((char *)i);
00973 return(makestring((char *)i, j)); }
00974 else if (ccar(resulttype)=K_FOREIGN_STRING) {
00975 resulttype=ccdr(resulttype);
00976 if (resulttype!=NIL) j=ckintval(ccar(resulttype));
00977 else j=strlen((char *)i);
00978 return(make_foreign_string(i, j)); }
00979 error(E_USER,(pointer)"unknown result type"); }
00980 else error(E_USER,(pointer)"result type?");
00981 }}
00982 #endif
00983 #endif
00984 #endif
00985
00986 pointer funcode(ctx,func,args,noarg)
00987 register context *ctx;
00988 register pointer func,args;
00989 register int noarg;
00990 { register pointer (*subr)();
00991 register pointer *argp=ctx->vsp;
00992 register int n=0;
00993 register eusinteger_t addr;
00994 pointer tmp;
00995 addr=(eusinteger_t)(func->c.code.entry);
00996 #ifdef x86_64
00997 addr &= ~3L;
00998 #else
00999 addr &= ~3;
01000 #endif
01001 #if ARM
01002 if (func->c.code.entry2 != NIL) {
01003 addr = addr | (intval(func->c.code.entry2)&0x0000ffff);
01004 }
01005 #endif
01006 subr=(pointer (*)())(addr);
01007 #ifdef FUNCODE_DEBUG
01008 printf( "funcode:func = " ); hoge_print( func );
01009 printf( "funcode:args = " ); hoge_print( args );
01010 #endif
01011 GC_POINT;
01012 switch((eusinteger_t)(func->c.code.subrtype)) {
01013 case (eusinteger_t)SUBR_FUNCTION:
01014 if (noarg<0) {
01015 while (piscons(args)) {
01016 vpush(eval(ctx,ccar(args))); args=ccdr(args); n++; GC_POINT;}
01017 if (pisfcode(func))
01018 return(call_foreign((eusinteger_t (*)())subr,func,n,argp));
01019 else return((*subr)(ctx,n,argp));}
01020 else if (pisfcode(func))
01021 return(call_foreign((eusinteger_t (*)())subr,func,noarg,(pointer *)args));
01022 else return((*subr)(ctx,noarg,args,0));
01023 break;
01024 case (eusinteger_t)SUBR_MACRO:
01025 if (noarg>=0) error(E_ILLFUNC);
01026 while (iscons(args)) { vpush(ccar(args)); args=ccdr(args); n++;}
01027 GC_POINT;
01028 tmp = (*subr)(ctx,n,argp);
01029 GC_POINT;
01030 return(eval(ctx,tmp));
01031 case (eusinteger_t)SUBR_SPECIAL:
01032 if (noarg>=0) error(E_ILLFUNC);
01033 else return((*subr)(ctx,args));
01034
01035
01036
01037 default: error(E_ILLFUNC); break;}
01038 }
01039
01040 pointer clofunc;
01041 pointer ufuncall(ctx,form,fn,args,env,noarg)
01042 register context *ctx;
01043 pointer form,fn;
01044 register pointer args;
01045 struct bindframe *env;
01046 int noarg;
01047 { pointer func,formal,aval,ftype,result,*argp,hook;
01048 register struct callframe *vf=(struct callframe *)(ctx->vsp);
01049 struct specialbindframe *sbfps=ctx->sbindfp;
01050 register int n=0,i;
01051 register pointer (*subr)();
01052 struct fletframe *oldfletfp=ctx->fletfp, *fenv;
01053 GC_POINT;
01054
01055 if (Spevalof(QEVALHOOK)!=NIL && ehbypass==0) {
01056 hook=Spevalof(QEVALHOOK);
01057 bindspecial(ctx,QEVALHOOK,NIL);
01058 if (noarg<0) vpush(cons(ctx,fn,args));
01059 else {
01060 argp=(pointer *)args;
01061 aval=NIL;
01062 i=noarg;
01063 while (--i>=0) aval=cons(ctx,argp[i],aval);
01064 vpush(cons(ctx,fn,aval));}
01065 vpush(env);
01066 GC_POINT;
01067 result=ufuncall(ctx,form,hook,(pointer)(ctx->vsp-2),env,2);
01068 ctx->vsp=(pointer *)vf;
01069 unbindspecial(ctx,sbfps+1);
01070 #ifdef __RETURN_BARRIER
01071 check_return_barrier(ctx);
01072
01073 #endif
01074 return(result);}
01075 else ehbypass=0;
01076
01077 if (issymbol(fn)) {
01078 func=getfunc(ctx,fn);
01079 }
01080 else {
01081 if (islist(fn)) env=ctx->bindfp;
01082 func=fn;}
01083 if (!ispointer(func)) error(E_ILLFUNC);
01084
01085
01086 stackck;
01087 breakck;
01088 vf->vlink=ctx->callfp;
01089 vf->form=form;
01090 ctx->callfp=vf;
01091 ctx->vsp+=sizeof(struct callframe)/(sizeof(pointer));
01092 argp=ctx->vsp;
01093
01094 if (pisclosure(func)) {
01095 clofunc=func;
01096 fn=func;
01097 if (fn->c.code.subrtype!=SUBR_FUNCTION) error(E_ILLFUNC);
01098 subr=(pointer (*)())((eusinteger_t)(fn->c.code.entry) & ~3 );
01099 #if ARM
01100 register eusinteger_t addr;
01101 addr = (eusinteger_t)(fn->c.code.entry);
01102 #ifdef x86_64
01103 addr &= ~3L;
01104 #else
01105 addr &= ~3;
01106 #endif
01107 if (fn->c.code.entry2 != NIL) {
01108 addr = addr | (intval(fn->c.code.entry2)&0x0000ffff);
01109 }
01110 subr=(pointer (*)())(addr);
01111 #endif
01112 #if !Solaris2 && !SunOS4_1 && !Linux && !IRIX && !IRIX6 && !alpha && !Cygwin
01113 if ((char *)subr>maxmemory) {
01114 prinx(ctx,clofunc, STDOUT);
01115 error(E_USER,(pointer)"garbage closure, fatal bug!"); }
01116 #endif
01117 if (noarg<0) {
01118 while (iscons(args)) {
01119 vpush(eval(ctx,ccar(args))); args=ccdr(args); n++; GC_POINT;}
01120 result=(*subr)(ctx,n,argp,func);}
01121 else result=(*subr)(ctx,noarg,args,func);
01122
01123 ctx->vsp=(pointer *)vf;
01124 ctx->callfp= vf->vlink;
01125 ctx->fletfp=oldfletfp;
01126 #ifdef __RETURN_BARRIER
01127 check_return_barrier(ctx);
01128
01129 #endif
01130 return(result);}
01131
01132 else if (piscode(func)) {
01133 GC_POINT;
01134 result=funcode(ctx,func,args,noarg);
01135 ctx->vsp=(pointer *)vf;
01136 ctx->callfp= vf->vlink;
01137 ctx->fletfp=oldfletfp;
01138 #ifdef __RETURN_BARRIER
01139 check_return_barrier(ctx);
01140 #endif
01141 return(result);}
01142 else if (piscons(func)) {
01143 ftype=ccar(func);
01144 func=ccdr(func);
01145 if (!issymbol(ftype)) error(E_LAMBDA);
01146 if (ftype->c.sym.homepkg==keywordpkg) fn=ftype;
01147 else if (ftype==LAMCLOSURE) {
01148 fn=ccar(func); func=ccdr(func);
01149 env=(struct bindframe *)intval(ccar(func));
01150 if (env < (struct bindframe *)ctx->stack ||
01151 (struct bindframe *)ctx->stacklimit < env) env=0;
01152 func=ccdr(func);
01153
01154 fenv=(struct fletframe *)intval(ccar(func));
01155 func=ccdr(func);}
01156 else if (ftype!=LAMBDA && ftype!=MACRO) error(E_LAMBDA);
01157 else env=NULL ;
01158 formal=carof(func,E_LAMBDA);
01159 func=ccdr(func);
01160 if (noarg<0) {
01161 noarg=0;
01162 while (iscons(args)) {
01163 aval=ccar(args);
01164 args=ccdr(args);
01165 if (ftype!=MACRO) {GC_POINT;aval=eval(ctx,aval);}
01166 vpush(aval); noarg++;}}
01167 else {
01168 argp=(pointer *)args;
01169 if (ftype==MACRO) error(E_ILLFUNC);}
01170 GC_POINT;
01171 if (ftype==LAMCLOSURE) { ctx->fletfp=fenv; }
01172 result=funlambda(ctx,fn,formal,func,argp,env,noarg);
01173 ctx->vsp=(pointer *)vf;
01174 ctx->callfp=vf->vlink;
01175 GC_POINT;
01176 if (ftype==MACRO) result=eval(ctx,result);
01177 ctx->fletfp=oldfletfp;
01178 #ifdef __RETURN_BARRIER
01179 check_return_barrier(ctx);
01180
01181 #endif
01182 return(result);}
01183 else error(E_ILLFUNC);
01184 }
01185
01186 pointer eval(ctx,form)
01187 register context *ctx;
01188 register pointer form;
01189 { register pointer c;
01190 register pointer p;
01191 #if defined(DEBUG_COUNT) || defined(EVAL_DEBUG)
01192 static int count=0;
01193 int save_count;
01194
01195 count++;
01196 save_count = count;
01197 #endif
01198 #ifdef EVAL_DEBUG
01199 if( evaldebug ) {
01200 printf( "%d:", count );
01201 hoge_print(form);
01202 }
01203 #endif
01204 GC_POINT;
01205 if (isnum(form)) p = form;
01206 else if (pissymbol(form)) p = getval(ctx,form);
01207 else if (!piscons(form)) p = form;
01208 else {
01209 c=ccdr(form);
01210 if (c!=NIL && issymbol(c)) p = (*ovafptr(eval(ctx,ccar(form)),c));
01211 else {
01212 p = ufuncall(ctx,form,ccar(form),c,NULL,-1);
01213 #ifdef SAFETY
01214 take_care(p);
01215 #endif
01216 }
01217 }
01218
01219 #ifdef EVAL_DEBUG
01220 if( evaldebug ) {
01221 printf( "%d:--- ", save_count );
01222 hoge_print(p);
01223 }
01224 #endif
01225 return(p);
01226 }
01227
01228 pointer eval2(ctx,form,env)
01229 register context *ctx;
01230 register pointer form;
01231 pointer env;
01232 { register pointer c;
01233 GC_POINT;
01234 if (isnum(form)) return(form);
01235 else if (pissymbol(form)) return(getval(ctx,form));
01236 else if (!piscons(form)) return(form);
01237 else {
01238 c=ccdr(form);
01239 if (c!=NIL && issymbol(c)) return(*ovafptr(eval(ctx,ccar(form)),c));
01240 else return(ufuncall(ctx,form,ccar(form),(pointer)c,(struct bindframe *)env,-1));}
01241 }
01242
01243 pointer progn(ctx,forms)
01244 register context *ctx;
01245 register pointer forms;
01246 { register pointer result=NIL;
01247 while (iscons(forms)) {
01248 GC_POINT;
01249 result=eval(ctx,ccar(forms)); forms=ccdr(forms);}
01250 return(result);}
01251
01252
01253
01254 #ifdef USE_STDARG
01255
01256 pointer csend(context *ctx, ...)
01257 {
01258 va_list ap;
01259
01260 pointer rec,sel;
01261 int cnt;
01262 pointer res,*spsave;
01263 int i=0;
01264
01265 va_start(ap, ctx);
01266
01267 rec = va_arg(ap,pointer);
01268 sel = va_arg(ap,pointer);
01269 cnt = va_arg(ap,int);
01270 spsave=ctx->vsp;
01271 vpush(rec); vpush(sel);
01272 while (i++ < cnt) vpush(va_arg(ap,pointer));
01273 GC_POINT;
01274 res=(pointer)SEND(ctx,cnt+2, spsave);
01275 ctx->vsp=spsave;
01276 return(res);}
01277
01278 #else
01279 pointer csend(va_alist)
01280 va_dcl
01281 { va_list ap;
01282 pointer rec,sel;
01283 int cnt;
01284 pointer res,*spsave;
01285 int i=0;
01286 register context *ctx;
01287
01288 va_start(ap);
01289 ctx = va_arg(ap,context *);
01290 rec = va_arg(ap,pointer);
01291 sel = va_arg(ap,pointer);
01292 cnt = va_arg(ap,int);
01293 spsave=ctx->vsp;
01294 vpush(rec); vpush(sel);
01295 while (i++ < cnt) vpush(va_arg(ap,pointer));
01296 GC_POINT;
01297 res=(pointer)SEND(ctx,cnt+2, spsave);
01298 ctx->vsp=spsave;
01299 #ifdef SAFETY
01300 take_care(res);
01301 #endif
01302 return(res);}
01303 #endif
01304