Skip to content

Commit aeafa98

Browse files
committed
Make sure we convert borrowed refs on frame
1 parent 259d5db commit aeafa98

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

Include/internal/pycore_stackref.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,16 @@ _PyStackRef_StealIfUnborrowed(_PyStackRef stackref)
231231
return stackref;
232232
}
233233

234+
static inline bool
235+
_PyStackRef_IsBorrowed(_PyStackRef stackref)
236+
{
237+
if (PyStackRef_IsNull(stackref) || !PyStackRef_IsDeferred(stackref)) {
238+
return false;
239+
}
240+
PyObject *obj = PyStackRef_AsPyObjectBorrow(stackref);
241+
return !(_Py_IsImmortal(obj) || _PyObject_HasDeferredRefcount(obj));
242+
}
243+
234244
static inline _PyStackRef
235245
PyStackRef_FromPyObjectNew(PyObject *obj)
236246
{

Python/frame.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
5757
frame->f_executable = PyStackRef_DUP(frame->f_executable);
5858
int stacktop = (int)(frame->stackpointer - frame->localsplus);
5959
assert(stacktop >= _PyFrame_GetCode(frame)->co_nlocalsplus);
60+
// XXX - Maybe more optimal sequence to do here
61+
if (_PyStackRef_IsBorrowed(frame->f_executable)) {
62+
Py_INCREF(PyStackRef_AsPyObjectBorrow(frame->f_executable));
63+
}
64+
if (_PyStackRef_IsBorrowed(frame->f_funcobj)) {
65+
Py_INCREF(PyStackRef_AsPyObjectBorrow(frame->f_funcobj));
66+
}
6067
for (int i = 0; i < stacktop; i++) {
6168
frame->localsplus[i] = _PyStackRef_StealIfUnborrowed(frame->localsplus[i]);
6269
}

0 commit comments

Comments
 (0)