|
|
1.1 root 1: /* Copyright (c) 1982 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)frame.c 1.1 1/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.