/[ascend]/trunk/base/generic/compiler/procframe.h
ViewVC logotype

Contents of /trunk/base/generic/compiler/procframe.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 908 - (show annotations) (download) (as text)
Thu Oct 26 10:18:53 2006 UTC (17 years, 11 months ago) by johnpye
File MIME type: text/x-chdr
File size: 11331 byte(s)
first attempt at merging with Ben's changes on the trunk
1 /*
2 * procframe.h: Method interpreter debugger stack frame information.
3 * by Benjamin Allan
4 * March 17, 1998
5 * Part of ASCEND
6 * Version: $Revision: 1.2 $
7 * Version control file: $RCSfile: procframe.h,v $
8 * Date last modified: $Date: 1998/06/16 16:38:49 $
9 * Last modified by: $Author: mthomas $
10 *
11 * This file is part of the Ascend Language Interpreter.
12 *
13 * Copyright (C) 1998 Carnegie Mellon University
14 *
15 * The Ascend Language Interpreter is free software; you can
16 * redistribute it and/or modify it under the terms of the GNU
17 * General Public License as published by the Free Software
18 * Foundation; either version 2 of the License, or (at your option)
19 * any later version.
20 *
21 * The Ascend Language Interpreter is distributed in hope that it
22 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
23 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 * See the GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with the program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check
29 * the file named COPYING.
30 */
31
32 /** @file
33 * Method interpreter debugger stack frame information.
34 * The data structures in this header should not be passed
35 * through headers except inside gl_lists. This header
36 * should not be accessed except by the interpreter and
37 * interpreter io routines. watchpt.h is the header for
38 * client consumption.
39 * <pre>
40 * When #including procframe.h, make sure these files are #included first:
41 * #include <stdio.h>
42 * #include "utilities/ascConfig.h"
43 * </pre>
44 */
45
46 #ifndef __PROCFRAME_H_SEEN__
47 #define __PROCFRAME_H_SEEN__
48
49 enum FrameMode {
50 FrameInherit, /**< Inherit previous mode when used in Add. */
51 FrameNormal, /**< Normal operations. Inheritable. */
52 FrameDebug, /**< Trace operations. Inheritable. */
53 FrameStart, /**< Not yet supported. Initiate something. */
54 FrameStep, /**< Not yet supported. Do next statement any scope. */
55 FrameNext, /**< Not yet supported. Do next instruction this scope. */
56 FrameDestroyed /**< Severe error if seen. */
57 };
58
59 /**
60 * Because error handling is user defined according to watchpt.h
61 * the following enum is used internally.
62 * External package functions
63 * should return Proc_CallOK, Proc_CallError,
64 * Proc_CallBreak, or Proc_CallContinue.
65 * Error message output is affected by FrameControl.
66 */
67 enum FrameControl {
68 FrameOK = 0, /**< Normal return and entry state. */
69 FrameError, /**< Error return. only the erroneous frame uses this. */
70 FrameBreak, /**< Break from an enclosing loop. If no enclosing loop
71 exists, will be passed up to calling frame. */
72 FrameContinue, /**< Skip to next iteration in an enclosing loop. If no
73 enclosing loop exists, will be passed up to calling frame. */
74 FrameFallthru, /**< Suppress break inside switch processing of cases. */
75 FrameReturn, /**< Frames above a FrameError or FrameReturn stop & return.
76 Initialize morphs this back to a FrameError for client. */
77 FrameLoop /**< In the scope of a loop. Valid entry state. */
78 };
79 /* keep the above in sync with the internals of FrameControlToString below */
80
81 /**
82 * some watch point structures for internal use only.
83 * see watchpt.h for UI watchpoint input structures.
84 */
85 struct anywatch {
86 void *key; /**< all watches hash on some sort of unique ptr key */
87 void *next; /**< all watches are in hash tables. */
88 void *data; /**< everyone wants to know something. */
89 unsigned long flags; /**< control bits */
90 };
91
92 struct namewatch {
93 symchar *leafname;
94 struct namewatch *next;
95 struct gl_list_t *where;
96 unsigned long flags; /**< control bits */
97 };
98
99 struct procwatch {
100 symchar *leafname;
101 struct procwatch *next;
102 struct gl_list_t *where;
103 unsigned long flags; /**< control bits */
104 };
105
106 struct statwatch {
107 struct Statement *stat;
108 struct statwatch *next;
109 struct gl_list_t *where;
110 unsigned long flags; /**< control bits */
111 };
112
113 struct varswatch {
114 struct Instance *var; /**< watched var */
115 struct varswatch *next;
116 struct gl_list_t *where; /**< list of statement/context pairs */
117 unsigned long flags; /**< control bits */
118 };
119
120 struct typewatch {
121 struct TypeDescription *desc; /**< watched var type */
122 struct typewatch *next;
123 struct TypeDescription *ancestor; /**< watched ancestor causing this */
124 unsigned long flags; /**< control bits */
125 };
126
127 /**
128 * Masks are always = 2^N -1 for some N. Such a mask
129 * can be used in hashing a pointer into an array of size 2^N.
130 * N should be even.
131 * Until we run tests, hard to say what the masks should be.
132 * Would expect that VWTMASK may need to be much larger when
133 * debugging very large variables and monitoring for multiple
134 * assignments.
135 * The shift for a given mask 2^N-1 should be 32-(N+2).
136 * Note that an excessive upper bound for N is probably 16
137 * on a 32 bit hardware with memory considered to cost something.
138 */
139 #define NWTMASK 255
140 #define PWTMASK 255
141 #define SWTMASK 255
142 #define TWTMASK 255
143 #define VWTMASK 255
144 #define NWTSHIFT 22
145 #define PWTSHIFT 22
146 #define SWTSHIFT 22
147 #define TWTSHIFT 22
148 #define VWTSHIFT 22
149 /** The idea here is that pointers (to persistent instances, names, types
150 * and methods, but not stack instances) are unique keys during method
151 * execution, so these can be hashed for more or less linear cost trace
152 * operations. We're hashing things because it's really gross to use
153 * interface ptrs.
154 */
155 #define PTRMAGICHASH 1103515245
156 #define NWTINDEX(p) (((((long) (p))*PTRMAGICHASH) << NWTSHIFT) & NWTMASK)
157 #define PWTINDEX(p) (((((long) (p))*PTRMAGICHASH) << PWTSHIFT) & PWTMASK)
158 #define SWTINDEX(p) (((((long) (p))*PTRMAGICHASH) << SWTSHIFT) & SWTMASK)
159 #define TWTINDEX(p) (((((long) (p))*PTRMAGICHASH) << TWTSHIFT) & TWTMASK)
160 #define VWTINDEX(p) (((((long) (p))*PTRMAGICHASH) << VWTSHIFT) & VWTMASK)
161
162 struct procDebug {
163 wpflags what;
164 /**< what tells what tables are active. check it, not the table ptrs */
165 FILE *log; /**< where debugger output should go. probably same as err */
166 int errcnt; /**< total error messages issued while processing this stack */
167 struct namewatch **ntab; /**< hash table of leaf names being watched */
168 struct procwatch **ptab; /**< hash table of proc names being watched */
169 struct statwatch **stab; /**< hash table of statements being watched */
170 struct typewatch **ttab; /**< hash table of var types being watched */
171 struct varswatch **vtab; /**< hash table of variables being watched */
172 /* above watch tables point at below data spaces unless no break points
173 * of the classes involved are set. If a table is not used, its tab
174 * pointer is left NULL instead of being assigned to its head.
175 */
176 struct namewatch *namehead[NWTMASK+1];
177 struct procwatch *prochead[PWTMASK+1];
178 struct statwatch *stathead[SWTMASK+1];
179 struct typewatch *typehead[TWTMASK+1];
180 struct varswatch *varshead[VWTMASK+1];
181 };
182
183 /**
184 * a procFrame defines the stack information we may carry about while
185 * executing a method call from the interface. It is for the
186 * internal use of initialize.c only.
187 */
188 struct procFrame {
189 enum FrameMode m; /**< 0 -> no -> rest of frame data empty */
190 enum FrameControl flow; /**< flow of control info */
191 enum Proc_enum ErrNo; /**< last status computed */
192 int depth; /**< where on the stack. redundant. */
193 FILE *err; /**< where interactive messages should be sent */
194 struct Instance *i; /**< scope proc is being executed in. */
195 char *cname; /**< name of scope by which we got here. */
196 struct InitProcedure *proc; /**< proc being evaluated. */
197 struct Statement *stat; /**< statement being evaluated. */
198 struct procFrame *caller; /**< scope that lead here in execution.
199 * NULL if caller was a user interface.
200 */
201 wpflags gen; /**< some general debug options valid
202 * whether or not dbi == NULL.
203 */
204 struct procDebug *dbi; /**< points to debugging information which
205 * is shared by all frames in a stack since
206 * debugging is a global activity.
207 * The root frame should create this data.
208 * If NULL, no messaging at all.
209 */
210 /* not yet supported: */
211 struct gl_list_t *locals; /**< local vars simulation list. */
212 };
213
214 /**
215 * Setting this to 1 causes a STOP at the next sensible moment.
216 * UIs access this variable through watchpt.h only.
217 */
218 extern int g_procframe_stop;
219
220 /** Return a string (not caller's to free). Form of the enum given. */
221 extern char *FrameControlToString(enum FrameControl frc);
222 /*
223 * Doing anything more than output during execution probably calls for
224 * a real debugging thread or a most careful inside-out method
225 * execution protocol.
226 */
227
228 /** Init a top procFrame for normal execution with no debugging. */
229 extern void InitNormalTopProcFrame(struct procFrame *fm,
230 struct Instance *i,
231 char *cname,
232 FILE *eff,
233 int options);
234
235 /** Init a top procFrame for debugging execution. */
236 extern void InitDebugTopProcFrame(struct procFrame *fm,
237 struct Instance *i,
238 char *cname,
239 FILE *err,
240 int options,
241 struct procDebug *dbi,
242 struct gl_list_t *watches,
243 FILE *dplog);
244
245 /**
246 * Add a frame
247 *
248 * Create a frame for a stack. parent should be the
249 * containing frame unless this is the first frame in a
250 * stack. Context is the instance statements are supposed
251 * to be executed in/on. incrname is the name by which
252 * we got here from last frame, or global name if there
253 * is no parent frame. Proc should be the proc that will
254 * be executed using the returned frame.
255 * M is the trace mode which should be FrameDebug,
256 * FrameNormal, or (IFF parent != NULL) FrameInherit.
257 */
258 extern struct procFrame *AddProcFrame(struct procFrame *parent,
259 struct Instance *context,
260 char *incrname,
261 struct InitProcedure *proc,
262 enum FrameMode m);
263
264 /**
265 * Update context info in a frame.
266 * Set the statement for the given frame. Statement had best be somewhere
267 * in the proc list of the frame. i had better be the context the
268 * statement is to be evaluated in if it is evaluated.
269 */
270 extern void UpdateProcFrame(struct procFrame *fm,
271 struct Statement *stat,
272 struct Instance *i);
273
274 /** iffy */
275 extern void DestroyProcFrame(struct procFrame *fm);
276
277 #endif /* __PROCFRAME_H_SEEN__ */
278

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22