@@ -596,6 +596,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
596
596
#define LLTRACE_HANDLE_UNWINDING (obj__ , msg__ ) (void)1
597
597
#endif
598
598
599
+ #if 1
600
+ static inline int
601
+ handle_unwinding (int lineno , PyFrameObject * f ,
602
+ PyObject * * stack_pointer , int oparg , PyThreadState * tstate ,
603
+ const _Py_CODEUNIT * first_instr , const _Py_CODEUNIT * next_instr ,
604
+ char frame_func , int has_opcode , PyObject * * pretval );
605
+ #define HANDLE_UNWINDING (frame_func , has_opcode , retval__ ) \
606
+ if (handle_unwinding(__LINE__, f, stack_pointer, oparg, tstate, \
607
+ first_instr, next_instr, (frame_func), (has_opcode), &(retval__)))\
608
+ return (retval__)
609
+ #else
610
+ /* keep the old macro in case of performance problems */
599
611
#define HANDLE_UNWINDING (frame_func , has_opcode , retval__ ) \
600
612
do { \
601
613
if (has_opcode) \
@@ -642,6 +654,7 @@ do { \
642
654
next_instr += 1 + EXTENDED_ARG_OFFSET (oparg ); \
643
655
LLTRACE_HANDLE_UNWINDING ((retval__ ), "handle_unwinding end:" );\
644
656
} while (0 )
657
+ #endif
645
658
646
659
/* To be called in the slp_continue_<xxxx> block, if
647
660
* HANDLE_UNWINDING is used with has_opcode==1
@@ -3824,6 +3837,56 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3824
3837
3825
3838
3826
3839
#ifdef STACKLESS
3840
+ static inline int
3841
+ handle_unwinding (int lineno , PyFrameObject * f ,
3842
+ PyObject * * stack_pointer , int oparg , PyThreadState * tstate ,
3843
+ const _Py_CODEUNIT * first_instr , const _Py_CODEUNIT * next_instr ,
3844
+ char frame_func , int has_opcode , PyObject * * pretval )
3845
+ {
3846
+ assert (* pretval ); /* check argument */
3847
+ if (has_opcode )
3848
+ next_instr -= 1 + EXTENDED_ARG_OFFSET (oparg );
3849
+ assert (SLP_FRAME_EXECUTING_VALUE == f -> f_executing );
3850
+ if (frame_func != SLP_FRAME_EXECUTING_VALUE ) {
3851
+ f -> f_executing = frame_func ;
3852
+ /* check argument: must be an executing frame with retval */
3853
+ assert (frame_func != SLP_FRAME_EXECUTING_NOVAL );
3854
+ assert (SLP_FRAME_IS_EXECUTING (f ));
3855
+ }
3856
+ /* keep the reference to the frame to be called. */
3857
+ f -> f_stacktop = stack_pointer ;
3858
+ /* Set f->f_lasti to the instruction before the current one or to the */
3859
+ /* first instruction (-1). See "f->f_lasti refers to ..." above. */
3860
+ f -> f_lasti = INSTR_OFFSET () != 0 ?
3861
+ assert (INSTR_OFFSET () >= sizeof (_Py_CODEUNIT )),
3862
+ (int )(INSTR_OFFSET () - sizeof (_Py_CODEUNIT )) : -1 ;
3863
+ if (SLP_PEEK_NEXT_FRAME (tstate )-> f_back != f ) {
3864
+ LLTRACE_HANDLE_UNWINDING (STACKLESS_RETVAL (tstate , * pretval ), "handle_unwinding return:" );
3865
+ return 1 ;
3866
+ }
3867
+ STACKLESS_UNPACK (tstate , * pretval );
3868
+ {
3869
+ LLTRACE_HANDLE_UNWINDING (* pretval , "handle_unwinding call next frame:" );
3870
+ PyFrameObject * f2 = SLP_CLAIM_NEXT_FRAME (tstate );
3871
+ * pretval = CALL_FRAME_FUNCTION (f2 , 0 , * pretval );
3872
+ Py_DECREF (f2 );
3873
+ if (SLP_PEEK_NEXT_FRAME (tstate ) != f ) {
3874
+ assert (f -> f_executing == (frame_func ));
3875
+ LLTRACE_HANDLE_UNWINDING (STACKLESS_RETVAL (tstate , * pretval ), "handle_unwinding return from next frame:" );
3876
+ return 1 ;
3877
+ }
3878
+ f2 = SLP_CLAIM_NEXT_FRAME (tstate );
3879
+ assert (f == f2 );
3880
+ Py_DECREF (f2 );
3881
+ }
3882
+ if (STACKLESS_UNWINDING (* pretval ))
3883
+ STACKLESS_UNPACK (tstate , * pretval );
3884
+ f -> f_stacktop = NULL ;
3885
+ assert (f -> f_executing == frame_func );
3886
+ f -> f_executing = SLP_FRAME_EXECUTING_VALUE ;
3887
+ LLTRACE_HANDLE_UNWINDING (* pretval , "handle_unwinding end:" );
3888
+ return 0 ;
3889
+ }
3827
3890
3828
3891
static PyObject *
3829
3892
run_frame_dispatch (PyCFrameObject * cf , int exc , PyObject * retval )
0 commit comments