LCOV - code coverage report
Current view: top level - Python - frame.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 68 71 95.8 %
Date: 2022-07-07 18:19:46 Functions: 6 6 100.0 %

          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      537424 : _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg)
      13             : {
      14      537424 :     Py_VISIT(frame->frame_obj);
      15      537424 :     Py_VISIT(frame->f_locals);
      16      537424 :     Py_VISIT(frame->f_func);
      17      537423 :     Py_VISIT(frame->f_code);
      18             :    /* locals */
      19      537423 :     PyObject **locals = _PyFrame_GetLocalsArray(frame);
      20      537423 :     int i = 0;
      21             :     /* locals and stack */
      22     4655340 :     for (; i <frame->stacktop; i++) {
      23     4117920 :         Py_VISIT(locals[i]);
      24             :     }
      25      537423 :     return 0;
      26             : }
      27             : 
      28             : PyFrameObject *
      29     5185450 : _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
      30             : {
      31     5185450 :     assert(frame->frame_obj == NULL);
      32             :     PyObject *error_type, *error_value, *error_traceback;
      33     5185450 :     PyErr_Fetch(&error_type, &error_value, &error_traceback);
      34             : 
      35     5185450 :     PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
      36     5185450 :     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     5185410 :         assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
      43     5185410 :         assert(frame->owner != FRAME_CLEARED);
      44     5185410 :         f->f_frame = frame;
      45     5185410 :         frame->frame_obj = f;
      46     5185410 :         PyErr_Restore(error_type, error_value, error_traceback);
      47             :     }
      48     5185450 :     return f;
      49             : }
      50             : 
      51             : void
      52    17186100 : _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
      53             : {
      54    17186100 :     assert(src->stacktop >= src->f_code->co_nlocalsplus);
      55    17186100 :     Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src;
      56    17186100 :     memcpy(dest, src, size);
      57    17186100 : }
      58             : 
      59             : 
      60             : static void
      61     1715610 : take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
      62             : {
      63     1715610 :     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
      64     1715610 :     assert(frame->owner != FRAME_CLEARED);
      65     1715610 :     Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
      66     1715610 :     memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
      67     1715610 :     frame = (_PyInterpreterFrame *)f->_f_frame_data;
      68     1715610 :     f->f_frame = frame;
      69     1715610 :     frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
      70     1715610 :     assert(f->f_back == NULL);
      71     1715610 :     _PyInterpreterFrame *prev = frame->previous;
      72     1715610 :     while (prev && _PyFrame_IsIncomplete(prev)) {
      73           0 :         prev = prev->previous;
      74             :     }
      75     1715610 :     if (prev) {
      76             :         /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */
      77     1100730 :         PyFrameObject *back = _PyFrame_GetFrameObject(prev);
      78     1100730 :         if (back == NULL) {
      79             :             /* Memory error here. */
      80           0 :             assert(PyErr_ExceptionMatches(PyExc_MemoryError));
      81             :             /* Nothing we can do about it */
      82           0 :             PyErr_Clear();
      83             :         }
      84             :         else {
      85     1100730 :             f->f_back = (PyFrameObject *)Py_NewRef(back);
      86             :         }
      87     1100730 :         frame->previous = NULL;
      88             :     }
      89     1715610 :     if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) {
      90     1715610 :         _PyObject_GC_TRACK((PyObject *)f);
      91             :     }
      92     1715610 : }
      93             : 
      94             : void
      95   274560000 : _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   274560000 :     assert(frame->owner != FRAME_OWNED_BY_GENERATOR ||
     100             :         _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
     101   274560000 :     if (frame->frame_obj) {
     102     5185380 :         PyFrameObject *f = frame->frame_obj;
     103     5185380 :         frame->frame_obj = NULL;
     104     5185380 :         if (Py_REFCNT(f) > 1) {
     105     1715610 :             take_ownership(f, frame);
     106     1715610 :             Py_DECREF(f);
     107     1715610 :             return;
     108             :         }
     109     3469770 :         Py_DECREF(f);
     110             :     }
     111   272845000 :     assert(frame->stacktop >= 0);
     112  1383780000 :     for (int i = 0; i < frame->stacktop; i++) {
     113  1110940000 :         Py_XDECREF(frame->localsplus[i]);
     114             :     }
     115   272845000 :     Py_XDECREF(frame->frame_obj);
     116   272845000 :     Py_XDECREF(frame->f_locals);
     117   272845000 :     Py_DECREF(frame->f_func);
     118   272845000 :     Py_DECREF(frame->f_code);
     119             : }
     120             : 
     121             : int
     122    13170800 : _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame)
     123             : {
     124    13170800 :     int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
     125    13170800 :     return PyCode_Addr2Line(frame->f_code, addr);
     126             : }

Generated by: LCOV version 1.14