1 
2 #include "Python.h"
3 #include "frameobject.h"
4 #include "pycore_code.h"          // stats
5 #include "pycore_frame.h"
6 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
7 #include "opcode.h"
8 
9 int
_PyFrame_Traverse(_PyInterpreterFrame * frame,visitproc visit,void * arg)10 _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg)
11 {
12     Py_VISIT(frame->frame_obj);
13     Py_VISIT(frame->f_locals);
14     Py_VISIT(frame->f_func);
15     Py_VISIT(frame->f_code);
16    /* locals */
17     PyObject **locals = _PyFrame_GetLocalsArray(frame);
18     int i = 0;
19     /* locals and stack */
20     for (; i <frame->stacktop; i++) {
21         Py_VISIT(locals[i]);
22     }
23     return 0;
24 }
25 
26 PyFrameObject *
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame * frame)27 _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
28 {
29     assert(frame->frame_obj == NULL);
30     PyObject *error_type, *error_value, *error_traceback;
31     PyErr_Fetch(&error_type, &error_value, &error_traceback);
32 
33     PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
34     if (f == NULL) {
35         Py_XDECREF(error_type);
36         Py_XDECREF(error_value);
37         Py_XDECREF(error_traceback);
38         return NULL;
39     }
40     PyErr_Restore(error_type, error_value, error_traceback);
41     if (frame->frame_obj) {
42         // GH-97002: How did we get into this horrible situation? Most likely,
43         // allocating f triggered a GC collection, which ran some code that
44         // *also* created the same frame... while we were in the middle of
45         // creating it! See test_sneaky_frame_object in test_frame.py for a
46         // concrete example.
47         //
48         // Regardless, just throw f away and use that frame instead, since it's
49         // already been exposed to user code. It's actually a bit tricky to do
50         // this, since we aren't backed by a real _PyInterpreterFrame anymore.
51         // Just pretend that we have an owned, cleared frame so frame_dealloc
52         // doesn't make the situation worse:
53         f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data;
54         f->f_frame->owner = FRAME_CLEARED;
55         f->f_frame->frame_obj = f;
56         Py_DECREF(f);
57         return frame->frame_obj;
58     }
59     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
60     assert(frame->owner != FRAME_CLEARED);
61     f->f_frame = frame;
62     frame->frame_obj = f;
63     return f;
64 }
65 
66 void
_PyFrame_Copy(_PyInterpreterFrame * src,_PyInterpreterFrame * dest)67 _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
68 {
69     assert(src->stacktop >= src->f_code->co_nlocalsplus);
70     Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src;
71     memcpy(dest, src, size);
72     // Don't leave a dangling pointer to the old frame when creating generators
73     // and coroutines:
74     dest->previous = NULL;
75 }
76 
77 
78 static void
take_ownership(PyFrameObject * f,_PyInterpreterFrame * frame)79 take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
80 {
81     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
82     assert(frame->owner != FRAME_CLEARED);
83     Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
84     memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
85     frame = (_PyInterpreterFrame *)f->_f_frame_data;
86     f->f_frame = frame;
87     frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
88     if (_PyFrame_IsIncomplete(frame)) {
89         // This may be a newly-created generator or coroutine frame. Since it's
90         // dead anyways, just pretend that the first RESUME ran:
91         PyCodeObject *code = frame->f_code;
92         frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable;
93     }
94     assert(!_PyFrame_IsIncomplete(frame));
95     assert(f->f_back == NULL);
96     _PyInterpreterFrame *prev = frame->previous;
97     while (prev && _PyFrame_IsIncomplete(prev)) {
98         prev = prev->previous;
99     }
100     if (prev) {
101         /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */
102         PyFrameObject *back = _PyFrame_GetFrameObject(prev);
103         if (back == NULL) {
104             /* Memory error here. */
105             assert(PyErr_ExceptionMatches(PyExc_MemoryError));
106             /* Nothing we can do about it */
107             PyErr_Clear();
108         }
109         else {
110             f->f_back = (PyFrameObject *)Py_NewRef(back);
111         }
112         frame->previous = NULL;
113     }
114     if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) {
115         _PyObject_GC_TRACK((PyObject *)f);
116     }
117 }
118 
119 void
_PyFrame_Clear(_PyInterpreterFrame * frame)120 _PyFrame_Clear(_PyInterpreterFrame *frame)
121 {
122     /* It is the responsibility of the owning generator/coroutine
123      * to have cleared the enclosing generator, if any. */
124     assert(frame->owner != FRAME_OWNED_BY_GENERATOR ||
125         _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
126     // GH-99729: Clearing this frame can expose the stack (via finalizers). It's
127     // crucial that this frame has been unlinked, and is no longer visible:
128     assert(_PyThreadState_GET()->cframe->current_frame != frame);
129     if (frame->frame_obj) {
130         PyFrameObject *f = frame->frame_obj;
131         frame->frame_obj = NULL;
132         if (Py_REFCNT(f) > 1) {
133             take_ownership(f, frame);
134             Py_DECREF(f);
135             return;
136         }
137         Py_DECREF(f);
138     }
139     assert(frame->stacktop >= 0);
140     for (int i = 0; i < frame->stacktop; i++) {
141         Py_XDECREF(frame->localsplus[i]);
142     }
143     Py_XDECREF(frame->frame_obj);
144     Py_XDECREF(frame->f_locals);
145     Py_DECREF(frame->f_func);
146     Py_DECREF(frame->f_code);
147 }
148 
149 /* Consumes reference to func */
150 _PyInterpreterFrame *
_PyFrame_Push(PyThreadState * tstate,PyFunctionObject * func)151 _PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func)
152 {
153     PyCodeObject *code = (PyCodeObject *)func->func_code;
154     size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE;
155     CALL_STAT_INC(frames_pushed);
156     _PyInterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size);
157     if (new_frame == NULL) {
158         Py_DECREF(func);
159         return NULL;
160     }
161     _PyFrame_InitializeSpecials(new_frame, func, NULL, code->co_nlocalsplus);
162     return new_frame;
163 }
164 
165 int
_PyInterpreterFrame_GetLine(_PyInterpreterFrame * frame)166 _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame)
167 {
168     int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
169     return PyCode_Addr2Line(frame->f_code, addr);
170 }
171