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) 6/6/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: }
Defined functions
Defined variables
sccsid
defined in line
8;
never used
Defined macros