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