|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.