Annotation of 41BSD/cmd/lisp/evalf.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)evalf.c     34.1 10/3/80";
        !             2: 
        !             3: #include "global.h"
        !             4: #include "frame.h"
        !             5: /* evalframe off of the c stack.  
        !             6:     We will set fp to point where the register fp points.
        !             7:     Then fp+2 = saved ap
        !             8:          fp+4 = saved pc
        !             9:          fp+3 = saved fp
        !            10:          ap+1 = first arg
        !            11: */
        !            12: 
        !            13: /* These will keep track of the current saved values of np and lbot
        !            14: as we decend the evalstack.  These must be read by decoding the registers saved
        !            15: by each function call. */
        !            16: struct argent *fakenp;
        !            17: struct argent *fakelbot;
        !            18: 
        !            19: lispval
        !            20: Levalf ()
        !            21: {
        !            22:     register struct frame *myfp;
        !            23:     struct frame *nextevf();
        !            24:     register lispval handy, result;
        !            25:     int **fp;  /* this must be the first local */
        !            26:     int evaltype;
        !            27:     snpand(3);
        !            28:     if(lbot==np) {
        !            29:        protect (nil);
        !            30:     };
        !            31:     chkarg(1,"evalf");
        !            32:     fakenp = NULL;
        !            33:     fakelbot = NULL;
        !            34:     if (lbot->val == nil) { /* Arg of nil means start at the top */
        !            35:        myfp = nextevf ((struct frame *) (&fp +1), &evaltype);  
        !            36:                    /* myfp  now points to evalframe of call to evalframe */
        !            37:        myfp = myfp->fp; /* and now to the one past evalframe */
        !            38:     } else {
        !            39:        if( TYPE(lbot->val) != INT )
        !            40:            /* Interesting artifact: A pdl pointer will be an INT, but if
        !            41:            read in, the Franz reader produces a bignum, thus giving some
        !            42:            protection from being hacked.  */
        !            43:            error("ARG TO EVALFRAME MUST BE INTEGER",TRUE);
        !            44:        myfp = (struct frame *) (lbot->val->i);
        !            45:        if (myfp < (struct frame *) (&fp +1)){
        !            46:                /* if purported fp is less than current fp, a fraud
        !            47:                (since stack grows down, and current fp must be bottom) */
        !            48:            error("ARG TO EVALFRAME NOT EVALFRAME POINTER", TRUE);
        !            49:        }
        !            50:     };
        !            51:     myfp = nextevf(myfp, &evaltype);  /* get pointer to frame above */
        !            52:     if(myfp > myfp->fp) return(nil);   /* end of frames */
        !            53:        /* return ( <eval or apply> <fp> <exp being evaled> <bnp>) */
        !            54:     protect(result = newdot());
        !            55:        /* See maclisp manual for difference between eval frames and apply
        !            56:        frames, or else see the code below. */
        !            57:     result->d.car = matom (evaltype ? "eval" : "apply"); 
        !            58:     result->d.cdr = (handy = newdot());
        !            59:     handy->d.car = inewint(myfp->fp); /* The frame pointer as a lisp int */
        !            60:     handy->d.cdr = newdot();
        !            61:     handy = handy->d.cdr;
        !            62:     if (evaltype)
        !            63:        handy->d.car = myfp->ap[1];  /* eval type - simply the arg to eval */
        !            64:     else {  /*  apply type ; must build argument list. The form will look like
        !            65:                  (<function> (<evaled arg1> <evaled arg2> ....))
        !            66:              i.e. the function name followed by a list of evaluated args */
        !            67:        lispval form, handy1, arglist;
        !            68:        struct argent *pntr;
        !            69:            /* name of function will either be arg to Lfuncal or on argstack */
        !            70:        (form = newdot())->d.car = 
        !            71:            (int)myfp->ap[0] & 1? myfp->ap[1] : (fakelbot-1)->val; 
        !            72:                        /* Assume that Lfuncal increments lbot after getting
        !            73:                          function to call. */
        !            74:        (form->d.cdr = newdot())->d.cdr = nil;
        !            75:        for (arglist = nil, pntr = fakenp;
        !            76:             pntr > fakelbot;) {
        !            77:            (handy1 = newdot())->d.cdr = arglist;
        !            78:            (arglist = handy1)->d.car = (--pntr)->val;
        !            79:        };
        !            80:        form->d.cdr->d.car = arglist;
        !            81:        handy->d.car = form;
        !            82:     };
        !            83:     handy->d.cdr = newdot();
        !            84:     handy = handy->d.cdr;
        !            85:        /* Next is index into bindstack lisp pseudo-array, for maximum
        !            86:            usefulness */
        !            87:     handy->d.car = inewint( ((struct nament *) *( ((long *)myfp->fp) -1))
        !            88:                         -orgbnp); /* first part gets oldbnp, if first local */
        !            89:     handy->d.cdr = newdot();
        !            90:     handy = handy->d.cdr;
        !            91:        
        !            92:     handy->d.car = inewint(fakenp-orgnp);   /* index of np in namestack*/
        !            93:     handy->d.cdr = newdot();
        !            94:     handy = handy->d.cdr;
        !            95:     handy->d.car = inewint(fakelbot-orgnp); /* index of lbot in namestack*/
        !            96:     return(result);
        !            97: }
        !            98: 
        !            99: #define LBOTNPMASK 03<<22  /* Octal 3 */
        !           100: /* We assume that r6 and r7 are saved as pairs, and that no earlier
        !           101: registers are saved.  If the Franz snpand hack is changed, this may
        !           102: have to change too. */
        !           103: struct frame *nextevf (curfp, ftypep)
        !           104: struct frame *curfp;
        !           105: int *ftypep;
        !           106: {
        !           107:     register struct frame *myfp;
        !           108:     lispval _qfuncl(),tynames();       /* locations in qfuncl */
        !           109:     lispval fchack();                  /*pseudo function after Lfuncal */
        !           110:     for (myfp = curfp; myfp < myfp->fp; myfp = myfp->fp) {
        !           111:                /* Look up stack until find a frame with the right saved pc */
        !           112:        if (myfp->mask & LBOTNPMASK)  {
        !           113:            fakenp = (struct argent *)(myfp->r6);
        !           114:            fakelbot = (struct argent *)(myfp->r7);
        !           115:            };
        !           116:        if (myfp->pc > eval && myfp->pc < popnames) {   /* interpreted code */
        !           117:            *ftypep = TRUE;
        !           118:            break;
        !           119:        } else 
        !           120: /*     if (myfp->pc > _qfuncl && myfp->pc < tynames) { /* compiled code *//*
        !           121:            *ftypep = FALSE;
        !           122:            break;
        !           123:        } else   */
        !           124:        if (myfp->pc > Lfuncal && myfp->pc < fchack) { /* call to funcall */
        !           125:            *ftypep = FALSE;
        !           126:            break;
        !           127:        };
        !           128:     };
        !           129:     return(myfp);
        !           130: }
        !           131: 
        !           132: #include "catchfram.h"
        !           133: lispval
        !           134: Lfretn ()
        !           135: {
        !           136:     int **fp;                  /* this must be the first local */
        !           137:     struct frame *myfp;        
        !           138:     struct nament *mybnp;
        !           139:     extern long errp;
        !           140:     extern long exitlnk;
        !           141:     typedef struct catchfr *cp;
        !           142:     typedef struct savblock *savp;
        !           143:     cp curp;
        !           144:     savp cursavp;
        !           145:     chkarg(2,"freturn");
        !           146:     if( TYPE(lbot->val) != INT )
        !           147:        error("freturn: 1st arg not pdl pointer",FALSE);
        !           148:     myfp = (struct frame *) (lbot->val->i);
        !           149:     if (myfp < (struct frame *) (&fp +1)){
        !           150:            /* if purported fp is less than current fp, a fraud
        !           151:            (since stack grows down, and current fp must be bottom) */
        !           152:        error("freturn: 1st arg not current pdl pointer", FALSE);
        !           153:     };
        !           154:        /* Unwind name stack.  The oldbnp will be the first local variable of
        !           155:        the function we are returning from, so it will be immediately below this
        !           156:        stack frame (i.e. it was pushed right after the call). */
        !           157:     mybnp = (struct nament *) *(((long *)myfp) - 1);
        !           158:     if (mybnp < orgbnp || mybnp > bnp) 
        !           159:        error("freturn: problem with pdl pointer", FALSE);
        !           160:     popnames (mybnp);
        !           161:        /* Reset pointer to next catchframe in stack appropriately. */
        !           162:     for (curp = (cp) errp ; curp != (cp) nil ; curp = curp->link){
        !           163:        /* Debugging...
        !           164:        printf ("Considering catchframe at %d\n", curp); fflush(stdout); */
        !           165:        if ((long *) myfp < (long *) curp) {
        !           166:            /* printf ("Won\n"); fflush(stdout); */
        !           167:            break;
        !           168:        };
        !           169:     };
        !           170:     errp = (long)curp;
        !           171:     /* printf ("errp is now %d\n", errp);fflush(stdout); */
        !           172:        /* Reset saveblock for setexit/reset appropriately. */
        !           173:     for (cursavp = (savp)exitlnk; cursavp != (savp) NULL; 
        !           174:                 cursavp = cursavp->savlnk) {
        !           175:        /* printf("Considering saveblock at %d\n", cursavp);
        !           176:        fflush (stdout); */
        !           177:        if ((savp) myfp > cursavp && 
        !           178:            ((savp)myfp < cursavp->savlnk || cursavp->savlnk == 0)) {
        !           179:            /* printf("Won\n"); fflush(stdout); */
        !           180:            resexit(cursavp);
        !           181:            break;
        !           182:        };
        !           183:     };
        !           184:     fsmash(myfp, (np-1)->val); /* Smash the fp register..(If myfp not valid fp,
        !           185:                            real trouble follows)  Will really return 
        !           186:                            from other guy (ha ha) */
        !           187: }
        !           188: 
        !           189: fsmash(framep, retval)
        !           190: struct frame *framep;
        !           191: lispval retval;
        !           192: {
        !           193:     asm("      movl    4(ap), fp");
        !           194:     asm("      movl    8(ap), r0");
        !           195:     asm("      ret");
        !           196: }
        !           197: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.