1*22519Sdist /* 2*22519Sdist * Copyright (c) 1980 Regents of the University of California. 3*22519Sdist * All rights reserved. The Berkeley software License Agreement 4*22519Sdist * specifies the terms and conditions for redistribution. 5*22519Sdist */ 65517Slinton 7*22519Sdist #ifndef lint 8*22519Sdist static char sccsid[] = "@(#)frame.c 5.1 (Berkeley) 06/06/85"; 9*22519Sdist #endif not lint 105517Slinton 115517Slinton /* 125517Slinton * Activation record handling. 135517Slinton * 145517Slinton * The routines curframe and nextframe cheat by using a global copy 155517Slinton * of the display. This means there can't be multiple instances of 165517Slinton * them active at the same time and nextframe won't work in arbitrary cases. 175517Slinton * 185517Slinton * This could be solved by putting the display copy into the FRAME structure, 195517Slinton * but I didn't feel like doing this. The idea is that they be used 205517Slinton * in looping through all frames, if I had generators I would use them. 215517Slinton */ 225517Slinton 235517Slinton #include "defs.h" 245517Slinton #include "runtime.h" 255517Slinton #include "machine.h" 265517Slinton #include "process.h" 275517Slinton #include "sym.h" 285517Slinton #include "object.h" 295517Slinton #include "mappings.h" 305517Slinton #include "process/pxinfo.h" 315517Slinton #include "frame.rep" 325517Slinton 335517Slinton /* 345517Slinton * Return a pointer to the current activation record. 355517Slinton * Return NIL if currently in the main program. 365517Slinton * The storage is static. 375517Slinton */ 385517Slinton 395517Slinton #define MAXDEPTH 7 405517Slinton #define dispblk(dp) ((dp - DISPLAY) / 2) 415517Slinton 425517Slinton LOCAL ADDRESS *display[MAXDEPTH]; 435517Slinton LOCAL int dispindex; 445517Slinton 455517Slinton FRAME *curframe() 465517Slinton { 475517Slinton static FRAME frame; 485517Slinton FRAME *frp; 495517Slinton ADDRESS *dp, *disp; 505517Slinton int i; 515517Slinton 525517Slinton frp = &frame; 535517Slinton dp = curdp(); 545517Slinton disp = contents(dp); 555517Slinton if (dispblk(dp) <= MAINBLK) { 565517Slinton return NIL; 575517Slinton } else { 585517Slinton getframe(frp, disp); 595517Slinton for (i = 1; i < MAXDEPTH; i++) { 605517Slinton display[i] = dispval(i); 615517Slinton } 625517Slinton dispindex = dispblk(dp); 635517Slinton return frp; 645517Slinton } 655517Slinton } 665517Slinton 675517Slinton /* 685517Slinton * Return a pointer to the next activation record up the stack. 695517Slinton * Return NIL if there is none. 705517Slinton * Writes over space pointed to by given argument. 715517Slinton */ 725517Slinton 735517Slinton FRAME *nextframe(frp) 745517Slinton FRAME *frp; 755517Slinton { 765517Slinton ADDRESS *fp; 775517Slinton 785517Slinton if (dispblk(frp->save_dp) <= MAINBLK) { 795517Slinton return(NIL); 805517Slinton } else { 815517Slinton display[dispindex] = frp->save_disp; 825517Slinton dispindex = dispblk(frp->save_dp); 835517Slinton fp = display[dispindex]; 845517Slinton getframe(frp, fp); 855517Slinton return(frp); 865517Slinton } 875517Slinton } 885517Slinton 895517Slinton /* 905517Slinton * Return the frame associated with the given function. 915517Slinton */ 925517Slinton 935517Slinton FRAME *findframe(f) 945517Slinton SYM *f; 955517Slinton { 965517Slinton static FRAME frame; 975517Slinton FRAME *frp, *prevfrp; 985517Slinton 995517Slinton frame.save_dp = curdp(); 1005517Slinton frame.save_disp = contents(frame.save_dp); 1015517Slinton prevfrp = &frame; 1025517Slinton for (frp = curframe(); frp != NIL; frp = nextframe(frp)) { 1035517Slinton if (whatblock(entry(frp)) == f) { 1045517Slinton return frp; 1055517Slinton } 1065517Slinton *prevfrp = *frp; 1075517Slinton } 1085517Slinton if (f == program) { 1095517Slinton return prevfrp; 1105517Slinton } else { 1115517Slinton return NIL; 1125517Slinton } 1135517Slinton } 1145517Slinton 1155517Slinton /* 1165517Slinton * Get the activation record associated with the given display pointer. 1175517Slinton */ 1185517Slinton 1195517Slinton LOCAL getframe(frp, disp) 1205517Slinton FRAME *frp; 1215517Slinton ADDRESS *disp; 1225517Slinton { 1235517Slinton if (disp == NIL) { 1245517Slinton panic("bad disp in getframe"); 1255517Slinton } 1265517Slinton dread(frp, disp, sizeof(FRAME)); 1275517Slinton frp->save_pc -= ENDOFF; 1285517Slinton } 1295517Slinton 1305517Slinton /* 1315517Slinton * Return the address of the display in the px process for the given block. 1325517Slinton */ 1335517Slinton 1345517Slinton ADDRESS *dispval(b) 1355517Slinton int b; 1365517Slinton { 1375517Slinton ADDRESS *r; 1385517Slinton 1395517Slinton dread(&r, (ADDRESS) (DISPLAY + 2*b), sizeof(r)); 1405517Slinton return r; 1415517Slinton } 1425517Slinton 1435517Slinton /* 1445517Slinton * Return the current display pointer. 1455517Slinton */ 1465517Slinton 1475517Slinton ADDRESS *curdp() 1485517Slinton { 1495517Slinton ADDRESS *r; 1505517Slinton 1515517Slinton dread(&r, (ADDRESS) DP, sizeof(r)); 1525517Slinton return r; 1535517Slinton } 1545517Slinton 1555517Slinton /* 1565517Slinton * Return the contents of the given display pointer. 1575517Slinton */ 1585517Slinton 1595517Slinton ADDRESS *contents(dp) 1605517Slinton ADDRESS *dp; 1615517Slinton { 1625517Slinton ADDRESS *r; 1635517Slinton 1645517Slinton dread(&r, (ADDRESS) dp, sizeof(r)); 1655517Slinton return r; 1665517Slinton } 1675517Slinton 1685517Slinton /* 1695517Slinton * Return the px stack address associated with a given frame pointer. 1705517Slinton * Actually, to confuse the issue we want the stack address of the 1715517Slinton * frame one up from the given one. 1725517Slinton */ 1735517Slinton 1745517Slinton ADDRESS stkaddr(frp, b) 1755517Slinton FRAME *frp; 1765517Slinton int b; 1775517Slinton { 1785517Slinton return (ADDRESS) display[b]; 1795517Slinton } 180