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