Skip to content

Commit fa60366

Browse files
committed
Pass reference to func, as well as args, when pushing frame.
1 parent 187930f commit fa60366

File tree

5 files changed

+11
-29
lines changed

5 files changed

+11
-29
lines changed

Include/internal/pycore_frame.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ static inline void _PyFrame_StackPush(InterpreterFrame *f, PyObject *value) {
8787

8888
void _PyFrame_Copy(InterpreterFrame *src, InterpreterFrame *dest);
8989

90+
/* Consumes reference to func */
9091
static inline void
9192
_PyFrame_InitializeSpecials(
9293
InterpreterFrame *frame, PyFunctionObject *func,
9394
PyObject *locals, int nlocalsplus)
9495
{
95-
Py_INCREF(func);
9696
frame->f_func = func;
9797
frame->f_code = (PyCodeObject *)Py_NewRef(func->func_code);
9898
frame->f_builtins = func->func_builtins;
@@ -166,9 +166,6 @@ _PyFrame_FastToLocalsWithError(InterpreterFrame *frame);
166166
void
167167
_PyFrame_LocalsToFast(InterpreterFrame *frame, int clear);
168168

169-
InterpreterFrame *_PyThreadState_PushFrame(
170-
PyThreadState *tstate, PyFunctionObject *func, PyObject *locals);
171-
172169
extern InterpreterFrame *
173170
_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size);
174171

@@ -189,6 +186,7 @@ _PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size)
189186

190187
void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame);
191188

189+
/* Consume reference to func */
192190
InterpreterFrame *
193191
_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func);
194192

Objects/frameobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,8 @@ _Py_IDENTIFIER(__builtins__);
784784
static void
785785
init_frame(InterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
786786
{
787+
/* _PyFrame_InitializeSpecials consumes reference to func */
788+
Py_INCREF(func);
787789
PyCodeObject *code = (PyCodeObject *)func->func_code;
788790
_PyFrame_InitializeSpecials(frame, func, locals, code->co_nlocalsplus);
789791
for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) {

Python/ceval.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
22432243
goto error;
22442244
}
22452245
CALL_STAT_INC(frames_pushed);
2246+
Py_INCREF(getitem);
22462247
_PyFrame_InitializeSpecials(new_frame, getitem,
22472248
NULL, code->co_nlocalsplus);
22482249
STACK_SHRINK(2);
@@ -4585,7 +4586,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
45854586
STACK_SHRINK(call_shape.postcall_shrink);
45864587
// The frame has stolen all the arguments from the stack,
45874588
// so there is no need to clean them up.
4588-
Py_DECREF(function);
45894589
if (new_frame == NULL) {
45904590
goto error;
45914591
}
@@ -4670,7 +4670,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
46704670
new_frame->localsplus[i] = NULL;
46714671
}
46724672
STACK_SHRINK(call_shape.postcall_shrink);
4673-
Py_DECREF(func);
46744673
_PyFrame_SetStackPointer(frame, stack_pointer);
46754674
new_frame->previous = frame;
46764675
frame = cframe.current_frame = new_frame;
@@ -4707,7 +4706,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
47074706
new_frame->localsplus[i] = NULL;
47084707
}
47094708
STACK_SHRINK(call_shape.postcall_shrink);
4710-
Py_DECREF(func);
47114709
_PyFrame_SetStackPointer(frame, stack_pointer);
47124710
new_frame->previous = frame;
47134711
frame = cframe.current_frame = new_frame;
@@ -6072,7 +6070,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
60726070
return -1;
60736071
}
60746072

6075-
/* Consumes all the references to the args */
6073+
/* Consumes references to func and all the args */
60766074
static InterpreterFrame *
60776075
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
60786076
PyObject *locals, PyObject* const* args,
@@ -6126,7 +6124,9 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
61266124
PyObject* const* args, size_t argcount,
61276125
PyObject *kwnames)
61286126
{
6129-
/* _PyEvalFramePushAndInit consumes all the references to its arguments */
6127+
/* _PyEvalFramePushAndInit consumes the references
6128+
* to func and all its arguments */
6129+
Py_INCREF(func);
61306130
for (size_t i = 0; i < argcount; i++) {
61316131
Py_INCREF(args[i]);
61326132
}

Python/frame.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ _PyFrame_Clear(InterpreterFrame *frame)
109109
Py_DECREF(frame->f_code);
110110
}
111111

112+
/* Consumes reference to func */
112113
InterpreterFrame *
113114
_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func)
114115
{
@@ -117,6 +118,7 @@ _PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func)
117118
CALL_STAT_INC(frames_pushed);
118119
InterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size);
119120
if (new_frame == NULL) {
121+
Py_DECREF(func);
120122
return NULL;
121123
}
122124
_PyFrame_InitializeSpecials(new_frame, func, NULL, code->co_nlocalsplus);

Python/pystate.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,26 +2212,6 @@ _PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size)
22122212
return (InterpreterFrame *)base;
22132213
}
22142214

2215-
2216-
InterpreterFrame *
2217-
_PyThreadState_PushFrame(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals)
2218-
{
2219-
PyCodeObject *code = (PyCodeObject *)func->func_code;
2220-
int nlocalsplus = code->co_nlocalsplus;
2221-
size_t size = nlocalsplus + code->co_stacksize +
2222-
FRAME_SPECIALS_SIZE;
2223-
CALL_STAT_INC(frames_pushed);
2224-
InterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size);
2225-
if (frame == NULL) {
2226-
return NULL;
2227-
}
2228-
_PyFrame_InitializeSpecials(frame, func, locals, nlocalsplus);
2229-
for (int i=0; i < nlocalsplus; i++) {
2230-
frame->localsplus[i] = NULL;
2231-
}
2232-
return frame;
2233-
}
2234-
22352215
void
22362216
_PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame * frame)
22372217
{

0 commit comments

Comments
 (0)