eval.c
Go to the documentation of this file.
00001 /*****************************************************************/
00002 /* eval.c
00003 /       interpreted evaluation of lisp forms
00004 /*      1986-Jun-6
00005 /*      Copyright Toshihiro Matsui, ETL Umezono Sakuramura
00006 /*      0298-54-5459
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]; /*sym->c.sym.speval;*/
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) {             /*found in bind-frame*/
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   /*get special value from the symbol cell*/
00062   /*if (sym->c.sym.vtype==V_GLOBAL) goto getspecial;*/
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   /* no local var found. try global binding */
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);  /* global val*/
00093   return(val);
00094   }
00095 
00096 
00097 pointer getfunc(ctx,f)
00098 register context *ctx;
00099 register pointer f;     /*must be a symbol*/
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 {        /*global function definition is taken, context changes*/
00106     return(f->c.sym.spefunc);}}
00107 
00108 /* called from compiled code*/
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 /***** special variable binding *****/
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 /* called by compiled code */
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) {       /* < is harmful to unwind in eus.c */
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;       /*update bindfp*/
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   /*not found in declare scope*/
00209   if (var->c.sym.vtype>= /* V_SPECIAL */  V_GLOBAL ) {
00210         /* For defun-c-callable in eusforeign.l to create a foreign-pod,
00211                 global value of SYMBOL must be replaced with FOREIGN-POD
00212                 by let binding.  Since SYMBOL is V_GLOBAL, special binding
00213                 (global binding) must be made for V_GLOBAL.  Proclaiming
00214                 symbol as SPECIAL is no use, since INTERN does not refer
00215                 thread local binding. */                
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) { /*special binding*/
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  /*for compiled codes*/
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;        /*search for keyword*/
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) {    /*keyword found*/
00262       bitpos = 1<<i;
00263       if ((suppliedbits & bitpos) ==0) {        /*already supplied-->ignore*/
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   /*parse lambda list and make keyword tables*/
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;      /*search for keyword*/
00332       while (i<nokeys && keys[i]!=akeyvar) i++;
00333       if (n>=noarg) error(E_KEYPARAM);  /*not paired*/
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     /*declaration*/
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     /* make a new bind frame */
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);   /*take one 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) { /*an actual arg is supplied*/
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     /*list up all rest arguments*/
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     /*create block around lambda*/
00433     myblock=(struct blockframe *)makeblock(ctx,BLOCKFRAME,fn,(jmp_buf *)funjmp,NULL);
00434     /*evaluate body*/
00435     if ((result=(pointer)eussetjmp(funjmp))==0) {GC_POINT;result=progn(ctx,body);}
00436     else if (result==(pointer)1) result=makeint(0);
00437     /*end of body evaluation: clean up stack frames*/
00438     ctx->blkfp=myblock->dynklink;
00439     ctx->bindfp=bf;
00440     ctx->vsp=vspsave;
00441 
00442 #ifdef __RETURN_BARRIER
00443     check_return_barrier(ctx);
00444     /* check return barrier */
00445 #endif
00446 /*    unbindspecial(ctx,(struct specialbindframe *)ctx->vsp); */
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   /* &rest arguments?  */
00482   while (i<n) { /* i is the counter for the actual arguments*/
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         /* (:string [10]) (:foreign-string [20]) */
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 /* IRIX6 */
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   /* &rest arguments?  */
00563   while (i<n) { /* i is the counter for the actual arguments*/
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         /* (:string [10]) (:foreign-string [20]) */
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 /* IRIX */
00611 
00612 /* not IRIS */
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 // func  %rdi
00617 // iargv %rsi
00618 // fargv %rdx
00619 // vargc %rcx
00620 // vargv %r8
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; /*lisp argument counter*//* ???? */
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     /* R.Hanai 090726 */
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   /* &rest arguments?  */
00765   while (j<n) { /* j is the counter for the actual arguments*/
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);       /* i advances independently */
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       /* (:string [10]) (:foreign-string [20]) */
00810       if (ccar(resulttype)==K_STRING) { /* R.Hanai 09/07/25 */
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) { /* R.Hanai 09/07/25 */
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 /* not x86_64 */
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; /*C argument counter*//* ???? */
00837   eusinteger_t j=0; /*lisp argument counter*//* ???? */
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);    /* kanehiro's patch 2000.12.13 */
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   /* &rest arguments?  */
00866   while (j<n) { /* j is the counter for the actual arguments*/
00867     lisparg=args[j++];
00868     if (isint(lisparg)) cargv[i++]=intval(lisparg);
00869     else if (isflt(lisparg)) {
00870       numbox.d=ckfltval(lisparg);       /* i advances independently */
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    /* begin kanehiro's patch 2000.12.13 */
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    /* end of kanehiro's patch 2000.12.13 */
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         /* (:string [10]) (:foreign-string [20]) */
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 /* x86_64 */
00983 #endif /* IRIX */
00984 #endif /* IRIX6 */
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;  /*0xfffffffc; ???? */
00998 #else
00999   addr &= ~3;  /*0xfffffffc; ???? */
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)) {       /*func,macro or special form*//* ???? */
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))     /*foreign function?*/
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 /*      case (int)SUBR_ENTRY:
01035               func=(*subr)(func);
01036               return(makeint(func)); */
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;  /*or 'pointer *' */
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   /* evalhook */
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);       /*apply evalhook function*/
01068       ctx->vsp=(pointer *)vf;
01069       unbindspecial(ctx,sbfps+1);
01070 #ifdef __RETURN_BARRIER
01071       check_return_barrier(ctx);
01072       /* check return barrier */
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   /*make a new stack frame*/
01086   stackck;      /*stack overflow?*/
01087   breakck;      /*signal exists?*/
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 /*0xfffffffc ????*/);
01099 #if ARM
01100     register eusinteger_t addr;
01101     addr = (eusinteger_t)(fn->c.code.entry);
01102 #ifdef x86_64
01103     addr &= ~3L;  /*0xfffffffc; ???? */
01104 #else
01105     addr &= ~3;  /*0xfffffffc; ???? */
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);}       /*call func with env*/
01121       else result=(*subr)(ctx,noarg,args,func);
01122     /*recover call frame and stack pointer*/
01123     ctx->vsp=(pointer *)vf;
01124     ctx->callfp= vf->vlink;
01125     ctx->fletfp=oldfletfp;
01126 #ifdef __RETURN_BARRIER
01127     check_return_barrier(ctx);
01128     /* check return barrier */
01129 #endif
01130     return(result);}
01131 
01132   else if (piscode(func)) {     /*call subr*/
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;     /*blockname=selector*/
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       /* ctx->fletfp=(struct fletframe *)intval(ccar(func)); */
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 /*0 ????*/; 
01158     formal=carof(func,E_LAMBDA);
01159     func=ccdr(func);
01160     if (noarg<0) {      /*spread args on stack*/
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     /* check return barrier */
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 /* csend(ctx,object,selector,argc,arg1,arg2,....) */
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 


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Sep 3 2015 10:36:19