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