|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)frame.c 1.1 1/18/82"; ! 4: ! 5: /* ! 6: * Activation record handling. ! 7: * ! 8: * The routines curframe and nextframe cheat by using a global copy ! 9: * of the display. This means there can't be multiple instances of ! 10: * them active at the same time and nextframe won't work in arbitrary cases. ! 11: * ! 12: * This could be solved by putting the display copy into the FRAME structure, ! 13: * but I didn't feel like doing this. The idea is that they be used ! 14: * in looping through all frames, if I had generators I would use them. ! 15: */ ! 16: ! 17: #include "defs.h" ! 18: #include "runtime.h" ! 19: #include "machine.h" ! 20: #include "process.h" ! 21: #include "sym.h" ! 22: #include "object.h" ! 23: #include "mappings.h" ! 24: #include "process/pxinfo.h" ! 25: #include "frame.rep" ! 26: ! 27: /* ! 28: * Return a pointer to the current activation record. ! 29: * Return NIL if currently in the main program. ! 30: * The storage is static. ! 31: */ ! 32: ! 33: #define MAXDEPTH 7 ! 34: #define dispblk(dp) ((dp - DISPLAY) / 2) ! 35: ! 36: LOCAL ADDRESS *display[MAXDEPTH]; ! 37: LOCAL int dispindex; ! 38: ! 39: FRAME *curframe() ! 40: { ! 41: static FRAME frame; ! 42: FRAME *frp; ! 43: ADDRESS *dp, *disp; ! 44: int i; ! 45: ! 46: frp = &frame; ! 47: dp = curdp(); ! 48: disp = contents(dp); ! 49: if (dispblk(dp) <= MAINBLK) { ! 50: return NIL; ! 51: } else { ! 52: getframe(frp, disp); ! 53: for (i = 1; i < MAXDEPTH; i++) { ! 54: display[i] = dispval(i); ! 55: } ! 56: dispindex = dispblk(dp); ! 57: return frp; ! 58: } ! 59: } ! 60: ! 61: /* ! 62: * Return a pointer to the next activation record up the stack. ! 63: * Return NIL if there is none. ! 64: * Writes over space pointed to by given argument. ! 65: */ ! 66: ! 67: FRAME *nextframe(frp) ! 68: FRAME *frp; ! 69: { ! 70: ADDRESS *fp; ! 71: ! 72: if (dispblk(frp->save_dp) <= MAINBLK) { ! 73: return(NIL); ! 74: } else { ! 75: display[dispindex] = frp->save_disp; ! 76: dispindex = dispblk(frp->save_dp); ! 77: fp = display[dispindex]; ! 78: getframe(frp, fp); ! 79: return(frp); ! 80: } ! 81: } ! 82: ! 83: /* ! 84: * Return the frame associated with the given function. ! 85: */ ! 86: ! 87: FRAME *findframe(f) ! 88: SYM *f; ! 89: { ! 90: static FRAME frame; ! 91: FRAME *frp, *prevfrp; ! 92: ! 93: frame.save_dp = curdp(); ! 94: frame.save_disp = contents(frame.save_dp); ! 95: prevfrp = &frame; ! 96: for (frp = curframe(); frp != NIL; frp = nextframe(frp)) { ! 97: if (whatblock(entry(frp)) == f) { ! 98: return frp; ! 99: } ! 100: *prevfrp = *frp; ! 101: } ! 102: if (f == program) { ! 103: return prevfrp; ! 104: } else { ! 105: return NIL; ! 106: } ! 107: } ! 108: ! 109: /* ! 110: * Get the activation record associated with the given display pointer. ! 111: */ ! 112: ! 113: LOCAL getframe(frp, disp) ! 114: FRAME *frp; ! 115: ADDRESS *disp; ! 116: { ! 117: if (disp == NIL) { ! 118: panic("bad disp in getframe"); ! 119: } ! 120: dread(frp, disp, sizeof(FRAME)); ! 121: frp->save_pc -= ENDOFF; ! 122: } ! 123: ! 124: /* ! 125: * Return the address of the display in the px process for the given block. ! 126: */ ! 127: ! 128: ADDRESS *dispval(b) ! 129: int b; ! 130: { ! 131: ADDRESS *r; ! 132: ! 133: dread(&r, (ADDRESS) (DISPLAY + 2*b), sizeof(r)); ! 134: return r; ! 135: } ! 136: ! 137: /* ! 138: * Return the current display pointer. ! 139: */ ! 140: ! 141: ADDRESS *curdp() ! 142: { ! 143: ADDRESS *r; ! 144: ! 145: dread(&r, (ADDRESS) DP, sizeof(r)); ! 146: return r; ! 147: } ! 148: ! 149: /* ! 150: * Return the contents of the given display pointer. ! 151: */ ! 152: ! 153: ADDRESS *contents(dp) ! 154: ADDRESS *dp; ! 155: { ! 156: ADDRESS *r; ! 157: ! 158: dread(&r, (ADDRESS) dp, sizeof(r)); ! 159: return r; ! 160: } ! 161: ! 162: /* ! 163: * Return the px stack address associated with a given frame pointer. ! 164: * Actually, to confuse the issue we want the stack address of the ! 165: * frame one up from the given one. ! 166: */ ! 167: ! 168: ADDRESS stkaddr(frp, b) ! 169: FRAME *frp; ! 170: int b; ! 171: { ! 172: return (ADDRESS) display[b]; ! 173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.