Skip to content

Commit 5a35c20

Browse files
committed
Add comment and use _PyCStackRef for self
1 parent d86950f commit 5a35c20

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

Python/ceval.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,10 +1025,17 @@ _Py_LoadAttr_StackRefSteal(
10251025
PyThreadState *tstate, _PyStackRef owner,
10261026
PyObject *name, _PyStackRef *self_or_null)
10271027
{
1028-
_PyCStackRef method;
1028+
// Use _PyCStackRefs to ensure that both method and self are visible to
1029+
// the GC. Even though self_or_null is on the evaluation stack, it may be
1030+
// after the stackpointer and therefore not visible to the GC.
1031+
_PyCStackRef method, self;
10291032
_PyThreadState_PushCStackRef(tstate, &method);
1030-
*self_or_null = owner;
1031-
_PyObject_GetMethodStackRef(tstate, self_or_null, name, &method.ref);
1033+
_PyThreadState_PushCStackRef(tstate, &self);
1034+
self.ref = owner; // steal reference to owner
1035+
// NOTE: method.ref is initialized to PyStackRef_NULL and remains null on
1036+
// error, so we don't need to explicitly use the return code from the call.
1037+
_PyObject_GetMethodStackRef(tstate, &self.ref, name, &method.ref);
1038+
*self_or_null = _PyThreadState_PopCStackRefSteal(tstate, &self);
10321039
return _PyThreadState_PopCStackRefSteal(tstate, &method);
10331040
}
10341041

0 commit comments

Comments
 (0)