LCOV - code coverage report
Current view: top level - Python - frame.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 59 61 96.7 %
Date: 2022-07-20 13:12:14 Functions: 6 6 100.0 %
Branches: 31 40 77.5 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : #define _PY_INTERPRETER
       3                 :            : 
       4                 :            : #include "Python.h"
       5                 :            : #include "frameobject.h"
       6                 :            : #include "pycore_code.h"          // stats
       7                 :            : #include "pycore_frame.h"
       8                 :            : #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
       9                 :            : #include "opcode.h"
      10                 :            : 
      11                 :            : int
      12                 :     537645 : _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg)
      13                 :            : {
      14   [ +  +  -  + ]:     537645 :     Py_VISIT(frame->frame_obj);
      15   [ +  +  -  + ]:     537645 :     Py_VISIT(frame->f_locals);
      16   [ +  -  +  + ]:     537645 :     Py_VISIT(frame->f_func);
      17   [ +  -  -  + ]:     537644 :     Py_VISIT(frame->f_code);
      18                 :            :    /* locals */
      19                 :     537644 :     PyObject **locals = _PyFrame_GetLocalsArray(frame);
      20                 :     537644 :     int i = 0;
      21                 :            :     /* locals and stack */
      22         [ +  + ]:    4709289 :     for (; i <frame->stacktop; i++) {
      23   [ +  +  -  + ]:    4171645 :         Py_VISIT(locals[i]);
      24                 :            :     }
      25                 :     537644 :     return 0;
      26                 :            : }
      27                 :            : 
      28                 :            : PyFrameObject *
      29                 :    5183741 : _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
      30                 :            : {
      31                 :            :     assert(frame->frame_obj == NULL);
      32                 :            :     PyObject *error_type, *error_value, *error_traceback;
      33                 :    5183741 :     PyErr_Fetch(&error_type, &error_value, &error_traceback);
      34                 :            : 
      35                 :    5183741 :     PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
      36         [ +  + ]:    5183741 :     if (f == NULL) {
      37                 :         38 :         Py_XDECREF(error_type);
      38                 :         38 :         Py_XDECREF(error_value);
      39                 :         38 :         Py_XDECREF(error_traceback);
      40                 :            :     }
      41                 :            :     else {
      42                 :            :         assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
      43                 :            :         assert(frame->owner != FRAME_CLEARED);
      44                 :    5183703 :         f->f_frame = frame;
      45                 :    5183703 :         frame->frame_obj = f;
      46                 :    5183703 :         PyErr_Restore(error_type, error_value, error_traceback);
      47                 :            :     }
      48                 :    5183741 :     return f;
      49                 :            : }
      50                 :            : 
      51                 :            : void
      52                 :   17063267 : _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
      53                 :            : {
      54                 :            :     assert(src->stacktop >= src->f_code->co_nlocalsplus);
      55                 :   17063267 :     Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src;
      56                 :   17063267 :     memcpy(dest, src, size);
      57                 :   17063267 : }
      58                 :            : 
      59                 :            : 
      60                 :            : static void
      61                 :    1718859 : take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
      62                 :            : {
      63                 :            :     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
      64                 :            :     assert(frame->owner != FRAME_CLEARED);
      65                 :    1718859 :     Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
      66                 :    1718859 :     memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
      67                 :    1718859 :     frame = (_PyInterpreterFrame *)f->_f_frame_data;
      68                 :    1718859 :     f->f_frame = frame;
      69                 :    1718859 :     frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
      70                 :            :     assert(f->f_back == NULL);
      71                 :    1718859 :     _PyInterpreterFrame *prev = frame->previous;
      72   [ +  +  -  + ]:    1718859 :     while (prev && _PyFrame_IsIncomplete(prev)) {
      73                 :          0 :         prev = prev->previous;
      74                 :            :     }
      75         [ +  + ]:    1718859 :     if (prev) {
      76                 :            :         /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */
      77                 :    1096452 :         PyFrameObject *back = _PyFrame_GetFrameObject(prev);
      78         [ -  + ]:    1096452 :         if (back == NULL) {
      79                 :            :             /* Memory error here. */
      80                 :            :             assert(PyErr_ExceptionMatches(PyExc_MemoryError));
      81                 :            :             /* Nothing we can do about it */
      82                 :          0 :             PyErr_Clear();
      83                 :            :         }
      84                 :            :         else {
      85                 :    1096452 :             f->f_back = (PyFrameObject *)Py_NewRef(back);
      86                 :            :         }
      87                 :    1096452 :         frame->previous = NULL;
      88                 :            :     }
      89         [ +  - ]:    1718859 :     if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) {
      90                 :    1718859 :         _PyObject_GC_TRACK((PyObject *)f);
      91                 :            :     }
      92                 :    1718859 : }
      93                 :            : 
      94                 :            : void
      95                 :  271114129 : _PyFrame_Clear(_PyInterpreterFrame *frame)
      96                 :            : {
      97                 :            :     /* It is the responsibility of the owning generator/coroutine
      98                 :            :      * to have cleared the enclosing generator, if any. */
      99                 :            :     assert(frame->owner != FRAME_OWNED_BY_GENERATOR ||
     100                 :            :         _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
     101         [ +  + ]:  271114129 :     if (frame->frame_obj) {
     102                 :    5183671 :         PyFrameObject *f = frame->frame_obj;
     103                 :    5183671 :         frame->frame_obj = NULL;
     104         [ +  + ]:    5183671 :         if (Py_REFCNT(f) > 1) {
     105                 :    1718859 :             take_ownership(f, frame);
     106                 :    1718859 :             Py_DECREF(f);
     107                 :    1718859 :             return;
     108                 :            :         }
     109                 :    3464812 :         Py_DECREF(f);
     110                 :            :     }
     111                 :            :     assert(frame->stacktop >= 0);
     112         [ +  + ]: 1375082284 :     for (int i = 0; i < frame->stacktop; i++) {
     113                 : 1105687014 :         Py_XDECREF(frame->localsplus[i]);
     114                 :            :     }
     115                 :  269395270 :     Py_XDECREF(frame->frame_obj);
     116                 :  269395270 :     Py_XDECREF(frame->f_locals);
     117                 :  269395270 :     Py_DECREF(frame->f_func);
     118                 :  269395270 :     Py_DECREF(frame->f_code);
     119                 :            : }
     120                 :            : 
     121                 :            : int
     122                 :   11008745 : _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame)
     123                 :            : {
     124                 :   11008745 :     int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
     125                 :   11008745 :     return PyCode_Addr2Line(frame->f_code, addr);
     126                 :            : }

Generated by: LCOV version 1.14