bpo-44032: Move pointer to code object from frame-object to frame spe… · python/cpython@0982ded
@@ -46,7 +46,7 @@ PyFrame_GetLineNumber(PyFrameObject *f)
4646return f->f_lineno;
4747 }
4848else {
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 }
473473new_lineno = (int)l_new_lineno;
474474475-if (new_lineno < f->f_code->co_firstlineno) {
475+if (new_lineno < _PyFrame_GetCode(f)->co_firstlineno) {
476476PyErr_Format(PyExc_ValueError,
477477"line %d comes before the current code block",
478478new_lineno);
@@ -481,8 +481,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
481481482482/* 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);
486486if (lines == NULL) {
487487return -1;
488488 }
@@ -496,7 +496,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
496496return -1;
497497 }
498498499-int64_t *stacks = mark_stacks(f->f_code, len);
499+int64_t *stacks = mark_stacks(_PyFrame_GetCode(f), len);
500500if (stacks == NULL) {
501501PyMem_Free(lines);
502502return -1;
@@ -610,11 +610,17 @@ frame_dealloc(PyFrameObject *f)
610610 }
611611612612Py_TRASHCAN_SAFE_BEGIN(f)
613-PyCodeObject *co = f->f_code;
613+PyCodeObject *co = NULL;
614614615615/* Kill all local variables including specials. */
616616if (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++) {
618624Py_CLEAR(f->f_localsptr[i]);
619625 }
620626/* Free items on stack */
@@ -625,6 +631,7 @@ frame_dealloc(PyFrameObject *f)
625631PyMem_Free(f->f_localsptr);
626632f->f_own_locals_memory = 0;
627633 }
634+f->f_localsptr = NULL;
628635 }
629636f->f_stackdepth = 0;
630637Py_XDECREF(f->f_back);
@@ -643,7 +650,7 @@ frame_dealloc(PyFrameObject *f)
643650PyObject_GC_Del(f);
644651 }
645652646-Py_DECREF(co);
653+Py_XDECREF(co);
647654Py_TRASHCAN_SAFE_END(f)
648655}
649656@@ -683,7 +690,7 @@ frame_tp_clear(PyFrameObject *f)
683690f->f_state = FRAME_CLEARED;
684691685692Py_CLEAR(f->f_trace);
686-PyCodeObject *co = f->f_code;
693+PyCodeObject *co = _PyFrame_GetCode(f);
687694/* locals */
688695for (int i = 0; i < co->co_nlocalsplus; i++) {
689696Py_CLEAR(f->f_localsptr[i]);
@@ -722,7 +729,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
722729Py_ssize_t res;
723730res = sizeof(PyFrameObject);
724731if (f->f_own_locals_memory) {
725-PyCodeObject *code = f->f_code;
732+PyCodeObject *code = _PyFrame_GetCode(f);
726733res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *);
727734 }
728735return PyLong_FromSsize_t(res);
@@ -735,7 +742,7 @@ static PyObject *
735742frame_repr(PyFrameObject *f)
736743{
737744int lineno = PyFrame_GetLineNumber(f);
738-PyCodeObject *code = f->f_code;
745+PyCodeObject *code = _PyFrame_GetCode(f);
739746return PyUnicode_FromFormat(
740747"<frame at %p, file %R, line %d, code %S>",
741748f, code->co_filename, lineno, code->co_name);
@@ -876,7 +883,7 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyFrameConstructor *con, PyObject *l
876883PyObject **specials = f->f_localsptr + code->co_nlocalsplus;
877884f->f_valuestack = specials + FRAME_SPECIALS_SIZE;
878885f->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);
880887specials[FRAME_SPECIALS_BUILTINS_OFFSET] = Py_NewRef(con->fc_builtins);
881888specials[FRAME_SPECIALS_GLOBALS_OFFSET] = Py_NewRef(con->fc_globals);
882889specials[FRAME_SPECIALS_LOCALS_OFFSET] = Py_XNewRef(locals);
@@ -921,7 +928,7 @@ static int
921928_PyFrame_OpAlreadyRan(PyFrameObject *f, int opcode, int oparg)
922929{
923930const _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);
925932for (int i = 0; i < f->f_lasti; i++) {
926933if (_Py_OPCODE(code[i]) == opcode && _Py_OPARG(code[i]) == oparg) {
927934return 1;
@@ -948,7 +955,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f)
948955if (locals == NULL)
949956return -1;
950957 }
951-co = f->f_code;
958+co = _PyFrame_GetCode(f);
952959fast = f->f_localsptr;
953960for (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)
10411048if (locals == NULL)
10421049return;
10431050fast = f->f_localsptr;
1044-co = f->f_code;
1051+co = _PyFrame_GetCode(f);
1045105210461053PyErr_Fetch(&error_type, &error_value, &error_traceback);
10471054for (int i = 0; i < co->co_nlocalsplus; i++) {
@@ -1134,7 +1141,7 @@ PyCodeObject *
11341141PyFrame_GetCode(PyFrameObject *frame)
11351142{
11361143assert(frame != NULL);
1137-PyCodeObject *code = frame->f_code;
1144+PyCodeObject *code = _PyFrame_GetCode(frame);
11381145assert(code != NULL);
11391146Py_INCREF(code);
11401147return code;