LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - frameobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 149 395 37.7 %
Date: 2012-12-17 Functions: 9 21 42.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10