2 /* Frame object implementation */
7 #include "frameobject.h"
9 #include "structmember.h"
11 #define OFF(x) offsetof(PyFrameObject, x)
13 static PyMemberDef 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_lasti", T_INT
, OFF(f_lasti
), RO
},
19 {"f_lineno", T_INT
, OFF(f_lineno
), RO
},
20 {"f_restricted",T_INT
, OFF(f_restricted
),RO
},
21 {"f_trace", T_OBJECT
, OFF(f_trace
)},
22 {"f_exc_type", T_OBJECT
, OFF(f_exc_type
)},
23 {"f_exc_value", T_OBJECT
, OFF(f_exc_value
)},
24 {"f_exc_traceback", T_OBJECT
, OFF(f_exc_traceback
)},
29 frame_getlocals(PyFrameObject
*f
, void *closure
)
31 PyFrame_FastToLocals(f
);
32 Py_INCREF(f
->f_locals
);
36 static PyGetSetDef frame_getsetlist
[] = {
37 {"f_locals", (getter
)frame_getlocals
, NULL
, NULL
},
41 /* Stack frames are allocated and deallocated at a considerable rate.
42 In an attempt to improve the speed of function calls, we maintain a
43 separate free list of stack frames (just like integers are
44 allocated in a special way -- see intobject.c). When a stack frame
45 is on the free list, only the following members have a meaning:
47 f_back next item on free list, or NULL
48 f_nlocals number of locals
49 f_stacksize size of value stack
50 ob_size size of localsplus
51 Note that the value and block stacks are preserved -- this can save
52 another malloc() call or two (and two free() calls as well!).
53 Also note that, unlike for integers, each frame object is a
54 malloc'ed object in its own right -- it is only the actual calls to
55 malloc() that we are trying to save here, not the administration.
56 After all, while a typical program may make millions of calls, a
57 call depth of more than 20 or 30 is probably already exceptional
58 unless the program contains run-away recursion. I hope.
61 static PyFrameObject
*free_list
= NULL
;
64 frame_dealloc(PyFrameObject
*f
)
67 PyObject
**fastlocals
;
70 PyObject_GC_UnTrack(f
);
71 Py_TRASHCAN_SAFE_BEGIN(f
)
72 /* Kill all local variables */
73 slots
= f
->f_nlocals
+ f
->f_ncells
+ f
->f_nfreevars
;
74 fastlocals
= f
->f_localsplus
;
75 for (i
= slots
; --i
>= 0; ++fastlocals
) {
76 Py_XDECREF(*fastlocals
);
80 if (f
->f_stacktop
!= NULL
) {
81 for (p
= f
->f_valuestack
; p
< f
->f_stacktop
; p
++)
85 Py_XDECREF(f
->f_back
);
86 Py_XDECREF(f
->f_code
);
87 Py_XDECREF(f
->f_builtins
);
88 Py_XDECREF(f
->f_globals
);
89 Py_XDECREF(f
->f_locals
);
90 Py_XDECREF(f
->f_trace
);
91 Py_XDECREF(f
->f_exc_type
);
92 Py_XDECREF(f
->f_exc_value
);
93 Py_XDECREF(f
->f_exc_traceback
);
94 f
->f_back
= free_list
;
96 Py_TRASHCAN_SAFE_END(f
)
100 frame_traverse(PyFrameObject
*f
, visitproc visit
, void *arg
)
102 PyObject
**fastlocals
, **p
;
104 #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;}
108 VISIT(f
->f_builtins
);
112 VISIT(f
->f_exc_type
);
113 VISIT(f
->f_exc_value
);
114 VISIT(f
->f_exc_traceback
);
117 slots
= f
->f_nlocals
+ f
->f_ncells
+ f
->f_nfreevars
;
118 fastlocals
= f
->f_localsplus
;
119 for (i
= slots
; --i
>= 0; ++fastlocals
) {
124 if (f
->f_stacktop
!= NULL
) {
125 for (p
= f
->f_valuestack
; p
< f
->f_stacktop
; p
++)
132 frame_clear(PyFrameObject
*f
)
134 PyObject
**fastlocals
, **p
;
137 Py_XDECREF(f
->f_exc_type
);
138 f
->f_exc_type
= NULL
;
140 Py_XDECREF(f
->f_exc_value
);
141 f
->f_exc_value
= NULL
;
143 Py_XDECREF(f
->f_exc_traceback
);
144 f
->f_exc_traceback
= NULL
;
146 Py_XDECREF(f
->f_trace
);
150 slots
= f
->f_nlocals
+ f
->f_ncells
+ f
->f_nfreevars
;
151 fastlocals
= f
->f_localsplus
;
152 for (i
= slots
; --i
>= 0; ++fastlocals
) {
153 if (*fastlocals
!= NULL
) {
154 Py_XDECREF(*fastlocals
);
160 if (f
->f_stacktop
!= NULL
) {
161 for (p
= f
->f_valuestack
; p
< f
->f_stacktop
; p
++) {
169 PyTypeObject PyFrame_Type
= {
170 PyObject_HEAD_INIT(&PyType_Type
)
173 sizeof(PyFrameObject
),
175 (destructor
)frame_dealloc
, /* tp_dealloc */
181 0, /* tp_as_number */
182 0, /* tp_as_sequence */
183 0, /* tp_as_mapping */
187 PyObject_GenericGetAttr
, /* tp_getattro */
188 PyObject_GenericSetAttr
, /* tp_setattro */
189 0, /* tp_as_buffer */
190 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
192 (traverseproc
)frame_traverse
, /* tp_traverse */
193 (inquiry
)frame_clear
, /* tp_clear */
194 0, /* tp_richcompare */
195 0, /* tp_weaklistoffset */
199 frame_memberlist
, /* tp_members */
200 frame_getsetlist
, /* tp_getset */
206 PyFrame_New(PyThreadState
*tstate
, PyCodeObject
*code
, PyObject
*globals
,
209 PyFrameObject
*back
= tstate
->frame
;
210 static PyObject
*builtin_object
;
213 int extras
, ncells
, nfrees
;
215 if (builtin_object
== NULL
) {
216 builtin_object
= PyString_InternFromString("__builtins__");
217 if (builtin_object
== NULL
)
220 if ((back
!= NULL
&& !PyFrame_Check(back
)) ||
221 code
== NULL
|| !PyCode_Check(code
) ||
222 globals
== NULL
|| !PyDict_Check(globals
) ||
223 (locals
!= NULL
&& !PyDict_Check(locals
))) {
224 PyErr_BadInternalCall();
227 ncells
= PyTuple_GET_SIZE(code
->co_cellvars
);
228 nfrees
= PyTuple_GET_SIZE(code
->co_freevars
);
229 extras
= code
->co_stacksize
+ code
->co_nlocals
+ ncells
+ nfrees
;
230 if (back
== NULL
|| back
->f_globals
!= globals
) {
231 builtins
= PyDict_GetItem(globals
, builtin_object
);
232 if (builtins
!= NULL
&& PyModule_Check(builtins
))
233 builtins
= PyModule_GetDict(builtins
);
236 /* If we share the globals, we share the builtins.
237 Save a lookup and a call. */
238 builtins
= back
->f_builtins
;
240 if (builtins
!= NULL
&& !PyDict_Check(builtins
))
242 if (free_list
== NULL
) {
243 f
= PyObject_GC_NewVar(PyFrameObject
, &PyFrame_Type
, extras
);
249 free_list
= free_list
->f_back
;
250 if (f
->ob_size
< extras
) {
251 f
= PyObject_GC_Resize(PyFrameObject
, f
, extras
);
257 _Py_NewReference((PyObject
*)f
);
259 if (builtins
== NULL
) {
260 /* No builtins! Make up a minimal one. */
261 builtins
= PyDict_New();
262 if (builtins
== NULL
|| /* Give them 'None', at least. */
263 PyDict_SetItemString(builtins
, "None", Py_None
) < 0) {
269 Py_XINCREF(builtins
);
270 f
->f_builtins
= builtins
;
276 f
->f_globals
= globals
;
277 if (code
->co_flags
& CO_NEWLOCALS
) {
278 if (code
->co_flags
& CO_OPTIMIZED
)
279 locals
= NULL
; /* Let fast_2_locals handle it */
281 locals
= PyDict_New();
282 if (locals
== NULL
) {
293 f
->f_locals
= locals
;
295 f
->f_exc_type
= f
->f_exc_value
= f
->f_exc_traceback
= NULL
;
296 f
->f_tstate
= tstate
;
299 f
->f_lineno
= code
->co_firstlineno
;
300 f
->f_restricted
= (builtins
!= tstate
->interp
->builtins
);
302 f
->f_nlocals
= code
->co_nlocals
;
303 f
->f_stacksize
= code
->co_stacksize
;
304 f
->f_ncells
= ncells
;
305 f
->f_nfreevars
= nfrees
;
307 while (--extras
>= 0)
308 f
->f_localsplus
[extras
] = NULL
;
310 f
->f_valuestack
= f
->f_localsplus
+ (f
->f_nlocals
+ ncells
+ nfrees
);
311 f
->f_stacktop
= f
->f_valuestack
;
312 _PyObject_GC_TRACK(f
);
316 /* Block management */
319 PyFrame_BlockSetup(PyFrameObject
*f
, int type
, int handler
, int level
)
322 if (f
->f_iblock
>= CO_MAXBLOCKS
)
323 Py_FatalError("XXX block stack overflow");
324 b
= &f
->f_blockstack
[f
->f_iblock
++];
327 b
->b_handler
= handler
;
331 PyFrame_BlockPop(PyFrameObject
*f
)
334 if (f
->f_iblock
<= 0)
335 Py_FatalError("XXX block stack underflow");
336 b
= &f
->f_blockstack
[--f
->f_iblock
];
340 /* Convert between "fast" version of locals and dictionary version */
343 map_to_dict(PyObject
*map
, int nmap
, PyObject
*dict
, PyObject
**values
,
347 for (j
= nmap
; --j
>= 0; ) {
348 PyObject
*key
= PyTuple_GET_ITEM(map
, j
);
349 PyObject
*value
= values
[j
];
351 value
= PyCell_GET(value
);
353 if (PyDict_DelItem(dict
, key
) != 0)
357 if (PyDict_SetItem(dict
, key
, value
) != 0)
364 dict_to_map(PyObject
*map
, int nmap
, PyObject
*dict
, PyObject
**values
,
365 int deref
, int clear
)
368 for (j
= nmap
; --j
>= 0; ) {
369 PyObject
*key
= PyTuple_GET_ITEM(map
, j
);
370 PyObject
*value
= PyDict_GetItem(dict
, key
);
372 if (value
|| clear
) {
373 if (PyCell_GET(values
[j
]) != value
) {
374 if (PyCell_Set(values
[j
], value
) < 0)
378 } else if (value
!= NULL
|| clear
) {
379 if (values
[j
] != value
) {
381 Py_XDECREF(values
[j
]);
389 PyFrame_FastToLocals(PyFrameObject
*f
)
391 /* Merge fast locals into f->f_locals */
392 PyObject
*locals
, *map
;
394 PyObject
*error_type
, *error_value
, *error_traceback
;
398 locals
= f
->f_locals
;
399 if (locals
== NULL
) {
400 locals
= f
->f_locals
= PyDict_New();
401 if (locals
== NULL
) {
402 PyErr_Clear(); /* Can't report it :-( */
406 if (f
->f_nlocals
== 0)
408 map
= f
->f_code
->co_varnames
;
409 if (!PyDict_Check(locals
) || !PyTuple_Check(map
))
411 PyErr_Fetch(&error_type
, &error_value
, &error_traceback
);
412 fast
= f
->f_localsplus
;
413 j
= PyTuple_Size(map
);
414 if (j
> f
->f_nlocals
)
416 map_to_dict(map
, j
, locals
, fast
, 0);
417 if (f
->f_ncells
|| f
->f_nfreevars
) {
418 if (!(PyTuple_Check(f
->f_code
->co_cellvars
)
419 && PyTuple_Check(f
->f_code
->co_freevars
))) {
423 map_to_dict(f
->f_code
->co_cellvars
,
424 PyTuple_GET_SIZE(f
->f_code
->co_cellvars
),
425 locals
, fast
+ f
->f_nlocals
, 1);
426 map_to_dict(f
->f_code
->co_freevars
,
427 PyTuple_GET_SIZE(f
->f_code
->co_freevars
),
428 locals
, fast
+ f
->f_nlocals
+ f
->f_ncells
, 1);
430 PyErr_Restore(error_type
, error_value
, error_traceback
);
434 PyFrame_LocalsToFast(PyFrameObject
*f
, int clear
)
436 /* Merge f->f_locals into fast locals */
437 PyObject
*locals
, *map
;
439 PyObject
*error_type
, *error_value
, *error_traceback
;
443 locals
= f
->f_locals
;
444 map
= f
->f_code
->co_varnames
;
445 if (locals
== NULL
|| f
->f_code
->co_nlocals
== 0)
447 if (!PyDict_Check(locals
) || !PyTuple_Check(map
))
449 PyErr_Fetch(&error_type
, &error_value
, &error_traceback
);
450 fast
= f
->f_localsplus
;
451 j
= PyTuple_Size(map
);
452 if (j
> f
->f_nlocals
)
454 dict_to_map(f
->f_code
->co_varnames
, j
, locals
, fast
, 0, clear
);
455 if (f
->f_ncells
|| f
->f_nfreevars
) {
456 if (!(PyTuple_Check(f
->f_code
->co_cellvars
)
457 && PyTuple_Check(f
->f_code
->co_freevars
)))
459 dict_to_map(f
->f_code
->co_cellvars
,
460 PyTuple_GET_SIZE(f
->f_code
->co_cellvars
),
461 locals
, fast
+ f
->f_nlocals
, 1, clear
);
462 dict_to_map(f
->f_code
->co_freevars
,
463 PyTuple_GET_SIZE(f
->f_code
->co_freevars
),
464 locals
, fast
+ f
->f_nlocals
+ f
->f_ncells
, 1, clear
);
466 PyErr_Restore(error_type
, error_value
, error_traceback
);
469 /* Clear out the free list */
474 while (free_list
!= NULL
) {
475 PyFrameObject
*f
= free_list
;
476 free_list
= free_list
->f_back
;