2 /* Frame object implementation */
7 #include "frameobject.h"
9 #include "structmember.h"
11 #define OFF(x) offsetof(PyFrameObject, x)
13 static struct memberlist frame_memberlist
[] = {
14 {"f_back", T_OBJECT
, OFF(f_back
), RO
},
15 {"f_code", T_OBJECT
, OFF(f_code
), RO
},
16 {"f_builtins", T_OBJECT
, OFF(f_builtins
),RO
},
17 {"f_globals", T_OBJECT
, OFF(f_globals
), RO
},
18 {"f_locals", T_OBJECT
, OFF(f_locals
), RO
},
19 {"f_lasti", T_INT
, OFF(f_lasti
), RO
},
20 {"f_lineno", T_INT
, OFF(f_lineno
), RO
},
21 {"f_restricted",T_INT
, OFF(f_restricted
),RO
},
22 {"f_trace", T_OBJECT
, OFF(f_trace
)},
23 {"f_exc_type", T_OBJECT
, OFF(f_exc_type
)},
24 {"f_exc_value", T_OBJECT
, OFF(f_exc_value
)},
25 {"f_exc_traceback", T_OBJECT
, OFF(f_exc_traceback
)},
30 frame_getattr(PyFrameObject
*f
, char *name
)
32 if (strcmp(name
, "f_locals") == 0)
33 PyFrame_FastToLocals(f
);
34 return PyMember_Get((char *)f
, frame_memberlist
, name
);
38 frame_setattr(PyFrameObject
*f
, char *name
, PyObject
*value
)
40 return PyMember_Set((char *)f
, frame_memberlist
, name
, value
);
43 /* Stack frames are allocated and deallocated at a considerable rate.
44 In an attempt to improve the speed of function calls, we maintain a
45 separate free list of stack frames (just like integers are
46 allocated in a special way -- see intobject.c). When a stack frame
47 is on the free list, only the following members have a meaning:
49 f_back next item on free list, or NULL
50 f_nlocals number of locals
51 f_stacksize size of value stack
52 Note that the value and block stacks are preserved -- this can save
53 another malloc() call or two (and two free() calls as well!).
54 Also note that, unlike for integers, each frame object is a
55 malloc'ed object in its own right -- it is only the actual calls to
56 malloc() that we are trying to save here, not the administration.
57 After all, while a typical program may make millions of calls, a
58 call depth of more than 20 or 30 is probably already exceptional
59 unless the program contains run-away recursion. I hope.
62 static PyFrameObject
*free_list
= NULL
;
65 frame_dealloc(PyFrameObject
*f
)
68 PyObject
**fastlocals
;
70 Py_TRASHCAN_SAFE_BEGIN(f
)
71 /* Kill all local variables */
72 fastlocals
= f
->f_localsplus
;
73 for (i
= f
->f_nlocals
; --i
>= 0; ++fastlocals
) {
74 Py_XDECREF(*fastlocals
);
77 Py_XDECREF(f
->f_back
);
78 Py_XDECREF(f
->f_code
);
79 Py_XDECREF(f
->f_builtins
);
80 Py_XDECREF(f
->f_globals
);
81 Py_XDECREF(f
->f_locals
);
82 Py_XDECREF(f
->f_trace
);
83 Py_XDECREF(f
->f_exc_type
);
84 Py_XDECREF(f
->f_exc_value
);
85 Py_XDECREF(f
->f_exc_traceback
);
86 f
->f_back
= free_list
;
88 Py_TRASHCAN_SAFE_END(f
)
91 PyTypeObject PyFrame_Type
= {
92 PyObject_HEAD_INIT(&PyType_Type
)
95 sizeof(PyFrameObject
),
97 (destructor
)frame_dealloc
, /*tp_dealloc*/
99 (getattrfunc
)frame_getattr
, /*tp_getattr*/
100 (setattrfunc
)frame_setattr
, /*tp_setattr*/
104 0, /*tp_as_sequence*/
109 PyFrame_New(PyThreadState
*tstate
, PyCodeObject
*code
,
110 PyObject
*globals
, PyObject
*locals
)
112 PyFrameObject
*back
= tstate
->frame
;
113 static PyObject
*builtin_object
;
118 if (builtin_object
== NULL
) {
119 builtin_object
= PyString_InternFromString("__builtins__");
120 if (builtin_object
== NULL
)
123 if ((back
!= NULL
&& !PyFrame_Check(back
)) ||
124 code
== NULL
|| !PyCode_Check(code
) ||
125 globals
== NULL
|| !PyDict_Check(globals
) ||
126 (locals
!= NULL
&& !PyDict_Check(locals
))) {
127 PyErr_BadInternalCall();
130 extras
= code
->co_stacksize
+ code
->co_nlocals
;
131 if (back
== NULL
|| back
->f_globals
!= globals
) {
132 builtins
= PyDict_GetItem(globals
, builtin_object
);
133 if (builtins
!= NULL
&& PyModule_Check(builtins
))
134 builtins
= PyModule_GetDict(builtins
);
137 /* If we share the globals, we share the builtins.
138 Save a lookup and a call. */
139 builtins
= back
->f_builtins
;
141 if (builtins
!= NULL
&& !PyDict_Check(builtins
))
143 if (free_list
== NULL
) {
144 /* PyObject_New is inlined */
145 f
= (PyFrameObject
*)
146 PyObject_MALLOC(sizeof(PyFrameObject
) +
147 extras
*sizeof(PyObject
*));
149 return (PyFrameObject
*)PyErr_NoMemory();
150 PyObject_INIT(f
, &PyFrame_Type
);
154 free_list
= free_list
->f_back
;
155 if (f
->f_nlocals
+ f
->f_stacksize
< extras
) {
156 f
= (PyFrameObject
*)
157 PyObject_REALLOC(f
, sizeof(PyFrameObject
) +
158 extras
*sizeof(PyObject
*));
160 return (PyFrameObject
*)PyErr_NoMemory();
163 extras
= f
->f_nlocals
+ f
->f_stacksize
;
164 PyObject_INIT(f
, &PyFrame_Type
);
166 if (builtins
== NULL
) {
167 /* No builtins! Make up a minimal one. */
168 builtins
= PyDict_New();
169 if (builtins
== NULL
|| /* Give them 'None', at least. */
170 PyDict_SetItemString(builtins
, "None", Py_None
) < 0) {
176 Py_XINCREF(builtins
);
177 f
->f_builtins
= builtins
;
183 f
->f_globals
= globals
;
184 if (code
->co_flags
& CO_NEWLOCALS
) {
185 if (code
->co_flags
& CO_OPTIMIZED
)
186 locals
= NULL
; /* Let fast_2_locals handle it */
188 locals
= PyDict_New();
189 if (locals
== NULL
) {
200 f
->f_locals
= locals
;
202 f
->f_exc_type
= f
->f_exc_value
= f
->f_exc_traceback
= NULL
;
203 f
->f_tstate
= tstate
;
206 f
->f_lineno
= code
->co_firstlineno
;
207 f
->f_restricted
= (builtins
!= tstate
->interp
->builtins
);
209 f
->f_nlocals
= code
->co_nlocals
;
210 f
->f_stacksize
= extras
- code
->co_nlocals
;
212 while (--extras
>= 0)
213 f
->f_localsplus
[extras
] = NULL
;
215 f
->f_valuestack
= f
->f_localsplus
+ f
->f_nlocals
;
220 /* Block management */
223 PyFrame_BlockSetup(PyFrameObject
*f
, int type
, int handler
, int level
)
226 if (f
->f_iblock
>= CO_MAXBLOCKS
)
227 Py_FatalError("XXX block stack overflow");
228 b
= &f
->f_blockstack
[f
->f_iblock
++];
231 b
->b_handler
= handler
;
235 PyFrame_BlockPop(PyFrameObject
*f
)
238 if (f
->f_iblock
<= 0)
239 Py_FatalError("XXX block stack underflow");
240 b
= &f
->f_blockstack
[--f
->f_iblock
];
244 /* Convert between "fast" version of locals and dictionary version */
247 PyFrame_FastToLocals(PyFrameObject
*f
)
249 /* Merge fast locals into f->f_locals */
250 PyObject
*locals
, *map
;
252 PyObject
*error_type
, *error_value
, *error_traceback
;
256 locals
= f
->f_locals
;
257 if (locals
== NULL
) {
258 locals
= f
->f_locals
= PyDict_New();
259 if (locals
== NULL
) {
260 PyErr_Clear(); /* Can't report it :-( */
264 if (f
->f_nlocals
== 0)
266 map
= f
->f_code
->co_varnames
;
267 if (!PyDict_Check(locals
) || !PyTuple_Check(map
))
269 PyErr_Fetch(&error_type
, &error_value
, &error_traceback
);
270 fast
= f
->f_localsplus
;
271 j
= PyTuple_Size(map
);
272 if (j
> f
->f_nlocals
)
275 PyObject
*key
= PyTuple_GetItem(map
, j
);
276 PyObject
*value
= fast
[j
];
279 if (PyDict_DelItem(locals
, key
) != 0)
283 if (PyDict_SetItem(locals
, key
, value
) != 0)
287 PyErr_Restore(error_type
, error_value
, error_traceback
);
291 PyFrame_LocalsToFast(PyFrameObject
*f
, int clear
)
293 /* Merge f->f_locals into fast locals */
294 PyObject
*locals
, *map
;
296 PyObject
*error_type
, *error_value
, *error_traceback
;
300 locals
= f
->f_locals
;
301 map
= f
->f_code
->co_varnames
;
302 if (locals
== NULL
|| f
->f_code
->co_nlocals
== 0)
304 if (!PyDict_Check(locals
) || !PyTuple_Check(map
))
306 PyErr_Fetch(&error_type
, &error_value
, &error_traceback
);
307 fast
= f
->f_localsplus
;
308 j
= PyTuple_Size(map
);
309 if (j
> f
->f_nlocals
)
312 PyObject
*key
= PyTuple_GetItem(map
, j
);
313 PyObject
*value
= PyDict_GetItem(locals
, key
);
315 if (value
!= NULL
|| clear
) {
320 PyErr_Restore(error_type
, error_value
, error_traceback
);
323 /* Clear out the free list */
328 while (free_list
!= NULL
) {
329 PyFrameObject
*f
= free_list
;
330 free_list
= free_list
->f_back
;