port to tahoe by Nir peleg of CCI
[unix-history] / usr / src / usr.bin / pascal / pdx / runtime / frame.c
CommitLineData
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 8static 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
43LOCAL ADDRESS *display[MAXDEPTH];
44LOCAL int dispindex;
45
46FRAME *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
74FRAME *nextframe(frp)
75FRAME *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
94FRAME *findframe(f)
95SYM *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
120LOCAL getframe(frp, disp)
121FRAME *frp;
122ADDRESS *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
135ADDRESS *dispval(b)
136int 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
148ADDRESS *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
160ADDRESS *contents(dp)
161ADDRESS *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
175ADDRESS stkaddr(frp, b)
176FRAME *frp;
177int b;
178{
179 return (ADDRESS) display[b];
180}