1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)frame.c 1.1 01/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 } 174