@@ -642,6 +642,7 @@ _PyFrame_GetState(PyFrameObject *frame)
642642static int
643643frame_setlineno (PyFrameObject * f , PyObject * p_new_lineno , void * Py_UNUSED (ignored ))
644644{
645+ PyCodeObject * code = _PyFrame_GetCode (f -> f_frame );
645646 if (p_new_lineno == NULL ) {
646647 PyErr_SetString (PyExc_AttributeError , "cannot delete attribute" );
647648 return -1 ;
@@ -719,7 +720,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
719720 }
720721 new_lineno = (int )l_new_lineno ;
721722
722- if (new_lineno < f -> f_frame -> f_code -> co_firstlineno ) {
723+ if (new_lineno < code -> co_firstlineno ) {
723724 PyErr_Format (PyExc_ValueError ,
724725 "line %d comes before the current code block" ,
725726 new_lineno );
@@ -728,8 +729,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
728729
729730 /* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this
730731 * should never overflow. */
731- int len = (int )Py_SIZE (f -> f_frame -> f_code );
732- int * lines = marklines (f -> f_frame -> f_code , len );
732+ int len = (int )Py_SIZE (code );
733+ int * lines = marklines (code , len );
733734 if (lines == NULL ) {
734735 return -1 ;
735736 }
@@ -743,7 +744,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
743744 return -1 ;
744745 }
745746
746- int64_t * stacks = mark_stacks (f -> f_frame -> f_code , len );
747+ int64_t * stacks = mark_stacks (code , len );
747748 if (stacks == NULL ) {
748749 PyMem_Free (lines );
749750 return -1 ;
@@ -788,7 +789,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
788789 // in the new location. Rather than crashing or changing co_code, just bind
789790 // None instead:
790791 int unbound = 0 ;
791- for (int i = 0 ; i < f -> f_frame -> f_code -> co_nlocalsplus ; i ++ ) {
792+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
792793 // Counting every unbound local is overly-cautious, but a full flow
793794 // analysis (like we do in the compiler) is probably too expensive:
794795 unbound += f -> f_frame -> localsplus [i ] == NULL ;
@@ -801,7 +802,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
801802 }
802803 // Do this in a second pass to avoid writing a bunch of Nones when
803804 // warnings are being treated as errors and the previous bit raises:
804- for (int i = 0 ; i < f -> f_frame -> f_code -> co_nlocalsplus ; i ++ ) {
805+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
805806 if (f -> f_frame -> localsplus [i ] == NULL ) {
806807 f -> f_frame -> localsplus [i ] = Py_NewRef (Py_None );
807808 unbound -- ;
@@ -832,7 +833,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
832833 }
833834 /* Finally set the new lasti and return OK. */
834835 f -> f_lineno = 0 ;
835- f -> f_frame -> prev_instr = _PyCode_CODE (f -> f_frame -> f_code ) + best_addr ;
836+ f -> f_frame -> prev_instr = _PyCode_CODE (code ) + best_addr ;
836837 return 0 ;
837838}
838839
@@ -886,15 +887,15 @@ frame_dealloc(PyFrameObject *f)
886887 }
887888
888889 Py_TRASHCAN_BEGIN (f , frame_dealloc );
889- PyCodeObject * co = NULL ;
890+ PyObject * co = NULL ;
890891
891892 /* Kill all local variables including specials, if we own them */
892893 if (f -> f_frame -> owner == FRAME_OWNED_BY_FRAME_OBJECT ) {
893894 assert (f -> f_frame == (_PyInterpreterFrame * )f -> _f_frame_data );
894895 _PyInterpreterFrame * frame = (_PyInterpreterFrame * )f -> _f_frame_data ;
895896 /* Don't clear code object until the end */
896- co = frame -> f_code ;
897- frame -> f_code = NULL ;
897+ co = frame -> f_executable ;
898+ frame -> f_executable = NULL ;
898899 Py_CLEAR (frame -> f_funcobj );
899900 Py_CLEAR (frame -> f_locals );
900901 PyObject * * locals = _PyFrame_GetLocalsArray (frame );
@@ -968,7 +969,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
968969{
969970 Py_ssize_t res ;
970971 res = offsetof(PyFrameObject , _f_frame_data ) + offsetof(_PyInterpreterFrame , localsplus );
971- PyCodeObject * code = f -> f_frame -> f_code ;
972+ PyCodeObject * code = _PyFrame_GetCode ( f -> f_frame ) ;
972973 res += _PyFrame_NumSlotsForCodeObject (code ) * sizeof (PyObject * );
973974 return PyLong_FromSsize_t (res );
974975}
@@ -980,7 +981,7 @@ static PyObject *
980981frame_repr (PyFrameObject * f )
981982{
982983 int lineno = PyFrame_GetLineNumber (f );
983- PyCodeObject * code = f -> f_frame -> f_code ;
984+ PyCodeObject * code = _PyFrame_GetCode ( f -> f_frame ) ;
984985 return PyUnicode_FromFormat (
985986 "<frame at %p, file %R, line %d, code %S>" ,
986987 f , code -> co_filename , lineno , code -> co_name );
@@ -1102,7 +1103,7 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg)
11021103 // This only works when opcode is a non-quickened form:
11031104 assert (_PyOpcode_Deopt [opcode ] == opcode );
11041105 int check_oparg = 0 ;
1105- for (_Py_CODEUNIT * instruction = _PyCode_CODE (frame -> f_code );
1106+ for (_Py_CODEUNIT * instruction = _PyCode_CODE (_PyFrame_GetCode ( frame ) );
11061107 instruction < frame -> prev_instr ; instruction ++ )
11071108 {
11081109 int check_opcode = _PyOpcode_Deopt [instruction -> op .code ];
@@ -1128,7 +1129,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
11281129{
11291130 // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt
11301131 // here:
1131- PyCodeObject * co = frame -> f_code ;
1132+ PyCodeObject * co = _PyFrame_GetCode ( frame ) ;
11321133 int lasti = _PyInterpreterFrame_LASTI (frame );
11331134 if (!(lasti < 0 && _PyCode_CODE (co )-> op .code == COPY_FREE_VARS
11341135 && PyFunction_Check (frame -> f_funcobj )))
@@ -1145,7 +1146,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
11451146 frame -> localsplus [offset + i ] = Py_NewRef (o );
11461147 }
11471148 // COPY_FREE_VARS doesn't have inline CACHEs, either:
1148- frame -> prev_instr = _PyCode_CODE (frame -> f_code );
1149+ frame -> prev_instr = _PyCode_CODE (_PyFrame_GetCode ( frame ) );
11491150}
11501151
11511152
@@ -1213,7 +1214,7 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame)
12131214
12141215 frame_init_get_vars (frame );
12151216
1216- PyCodeObject * co = frame -> f_code ;
1217+ PyCodeObject * co = _PyFrame_GetCode ( frame ) ;
12171218 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
12181219 PyObject * value ; // borrowed reference
12191220 if (!frame_get_var (frame , co , i , & value )) {
@@ -1257,7 +1258,7 @@ PyFrame_GetVar(PyFrameObject *frame_obj, PyObject *name)
12571258 _PyInterpreterFrame * frame = frame_obj -> f_frame ;
12581259 frame_init_get_vars (frame );
12591260
1260- PyCodeObject * co = frame -> f_code ;
1261+ PyCodeObject * co = _PyFrame_GetCode ( frame ) ;
12611262 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
12621263 PyObject * var_name = PyTuple_GET_ITEM (co -> co_localsplusnames , i );
12631264 if (!_PyUnicode_Equal (var_name , name )) {
@@ -1331,7 +1332,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
13311332 return ;
13321333 }
13331334 fast = _PyFrame_GetLocalsArray (frame );
1334- co = frame -> f_code ;
1335+ co = _PyFrame_GetCode ( frame ) ;
13351336
13361337 PyObject * exc = PyErr_GetRaisedException ();
13371338 for (int i = 0 ; i < co -> co_nlocalsplus ; i ++ ) {
@@ -1417,7 +1418,7 @@ PyFrame_GetCode(PyFrameObject *frame)
14171418{
14181419 assert (frame != NULL );
14191420 assert (!_PyFrame_IsIncomplete (frame -> f_frame ));
1420- PyCodeObject * code = frame -> f_frame -> f_code ;
1421+ PyCodeObject * code = _PyFrame_GetCode ( frame -> f_frame ) ;
14211422 assert (code != NULL );
14221423 return (PyCodeObject * )Py_NewRef (code );
14231424}
0 commit comments