/src/cpython/Python/frame.c
Line | Count | Source (jump to first uncovered line) |
1 | | #define _PY_INTERPRETER |
2 | | |
3 | | #include "Python.h" |
4 | | #include "pycore_frame.h" // _PyFrame_New_NoTrack() |
5 | | #include "pycore_interpframe.h" // _PyFrame_GetCode() |
6 | | #include "pycore_genobject.h" // _PyGen_GetGeneratorFromFrame() |
7 | | #include "pycore_stackref.h" // _Py_VISIT_STACKREF() |
8 | | |
9 | | |
10 | | int |
11 | | _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) |
12 | 486k | { |
13 | 486k | Py_VISIT(frame->frame_obj); |
14 | 486k | Py_VISIT(frame->f_locals); |
15 | 486k | _Py_VISIT_STACKREF(frame->f_funcobj); |
16 | 486k | _Py_VISIT_STACKREF(frame->f_executable); |
17 | 486k | return _PyGC_VisitFrameStack(frame, visit, arg); |
18 | 486k | } |
19 | | |
20 | | PyFrameObject * |
21 | | _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) |
22 | 27.3M | { |
23 | 27.3M | assert(frame->frame_obj == NULL); |
24 | 27.3M | PyObject *exc = PyErr_GetRaisedException(); |
25 | | |
26 | 27.3M | PyFrameObject *f = _PyFrame_New_NoTrack(_PyFrame_GetCode(frame)); |
27 | 27.3M | if (f == NULL) { |
28 | 0 | Py_XDECREF(exc); |
29 | 0 | return NULL; |
30 | 0 | } |
31 | 27.3M | PyErr_SetRaisedException(exc); |
32 | | |
33 | | // GH-97002: There was a time when a frame object could be created when we |
34 | | // are allocating the new frame object f above, so frame->frame_obj would |
35 | | // be assigned already. That path does not exist anymore. We won't call any |
36 | | // Python code in this function and garbage collection will not run. |
37 | | // Notice that _PyFrame_New_NoTrack() can potentially raise a MemoryError, |
38 | | // but it won't allocate a traceback until the frame unwinds, so we are safe |
39 | | // here. |
40 | 27.3M | assert(frame->frame_obj == NULL); |
41 | 27.3M | assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); |
42 | 27.3M | f->f_frame = frame; |
43 | 27.3M | frame->frame_obj = f; |
44 | 27.3M | return f; |
45 | 27.3M | } |
46 | | |
47 | | static void |
48 | | take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) |
49 | 13.3M | { |
50 | 13.3M | Py_BEGIN_CRITICAL_SECTION(f); |
51 | 13.3M | assert(frame->owner < FRAME_OWNED_BY_INTERPRETER); |
52 | 13.3M | assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); |
53 | 13.3M | _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)f->_f_frame_data; |
54 | 13.3M | _PyFrame_Copy(frame, new_frame); |
55 | | // _PyFrame_Copy takes the reference to the executable, |
56 | | // so we need to restore it. |
57 | 13.3M | frame->f_executable = PyStackRef_DUP(new_frame->f_executable); |
58 | 13.3M | f->f_frame = new_frame; |
59 | 13.3M | new_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; |
60 | 13.3M | if (_PyFrame_IsIncomplete(new_frame)) { |
61 | | // This may be a newly-created generator or coroutine frame. Since it's |
62 | | // dead anyways, just pretend that the first RESUME ran: |
63 | 0 | PyCodeObject *code = _PyFrame_GetCode(new_frame); |
64 | 0 | new_frame->instr_ptr = |
65 | 0 | _PyFrame_GetBytecode(new_frame) + code->_co_firsttraceable + 1; |
66 | 0 | } |
67 | 13.3M | assert(!_PyFrame_IsIncomplete(new_frame)); |
68 | 13.3M | assert(f->f_back == NULL); |
69 | 13.3M | _PyInterpreterFrame *prev = _PyFrame_GetFirstComplete(frame->previous); |
70 | 13.3M | if (prev) { |
71 | 13.3M | assert(prev->owner < FRAME_OWNED_BY_INTERPRETER); |
72 | 13.3M | PyObject *exc = PyErr_GetRaisedException(); |
73 | | /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */ |
74 | 13.3M | PyFrameObject *back = _PyFrame_GetFrameObject(prev); |
75 | 13.3M | if (back == NULL) { |
76 | | /* Memory error here. */ |
77 | 0 | assert(PyErr_ExceptionMatches(PyExc_MemoryError)); |
78 | | /* Nothing we can do about it */ |
79 | 0 | PyErr_Clear(); |
80 | 0 | } |
81 | 13.3M | else { |
82 | 13.3M | f->f_back = (PyFrameObject *)Py_NewRef(back); |
83 | 13.3M | } |
84 | 13.3M | PyErr_SetRaisedException(exc); |
85 | 13.3M | } |
86 | 13.3M | if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) { |
87 | 13.3M | _PyObject_GC_TRACK((PyObject *)f); |
88 | 13.3M | } |
89 | 13.3M | Py_END_CRITICAL_SECTION(); |
90 | 13.3M | } |
91 | | |
92 | | void |
93 | | _PyFrame_ClearLocals(_PyInterpreterFrame *frame) |
94 | 513M | { |
95 | 513M | assert(frame->stackpointer != NULL); |
96 | 513M | _PyStackRef *sp = frame->stackpointer; |
97 | 513M | _PyStackRef *locals = frame->localsplus; |
98 | 513M | frame->stackpointer = locals; |
99 | 2.25G | while (sp > locals) { |
100 | 1.74G | sp--; |
101 | 1.74G | PyStackRef_XCLOSE(*sp); |
102 | 1.74G | } |
103 | 513M | Py_CLEAR(frame->f_locals); |
104 | 513M | } |
105 | | |
106 | | void |
107 | | _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame) |
108 | 526M | { |
109 | | /* It is the responsibility of the owning generator/coroutine |
110 | | * to have cleared the enclosing generator, if any. */ |
111 | 526M | assert(frame->owner != FRAME_OWNED_BY_GENERATOR || |
112 | 526M | _PyGen_GetGeneratorFromFrame(frame)->gi_frame_state == FRAME_CLEARED); |
113 | | // GH-99729: Clearing this frame can expose the stack (via finalizers). It's |
114 | | // crucial that this frame has been unlinked, and is no longer visible: |
115 | 526M | assert(_PyThreadState_GET()->current_frame != frame); |
116 | 526M | if (frame->frame_obj) { |
117 | 27.3M | PyFrameObject *f = frame->frame_obj; |
118 | 27.3M | frame->frame_obj = NULL; |
119 | 27.3M | if (!_PyObject_IsUniquelyReferenced((PyObject *)f)) { |
120 | 13.3M | take_ownership(f, frame); |
121 | 13.3M | Py_DECREF(f); |
122 | 13.3M | return; |
123 | 13.3M | } |
124 | 13.9M | Py_DECREF(f); |
125 | 13.9M | } |
126 | 513M | _PyFrame_ClearLocals(frame); |
127 | 513M | PyStackRef_CLEAR(frame->f_funcobj); |
128 | 513M | } |
129 | | |
130 | | /* Unstable API functions */ |
131 | | |
132 | | PyObject * |
133 | | PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame) |
134 | 0 | { |
135 | 0 | return PyStackRef_AsPyObjectNew(frame->f_executable); |
136 | 0 | } |
137 | | |
138 | | int |
139 | | PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame) |
140 | 0 | { |
141 | 0 | return _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); |
142 | 0 | } |
143 | | |
144 | | // NOTE: We allow racy accesses to the instruction pointer from other threads |
145 | | // for sys._current_frames() and similar APIs. |
146 | | int _Py_NO_SANITIZE_THREAD |
147 | | PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame) |
148 | 2.35k | { |
149 | 2.35k | int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); |
150 | 2.35k | return PyCode_Addr2Line(_PyFrame_GetCode(frame), addr); |
151 | 2.35k | } |
152 | | |
153 | | const PyTypeObject *const PyUnstable_ExecutableKinds[PyUnstable_EXECUTABLE_KINDS+1] = { |
154 | | [PyUnstable_EXECUTABLE_KIND_SKIP] = &_PyNone_Type, |
155 | | [PyUnstable_EXECUTABLE_KIND_PY_FUNCTION] = &PyCode_Type, |
156 | | [PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION] = &PyMethod_Type, |
157 | | [PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR] = &PyMethodDescr_Type, |
158 | | [PyUnstable_EXECUTABLE_KINDS] = NULL, |
159 | | }; |