@@ -250,6 +250,7 @@ maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals)
250250 lltrace = * python_lltrace - '0' ; // TODO: Parse an int and all that
251251 }
252252 }
253+ lltrace = 5 ;
253254 if (lltrace >= 5 ) {
254255 lltrace_resume_frame (frame );
255256 }
@@ -271,9 +272,8 @@ static void monitor_unwind(PyThreadState *tstate,
271272static int monitor_handled (PyThreadState * tstate ,
272273 _PyInterpreterFrame * frame ,
273274 _Py_CODEUNIT * instr , PyObject * exc );
274- static void monitor_throw (PyThreadState * tstate ,
275- _PyInterpreterFrame * frame ,
276- _Py_CODEUNIT * instr );
275+ void _Py_MonitorThrow (PyThreadState * tstate ,
276+ _PyInterpreterFrame * frame );
277277
278278static int get_exception_handler (PyCodeObject * , int , int * , int * , int * );
279279static _PyInterpreterFrame *
@@ -671,14 +671,22 @@ PyEval_EvalFrame(PyFrameObject *f)
671671{
672672 /* Function kept for backward compatibility */
673673 PyThreadState * tstate = _PyThreadState_GET ();
674- return _PyEval_EvalFrame (tstate , f -> f_frame , 0 );
674+ if (tstate -> interp -> eval_frame == NULL ) {
675+ return _PyEval_Interpret (tstate , f -> f_frame );
676+ }
677+ return tstate -> interp -> eval_frame (tstate , f -> f_frame , 0 );
675678}
676679
677680PyObject *
678681PyEval_EvalFrameEx (PyFrameObject * f , int throwflag )
679682{
680- PyThreadState * tstate = _PyThreadState_GET ();
681- return _PyEval_EvalFrame (tstate , f -> f_frame , throwflag );
683+ if (throwflag ) {
684+ PyThreadState * tstate = _PyThreadState_GET ();
685+ if (_Py_UnwindFrame (tstate , f -> f_frame , f -> f_frame -> instr_ptr )) {
686+ return NULL ;
687+ }
688+ }
689+ return PyEval_EvalFrame (f );
682690}
683691
684692#include "ceval_macros.h"
@@ -761,14 +769,84 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch)
761769 }
762770}
763771
772+ _Py_CODEUNIT *
773+ unwind_frame (PyThreadState * tstate , _PyInterpreterFrame * frame , _Py_CODEUNIT * location )
774+ {
775+ int offset , level , handler , lasti ;
776+ start :
777+ /* We can't use frame->instr_ptr here, as RERAISE may have set it */
778+ offset = (int )(location - _PyCode_CODE (_PyFrame_GetCode (frame )));
779+ if (get_exception_handler (_PyFrame_GetCode (frame ), offset , & level , & handler , & lasti ) == 0 ) {
780+ // No handlers, so exit.
781+ assert (PyErr_Occurred ());
782+
783+ /* Pop remaining stack entries. */
784+ _PyStackRef * stackbase = _PyFrame_Stackbase (frame );
785+ while (frame -> stackpointer > stackbase ) {
786+ PyStackRef_XCLOSE (_PyFrame_StackPop (frame ));
787+ }
788+ monitor_unwind (tstate , frame , location );
789+ // GH-99729: We need to unlink the frame *before* clearing it:
790+ _PyInterpreterFrame * dying = frame ;
791+ tstate -> current_frame = dying -> previous ;
792+ _PyEval_FrameClearAndPop (tstate , dying );
793+ return NULL ;
794+ }
795+
796+ _PyStackRef * new_top = _PyFrame_Stackbase (frame ) + level ;
797+ assert (frame -> stackpointer >= new_top );
798+ while (frame -> stackpointer > new_top ) {
799+ PyStackRef_XCLOSE (_PyFrame_StackPop (frame ));
800+ }
801+ if (lasti ) {
802+ int frame_lasti = _PyInterpreterFrame_LASTI (frame );
803+ PyObject * lasti = PyLong_FromLong (frame_lasti );
804+ if (lasti == NULL ) {
805+ return NULL ;
806+ }
807+ _PyFrame_StackPush (frame , PyStackRef_FromPyObjectSteal (lasti ));
808+ }
809+
810+ /* Make the raw exception data
811+ available to the handler,
812+ so a program can emulate the
813+ Python main loop. */
814+ PyObject * exc = _PyErr_GetRaisedException (tstate );
815+ _PyFrame_StackPush (frame , PyStackRef_FromPyObjectSteal (exc ));
816+ location = _PyCode_CODE (_PyFrame_GetCode (frame )) + handler ;
817+ frame -> instr_ptr = location ;
818+ if (monitor_handled (tstate , frame , location , exc ) < 0 ) {
819+ goto start ;
820+ }
821+ return location ;
822+ }
823+
824+ _Py_CODEUNIT *
825+ _Py_UnwindFrame (PyThreadState * tstate , _PyInterpreterFrame * frame , _Py_CODEUNIT * location )
826+ {
827+ assert (frame -> stackpointer != NULL );
828+ return unwind_frame (tstate , frame , location );
829+ }
830+
764831
765832/* _PyEval_EvalFrameDefault() is a *big* function,
766833 * so consume 3 units of C stack */
767834#define PY_EVAL_C_STACK_UNITS 2
768835
769836
837+ PyObject *
838+ _PyEval_EvalFrameDefault (PyThreadState * tstate , struct _PyInterpreterFrame * frame , int throwflag )
839+ {
840+ if (throwflag ) {
841+ if (_Py_UnwindFrame (tstate , frame , frame -> instr_ptr )) {
842+ return NULL ;
843+ }
844+ }
845+ return _PyEval_Interpret (tstate , frame );
846+ }
847+
770848PyObject * _Py_HOT_FUNCTION
771- _PyEval_EvalFrameDefault (PyThreadState * tstate , _PyInterpreterFrame * frame , int throwflag )
849+ _PyEval_Interpret (PyThreadState * tstate , _PyInterpreterFrame * frame )
772850{
773851 _Py_EnsureTstateNotNULL (tstate );
774852 CALL_STAT_INC (pyeval_calls );
@@ -817,13 +895,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
817895 goto exit_unwind ;
818896 }
819897
820- /* support for generator.throw() */
821- if (throwflag ) {
822- if (_Py_EnterRecursivePy (tstate )) {
823- goto exit_unwind ;
824- }
825- /* Because this avoids the RESUME,
826- * we need to update instrumentation */
827898#ifdef Py_GIL_DISABLED
828899 /* Load thread-local bytecode */
829900 if (frame -> tlbc_index != ((_PyThreadStateImpl * )tstate )-> tlbc_index ) {
@@ -837,12 +908,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
837908 frame -> instr_ptr = bytecode + off ;
838909 }
839910#endif
840- _Py_Instrument (_PyFrame_GetCode (frame ), tstate -> interp );
841- monitor_throw (tstate , frame , frame -> instr_ptr );
842- /* TO DO -- Monitor throw entry. */
843- goto resume_with_error ;
844- }
845-
846911 /* Local "register" variables.
847912 * These are cached values from the frame and code object. */
848913 _Py_CODEUNIT * next_instr ;
@@ -893,6 +958,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
893958#ifdef _Py_JIT
894959 assert (0 );
895960#else
961+ stack_pointer = _PyFrame_GetStackPointer (frame );
896962
897963#undef LOAD_IP
898964#define LOAD_IP (UNUSED ) (void)0
@@ -1757,7 +1823,10 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
17571823 return NULL ;
17581824 }
17591825 EVAL_CALL_STAT_INC (EVAL_CALL_VECTOR );
1760- return _PyEval_EvalFrame (tstate , frame , 0 );
1826+ if (tstate -> interp -> eval_frame != NULL ) {
1827+ return tstate -> interp -> eval_frame (tstate , frame , 0 );
1828+ }
1829+ return _PyEval_Interpret (tstate , frame );
17611830}
17621831
17631832/* Legacy API */
@@ -2235,15 +2304,14 @@ monitor_handled(PyThreadState *tstate,
22352304 return _Py_call_instrumentation_arg (tstate , PY_MONITORING_EVENT_EXCEPTION_HANDLED , frame , instr , exc );
22362305}
22372306
2238- static void
2239- monitor_throw (PyThreadState * tstate ,
2240- _PyInterpreterFrame * frame ,
2241- _Py_CODEUNIT * instr )
2307+ void
2308+ _Py_MonitorThrow (PyThreadState * tstate ,
2309+ _PyInterpreterFrame * frame )
22422310{
22432311 if (no_tools_for_global_event (tstate , PY_MONITORING_EVENT_PY_THROW )) {
22442312 return ;
22452313 }
2246- do_monitor_exc (tstate , frame , instr , PY_MONITORING_EVENT_PY_THROW );
2314+ do_monitor_exc (tstate , frame , frame -> instr_ptr , PY_MONITORING_EVENT_PY_THROW );
22472315}
22482316
22492317void
0 commit comments