@@ -63,6 +63,7 @@ PyAPI_FUNC(PyObject *) _Py_stackref_get_object(_PyStackRef ref);
6363PyAPI_FUNC (PyObject * ) _Py_stackref_close (_PyStackRef ref , const char * filename , int linenumber );
6464PyAPI_FUNC (_PyStackRef ) _Py_stackref_create (PyObject * obj , uint16_t flags , const char * filename , int linenumber );
6565PyAPI_FUNC (void ) _Py_stackref_record_borrow (_PyStackRef ref , const char * filename , int linenumber );
66+ PyAPI_FUNC (void ) _Py_stackref_set_borrowed_from (_PyStackRef ref , _PyStackRef borrowed_from , const char * filename , int linenumber );
6667extern void _Py_stackref_associate (PyInterpreterState * interp , PyObject * obj , _PyStackRef ref );
6768
6869static const _PyStackRef PyStackRef_NULL = { .index = 0 };
@@ -259,6 +260,7 @@ _PyStackRef_CLOSE_SPECIALIZED(_PyStackRef ref, destructor destruct, const char *
259260 assert (!PyStackRef_IsNull (ref ));
260261 assert (!PyStackRef_IsTaggedInt (ref ));
261262 PyObject * obj = _Py_stackref_close (ref , filename , linenumber );
263+ assert (Py_REFCNT (obj ) > 0 );
262264 if (PyStackRef_RefcountOnObject (ref )) {
263265 _Py_DECREF_SPECIALIZED (obj , destruct );
264266 }
@@ -274,7 +276,11 @@ _PyStackRef_Borrow(_PyStackRef ref, const char *filename, int linenumber)
274276 return ref ;
275277 }
276278 PyObject * obj = _Py_stackref_get_object (ref );
277- return _Py_stackref_create (obj , Py_TAG_REFCNT , filename , linenumber );
279+ _PyStackRef new_ref = _Py_stackref_create (obj , Py_TAG_REFCNT , filename , linenumber );
280+ if (!_Py_IsImmortal (obj )) {
281+ _Py_stackref_set_borrowed_from (new_ref , ref , filename , linenumber );
282+ }
283+ return new_ref ;
278284}
279285#define PyStackRef_Borrow (REF ) _PyStackRef_Borrow((REF), __FILE__, __LINE__)
280286
@@ -310,13 +316,22 @@ PyStackRef_IsHeapSafe(_PyStackRef ref)
310316static inline _PyStackRef
311317_PyStackRef_MakeHeapSafe (_PyStackRef ref , const char * filename , int linenumber )
312318{
313- if (PyStackRef_IsHeapSafe (ref )) {
319+ // Special references that can't be closed.
320+ if (ref .index < INITIAL_STACKREF_INDEX ) {
314321 return ref ;
315322 }
316323
324+ bool heap_safe = PyStackRef_IsHeapSafe (ref );
317325 PyObject * obj = _Py_stackref_close (ref , filename , linenumber );
318- Py_INCREF (obj );
319- return _Py_stackref_create (obj , 0 , filename , linenumber );
326+ uint16_t flags = 0 ;
327+ if (heap_safe ) {
328+ // Close old ref and create a new one with the same flags.
329+ // This is necessary for correct borrow checking.
330+ flags = ref .index & Py_TAG_BITS ;
331+ } else {
332+ Py_INCREF (obj );
333+ }
334+ return _Py_stackref_create (obj , flags , filename , linenumber );
320335}
321336#define PyStackRef_MakeHeapSafe (REF ) _PyStackRef_MakeHeapSafe(REF, __FILE__, __LINE__)
322337
0 commit comments