Added 'list_only' option (and modified 'run()' to respect it).
[python/dscho.git] / Objects / frameobject.c
blob64fc52feb984dcb9d6a0a96fa5b01cdc93740fd2
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Frame object implementation */
34 #include "Python.h"
36 #include "compile.h"
37 #include "frameobject.h"
38 #include "opcode.h"
39 #include "structmember.h"
41 #define OFF(x) offsetof(PyFrameObject, x)
43 static struct memberlist frame_memberlist[] = {
44 {"f_back", T_OBJECT, OFF(f_back), RO},
45 {"f_code", T_OBJECT, OFF(f_code), RO},
46 {"f_builtins", T_OBJECT, OFF(f_builtins),RO},
47 {"f_globals", T_OBJECT, OFF(f_globals), RO},
48 {"f_locals", T_OBJECT, OFF(f_locals), RO},
49 {"f_lasti", T_INT, OFF(f_lasti), RO},
50 {"f_lineno", T_INT, OFF(f_lineno), RO},
51 {"f_restricted",T_INT, OFF(f_restricted),RO},
52 {"f_trace", T_OBJECT, OFF(f_trace)},
53 {"f_exc_type", T_OBJECT, OFF(f_exc_type)},
54 {"f_exc_value", T_OBJECT, OFF(f_exc_value)},
55 {"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
56 {NULL} /* Sentinel */
59 static PyObject *
60 frame_getattr(f, name)
61 PyFrameObject *f;
62 char *name;
64 if (strcmp(name, "f_locals") == 0)
65 PyFrame_FastToLocals(f);
66 return PyMember_Get((char *)f, frame_memberlist, name);
69 static int
70 frame_setattr(f, name, value)
71 PyFrameObject *f;
72 char *name;
73 PyObject *value;
75 return PyMember_Set((char *)f, frame_memberlist, name, value);
78 /* Stack frames are allocated and deallocated at a considerable rate.
79 In an attempt to improve the speed of function calls, we maintain a
80 separate free list of stack frames (just like integers are
81 allocated in a special way -- see intobject.c). When a stack frame
82 is on the free list, only the following members have a meaning:
83 ob_type == &Frametype
84 f_back next item on free list, or NULL
85 f_nlocals number of locals
86 f_stacksize size of value stack
87 Note that the value and block stacks are preserved -- this can save
88 another malloc() call or two (and two free() calls as well!).
89 Also note that, unlike for integers, each frame object is a
90 malloc'ed object in its own right -- it is only the actual calls to
91 malloc() that we are trying to save here, not the administration.
92 After all, while a typical program may make millions of calls, a
93 call depth of more than 20 or 30 is probably already exceptional
94 unless the program contains run-away recursion. I hope.
97 static PyFrameObject *free_list = NULL;
99 static void
100 frame_dealloc(f)
101 PyFrameObject *f;
103 int i;
104 PyObject **fastlocals;
106 /* Kill all local variables */
107 fastlocals = f->f_localsplus;
108 for (i = f->f_nlocals; --i >= 0; ++fastlocals) {
109 Py_XDECREF(*fastlocals);
112 Py_XDECREF(f->f_back);
113 Py_XDECREF(f->f_code);
114 Py_XDECREF(f->f_builtins);
115 Py_XDECREF(f->f_globals);
116 Py_XDECREF(f->f_locals);
117 Py_XDECREF(f->f_trace);
118 Py_XDECREF(f->f_exc_type);
119 Py_XDECREF(f->f_exc_value);
120 Py_XDECREF(f->f_exc_traceback);
121 f->f_back = free_list;
122 free_list = f;
125 PyTypeObject PyFrame_Type = {
126 PyObject_HEAD_INIT(&PyType_Type)
128 "frame",
129 sizeof(PyFrameObject),
131 (destructor)frame_dealloc, /*tp_dealloc*/
132 0, /*tp_print*/
133 (getattrfunc)frame_getattr, /*tp_getattr*/
134 (setattrfunc)frame_setattr, /*tp_setattr*/
135 0, /*tp_compare*/
136 0, /*tp_repr*/
137 0, /*tp_as_number*/
138 0, /*tp_as_sequence*/
139 0, /*tp_as_mapping*/
142 PyFrameObject *
143 PyFrame_New(tstate, code, globals, locals)
144 PyThreadState *tstate;
145 PyCodeObject *code;
146 PyObject *globals;
147 PyObject *locals;
149 PyFrameObject *back = tstate->frame;
150 static PyObject *builtin_object;
151 PyFrameObject *f;
152 PyObject *builtins;
153 int extras;
155 if (builtin_object == NULL) {
156 builtin_object = PyString_InternFromString("__builtins__");
157 if (builtin_object == NULL)
158 return NULL;
160 if ((back != NULL && !PyFrame_Check(back)) ||
161 code == NULL || !PyCode_Check(code) ||
162 globals == NULL || !PyDict_Check(globals) ||
163 (locals != NULL && !PyDict_Check(locals))) {
164 PyErr_BadInternalCall();
165 return NULL;
167 extras = code->co_stacksize + code->co_nlocals;
168 if (back == NULL || back->f_globals != globals) {
169 builtins = PyDict_GetItem(globals, builtin_object);
170 if (builtins != NULL && PyModule_Check(builtins))
171 builtins = PyModule_GetDict(builtins);
173 else {
174 /* If we share the globals, we share the builtins.
175 Save a lookup and a call. */
176 builtins = back->f_builtins;
178 if (builtins != NULL && !PyDict_Check(builtins))
179 builtins = NULL;
180 if (free_list == NULL) {
181 f = (PyFrameObject *)
182 malloc(sizeof(PyFrameObject) +
183 extras*sizeof(PyObject *));
184 if (f == NULL)
185 return (PyFrameObject *)PyErr_NoMemory();
186 f->ob_type = &PyFrame_Type;
187 _Py_NewReference(f);
189 else {
190 f = free_list;
191 free_list = free_list->f_back;
192 if (f->f_nlocals + f->f_stacksize < extras) {
193 f = (PyFrameObject *)
194 realloc(f, sizeof(PyFrameObject) +
195 extras*sizeof(PyObject *));
196 if (f == NULL)
197 return (PyFrameObject *)PyErr_NoMemory();
199 else
200 extras = f->f_nlocals + f->f_stacksize;
201 f->ob_type = &PyFrame_Type;
202 _Py_NewReference(f);
204 if (builtins == NULL) {
205 /* No builtins! Make up a minimal one. */
206 builtins = PyDict_New();
207 if (builtins == NULL || /* Give them 'None', at least. */
208 PyDict_SetItemString(builtins, "None", Py_None) < 0) {
209 Py_DECREF(f);
210 return NULL;
213 else
214 Py_XINCREF(builtins);
215 f->f_builtins = builtins;
216 Py_XINCREF(back);
217 f->f_back = back;
218 Py_INCREF(code);
219 f->f_code = code;
220 Py_INCREF(globals);
221 f->f_globals = globals;
222 if (code->co_flags & CO_NEWLOCALS) {
223 if (code->co_flags & CO_OPTIMIZED)
224 locals = NULL; /* Let fast_2_locals handle it */
225 else {
226 locals = PyDict_New();
227 if (locals == NULL) {
228 Py_DECREF(f);
229 return NULL;
233 else {
234 if (locals == NULL)
235 locals = globals;
236 Py_INCREF(locals);
238 f->f_locals = locals;
239 f->f_trace = NULL;
240 f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
241 f->f_tstate = tstate;
243 f->f_lasti = 0;
244 f->f_lineno = code->co_firstlineno;
245 f->f_restricted = (builtins != tstate->interp->builtins);
246 f->f_iblock = 0;
247 f->f_nlocals = code->co_nlocals;
248 f->f_stacksize = extras - code->co_nlocals;
250 while (--extras >= 0)
251 f->f_localsplus[extras] = NULL;
253 f->f_valuestack = f->f_localsplus + f->f_nlocals;
255 return f;
258 /* Block management */
260 void
261 PyFrame_BlockSetup(f, type, handler, level)
262 PyFrameObject *f;
263 int type;
264 int handler;
265 int level;
267 PyTryBlock *b;
268 if (f->f_iblock >= CO_MAXBLOCKS)
269 Py_FatalError("XXX block stack overflow");
270 b = &f->f_blockstack[f->f_iblock++];
271 b->b_type = type;
272 b->b_level = level;
273 b->b_handler = handler;
276 PyTryBlock *
277 PyFrame_BlockPop(f)
278 PyFrameObject *f;
280 PyTryBlock *b;
281 if (f->f_iblock <= 0)
282 Py_FatalError("XXX block stack underflow");
283 b = &f->f_blockstack[--f->f_iblock];
284 return b;
287 /* Convert between "fast" version of locals and dictionary version */
289 void
290 PyFrame_FastToLocals(f)
291 PyFrameObject *f;
293 /* Merge fast locals into f->f_locals */
294 PyObject *locals, *map;
295 PyObject **fast;
296 PyObject *error_type, *error_value, *error_traceback;
297 int j;
298 if (f == NULL)
299 return;
300 locals = f->f_locals;
301 if (locals == NULL) {
302 locals = f->f_locals = PyDict_New();
303 if (locals == NULL) {
304 PyErr_Clear(); /* Can't report it :-( */
305 return;
308 if (f->f_nlocals == 0)
309 return;
310 map = f->f_code->co_varnames;
311 if (!PyDict_Check(locals) || !PyTuple_Check(map))
312 return;
313 PyErr_Fetch(&error_type, &error_value, &error_traceback);
314 fast = f->f_localsplus;
315 j = PyTuple_Size(map);
316 if (j > f->f_nlocals)
317 j = f->f_nlocals;
318 for (; --j >= 0; ) {
319 PyObject *key = PyTuple_GetItem(map, j);
320 PyObject *value = fast[j];
321 if (value == NULL) {
322 PyErr_Clear();
323 if (PyDict_DelItem(locals, key) != 0)
324 PyErr_Clear();
326 else {
327 if (PyDict_SetItem(locals, key, value) != 0)
328 PyErr_Clear();
331 PyErr_Restore(error_type, error_value, error_traceback);
334 void
335 PyFrame_LocalsToFast(f, clear)
336 PyFrameObject *f;
337 int clear;
339 /* Merge f->f_locals into fast locals */
340 PyObject *locals, *map;
341 PyObject **fast;
342 PyObject *error_type, *error_value, *error_traceback;
343 int j;
344 if (f == NULL)
345 return;
346 locals = f->f_locals;
347 map = f->f_code->co_varnames;
348 if (locals == NULL || f->f_code->co_nlocals == 0)
349 return;
350 if (!PyDict_Check(locals) || !PyTuple_Check(map))
351 return;
352 PyErr_Fetch(&error_type, &error_value, &error_traceback);
353 fast = f->f_localsplus;
354 j = PyTuple_Size(map);
355 if (j > f->f_nlocals)
356 j = f->f_nlocals;
357 for (; --j >= 0; ) {
358 PyObject *key = PyTuple_GetItem(map, j);
359 PyObject *value = PyDict_GetItem(locals, key);
360 Py_XINCREF(value);
361 if (value != NULL || clear) {
362 Py_XDECREF(fast[j]);
363 fast[j] = value;
366 PyErr_Restore(error_type, error_value, error_traceback);
369 /* Clear out the free list */
371 void
372 PyFrame_Fini()
374 while (free_list != NULL) {
375 PyFrameObject *f = free_list;
376 free_list = free_list->f_back;
377 PyMem_DEL(f);