frameobject.c revision 69734a52725f1ebd3b508098a61c820784471d66
1 2/* Frame object implementation */ 3 4#include "Python.h" 5 6#include "compile.h" 7#include "frameobject.h" 8#include "opcode.h" 9#include "structmember.h" 10 11#define OFF(x) offsetof(PyFrameObject, x) 12 13static 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_restricted",T_INT, OFF(f_restricted),RO}, 20 {"f_trace", T_OBJECT, OFF(f_trace)}, 21 {"f_exc_type", T_OBJECT, OFF(f_exc_type)}, 22 {"f_exc_value", T_OBJECT, OFF(f_exc_value)}, 23 {"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)}, 24 {NULL} /* Sentinel */ 25}; 26 27static PyObject * 28frame_getlocals(PyFrameObject *f, void *closure) 29{ 30 PyFrame_FastToLocals(f); 31 Py_INCREF(f->f_locals); 32 return f->f_locals; 33} 34 35static PyObject * 36frame_getlineno(PyFrameObject *f, void *closure) 37{ 38 int lineno; 39 40 lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); 41 42 return PyInt_FromLong(lineno); 43} 44 45static PyGetSetDef frame_getsetlist[] = { 46 {"f_locals", (getter)frame_getlocals, NULL, NULL}, 47 {"f_lineno", (getter)frame_getlineno, NULL, NULL}, 48 {0} 49}; 50 51/* Stack frames are allocated and deallocated at a considerable rate. 52 In an attempt to improve the speed of function calls, we maintain a 53 separate free list of stack frames (just like integers are 54 allocated in a special way -- see intobject.c). When a stack frame 55 is on the free list, only the following members have a meaning: 56 ob_type == &Frametype 57 f_back next item on free list, or NULL 58 f_nlocals number of locals 59 f_stacksize size of value stack 60 ob_size size of localsplus 61 Note that the value and block stacks are preserved -- this can save 62 another malloc() call or two (and two free() calls as well!). 63 Also note that, unlike for integers, each frame object is a 64 malloc'ed object in its own right -- it is only the actual calls to 65 malloc() that we are trying to save here, not the administration. 66 After all, while a typical program may make millions of calls, a 67 call depth of more than 20 or 30 is probably already exceptional 68 unless the program contains run-away recursion. I hope. 69 70 Later, MAXFREELIST was added to bound the # of frames saved on 71 free_list. Else programs creating lots of cyclic trash involving 72 frames could provoke free_list into growing without bound. 73*/ 74 75static PyFrameObject *free_list = NULL; 76static int numfree = 0; /* number of frames currently in free_list */ 77#define MAXFREELIST 200 /* max value for numfree */ 78 79static void 80frame_dealloc(PyFrameObject *f) 81{ 82 int i, slots; 83 PyObject **fastlocals; 84 PyObject **p; 85 86 PyObject_GC_UnTrack(f); 87 Py_TRASHCAN_SAFE_BEGIN(f) 88 /* Kill all local variables */ 89 slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; 90 fastlocals = f->f_localsplus; 91 for (i = slots; --i >= 0; ++fastlocals) { 92 Py_XDECREF(*fastlocals); 93 } 94 95 /* Free stack */ 96 if (f->f_stacktop != NULL) { 97 for (p = f->f_valuestack; p < f->f_stacktop; p++) 98 Py_XDECREF(*p); 99 } 100 101 Py_XDECREF(f->f_back); 102 Py_XDECREF(f->f_code); 103 Py_XDECREF(f->f_builtins); 104 Py_XDECREF(f->f_globals); 105 Py_XDECREF(f->f_locals); 106 Py_XDECREF(f->f_trace); 107 Py_XDECREF(f->f_exc_type); 108 Py_XDECREF(f->f_exc_value); 109 Py_XDECREF(f->f_exc_traceback); 110 if (numfree < MAXFREELIST) { 111 ++numfree; 112 f->f_back = free_list; 113 free_list = f; 114 } 115 else 116 PyObject_GC_Del(f); 117 Py_TRASHCAN_SAFE_END(f) 118} 119 120static int 121frame_traverse(PyFrameObject *f, visitproc visit, void *arg) 122{ 123 PyObject **fastlocals, **p; 124 int i, err, slots; 125#define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} 126 127 VISIT(f->f_back); 128 VISIT(f->f_code); 129 VISIT(f->f_builtins); 130 VISIT(f->f_globals); 131 VISIT(f->f_locals); 132 VISIT(f->f_trace); 133 VISIT(f->f_exc_type); 134 VISIT(f->f_exc_value); 135 VISIT(f->f_exc_traceback); 136 137 /* locals */ 138 slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; 139 fastlocals = f->f_localsplus; 140 for (i = slots; --i >= 0; ++fastlocals) { 141 VISIT(*fastlocals); 142 } 143 144 /* stack */ 145 if (f->f_stacktop != NULL) { 146 for (p = f->f_valuestack; p < f->f_stacktop; p++) 147 VISIT(*p); 148 } 149 return 0; 150} 151 152static void 153frame_clear(PyFrameObject *f) 154{ 155 PyObject **fastlocals, **p; 156 int i, slots; 157 158 Py_XDECREF(f->f_exc_type); 159 f->f_exc_type = NULL; 160 161 Py_XDECREF(f->f_exc_value); 162 f->f_exc_value = NULL; 163 164 Py_XDECREF(f->f_exc_traceback); 165 f->f_exc_traceback = NULL; 166 167 Py_XDECREF(f->f_trace); 168 f->f_trace = NULL; 169 170 /* locals */ 171 slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; 172 fastlocals = f->f_localsplus; 173 for (i = slots; --i >= 0; ++fastlocals) { 174 if (*fastlocals != NULL) { 175 Py_XDECREF(*fastlocals); 176 *fastlocals = NULL; 177 } 178 } 179 180 /* stack */ 181 if (f->f_stacktop != NULL) { 182 for (p = f->f_valuestack; p < f->f_stacktop; p++) { 183 Py_XDECREF(*p); 184 *p = NULL; 185 } 186 } 187} 188 189 190PyTypeObject PyFrame_Type = { 191 PyObject_HEAD_INIT(&PyType_Type) 192 0, 193 "frame", 194 sizeof(PyFrameObject), 195 sizeof(PyObject *), 196 (destructor)frame_dealloc, /* tp_dealloc */ 197 0, /* tp_print */ 198 0, /* tp_getattr */ 199 0, /* tp_setattr */ 200 0, /* tp_compare */ 201 0, /* tp_repr */ 202 0, /* tp_as_number */ 203 0, /* tp_as_sequence */ 204 0, /* tp_as_mapping */ 205 0, /* tp_hash */ 206 0, /* tp_call */ 207 0, /* tp_str */ 208 PyObject_GenericGetAttr, /* tp_getattro */ 209 PyObject_GenericSetAttr, /* tp_setattro */ 210 0, /* tp_as_buffer */ 211 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 212 0, /* tp_doc */ 213 (traverseproc)frame_traverse, /* tp_traverse */ 214 (inquiry)frame_clear, /* tp_clear */ 215 0, /* tp_richcompare */ 216 0, /* tp_weaklistoffset */ 217 0, /* tp_iter */ 218 0, /* tp_iternext */ 219 0, /* tp_methods */ 220 frame_memberlist, /* tp_members */ 221 frame_getsetlist, /* tp_getset */ 222 0, /* tp_base */ 223 0, /* tp_dict */ 224}; 225 226PyFrameObject * 227PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, 228 PyObject *locals) 229{ 230 PyFrameObject *back = tstate->frame; 231 static PyObject *builtin_object; 232 PyFrameObject *f; 233 PyObject *builtins; 234 int extras, ncells, nfrees; 235 236 if (builtin_object == NULL) { 237 builtin_object = PyString_InternFromString("__builtins__"); 238 if (builtin_object == NULL) 239 return NULL; 240 } 241#ifdef Py_DEBUG 242 if (code == NULL || globals == NULL || !PyDict_Check(globals) || 243 (locals != NULL && !PyDict_Check(locals))) { 244 PyErr_BadInternalCall(); 245 return NULL; 246 } 247#endif 248 ncells = PyTuple_GET_SIZE(code->co_cellvars); 249 nfrees = PyTuple_GET_SIZE(code->co_freevars); 250 extras = code->co_stacksize + code->co_nlocals + ncells + nfrees; 251 if (back == NULL || back->f_globals != globals) { 252 builtins = PyDict_GetItem(globals, builtin_object); 253 if (builtins != NULL && PyModule_Check(builtins)) 254 builtins = PyModule_GetDict(builtins); 255 } 256 else { 257 /* If we share the globals, we share the builtins. 258 Save a lookup and a call. */ 259 builtins = back->f_builtins; 260 } 261 if (builtins != NULL && !PyDict_Check(builtins)) 262 builtins = NULL; 263 if (free_list == NULL) { 264 f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); 265 if (f == NULL) 266 return NULL; 267 } 268 else { 269 assert(numfree > 0); 270 --numfree; 271 f = free_list; 272 free_list = free_list->f_back; 273 if (f->ob_size < extras) { 274 f = PyObject_GC_Resize(PyFrameObject, f, extras); 275 if (f == NULL) 276 return NULL; 277 } 278 _Py_NewReference((PyObject *)f); 279 } 280 if (builtins == NULL) { 281 /* No builtins! Make up a minimal one. */ 282 builtins = PyDict_New(); 283 if (builtins == NULL || /* Give them 'None', at least. */ 284 PyDict_SetItemString(builtins, "None", Py_None) < 0) { 285 Py_DECREF(f); 286 return NULL; 287 } 288 } 289 else 290 Py_XINCREF(builtins); 291 f->f_builtins = builtins; 292 Py_XINCREF(back); 293 f->f_back = back; 294 Py_INCREF(code); 295 f->f_code = code; 296 Py_INCREF(globals); 297 f->f_globals = globals; 298 if (code->co_flags & CO_NEWLOCALS) { 299 if (code->co_flags & CO_OPTIMIZED) 300 locals = NULL; /* Let fast_2_locals handle it */ 301 else { 302 locals = PyDict_New(); 303 if (locals == NULL) { 304 Py_DECREF(f); 305 return NULL; 306 } 307 } 308 } 309 else { 310 if (locals == NULL) 311 locals = globals; 312 Py_INCREF(locals); 313 } 314 f->f_locals = locals; 315 f->f_trace = NULL; 316 f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; 317 f->f_tstate = tstate; 318 319 f->f_lasti = -1; 320 f->f_lineno = code->co_firstlineno; 321 f->f_restricted = (builtins != tstate->interp->builtins); 322 f->f_iblock = 0; 323 f->f_nlocals = code->co_nlocals; 324 f->f_stacksize = code->co_stacksize; 325 f->f_ncells = ncells; 326 f->f_nfreevars = nfrees; 327 328 extras = f->f_nlocals + ncells + nfrees; 329 memset(f->f_localsplus, 0, extras * sizeof(f->f_localsplus[0])); 330 331 f->f_valuestack = f->f_localsplus + extras; 332 f->f_stacktop = f->f_valuestack; 333 _PyObject_GC_TRACK(f); 334 return f; 335} 336 337/* Block management */ 338 339void 340PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level) 341{ 342 PyTryBlock *b; 343 if (f->f_iblock >= CO_MAXBLOCKS) 344 Py_FatalError("XXX block stack overflow"); 345 b = &f->f_blockstack[f->f_iblock++]; 346 b->b_type = type; 347 b->b_level = level; 348 b->b_handler = handler; 349} 350 351PyTryBlock * 352PyFrame_BlockPop(PyFrameObject *f) 353{ 354 PyTryBlock *b; 355 if (f->f_iblock <= 0) 356 Py_FatalError("XXX block stack underflow"); 357 b = &f->f_blockstack[--f->f_iblock]; 358 return b; 359} 360 361/* Convert between "fast" version of locals and dictionary version */ 362 363static void 364map_to_dict(PyObject *map, int nmap, PyObject *dict, PyObject **values, 365 int deref) 366{ 367 int j; 368 for (j = nmap; --j >= 0; ) { 369 PyObject *key = PyTuple_GET_ITEM(map, j); 370 PyObject *value = values[j]; 371 if (deref) 372 value = PyCell_GET(value); 373 if (value == NULL) { 374 if (PyDict_DelItem(dict, key) != 0) 375 PyErr_Clear(); 376 } 377 else { 378 if (PyDict_SetItem(dict, key, value) != 0) 379 PyErr_Clear(); 380 } 381 } 382} 383 384static void 385dict_to_map(PyObject *map, int nmap, PyObject *dict, PyObject **values, 386 int deref, int clear) 387{ 388 int j; 389 for (j = nmap; --j >= 0; ) { 390 PyObject *key = PyTuple_GET_ITEM(map, j); 391 PyObject *value = PyDict_GetItem(dict, key); 392 if (deref) { 393 if (value || clear) { 394 if (PyCell_GET(values[j]) != value) { 395 if (PyCell_Set(values[j], value) < 0) 396 PyErr_Clear(); 397 } 398 } 399 } else if (value != NULL || clear) { 400 if (values[j] != value) { 401 Py_XINCREF(value); 402 Py_XDECREF(values[j]); 403 values[j] = value; 404 } 405 } 406 } 407} 408 409void 410PyFrame_FastToLocals(PyFrameObject *f) 411{ 412 /* Merge fast locals into f->f_locals */ 413 PyObject *locals, *map; 414 PyObject **fast; 415 PyObject *error_type, *error_value, *error_traceback; 416 int j; 417 if (f == NULL) 418 return; 419 locals = f->f_locals; 420 if (locals == NULL) { 421 locals = f->f_locals = PyDict_New(); 422 if (locals == NULL) { 423 PyErr_Clear(); /* Can't report it :-( */ 424 return; 425 } 426 } 427 map = f->f_code->co_varnames; 428 if (!PyDict_Check(locals) || !PyTuple_Check(map)) 429 return; 430 PyErr_Fetch(&error_type, &error_value, &error_traceback); 431 fast = f->f_localsplus; 432 j = PyTuple_Size(map); 433 if (j > f->f_nlocals) 434 j = f->f_nlocals; 435 if (f->f_nlocals) 436 map_to_dict(map, j, locals, fast, 0); 437 if (f->f_ncells || f->f_nfreevars) { 438 if (!(PyTuple_Check(f->f_code->co_cellvars) 439 && PyTuple_Check(f->f_code->co_freevars))) { 440 Py_DECREF(locals); 441 return; 442 } 443 map_to_dict(f->f_code->co_cellvars, 444 PyTuple_GET_SIZE(f->f_code->co_cellvars), 445 locals, fast + f->f_nlocals, 1); 446 map_to_dict(f->f_code->co_freevars, 447 PyTuple_GET_SIZE(f->f_code->co_freevars), 448 locals, fast + f->f_nlocals + f->f_ncells, 1); 449 } 450 PyErr_Restore(error_type, error_value, error_traceback); 451} 452 453void 454PyFrame_LocalsToFast(PyFrameObject *f, int clear) 455{ 456 /* Merge f->f_locals into fast locals */ 457 PyObject *locals, *map; 458 PyObject **fast; 459 PyObject *error_type, *error_value, *error_traceback; 460 int j; 461 if (f == NULL) 462 return; 463 locals = f->f_locals; 464 map = f->f_code->co_varnames; 465 if (locals == NULL) 466 return; 467 if (!PyDict_Check(locals) || !PyTuple_Check(map)) 468 return; 469 PyErr_Fetch(&error_type, &error_value, &error_traceback); 470 fast = f->f_localsplus; 471 j = PyTuple_Size(map); 472 if (j > f->f_nlocals) 473 j = f->f_nlocals; 474 if (f->f_nlocals) 475 dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear); 476 if (f->f_ncells || f->f_nfreevars) { 477 if (!(PyTuple_Check(f->f_code->co_cellvars) 478 && PyTuple_Check(f->f_code->co_freevars))) 479 return; 480 dict_to_map(f->f_code->co_cellvars, 481 PyTuple_GET_SIZE(f->f_code->co_cellvars), 482 locals, fast + f->f_nlocals, 1, clear); 483 dict_to_map(f->f_code->co_freevars, 484 PyTuple_GET_SIZE(f->f_code->co_freevars), 485 locals, fast + f->f_nlocals + f->f_ncells, 1, 486 clear); 487 } 488 PyErr_Restore(error_type, error_value, error_traceback); 489} 490 491/* Clear out the free list */ 492 493void 494PyFrame_Fini(void) 495{ 496 while (free_list != NULL) { 497 PyFrameObject *f = free_list; 498 free_list = free_list->f_back; 499 PyObject_GC_Del(f); 500 --numfree; 501 } 502 assert(numfree == 0); 503} 504