Commit | Line | Data |
---|---|---|
f644bb55 DF |
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 | */ | |
f39cdaac | 6 | |
f644bb55 | 7 | #ifndef lint |
82d3cd01 | 8 | static char sccsid[] = "@(#)frame.c 5.2 (Berkeley) %G%"; |
f644bb55 | 9 | #endif not lint |
f39cdaac ML |
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" | |
82d3cd01 | 32 | #include "process/process.rep" |
f39cdaac ML |
33 | |
34 | /* | |
35 | * Return a pointer to the current activation record. | |
36 | * Return NIL if currently in the main program. | |
37 | * The storage is static. | |
38 | */ | |
39 | ||
40 | #define MAXDEPTH 7 | |
41 | #define dispblk(dp) ((dp - DISPLAY) / 2) | |
42 | ||
43 | LOCAL ADDRESS *display[MAXDEPTH]; | |
44 | LOCAL int dispindex; | |
45 | ||
46 | FRAME *curframe() | |
47 | { | |
48 | static FRAME frame; | |
49 | FRAME *frp; | |
50 | ADDRESS *dp, *disp; | |
51 | int i; | |
52 | ||
53 | frp = &frame; | |
54 | dp = curdp(); | |
55 | disp = contents(dp); | |
56 | if (dispblk(dp) <= MAINBLK) { | |
57 | return NIL; | |
58 | } else { | |
59 | getframe(frp, disp); | |
60 | for (i = 1; i < MAXDEPTH; i++) { | |
61 | display[i] = dispval(i); | |
62 | } | |
63 | dispindex = dispblk(dp); | |
64 | return frp; | |
65 | } | |
66 | } | |
67 | ||
68 | /* | |
69 | * Return a pointer to the next activation record up the stack. | |
70 | * Return NIL if there is none. | |
71 | * Writes over space pointed to by given argument. | |
72 | */ | |
73 | ||
74 | FRAME *nextframe(frp) | |
75 | FRAME *frp; | |
76 | { | |
77 | ADDRESS *fp; | |
78 | ||
79 | if (dispblk(frp->save_dp) <= MAINBLK) { | |
80 | return(NIL); | |
81 | } else { | |
82 | display[dispindex] = frp->save_disp; | |
83 | dispindex = dispblk(frp->save_dp); | |
84 | fp = display[dispindex]; | |
85 | getframe(frp, fp); | |
86 | return(frp); | |
87 | } | |
88 | } | |
89 | ||
90 | /* | |
91 | * Return the frame associated with the given function. | |
92 | */ | |
93 | ||
94 | FRAME *findframe(f) | |
95 | SYM *f; | |
96 | { | |
97 | static FRAME frame; | |
98 | FRAME *frp, *prevfrp; | |
99 | ||
100 | frame.save_dp = curdp(); | |
101 | frame.save_disp = contents(frame.save_dp); | |
102 | prevfrp = &frame; | |
103 | for (frp = curframe(); frp != NIL; frp = nextframe(frp)) { | |
104 | if (whatblock(entry(frp)) == f) { | |
105 | return frp; | |
106 | } | |
107 | *prevfrp = *frp; | |
108 | } | |
109 | if (f == program) { | |
110 | return prevfrp; | |
111 | } else { | |
112 | return NIL; | |
113 | } | |
114 | } | |
115 | ||
116 | /* | |
117 | * Get the activation record associated with the given display pointer. | |
118 | */ | |
119 | ||
120 | LOCAL getframe(frp, disp) | |
121 | FRAME *frp; | |
122 | ADDRESS *disp; | |
123 | { | |
124 | if (disp == NIL) { | |
125 | panic("bad disp in getframe"); | |
126 | } | |
127 | dread(frp, disp, sizeof(FRAME)); | |
128 | frp->save_pc -= ENDOFF; | |
129 | } | |
130 | ||
131 | /* | |
132 | * Return the address of the display in the px process for the given block. | |
133 | */ | |
134 | ||
135 | ADDRESS *dispval(b) | |
136 | int b; | |
137 | { | |
138 | ADDRESS *r; | |
139 | ||
140 | dread(&r, (ADDRESS) (DISPLAY + 2*b), sizeof(r)); | |
141 | return r; | |
142 | } | |
143 | ||
144 | /* | |
145 | * Return the current display pointer. | |
146 | */ | |
147 | ||
148 | ADDRESS *curdp() | |
149 | { | |
150 | ADDRESS *r; | |
151 | ||
152 | dread(&r, (ADDRESS) DP, sizeof(r)); | |
153 | return r; | |
154 | } | |
155 | ||
156 | /* | |
157 | * Return the contents of the given display pointer. | |
158 | */ | |
159 | ||
160 | ADDRESS *contents(dp) | |
161 | ADDRESS *dp; | |
162 | { | |
163 | ADDRESS *r; | |
164 | ||
165 | dread(&r, (ADDRESS) dp, sizeof(r)); | |
166 | return r; | |
167 | } | |
168 | ||
169 | /* | |
170 | * Return the px stack address associated with a given frame pointer. | |
171 | * Actually, to confuse the issue we want the stack address of the | |
172 | * frame one up from the given one. | |
173 | */ | |
174 | ||
175 | ADDRESS stkaddr(frp, b) | |
176 | FRAME *frp; | |
177 | int b; | |
178 | { | |
179 | return (ADDRESS) display[b]; | |
180 | } |