@@ -781,13 +781,33 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch)
781781/* This setting is reversed below following _PyEval_EvalFrameDefault */
782782#endif
783783
784+ #ifdef Py_TAIL_CALL_INTERP
785+ #include "generated_cases_tail_call.c.h"
786+ #endif
787+
788+ #ifdef LLTRACE
789+ PyObject *
790+ _TAIL_CALL_shim (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer ,
791+ PyThreadState * tstate , _Py_CODEUNIT * next_instr , int oparg , _PyInterpreterFrame * entry_frame , int lltrace )
792+ {
793+ return (INSTRUCTION_TABLE [next_instr -> op .code ])(frame , stack_pointer , tstate , next_instr , next_instr -> op .arg , entry_frame , lltrace );
794+ }
795+ #else
796+ PyObject *
797+ _TAIL_CALL_shim (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer ,
798+ PyThreadState * tstate , _Py_CODEUNIT * next_instr , int oparg , _PyInterpreterFrame * entry_frame )
799+ {
800+ return (INSTRUCTION_TABLE [next_instr -> op .code ])(frame , stack_pointer , tstate , next_instr , next_instr -> op .arg , entry_frame );
801+ }
802+ #endif
803+
784804PyObject * _Py_HOT_FUNCTION
785805_PyEval_EvalFrameDefault (PyThreadState * tstate , _PyInterpreterFrame * frame , int throwflag )
786806{
787807 _Py_EnsureTstateNotNULL (tstate );
788808 CALL_STAT_INC (pyeval_calls );
789809
790- #if USE_COMPUTED_GOTOS
810+ #if USE_COMPUTED_GOTOS && !defined( Py_TAIL_CALL_INTERP )
791811/* Import the static jump table */
792812#include "opcode_targets.h"
793813#endif
@@ -801,27 +821,28 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
801821 int lltrace = 0 ;
802822#endif
803823
804- _PyInterpreterFrame entry_frame ;
824+ _PyInterpreterFrame e ;
825+ _PyInterpreterFrame * entry_frame = & e ;
805826
806827
807828
808829#if defined(Py_DEBUG ) && !defined(Py_STACKREF_DEBUG )
809830 /* Set these to invalid but identifiable values for debugging. */
810- entry_frame .f_funcobj = (_PyStackRef ){.bits = 0xaaa0 };
811- entry_frame .f_locals = (PyObject * )0xaaa1 ;
812- entry_frame .frame_obj = (PyFrameObject * )0xaaa2 ;
813- entry_frame .f_globals = (PyObject * )0xaaa3 ;
814- entry_frame .f_builtins = (PyObject * )0xaaa4 ;
831+ e .f_funcobj = (_PyStackRef ){.bits = 0xaaa0 };
832+ e .f_locals = (PyObject * )0xaaa1 ;
833+ e .frame_obj = (PyFrameObject * )0xaaa2 ;
834+ e .f_globals = (PyObject * )0xaaa3 ;
835+ e .f_builtins = (PyObject * )0xaaa4 ;
815836#endif
816- entry_frame .f_executable = PyStackRef_None ;
817- entry_frame .instr_ptr = (_Py_CODEUNIT * )_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1 ;
818- entry_frame .stackpointer = entry_frame .localsplus ;
819- entry_frame .owner = FRAME_OWNED_BY_CSTACK ;
820- entry_frame .visited = 0 ;
821- entry_frame .return_offset = 0 ;
837+ e .f_executable = PyStackRef_None ;
838+ e .instr_ptr = (_Py_CODEUNIT * )_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1 ;
839+ e .stackpointer = e .localsplus ;
840+ e .owner = FRAME_OWNED_BY_CSTACK ;
841+ e .visited = 0 ;
842+ e .return_offset = 0 ;
822843 /* Push frame */
823- entry_frame .previous = tstate -> current_frame ;
824- frame -> previous = & entry_frame ;
844+ e .previous = tstate -> current_frame ;
845+ frame -> previous = entry_frame ;
825846 tstate -> current_frame = frame ;
826847
827848 tstate -> c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1 );
@@ -878,7 +899,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
878899 stack_pointer = _PyFrame_GetStackPointer (frame );
879900
880901#ifdef LLTRACE
881- lltrace = maybe_lltrace_resume_frame (frame , & entry_frame , GLOBALS ());
902+ lltrace = maybe_lltrace_resume_frame (frame , entry_frame , GLOBALS ());
882903 if (lltrace < 0 ) {
883904 goto exit_unwind ;
884905 }
@@ -891,18 +912,26 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
891912 assert (!_PyErr_Occurred (tstate ));
892913#endif
893914
915+ #ifdef Py_TAIL_CALL_INTERP
916+ #ifdef LLTRACE
917+ return _TAIL_CALL_shim (frame , stack_pointer , tstate , next_instr , 0 , entry_frame , lltrace );
918+ #else
919+ return _TAIL_CALL_shim (frame , stack_pointer , tstate , next_instr , 0 , entry_frame );
920+ #endif
921+ #else
894922 DISPATCH ();
923+ #endif
895924
896925 {
897926 /* Start instructions */
898- #if !USE_COMPUTED_GOTOS
927+ #if !USE_COMPUTED_GOTOS && !defined( Py_TAIL_CALL_INTERP )
899928 dispatch_opcode :
900929 switch (opcode )
901930#endif
902931 {
903-
932+ #ifndef Py_TAIL_CALL_INTERP
904933#include "generated_cases.c.h"
905-
934+ #endif
906935
907936#if USE_COMPUTED_GOTOS
908937 _unknown_opcode :
@@ -945,7 +974,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
945974#endif
946975
947976 /* Log traceback info. */
948- assert (frame != & entry_frame );
977+ assert (frame != entry_frame );
949978 if (!_PyFrame_IsIncomplete (frame )) {
950979 PyFrameObject * f = _PyFrame_GetFrameObject (frame );
951980 if (f != NULL ) {
@@ -1004,20 +1033,29 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10041033 lltrace_resume_frame (frame );
10051034 }
10061035#endif
1036+
1037+ #ifdef Py_TAIL_CALL_INTERP
1038+ #ifdef LLTRACE
1039+ return _TAIL_CALL_shim (frame , stack_pointer , tstate , next_instr , 0 , entry_frame , lltrace );
1040+ #else
1041+ return _TAIL_CALL_shim (frame , stack_pointer , tstate , next_instr , 0 , entry_frame );
1042+ #endif
1043+ #else
10071044 DISPATCH ();
1045+ #endif
10081046 }
10091047 }
10101048
10111049exit_unwind :
10121050 assert (_PyErr_Occurred (tstate ));
10131051 _Py_LeaveRecursiveCallPy (tstate );
1014- assert (frame != & entry_frame );
1052+ assert (frame != entry_frame );
10151053 // GH-99729: We need to unlink the frame *before* clearing it:
10161054 _PyInterpreterFrame * dying = frame ;
10171055 frame = tstate -> current_frame = dying -> previous ;
10181056 _PyEval_FrameClearAndPop (tstate , dying );
10191057 frame -> return_offset = 0 ;
1020- if (frame == & entry_frame ) {
1058+ if (frame == entry_frame ) {
10211059 /* Restore previous frame and exit */
10221060 tstate -> current_frame = frame -> previous ;
10231061 tstate -> c_recursion_remaining += PY_EVAL_C_STACK_UNITS ;
0 commit comments