@@ -1532,13 +1532,13 @@ typedef struct {
15321532static int
15331533_PyEval_SyncLocalsToFast (_PyInterpreterFrame * frame )
15341534{
1535- PyObject * mapping = frame -> f_locals ;
1535+ PyObject * locals = frame -> f_locals ;
15361536 PyCodeObject * co = _PyFrame_GetCode (frame );
15371537 PyObject * names = co -> co_localsplusnames ;
15381538
15391539 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
15401540 PyObject * name = PyTuple_GET_ITEM (names , i );
1541- PyObject * value = PyObject_GetItem (mapping , name );
1541+ PyObject * value = PyObject_GetItem (locals , name );
15421542 if (value != NULL ) {
15431543 frame -> localsplus [i ] = PyStackRef_FromPyObjectSteal (value );
15441544 }
@@ -1552,19 +1552,32 @@ _PyEval_SyncLocalsToFast(_PyInterpreterFrame *frame)
15521552 return 0 ;
15531553}
15541554
1555+
15551556static int
15561557_PyEval_SyncFastToLocals (_PyInterpreterFrame * frame )
15571558{
1558- PyObject * mapping = frame -> f_locals ;
1559+ PyObject * locals = frame -> f_locals ;
15591560 PyCodeObject * co = _PyFrame_GetCode (frame );
15601561 PyObject * names = co -> co_localsplusnames ;
15611562
15621563 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
1564+ PyObject * name = PyTuple_GET_ITEM (names , i );
15631565 _PyStackRef sref = frame -> localsplus [i ];
1564- if (!PyStackRef_IsNull (sref )) {
1565- PyObject * name = PyTuple_GET_ITEM (names , i );
1566- PyObject * obj = PyStackRef_AsPyObjectSteal (sref );
1567- if (PyObject_SetItem (mapping , name , obj ) < 0 ) {
1566+
1567+ if (PyStackRef_IsNull (sref )) {
1568+ if (PyObject_DelItem (locals , name ) < 0 ) {
1569+ if (PyErr_ExceptionMatches (PyExc_KeyError )) {
1570+ PyErr_Clear ();
1571+ }
1572+ else {
1573+ return -1 ;
1574+ }
1575+ }
1576+ }
1577+ else {
1578+ PyObject * obj = PyStackRef_AsPyObjectNew (sref );
1579+ if (PyObject_SetItem (locals , name , obj ) < 0 ) {
1580+ Py_DECREF (obj );
15681581 return -1 ;
15691582 }
15701583 }
@@ -2428,7 +2441,7 @@ _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame)
24282441 PyCodeObject * co = _PyFrame_GetCode (frame );
24292442 if ((co -> co_flags & CO_OPTIMIZED ) && frame -> f_locals != NULL &&
24302443 frame -> f_locals != frame -> f_globals && _PyEval_SyncFastToLocals (frame ) < 0 ) {
2431- /* Swallow the error while the frame is in a teardown state */
2444+ /* Ignore any error while the frame is in a teardown state */
24322445 PyErr_WriteUnraisable (frame -> f_locals );
24332446 }
24342447 // Update last_profiled_frame for remote profiler frame caching.
@@ -2463,7 +2476,18 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, _PyStackRef func,
24632476 goto fail ;
24642477 }
24652478 _PyFrame_Initialize (tstate , frame , func , locals , code , 0 , previous );
2466- if (initialize_locals (tstate , func_obj , frame -> localsplus , args , argcount , kwnames )) {
2479+ if (code -> co_flags & CO_OPTIMIZED && locals != NULL && locals != func_obj -> func_globals ) {
2480+ for (size_t i = 0 ; i < argcount ; i ++ ) {
2481+ PyStackRef_CLOSE (args [i ]);
2482+ }
2483+ if (kwnames ) {
2484+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
2485+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
2486+ PyStackRef_CLOSE (args [i + argcount ]);
2487+ }
2488+ }
2489+ }
2490+ else if (initialize_locals (tstate , func_obj , frame -> localsplus , args , argcount , kwnames )) {
24672491 assert (frame -> owner == FRAME_OWNED_BY_THREAD );
24682492 clear_thread_frame (tstate , frame );
24692493 return NULL ;
0 commit comments