Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Python/frame.c
Line
Count
Source (jump to first uncovered line)
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
_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg)
13
{
14
    Py_VISIT(frame->frame_obj);
15
    Py_VISIT(frame->f_locals);
16
    Py_VISIT(frame->f_func);
17
    Py_VISIT(frame->f_code);
18
   /* locals */
19
    PyObject **locals = _PyFrame_GetLocalsArray(frame);
20
    int i = 0;
21
    /* locals and stack */
22
    for (; i <frame->stacktop; 
i++10.4M
) {
  Branch (22:12): [True: 10.4M, False: 1.93M]
23
        Py_VISIT(locals[i]);
24
    }
25
    return 0;
26
}
27
28
PyFrameObject *
29
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
30
{
31
    assert(frame->frame_obj == NULL);
32
    PyObject *error_type, *error_value, *error_traceback;
33
    PyErr_Fetch(&error_type, &error_value, &error_traceback);
34
35
    PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
36
    if (f == NULL) {
  Branch (36:9): [True: 0, False: 3.46M]
37
        Py_XDECREF(error_type);
38
        Py_XDECREF(error_value);
39
        Py_XDECREF(error_traceback);
40
    }
41
    else {
42
        assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
43
        assert(frame->owner != FRAME_CLEARED);
44
        f->f_frame = frame;
45
        frame->frame_obj = f;
46
        PyErr_Restore(error_type, error_value, error_traceback);
47
    }
48
    return f;
49
}
50
51
void
52
_PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
53
{
54
    assert(src->stacktop >= src->f_code->co_nlocalsplus);
55
    Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src;
56
    memcpy(dest, src, size);
57
}
58
59
60
static void
61
take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
62
{
63
    assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
64
    assert(frame->owner != FRAME_CLEARED);
65
    Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
66
    memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
67
    frame = (_PyInterpreterFrame *)f->_f_frame_data;
68
    f->f_frame = frame;
69
    frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
70
    assert(f->f_back == NULL);
71
    _PyInterpreterFrame *prev = frame->previous;
72
    while (prev && 
_PyFrame_IsIncomplete(prev)514k
) {
  Branch (72:12): [True: 514k, False: 612k]
  Branch (72:20): [True: 0, False: 514k]
73
        prev = prev->previous;
74
    }
75
    if (prev) {
  Branch (75:9): [True: 514k, False: 612k]
76
        /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */
77
        PyFrameObject *back = _PyFrame_GetFrameObject(prev);
78
        if (back == NULL) {
  Branch (78:13): [True: 0, False: 514k]
79
            /* Memory error here. */
80
            assert(PyErr_ExceptionMatches(PyExc_MemoryError));
81
            /* Nothing we can do about it */
82
            PyErr_Clear();
83
        }
84
        else {
85
            f->f_back = (PyFrameObject *)Py_NewRef(back);
86
        }
87
        frame->previous = NULL;
88
    }
89
    if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) {
  Branch (89:9): [True: 1.12M, False: 0]
90
        _PyObject_GC_TRACK((PyObject *)f);
91
    }
92
}
93
94
void
95
_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
    if (frame->frame_obj) {
  Branch (101:9): [True: 3.46M, False: 175M]
102
        PyFrameObject *f = frame->frame_obj;
103
        frame->frame_obj = NULL;
104
        if (Py_REFCNT(f) > 1) {
  Branch (104:13): [True: 1.12M, False: 2.33M]
105
            take_ownership(f, frame);
106
            Py_DECREF(f);
107
            return;
108
        }
109
        Py_DECREF(f);
110
    }
111
    assert(frame->stacktop >= 0);
112
    for (int i = 0; i < frame->stacktop; 
i++702M
) {
  Branch (112:21): [True: 702M, False: 178M]
113
        Py_XDECREF(frame->localsplus[i]);
114
    }
115
    Py_XDECREF(frame->frame_obj);
116
    Py_XDECREF(frame->f_locals);
117
    Py_DECREF(frame->f_func);
118
    Py_DECREF(frame->f_code);
119
}
120
121
int
122
_PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame)
123
{
124
    int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
125
    return PyCode_Addr2Line(frame->f_code, addr);
126
}