LCOV - code coverage report
Current view: top level - Objects - frameobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 161 399 40.4 %
Date: 2017-04-19 Functions: 11 27 40.7 %

          Line data    Source code
       1             : /* Frame object implementation */
       2             : 
       3             : #include "Python.h"
       4             : 
       5             : #include "code.h"
       6             : #include "frameobject.h"
       7             : #include "opcode.h"
       8             : #include "structmember.h"
       9             : 
      10             : #undef MIN
      11             : #undef MAX
      12             : #define MIN(a, b) ((a) < (b) ? (a) : (b))
      13             : #define MAX(a, b) ((a) > (b) ? (a) : (b))
      14             : 
      15             : #define OFF(x) offsetof(PyFrameObject, x)
      16             : 
      17             : static PyMemberDef frame_memberlist[] = {
      18             :     {"f_back",          T_OBJECT,       OFF(f_back),    RO},
      19             :     {"f_code",          T_OBJECT,       OFF(f_code),    RO},
      20             :     {"f_builtins",      T_OBJECT,       OFF(f_builtins),RO},
      21             :     {"f_globals",       T_OBJECT,       OFF(f_globals), RO},
      22             :     {"f_lasti",         T_INT,          OFF(f_lasti),   RO},
      23             :     {NULL}      /* Sentinel */
      24             : };
      25             : 
      26             : #define WARN_GET_SET(NAME) \
      27             : static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \
      28             :     if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
      29             :         return NULL; \
      30             :     if (f->NAME) { \
      31             :         Py_INCREF(f->NAME); \
      32             :         return f->NAME; \
      33             :     } \
      34             :     Py_RETURN_NONE;     \
      35             : } \
      36             : static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \
      37             :     if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
      38             :         return -1; \
      39             :     if (f->NAME) { \
      40             :         Py_CLEAR(f->NAME); \
      41             :     } \
      42             :     if (new == Py_None) \
      43             :         new = NULL; \
      44             :     Py_XINCREF(new); \
      45             :     f->NAME = new; \
      46             :     return 0; \
      47             : }
      48             : 
      49             : 
      50           0 : WARN_GET_SET(f_exc_traceback)
      51           0 : WARN_GET_SET(f_exc_type)
      52           0 : WARN_GET_SET(f_exc_value)
      53             : 
      54             : 
      55             : static PyObject *
      56           0 : frame_getlocals(PyFrameObject *f, void *closure)
      57             : {
      58           0 :     PyFrame_FastToLocals(f);
      59           0 :     Py_INCREF(f->f_locals);
      60           0 :     return f->f_locals;
      61             : }
      62             : 
      63             : int
      64        2154 : PyFrame_GetLineNumber(PyFrameObject *f)
      65             : {
      66        2154 :     if (f->f_trace)
      67           0 :         return f->f_lineno;
      68             :     else
      69        2154 :         return PyCode_Addr2Line(f->f_code, f->f_lasti);
      70             : }
      71             : 
      72             : static PyObject *
      73           0 : frame_getlineno(PyFrameObject *f, void *closure)
      74             : {
      75           0 :     return PyInt_FromLong(PyFrame_GetLineNumber(f));
      76             : }
      77             : 
      78             : /* Setter for f_lineno - you can set f_lineno from within a trace function in
      79             :  * order to jump to a given line of code, subject to some restrictions.  Most
      80             :  * lines are OK to jump to because they don't make any assumptions about the
      81             :  * state of the stack (obvious because you could remove the line and the code
      82             :  * would still work without any stack errors), but there are some constructs
      83             :  * that limit jumping:
      84             :  *
      85             :  *  o Lines with an 'except' statement on them can't be jumped to, because
      86             :  *    they expect an exception to be on the top of the stack.
      87             :  *  o Lines that live in a 'finally' block can't be jumped from or to, since
      88             :  *    the END_FINALLY expects to clean up the stack after the 'try' block.
      89             :  *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
      90             :  *    needs to be set up before their code runs, and for 'for' loops the
      91             :  *    iterator needs to be on the stack.
      92             :  */
      93             : static int
      94           0 : frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
      95             : {
      96           0 :     int new_lineno = 0;                 /* The new value of f_lineno */
      97           0 :     int new_lasti = 0;                  /* The new value of f_lasti */
      98           0 :     int new_iblock = 0;                 /* The new value of f_iblock */
      99           0 :     unsigned char *code = NULL;         /* The bytecode for the frame... */
     100           0 :     Py_ssize_t code_len = 0;            /* ...and its length */
     101           0 :     unsigned char *lnotab = NULL;       /* Iterating over co_lnotab */
     102           0 :     Py_ssize_t lnotab_len = 0;          /* (ditto) */
     103           0 :     int offset = 0;                     /* (ditto) */
     104           0 :     int line = 0;                       /* (ditto) */
     105           0 :     int addr = 0;                       /* (ditto) */
     106           0 :     int min_addr = 0;                   /* Scanning the SETUPs and POPs */
     107           0 :     int max_addr = 0;                   /* (ditto) */
     108           0 :     int delta_iblock = 0;               /* (ditto) */
     109           0 :     int min_delta_iblock = 0;           /* (ditto) */
     110           0 :     int min_iblock = 0;                 /* (ditto) */
     111           0 :     int f_lasti_setup_addr = 0;         /* Policing no-jump-into-finally */
     112           0 :     int new_lasti_setup_addr = 0;       /* (ditto) */
     113             :     int blockstack[CO_MAXBLOCKS];       /* Walking the 'finally' blocks */
     114             :     int in_finally[CO_MAXBLOCKS];       /* (ditto) */
     115           0 :     int blockstack_top = 0;             /* (ditto) */
     116           0 :     unsigned char setup_op = 0;         /* (ditto) */
     117             : 
     118             :     /* f_lineno must be an integer. */
     119           0 :     if (!PyInt_Check(p_new_lineno)) {
     120           0 :         PyErr_SetString(PyExc_ValueError,
     121             :                         "lineno must be an integer");
     122           0 :         return -1;
     123             :     }
     124             : 
     125             :     /* You can only do this from within a trace function, not via
     126             :      * _getframe or similar hackery. */
     127           0 :     if (!f->f_trace)
     128             :     {
     129           0 :         PyErr_Format(PyExc_ValueError,
     130             :                      "f_lineno can only be set by a"
     131             :                      " line trace function");
     132           0 :         return -1;
     133             :     }
     134             : 
     135             :     /* Fail if the line comes before the start of the code block. */
     136           0 :     new_lineno = (int) PyInt_AsLong(p_new_lineno);
     137           0 :     if (new_lineno < f->f_code->co_firstlineno) {
     138           0 :         PyErr_Format(PyExc_ValueError,
     139             :                      "line %d comes before the current code block",
     140             :                      new_lineno);
     141           0 :         return -1;
     142             :     }
     143           0 :     else if (new_lineno == f->f_code->co_firstlineno) {
     144           0 :         new_lasti = 0;
     145           0 :         new_lineno = f->f_code->co_firstlineno;
     146             :     }
     147             :     else {
     148             :         /* Find the bytecode offset for the start of the given
     149             :          * line, or the first code-owning line after it. */
     150             :         char *tmp;
     151           0 :         PyString_AsStringAndSize(f->f_code->co_lnotab,
     152             :                                  &tmp, &lnotab_len);
     153           0 :         lnotab = (unsigned char *) tmp;
     154           0 :         addr = 0;
     155           0 :         line = f->f_code->co_firstlineno;
     156           0 :         new_lasti = -1;
     157           0 :         for (offset = 0; offset < lnotab_len; offset += 2) {
     158           0 :             addr += lnotab[offset];
     159           0 :             line += lnotab[offset+1];
     160           0 :             if (line >= new_lineno) {
     161           0 :                 new_lasti = addr;
     162           0 :                 new_lineno = line;
     163           0 :                 break;
     164             :             }
     165             :         }
     166             :     }
     167             : 
     168             :     /* If we didn't reach the requested line, return an error. */
     169           0 :     if (new_lasti == -1) {
     170           0 :         PyErr_Format(PyExc_ValueError,
     171             :                      "line %d comes after the current code block",
     172             :                      new_lineno);
     173           0 :         return -1;
     174             :     }
     175             : 
     176             :     /* We're now ready to look at the bytecode. */
     177           0 :     PyString_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);
     178           0 :     min_addr = MIN(new_lasti, f->f_lasti);
     179           0 :     max_addr = MAX(new_lasti, f->f_lasti);
     180             : 
     181             :     /* You can't jump onto a line with an 'except' statement on it -
     182             :      * they expect to have an exception on the top of the stack, which
     183             :      * won't be true if you jump to them.  They always start with code
     184             :      * that either pops the exception using POP_TOP (plain 'except:'
     185             :      * lines do this) or duplicates the exception on the stack using
     186             :      * DUP_TOP (if there's an exception type specified).  See compile.c,
     187             :      * 'com_try_except' for the full details.  There aren't any other
     188             :      * cases (AFAIK) where a line's code can start with DUP_TOP or
     189             :      * POP_TOP, but if any ever appear, they'll be subject to the same
     190             :      * restriction (but with a different error message). */
     191           0 :     if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
     192           0 :         PyErr_SetString(PyExc_ValueError,
     193             :             "can't jump to 'except' line as there's no exception");
     194           0 :         return -1;
     195             :     }
     196             : 
     197             :     /* You can't jump into or out of a 'finally' block because the 'try'
     198             :      * block leaves something on the stack for the END_FINALLY to clean
     199             :      * up.      So we walk the bytecode, maintaining a simulated blockstack.
     200             :      * When we reach the old or new address and it's in a 'finally' block
     201             :      * we note the address of the corresponding SETUP_FINALLY.  The jump
     202             :      * is only legal if neither address is in a 'finally' block or
     203             :      * they're both in the same one.  'blockstack' is a stack of the
     204             :      * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
     205             :      * whether we're in a 'finally' block at each blockstack level. */
     206           0 :     f_lasti_setup_addr = -1;
     207           0 :     new_lasti_setup_addr = -1;
     208           0 :     memset(blockstack, '\0', sizeof(blockstack));
     209           0 :     memset(in_finally, '\0', sizeof(in_finally));
     210           0 :     blockstack_top = 0;
     211           0 :     for (addr = 0; addr < code_len; addr++) {
     212           0 :         unsigned char op = code[addr];
     213           0 :         switch (op) {
     214             :         case SETUP_LOOP:
     215             :         case SETUP_EXCEPT:
     216             :         case SETUP_FINALLY:
     217             :         case SETUP_WITH:
     218           0 :             blockstack[blockstack_top++] = addr;
     219           0 :             in_finally[blockstack_top-1] = 0;
     220           0 :             break;
     221             : 
     222             :         case POP_BLOCK:
     223             :             assert(blockstack_top > 0);
     224           0 :             setup_op = code[blockstack[blockstack_top-1]];
     225           0 :             if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
     226           0 :                 in_finally[blockstack_top-1] = 1;
     227             :             }
     228             :             else {
     229           0 :                 blockstack_top--;
     230             :             }
     231           0 :             break;
     232             : 
     233             :         case END_FINALLY:
     234             :             /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
     235             :              * in the bytecode but don't correspond to an actual
     236             :              * 'finally' block.  (If blockstack_top is 0, we must
     237             :              * be seeing such an END_FINALLY.) */
     238           0 :             if (blockstack_top > 0) {
     239           0 :                 setup_op = code[blockstack[blockstack_top-1]];
     240           0 :                 if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
     241           0 :                     blockstack_top--;
     242             :                 }
     243             :             }
     244           0 :             break;
     245             :         }
     246             : 
     247             :         /* For the addresses we're interested in, see whether they're
     248             :          * within a 'finally' block and if so, remember the address
     249             :          * of the SETUP_FINALLY. */
     250           0 :         if (addr == new_lasti || addr == f->f_lasti) {
     251           0 :             int i = 0;
     252           0 :             int setup_addr = -1;
     253           0 :             for (i = blockstack_top-1; i >= 0; i--) {
     254           0 :                 if (in_finally[i]) {
     255           0 :                     setup_addr = blockstack[i];
     256           0 :                     break;
     257             :                 }
     258             :             }
     259             : 
     260           0 :             if (setup_addr != -1) {
     261           0 :                 if (addr == new_lasti) {
     262           0 :                     new_lasti_setup_addr = setup_addr;
     263             :                 }
     264             : 
     265           0 :                 if (addr == f->f_lasti) {
     266           0 :                     f_lasti_setup_addr = setup_addr;
     267             :                 }
     268             :             }
     269             :         }
     270             : 
     271           0 :         if (op >= HAVE_ARGUMENT) {
     272           0 :             addr += 2;
     273             :         }
     274             :     }
     275             : 
     276             :     /* Verify that the blockstack tracking code didn't get lost. */
     277             :     assert(blockstack_top == 0);
     278             : 
     279             :     /* After all that, are we jumping into / out of a 'finally' block? */
     280           0 :     if (new_lasti_setup_addr != f_lasti_setup_addr) {
     281           0 :         PyErr_SetString(PyExc_ValueError,
     282             :                     "can't jump into or out of a 'finally' block");
     283           0 :         return -1;
     284             :     }
     285             : 
     286             : 
     287             :     /* Police block-jumping (you can't jump into the middle of a block)
     288             :      * and ensure that the blockstack finishes up in a sensible state (by
     289             :      * popping any blocks we're jumping out of).  We look at all the
     290             :      * blockstack operations between the current position and the new
     291             :      * one, and keep track of how many blocks we drop out of on the way.
     292             :      * By also keeping track of the lowest blockstack position we see, we
     293             :      * can tell whether the jump goes into any blocks without coming out
     294             :      * again - in that case we raise an exception below. */
     295           0 :     delta_iblock = 0;
     296           0 :     for (addr = min_addr; addr < max_addr; addr++) {
     297           0 :         unsigned char op = code[addr];
     298           0 :         switch (op) {
     299             :         case SETUP_LOOP:
     300             :         case SETUP_EXCEPT:
     301             :         case SETUP_FINALLY:
     302             :         case SETUP_WITH:
     303           0 :             delta_iblock++;
     304           0 :             break;
     305             : 
     306             :         case POP_BLOCK:
     307           0 :             delta_iblock--;
     308           0 :             break;
     309             :         }
     310             : 
     311           0 :         min_delta_iblock = MIN(min_delta_iblock, delta_iblock);
     312             : 
     313           0 :         if (op >= HAVE_ARGUMENT) {
     314           0 :             addr += 2;
     315             :         }
     316             :     }
     317             : 
     318             :     /* Derive the absolute iblock values from the deltas. */
     319           0 :     min_iblock = f->f_iblock + min_delta_iblock;
     320           0 :     if (new_lasti > f->f_lasti) {
     321             :         /* Forwards jump. */
     322           0 :         new_iblock = f->f_iblock + delta_iblock;
     323             :     }
     324             :     else {
     325             :         /* Backwards jump. */
     326           0 :         new_iblock = f->f_iblock - delta_iblock;
     327             :     }
     328             : 
     329             :     /* Are we jumping into a block? */
     330           0 :     if (new_iblock > min_iblock) {
     331           0 :         PyErr_SetString(PyExc_ValueError,
     332             :                         "can't jump into the middle of a block");
     333           0 :         return -1;
     334             :     }
     335             : 
     336             :     /* Pop any blocks that we're jumping out of. */
     337           0 :     while (f->f_iblock > new_iblock) {
     338           0 :         PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
     339           0 :         while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
     340           0 :             PyObject *v = (*--f->f_stacktop);
     341           0 :             Py_DECREF(v);
     342             :         }
     343             :     }
     344             : 
     345             :     /* Finally set the new f_lineno and f_lasti and return OK. */
     346           0 :     f->f_lineno = new_lineno;
     347           0 :     f->f_lasti = new_lasti;
     348           0 :     return 0;
     349             : }
     350             : 
     351             : static PyObject *
     352           0 : frame_gettrace(PyFrameObject *f, void *closure)
     353             : {
     354           0 :     PyObject* trace = f->f_trace;
     355             : 
     356           0 :     if (trace == NULL)
     357           0 :         trace = Py_None;
     358             : 
     359           0 :     Py_INCREF(trace);
     360             : 
     361           0 :     return trace;
     362             : }
     363             : 
     364             : static int
     365           0 : frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
     366             : {
     367             :     /* We rely on f_lineno being accurate when f_trace is set. */
     368           0 :     f->f_lineno = PyFrame_GetLineNumber(f);
     369             : 
     370           0 :     if (v == Py_None)
     371           0 :         v = NULL;
     372           0 :     Py_XINCREF(v);
     373           0 :     Py_XSETREF(f->f_trace, v);
     374             : 
     375           0 :     return 0;
     376             : }
     377             : 
     378             : static PyObject *
     379           0 : frame_getrestricted(PyFrameObject *f, void *closure)
     380             : {
     381           0 :     return PyBool_FromLong(PyFrame_IsRestricted(f));
     382             : }
     383             : 
     384             : static PyGetSetDef frame_getsetlist[] = {
     385             :     {"f_locals",        (getter)frame_getlocals, NULL, NULL},
     386             :     {"f_lineno",        (getter)frame_getlineno,
     387             :                     (setter)frame_setlineno, NULL},
     388             :     {"f_trace",         (getter)frame_gettrace, (setter)frame_settrace, NULL},
     389             :     {"f_restricted",(getter)frame_getrestricted,NULL, NULL},
     390             :     {"f_exc_traceback", (getter)frame_get_f_exc_traceback,
     391             :                     (setter)frame_set_f_exc_traceback, NULL},
     392             :     {"f_exc_type",  (getter)frame_get_f_exc_type,
     393             :                     (setter)frame_set_f_exc_type, NULL},
     394             :     {"f_exc_value", (getter)frame_get_f_exc_value,
     395             :                     (setter)frame_set_f_exc_value, NULL},
     396             :     {0}
     397             : };
     398             : 
     399             : /* Stack frames are allocated and deallocated at a considerable rate.
     400             :    In an attempt to improve the speed of function calls, we:
     401             : 
     402             :    1. Hold a single "zombie" frame on each code object. This retains
     403             :    the allocated and initialised frame object from an invocation of
     404             :    the code object. The zombie is reanimated the next time we need a
     405             :    frame object for that code object. Doing this saves the malloc/
     406             :    realloc required when using a free_list frame that isn't the
     407             :    correct size. It also saves some field initialisation.
     408             : 
     409             :    In zombie mode, no field of PyFrameObject holds a reference, but
     410             :    the following fields are still valid:
     411             : 
     412             :      * ob_type, ob_size, f_code, f_valuestack;
     413             : 
     414             :      * f_locals, f_trace,
     415             :        f_exc_type, f_exc_value, f_exc_traceback are NULL;
     416             : 
     417             :      * f_localsplus does not require re-allocation and
     418             :        the local variables in f_localsplus are NULL.
     419             : 
     420             :    2. We also maintain a separate free list of stack frames (just like
     421             :    integers are allocated in a special way -- see intobject.c).  When
     422             :    a stack frame is on the free list, only the following members have
     423             :    a meaning:
     424             :     ob_type             == &Frametype
     425             :     f_back              next item on free list, or NULL
     426             :     f_stacksize         size of value stack
     427             :     ob_size             size of localsplus
     428             :    Note that the value and block stacks are preserved -- this can save
     429             :    another malloc() call or two (and two free() calls as well!).
     430             :    Also note that, unlike for integers, each frame object is a
     431             :    malloc'ed object in its own right -- it is only the actual calls to
     432             :    malloc() that we are trying to save here, not the administration.
     433             :    After all, while a typical program may make millions of calls, a
     434             :    call depth of more than 20 or 30 is probably already exceptional
     435             :    unless the program contains run-away recursion.  I hope.
     436             : 
     437             :    Later, PyFrame_MAXFREELIST was added to bound the # of frames saved on
     438             :    free_list.  Else programs creating lots of cyclic trash involving
     439             :    frames could provoke free_list into growing without bound.
     440             : */
     441             : 
     442             : static PyFrameObject *free_list = NULL;
     443             : static int numfree = 0;         /* number of frames currently in free_list */
     444             : /* max value for numfree */
     445             : #define PyFrame_MAXFREELIST 200
     446             : 
     447             : static void
     448       85361 : frame_dealloc(PyFrameObject *f)
     449             : {
     450             :     PyObject **p, **valuestack;
     451             :     PyCodeObject *co;
     452             : 
     453       85361 :     PyObject_GC_UnTrack(f);
     454       85361 :     Py_TRASHCAN_SAFE_BEGIN(f)
     455             :     /* Kill all local variables */
     456       85361 :     valuestack = f->f_valuestack;
     457      479630 :     for (p = f->f_localsplus; p < valuestack; p++)
     458      394269 :         Py_CLEAR(*p);
     459             : 
     460             :     /* Free stack */
     461       85361 :     if (f->f_stacktop != NULL) {
     462           0 :         for (p = valuestack; p < f->f_stacktop; p++)
     463           0 :             Py_XDECREF(*p);
     464             :     }
     465             : 
     466       85361 :     Py_XDECREF(f->f_back);
     467       85361 :     Py_DECREF(f->f_builtins);
     468       85361 :     Py_DECREF(f->f_globals);
     469       85361 :     Py_CLEAR(f->f_locals);
     470       85361 :     Py_CLEAR(f->f_trace);
     471       85361 :     Py_CLEAR(f->f_exc_type);
     472       85361 :     Py_CLEAR(f->f_exc_value);
     473       85361 :     Py_CLEAR(f->f_exc_traceback);
     474             : 
     475       85361 :     co = f->f_code;
     476       85361 :     if (co->co_zombieframe == NULL)
     477       83205 :         co->co_zombieframe = f;
     478        2156 :     else if (numfree < PyFrame_MAXFREELIST) {
     479        2156 :         ++numfree;
     480        2156 :         f->f_back = free_list;
     481        2156 :         free_list = f;
     482             :     }
     483             :     else
     484           0 :         PyObject_GC_Del(f);
     485             : 
     486       85361 :     Py_DECREF(co);
     487       85361 :     Py_TRASHCAN_SAFE_END(f)
     488       85361 : }
     489             : 
     490             : static int
     491         538 : frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
     492             : {
     493             :     PyObject **fastlocals, **p;
     494             :     int i, slots;
     495             : 
     496         538 :     Py_VISIT(f->f_back);
     497         538 :     Py_VISIT(f->f_code);
     498         538 :     Py_VISIT(f->f_builtins);
     499         538 :     Py_VISIT(f->f_globals);
     500         538 :     Py_VISIT(f->f_locals);
     501         538 :     Py_VISIT(f->f_trace);
     502         538 :     Py_VISIT(f->f_exc_type);
     503         538 :     Py_VISIT(f->f_exc_value);
     504         538 :     Py_VISIT(f->f_exc_traceback);
     505             : 
     506             :     /* locals */
     507         538 :     slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
     508         538 :     fastlocals = f->f_localsplus;
     509        3752 :     for (i = slots; --i >= 0; ++fastlocals)
     510        3214 :         Py_VISIT(*fastlocals);
     511             : 
     512             :     /* stack */
     513         538 :     if (f->f_stacktop != NULL) {
     514          18 :         for (p = f->f_valuestack; p < f->f_stacktop; p++)
     515          12 :             Py_VISIT(*p);
     516             :     }
     517         538 :     return 0;
     518             : }
     519             : 
     520             : static void
     521           0 : frame_clear(PyFrameObject *f)
     522             : {
     523             :     PyObject **fastlocals, **p, **oldtop;
     524             :     int i, slots;
     525             : 
     526             :     /* Before anything else, make sure that this frame is clearly marked
     527             :      * as being defunct!  Else, e.g., a generator reachable from this
     528             :      * frame may also point to this frame, believe itself to still be
     529             :      * active, and try cleaning up this frame again.
     530             :      */
     531           0 :     oldtop = f->f_stacktop;
     532           0 :     f->f_stacktop = NULL;
     533             : 
     534           0 :     Py_CLEAR(f->f_exc_type);
     535           0 :     Py_CLEAR(f->f_exc_value);
     536           0 :     Py_CLEAR(f->f_exc_traceback);
     537           0 :     Py_CLEAR(f->f_trace);
     538             : 
     539             :     /* locals */
     540           0 :     slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
     541           0 :     fastlocals = f->f_localsplus;
     542           0 :     for (i = slots; --i >= 0; ++fastlocals)
     543           0 :         Py_CLEAR(*fastlocals);
     544             : 
     545             :     /* stack */
     546           0 :     if (oldtop != NULL) {
     547           0 :         for (p = f->f_valuestack; p < oldtop; p++)
     548           0 :             Py_CLEAR(*p);
     549             :     }
     550           0 : }
     551             : 
     552             : static PyObject *
     553           0 : frame_sizeof(PyFrameObject *f)
     554             : {
     555             :     Py_ssize_t res, extras, ncells, nfrees;
     556             : 
     557           0 :     ncells = PyTuple_GET_SIZE(f->f_code->co_cellvars);
     558           0 :     nfrees = PyTuple_GET_SIZE(f->f_code->co_freevars);
     559           0 :     extras = f->f_code->co_stacksize + f->f_code->co_nlocals +
     560             :              ncells + nfrees;
     561             :     /* subtract one as it is already included in PyFrameObject */
     562           0 :     res = sizeof(PyFrameObject) + (extras-1) * sizeof(PyObject *);
     563             : 
     564           0 :     return PyInt_FromSsize_t(res);
     565             : }
     566             : 
     567             : PyDoc_STRVAR(sizeof__doc__,
     568             : "F.__sizeof__() -> size of F in memory, in bytes");
     569             : 
     570             : static PyMethodDef frame_methods[] = {
     571             :     {"__sizeof__",      (PyCFunction)frame_sizeof,      METH_NOARGS,
     572             :      sizeof__doc__},
     573             :     {NULL,              NULL}   /* sentinel */
     574             : };
     575             : 
     576             : PyTypeObject PyFrame_Type = {
     577             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     578             :     "frame",
     579             :     sizeof(PyFrameObject),
     580             :     sizeof(PyObject *),
     581             :     (destructor)frame_dealloc,                  /* tp_dealloc */
     582             :     0,                                          /* tp_print */
     583             :     0,                                          /* tp_getattr */
     584             :     0,                                          /* tp_setattr */
     585             :     0,                                          /* tp_compare */
     586             :     0,                                          /* tp_repr */
     587             :     0,                                          /* tp_as_number */
     588             :     0,                                          /* tp_as_sequence */
     589             :     0,                                          /* tp_as_mapping */
     590             :     0,                                          /* tp_hash */
     591             :     0,                                          /* tp_call */
     592             :     0,                                          /* tp_str */
     593             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     594             :     PyObject_GenericSetAttr,                    /* tp_setattro */
     595             :     0,                                          /* tp_as_buffer */
     596             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
     597             :     0,                                          /* tp_doc */
     598             :     (traverseproc)frame_traverse,               /* tp_traverse */
     599             :     (inquiry)frame_clear,                       /* tp_clear */
     600             :     0,                                          /* tp_richcompare */
     601             :     0,                                          /* tp_weaklistoffset */
     602             :     0,                                          /* tp_iter */
     603             :     0,                                          /* tp_iternext */
     604             :     frame_methods,                              /* tp_methods */
     605             :     frame_memberlist,                           /* tp_members */
     606             :     frame_getsetlist,                           /* tp_getset */
     607             :     0,                                          /* tp_base */
     608             :     0,                                          /* tp_dict */
     609             : };
     610             : 
     611             : static PyObject *builtin_object;
     612             : 
     613           3 : int _PyFrame_Init()
     614             : {
     615           3 :     builtin_object = PyString_InternFromString("__builtins__");
     616           3 :     if (builtin_object == NULL)
     617           0 :         return 0;
     618           3 :     return 1;
     619             : }
     620             : 
     621             : PyFrameObject *
     622       85361 : PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
     623             :             PyObject *locals)
     624             : {
     625       85361 :     PyFrameObject *back = tstate->frame;
     626             :     PyFrameObject *f;
     627             :     PyObject *builtins;
     628             :     Py_ssize_t i;
     629             : 
     630             : #ifdef Py_DEBUG
     631             :     if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
     632             :         (locals != NULL && !PyMapping_Check(locals))) {
     633             :         PyErr_BadInternalCall();
     634             :         return NULL;
     635             :     }
     636             : #endif
     637       85361 :     if (back == NULL || back->f_globals != globals) {
     638       17092 :         builtins = PyDict_GetItem(globals, builtin_object);
     639       17092 :         if (builtins) {
     640       17092 :             if (PyModule_Check(builtins)) {
     641           3 :                 builtins = PyModule_GetDict(builtins);
     642           3 :                 assert(!builtins || PyDict_Check(builtins));
     643             :             }
     644       17089 :             else if (!PyDict_Check(builtins))
     645           0 :                 builtins = NULL;
     646             :         }
     647       34184 :         if (builtins == NULL) {
     648             :             /* No builtins!              Make up a minimal one
     649             :                Give them 'None', at least. */
     650           0 :             builtins = PyDict_New();
     651           0 :             if (builtins == NULL ||
     652           0 :                 PyDict_SetItemString(
     653             :                     builtins, "None", Py_None) < 0)
     654           0 :                 return NULL;
     655             :         }
     656             :         else
     657       17092 :             Py_INCREF(builtins);
     658             : 
     659             :     }
     660             :     else {
     661             :         /* If we share the globals, we share the builtins.
     662             :            Save a lookup and a call. */
     663       68269 :         builtins = back->f_builtins;
     664             :         assert(builtins != NULL && PyDict_Check(builtins));
     665       68269 :         Py_INCREF(builtins);
     666             :     }
     667       85361 :     if (code->co_zombieframe != NULL) {
     668       81111 :         f = code->co_zombieframe;
     669       81111 :         code->co_zombieframe = NULL;
     670       81111 :         _Py_NewReference((PyObject *)f);
     671             :         assert(f->f_code == code);
     672             :     }
     673             :     else {
     674             :         Py_ssize_t extras, ncells, nfrees;
     675        4250 :         ncells = PyTuple_GET_SIZE(code->co_cellvars);
     676        4250 :         nfrees = PyTuple_GET_SIZE(code->co_freevars);
     677        4250 :         extras = code->co_stacksize + code->co_nlocals + ncells +
     678             :             nfrees;
     679        4250 :         if (free_list == NULL) {
     680        2094 :             f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type,
     681             :             extras);
     682        2094 :             if (f == NULL) {
     683           0 :                 Py_DECREF(builtins);
     684           0 :                 return NULL;
     685             :             }
     686             :         }
     687             :         else {
     688             :             assert(numfree > 0);
     689        2156 :             --numfree;
     690        2156 :             f = free_list;
     691        2156 :             free_list = free_list->f_back;
     692        2156 :             if (Py_SIZE(f) < extras) {
     693         137 :                 f = PyObject_GC_Resize(PyFrameObject, f, extras);
     694         137 :                 if (f == NULL) {
     695           0 :                     Py_DECREF(builtins);
     696           0 :                     return NULL;
     697             :                 }
     698             :             }
     699        2156 :             _Py_NewReference((PyObject *)f);
     700             :         }
     701             : 
     702        4250 :         f->f_code = code;
     703        4250 :         extras = code->co_nlocals + ncells + nfrees;
     704        4250 :         f->f_valuestack = f->f_localsplus + extras;
     705       42848 :         for (i=0; i<extras; i++)
     706       38598 :             f->f_localsplus[i] = NULL;
     707        4250 :         f->f_locals = NULL;
     708        4250 :         f->f_trace = NULL;
     709        4250 :         f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
     710             :     }
     711       85361 :     f->f_stacktop = f->f_valuestack;
     712       85361 :     f->f_builtins = builtins;
     713       85361 :     Py_XINCREF(back);
     714       85361 :     f->f_back = back;
     715       85361 :     Py_INCREF(code);
     716       85361 :     Py_INCREF(globals);
     717       85361 :     f->f_globals = globals;
     718             :     /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */
     719       85361 :     if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
     720             :         (CO_NEWLOCALS | CO_OPTIMIZED))
     721             :         ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */
     722        1023 :     else if (code->co_flags & CO_NEWLOCALS) {
     723         729 :         locals = PyDict_New();
     724         729 :         if (locals == NULL) {
     725           0 :             Py_DECREF(f);
     726           0 :             return NULL;
     727             :         }
     728         729 :         f->f_locals = locals;
     729             :     }
     730             :     else {
     731         294 :         if (locals == NULL)
     732           0 :             locals = globals;
     733         294 :         Py_INCREF(locals);
     734         294 :         f->f_locals = locals;
     735             :     }
     736       85361 :     f->f_tstate = tstate;
     737             : 
     738       85361 :     f->f_lasti = -1;
     739       85361 :     f->f_lineno = code->co_firstlineno;
     740       85361 :     f->f_iblock = 0;
     741             : 
     742       85361 :     _PyObject_GC_TRACK(f);
     743       85361 :     return f;
     744             : }
     745             : 
     746             : /* Block management */
     747             : 
     748             : void
     749       35339 : PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
     750             : {
     751             :     PyTryBlock *b;
     752       35339 :     if (f->f_iblock >= CO_MAXBLOCKS)
     753           0 :         Py_FatalError("XXX block stack overflow");
     754       35339 :     b = &f->f_blockstack[f->f_iblock++];
     755       35339 :     b->b_type = type;
     756       35339 :     b->b_level = level;
     757       35339 :     b->b_handler = handler;
     758       35339 : }
     759             : 
     760             : PyTryBlock *
     761       23629 : PyFrame_BlockPop(PyFrameObject *f)
     762             : {
     763             :     PyTryBlock *b;
     764       23629 :     if (f->f_iblock <= 0)
     765           0 :         Py_FatalError("XXX block stack underflow");
     766       23629 :     b = &f->f_blockstack[--f->f_iblock];
     767       23629 :     return b;
     768             : }
     769             : 
     770             : /* Convert between "fast" version of locals and dictionary version.
     771             : 
     772             :    map and values are input arguments.  map is a tuple of strings.
     773             :    values is an array of PyObject*.  At index i, map[i] is the name of
     774             :    the variable with value values[i].  The function copies the first
     775             :    nmap variable from map/values into dict.  If values[i] is NULL,
     776             :    the variable is deleted from dict.
     777             : 
     778             :    If deref is true, then the values being copied are cell variables
     779             :    and the value is extracted from the cell variable before being put
     780             :    in dict.
     781             : 
     782             :    Exceptions raised while modifying the dict are silently ignored,
     783             :    because there is no good way to report them.
     784             :  */
     785             : 
     786             : static void
     787           0 : map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
     788             :             int deref)
     789             : {
     790             :     Py_ssize_t j;
     791             :     assert(PyTuple_Check(map));
     792             :     assert(PyDict_Check(dict));
     793             :     assert(PyTuple_Size(map) >= nmap);
     794           0 :     for (j = nmap; --j >= 0; ) {
     795           0 :         PyObject *key = PyTuple_GET_ITEM(map, j);
     796           0 :         PyObject *value = values[j];
     797             :         assert(PyString_Check(key));
     798           0 :         if (deref) {
     799             :             assert(PyCell_Check(value));
     800           0 :             value = PyCell_GET(value);
     801             :         }
     802           0 :         if (value == NULL) {
     803           0 :             if (PyObject_DelItem(dict, key) != 0)
     804           0 :                 PyErr_Clear();
     805             :         }
     806             :         else {
     807           0 :             if (PyObject_SetItem(dict, key, value) != 0)
     808           0 :                 PyErr_Clear();
     809             :         }
     810             :     }
     811           0 : }
     812             : 
     813             : /* Copy values from the "locals" dict into the fast locals.
     814             : 
     815             :    dict is an input argument containing string keys representing
     816             :    variables names and arbitrary PyObject* as values.
     817             : 
     818             :    map and values are input arguments.  map is a tuple of strings.
     819             :    values is an array of PyObject*.  At index i, map[i] is the name of
     820             :    the variable with value values[i].  The function copies the first
     821             :    nmap variable from map/values into dict.  If values[i] is NULL,
     822             :    the variable is deleted from dict.
     823             : 
     824             :    If deref is true, then the values being copied are cell variables
     825             :    and the value is extracted from the cell variable before being put
     826             :    in dict.  If clear is true, then variables in map but not in dict
     827             :    are set to NULL in map; if clear is false, variables missing in
     828             :    dict are ignored.
     829             : 
     830             :    Exceptions raised while modifying the dict are silently ignored,
     831             :    because there is no good way to report them.
     832             : */
     833             : 
     834             : static void
     835           0 : dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
     836             :             int deref, int clear)
     837             : {
     838             :     Py_ssize_t j;
     839             :     assert(PyTuple_Check(map));
     840             :     assert(PyDict_Check(dict));
     841             :     assert(PyTuple_Size(map) >= nmap);
     842           0 :     for (j = nmap; --j >= 0; ) {
     843           0 :         PyObject *key = PyTuple_GET_ITEM(map, j);
     844           0 :         PyObject *value = PyObject_GetItem(dict, key);
     845             :         assert(PyString_Check(key));
     846             :         /* We only care about NULLs if clear is true. */
     847           0 :         if (value == NULL) {
     848           0 :             PyErr_Clear();
     849           0 :             if (!clear)
     850           0 :                 continue;
     851             :         }
     852           0 :         if (deref) {
     853             :             assert(PyCell_Check(values[j]));
     854           0 :             if (PyCell_GET(values[j]) != value) {
     855           0 :                 if (PyCell_Set(values[j], value) < 0)
     856           0 :                     PyErr_Clear();
     857             :             }
     858           0 :         } else if (values[j] != value) {
     859           0 :             Py_XINCREF(value);
     860           0 :             Py_XSETREF(values[j], value);
     861             :         }
     862           0 :         Py_XDECREF(value);
     863             :     }
     864           0 : }
     865             : 
     866             : void
     867          33 : PyFrame_FastToLocals(PyFrameObject *f)
     868             : {
     869             :     /* Merge fast locals into f->f_locals */
     870             :     PyObject *locals, *map;
     871             :     PyObject **fast;
     872             :     PyObject *error_type, *error_value, *error_traceback;
     873             :     PyCodeObject *co;
     874             :     Py_ssize_t j;
     875             :     int ncells, nfreevars;
     876          33 :     if (f == NULL)
     877           0 :         return;
     878          33 :     locals = f->f_locals;
     879          33 :     if (locals == NULL) {
     880           0 :         locals = f->f_locals = PyDict_New();
     881           0 :         if (locals == NULL) {
     882           0 :             PyErr_Clear(); /* Can't report it :-( */
     883           0 :             return;
     884             :         }
     885             :     }
     886          33 :     co = f->f_code;
     887          33 :     map = co->co_varnames;
     888          33 :     if (!PyTuple_Check(map))
     889           0 :         return;
     890          33 :     PyErr_Fetch(&error_type, &error_value, &error_traceback);
     891          33 :     fast = f->f_localsplus;
     892          33 :     j = PyTuple_GET_SIZE(map);
     893          33 :     if (j > co->co_nlocals)
     894           0 :         j = co->co_nlocals;
     895          33 :     if (co->co_nlocals)
     896           0 :         map_to_dict(map, j, locals, fast, 0);
     897          33 :     ncells = PyTuple_GET_SIZE(co->co_cellvars);
     898          33 :     nfreevars = PyTuple_GET_SIZE(co->co_freevars);
     899          33 :     if (ncells || nfreevars) {
     900           0 :         map_to_dict(co->co_cellvars, ncells,
     901           0 :                     locals, fast + co->co_nlocals, 1);
     902             :         /* If the namespace is unoptimized, then one of the
     903             :            following cases applies:
     904             :            1. It does not contain free variables, because it
     905             :               uses import * or is a top-level namespace.
     906             :            2. It is a class namespace.
     907             :            We don't want to accidentally copy free variables
     908             :            into the locals dict used by the class.
     909             :         */
     910           0 :         if (co->co_flags & CO_OPTIMIZED) {
     911           0 :             map_to_dict(co->co_freevars, nfreevars,
     912           0 :                         locals, fast + co->co_nlocals + ncells, 1);
     913             :         }
     914             :     }
     915          33 :     PyErr_Restore(error_type, error_value, error_traceback);
     916             : }
     917             : 
     918             : void
     919          33 : PyFrame_LocalsToFast(PyFrameObject *f, int clear)
     920             : {
     921             :     /* Merge f->f_locals into fast locals */
     922             :     PyObject *locals, *map;
     923             :     PyObject **fast;
     924             :     PyObject *error_type, *error_value, *error_traceback;
     925             :     PyCodeObject *co;
     926             :     Py_ssize_t j;
     927             :     int ncells, nfreevars;
     928          33 :     if (f == NULL)
     929           0 :         return;
     930          33 :     locals = f->f_locals;
     931          33 :     co = f->f_code;
     932          33 :     map = co->co_varnames;
     933          33 :     if (locals == NULL)
     934           0 :         return;
     935          33 :     if (!PyTuple_Check(map))
     936           0 :         return;
     937          33 :     PyErr_Fetch(&error_type, &error_value, &error_traceback);
     938          33 :     fast = f->f_localsplus;
     939          33 :     j = PyTuple_GET_SIZE(map);
     940          33 :     if (j > co->co_nlocals)
     941           0 :         j = co->co_nlocals;
     942          33 :     if (co->co_nlocals)
     943           0 :         dict_to_map(co->co_varnames, j, locals, fast, 0, clear);
     944          33 :     ncells = PyTuple_GET_SIZE(co->co_cellvars);
     945          33 :     nfreevars = PyTuple_GET_SIZE(co->co_freevars);
     946          33 :     if (ncells || nfreevars) {
     947           0 :         dict_to_map(co->co_cellvars, ncells,
     948           0 :                     locals, fast + co->co_nlocals, 1, clear);
     949             :         /* Same test as in PyFrame_FastToLocals() above. */
     950           0 :         if (co->co_flags & CO_OPTIMIZED) {
     951           0 :             dict_to_map(co->co_freevars, nfreevars,
     952           0 :                 locals, fast + co->co_nlocals + ncells, 1,
     953             :                 clear);
     954             :         }
     955             :     }
     956          33 :     PyErr_Restore(error_type, error_value, error_traceback);
     957             : }
     958             : 
     959             : /* Clear out the free list */
     960             : int
     961           6 : PyFrame_ClearFreeList(void)
     962             : {
     963           6 :     int freelist_size = numfree;
     964             : 
     965          12 :     while (free_list != NULL) {
     966           0 :         PyFrameObject *f = free_list;
     967           0 :         free_list = free_list->f_back;
     968           0 :         PyObject_GC_Del(f);
     969           0 :         --numfree;
     970             :     }
     971             :     assert(numfree == 0);
     972           6 :     return freelist_size;
     973             : }
     974             : 
     975             : void
     976           3 : PyFrame_Fini(void)
     977             : {
     978           3 :     (void)PyFrame_ClearFreeList();
     979           3 :     Py_XDECREF(builtin_object);
     980           3 :     builtin_object = NULL;
     981           3 : }

Generated by: LCOV version 1.10