@@ -46,7 +46,7 @@ PyFrame_GetLineNumber(PyFrameObject *f)
4646 return f -> f_lineno ;
4747 }
4848 else {
49- return PyCode_Addr2Line (f -> f_code , f -> f_lasti * 2 );
49+ return PyCode_Addr2Line (_PyFrame_GetCode ( f ) , f -> f_lasti * 2 );
5050 }
5151}
5252
@@ -472,7 +472,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
472472 }
473473 new_lineno = (int )l_new_lineno ;
474474
475- if (new_lineno < f -> f_code -> co_firstlineno ) {
475+ if (new_lineno < _PyFrame_GetCode ( f ) -> co_firstlineno ) {
476476 PyErr_Format (PyExc_ValueError ,
477477 "line %d comes before the current code block" ,
478478 new_lineno );
@@ -481,8 +481,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
481481
482482 /* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this
483483 * should never overflow. */
484- int len = (int )(PyBytes_GET_SIZE (f -> f_code -> co_code ) / sizeof (_Py_CODEUNIT ));
485- int * lines = marklines (f -> f_code , len );
484+ int len = (int )(PyBytes_GET_SIZE (_PyFrame_GetCode ( f ) -> co_code ) / sizeof (_Py_CODEUNIT ));
485+ int * lines = marklines (_PyFrame_GetCode ( f ) , len );
486486 if (lines == NULL ) {
487487 return -1 ;
488488 }
@@ -496,7 +496,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
496496 return -1 ;
497497 }
498498
499- int64_t * stacks = mark_stacks (f -> f_code , len );
499+ int64_t * stacks = mark_stacks (_PyFrame_GetCode ( f ) , len );
500500 if (stacks == NULL ) {
501501 PyMem_Free (lines );
502502 return -1 ;
@@ -610,11 +610,17 @@ frame_dealloc(PyFrameObject *f)
610610 }
611611
612612 Py_TRASHCAN_SAFE_BEGIN (f )
613- PyCodeObject * co = f -> f_code ;
613+ PyCodeObject * co = NULL ;
614614
615615 /* Kill all local variables including specials. */
616616 if (f -> f_localsptr ) {
617- for (int i = 0 ; i < co -> co_nlocalsplus + FRAME_SPECIALS_SIZE ; i ++ ) {
617+ /* Don't clear code object until the end */
618+ co = _PyFrame_GetCode (f );
619+ PyObject * * specials = _PyFrame_Specials (f );
620+ Py_CLEAR (specials [FRAME_SPECIALS_GLOBALS_OFFSET ]);
621+ Py_CLEAR (specials [FRAME_SPECIALS_BUILTINS_OFFSET ]);
622+ Py_CLEAR (specials [FRAME_SPECIALS_LOCALS_OFFSET ]);
623+ for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
618624 Py_CLEAR (f -> f_localsptr [i ]);
619625 }
620626 /* Free items on stack */
@@ -625,6 +631,7 @@ frame_dealloc(PyFrameObject *f)
625631 PyMem_Free (f -> f_localsptr );
626632 f -> f_own_locals_memory = 0 ;
627633 }
634+ f -> f_localsptr = NULL ;
628635 }
629636 f -> f_stackdepth = 0 ;
630637 Py_XDECREF (f -> f_back );
@@ -643,7 +650,7 @@ frame_dealloc(PyFrameObject *f)
643650 PyObject_GC_Del (f );
644651 }
645652
646- Py_DECREF (co );
653+ Py_XDECREF (co );
647654 Py_TRASHCAN_SAFE_END (f )
648655}
649656
@@ -683,7 +690,7 @@ frame_tp_clear(PyFrameObject *f)
683690 f -> f_state = FRAME_CLEARED ;
684691
685692 Py_CLEAR (f -> f_trace );
686- PyCodeObject * co = f -> f_code ;
693+ PyCodeObject * co = _PyFrame_GetCode ( f ) ;
687694 /* locals */
688695 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
689696 Py_CLEAR (f -> f_localsptr [i ]);
@@ -722,7 +729,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
722729 Py_ssize_t res ;
723730 res = sizeof (PyFrameObject );
724731 if (f -> f_own_locals_memory ) {
725- PyCodeObject * code = f -> f_code ;
732+ PyCodeObject * code = _PyFrame_GetCode ( f ) ;
726733 res += (code -> co_nlocalsplus + code -> co_stacksize ) * sizeof (PyObject * );
727734 }
728735 return PyLong_FromSsize_t (res );
@@ -735,7 +742,7 @@ static PyObject *
735742frame_repr (PyFrameObject * f )
736743{
737744 int lineno = PyFrame_GetLineNumber (f );
738- PyCodeObject * code = f -> f_code ;
745+ PyCodeObject * code = _PyFrame_GetCode ( f ) ;
739746 return PyUnicode_FromFormat (
740747 "<frame at %p, file %R, line %d, code %S>" ,
741748 f , code -> co_filename , lineno , code -> co_name );
@@ -876,7 +883,7 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyFrameConstructor *con, PyObject *l
876883 PyObject * * specials = f -> f_localsptr + code -> co_nlocalsplus ;
877884 f -> f_valuestack = specials + FRAME_SPECIALS_SIZE ;
878885 f -> f_back = (PyFrameObject * )Py_XNewRef (tstate -> frame );
879- f -> f_code = ( PyCodeObject * ) Py_NewRef (con -> fc_code );
886+ specials [ FRAME_SPECIALS_CODE_OFFSET ] = Py_NewRef (con -> fc_code );
880887 specials [FRAME_SPECIALS_BUILTINS_OFFSET ] = Py_NewRef (con -> fc_builtins );
881888 specials [FRAME_SPECIALS_GLOBALS_OFFSET ] = Py_NewRef (con -> fc_globals );
882889 specials [FRAME_SPECIALS_LOCALS_OFFSET ] = Py_XNewRef (locals );
@@ -921,7 +928,7 @@ static int
921928_PyFrame_OpAlreadyRan (PyFrameObject * f , int opcode , int oparg )
922929{
923930 const _Py_CODEUNIT * code =
924- (const _Py_CODEUNIT * )PyBytes_AS_STRING (f -> f_code -> co_code );
931+ (const _Py_CODEUNIT * )PyBytes_AS_STRING (_PyFrame_GetCode ( f ) -> co_code );
925932 for (int i = 0 ; i < f -> f_lasti ; i ++ ) {
926933 if (_Py_OPCODE (code [i ]) == opcode && _Py_OPARG (code [i ]) == oparg ) {
927934 return 1 ;
@@ -948,7 +955,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
948955 if (locals == NULL )
949956 return -1 ;
950957 }
951- co = f -> f_code ;
958+ co = _PyFrame_GetCode ( f ) ;
952959 fast = f -> f_localsptr ;
953960 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
954961 _PyLocalsPlusKind kind = co -> co_localspluskinds [i ];
@@ -1041,7 +1048,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
10411048 if (locals == NULL )
10421049 return ;
10431050 fast = f -> f_localsptr ;
1044- co = f -> f_code ;
1051+ co = _PyFrame_GetCode ( f ) ;
10451052
10461053 PyErr_Fetch (& error_type , & error_value , & error_traceback );
10471054 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
@@ -1134,7 +1141,7 @@ PyCodeObject *
11341141PyFrame_GetCode (PyFrameObject * frame )
11351142{
11361143 assert (frame != NULL );
1137- PyCodeObject * code = frame -> f_code ;
1144+ PyCodeObject * code = _PyFrame_GetCode ( frame ) ;
11381145 assert (code != NULL );
11391146 Py_INCREF (code );
11401147 return code ;
0 commit comments