@@ -548,6 +548,64 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
548548 return tstate -> interp -> eval_frame (f , throwflag );
549549}
550550
551+ #ifdef STACKLESS
552+ #define EXTENDED_ARG_OFFSET (x ) \
553+ (assert(sizeof(x) == 4), \
554+ (!((x) >> 8) ? 0 : \
555+ (!((x) >> 16) ? 1 : \
556+ (!((x) >> 24) ? 2 : 3 ))))
557+
558+ #define HANDLE_UNWINDING (frame_func , has_opcode , retval__ ) \
559+ do { \
560+ if (has_opcode) \
561+ next_instr -= 1 + EXTENDED_ARG_OFFSET(oparg); \
562+ SLP_DISABLE_GCC_W_ADDRESS /* suppress warning, if frame_func is a function */ \
563+ if (frame_func != NULL ) { \
564+ SLP_RESTORE_WARNINGS \
565+ f -> f_execute = (frame_func ); \
566+ } \
567+ /* keep the reference to the frame to be called. */ \
568+ f -> f_stacktop = stack_pointer ; \
569+ /* Set f->f_lasti to the instruction before the current one or to the */ \
570+ /* first instruction (-1). See "f->f_lasti refers to ..." above. */ \
571+ f -> f_lasti = INSTR_OFFSET () != 0 ? \
572+ assert (INSTR_OFFSET () >= sizeof (_Py_CODEUNIT )), \
573+ (int )(INSTR_OFFSET () - sizeof (_Py_CODEUNIT )) : -1 ; \
574+ if (SLP_PEEK_NEXT_FRAME (tstate )-> f_back != f ) \
575+ return (retval__ ); \
576+ STACKLESS_UNPACK (tstate , (retval__ )); \
577+ { \
578+ PyFrameObject * f2 = SLP_CLAIM_NEXT_FRAME (tstate ); \
579+ (retval__ ) = CALL_FRAME_FUNCTION (f2 , 0 , (retval__ )); \
580+ Py_DECREF (f2 ); \
581+ if (SLP_PEEK_NEXT_FRAME (tstate ) != f ) { \
582+ assert (f -> f_execute == slp_eval_frame_value || f -> f_execute == slp_eval_frame_noval || \
583+ f -> f_execute == slp_eval_frame_setup_with || f -> f_execute == slp_eval_frame_with_cleanup ); \
584+ if (f -> f_execute == slp_eval_frame_noval ) \
585+ f -> f_execute = slp_eval_frame_value ; \
586+ return (retval__ ); \
587+ } \
588+ f2 = SLP_CLAIM_NEXT_FRAME (tstate ); \
589+ assert (f == f2 ); \
590+ Py_DECREF (f2 ); \
591+ } \
592+ if (STACKLESS_UNWINDING (retval__ )) \
593+ STACKLESS_UNPACK (tstate , (retval__ )); \
594+ f -> f_stacktop = NULL ; \
595+ SLP_DISABLE_GCC_W_ADDRESS /* suppress warning, if frame_func is a function */ \
596+ if (frame_func != NULL) { \
597+ SLP_RESTORE_WARNINGS \
598+ assert (f -> f_execute == (frame_func )); \
599+ } \
600+ else { \
601+ assert (f -> f_execute == slp_eval_frame_value || f -> f_execute == slp_eval_frame_noval ); \
602+ } \
603+ f -> f_execute = slp_eval_frame_value ; \
604+ if (has_opcode ) \
605+ next_instr += 1 + EXTENDED_ARG_OFFSET (oparg ); \
606+ } while (0 )
607+ #endif
608+
551609PyObject * _Py_HOT_FUNCTION
552610#ifdef STACKLESS
553611slp_eval_frame_value (PyFrameObject * f , int throwflag , PyObject * retval )
@@ -2945,10 +3003,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
29453003 STACKLESS_ASSERT ();
29463004 }
29473005 if (STACKLESS_UNWINDING (next )) {
2948- retval = next ;
2949- goto stackless_iter ;
2950- stackless_iter_return :
2951- next = retval ;
3006+ HANDLE_UNWINDING (slp_eval_frame_iter , 1 , next );
29523007 iter = TOP ();
29533008 }
29543009#else
@@ -3056,10 +3111,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
30563111 Py_DECREF (enter );
30573112#ifdef STACKLESS
30583113 if (STACKLESS_UNWINDING (res )) {
3059- retval = res ;
3060- goto stackless_setup_with ;
3061- stackless_setup_with_return :
3062- res = retval ;
3114+ HANDLE_UNWINDING (slp_eval_frame_setup_with , 1 , res );
30633115 }
30643116#endif
30653117 if (res == NULL )
@@ -3158,10 +3210,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
31583210 Py_DECREF (exit_func );
31593211#ifdef STACKLESS
31603212 if (STACKLESS_UNWINDING (res )) {
3161- retval = res ;
3162- goto stackless_with_cleanup ;
3163- stackless_with_cleanup_return :
3164- res = retval ;
3213+ HANDLE_UNWINDING (slp_eval_frame_with_cleanup , 0 , res );
31653214 /* recompute exc after the goto */
31663215 exc = TOP ();
31673216 if (PyLong_Check (exc ))
@@ -3283,8 +3332,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
32833332 }
32843333#ifdef STACKLESS
32853334 if (STACKLESS_UNWINDING (res )) {
3286- retval = res ;
3287- goto stackless_call ;
3335+ HANDLE_UNWINDING (NULL , 0 , res );
32883336 }
32893337#endif
32903338
@@ -3302,10 +3350,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
33023350 stack_pointer = sp ;
33033351#ifdef STACKLESS
33043352 if (STACKLESS_UNWINDING (res )) {
3305- retval = res ;
3306- goto stackless_call ;
3307- stackless_call_return :
3308- res = retval ;
3353+ HANDLE_UNWINDING (NULL , 0 , res );
33093354 }
33103355#endif
33113356 PUSH (res );
@@ -3326,8 +3371,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
33263371 Py_DECREF (names );
33273372#ifdef STACKLESS
33283373 if (STACKLESS_UNWINDING (res )) {
3329- retval = res ;
3330- goto stackless_call ;
3374+ HANDLE_UNWINDING (NULL , 0 , res );
33313375 }
33323376#endif
33333377 PUSH (res );
@@ -3387,12 +3431,11 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
33873431 Py_XDECREF (kwargs );
33883432#ifdef STACKLESS
33893433 if (STACKLESS_UNWINDING (result )) {
3390- retval = result ;
3391- ( void ) POP (); /* compensate for the PUSH(res) after label stackless_call_return: */
3392- goto stackless_call ;
3393- }
3434+ ( void ) POP (); /* top of stack causes a GC related assertion error */
3435+ HANDLE_UNWINDING ( NULL , 0 , result );
3436+ PUSH ( result )
3437+ } else
33943438#endif
3395-
33963439 SET_TOP (result );
33973440 if (result == NULL ) {
33983441 goto error ;
@@ -3710,77 +3753,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
37103753
37113754 return _Py_CheckFunctionResult (NULL , retval , "PyEval_EvalFrameEx" );
37123755
3713- stackless_setup_with :
3714- f -> f_execute = slp_eval_frame_setup_with ;
3715- goto stackless_call_with_opcode ;
3716-
3717- stackless_with_cleanup :
3718- f -> f_execute = slp_eval_frame_with_cleanup ;
3719- goto stackless_call ;
3720-
3721- stackless_iter :
3722- /* restore this opcode and enable frame to handle it */
3723- f -> f_execute = slp_eval_frame_iter ;
3724- stackless_call_with_opcode :
3725-
3726- #define EXTENDED_ARG_OFFSET (x ) \
3727- (assert(sizeof(x) == 4), \
3728- (!((x) >> 8) ? 0 : \
3729- (!((x) >> 16) ? 1 : \
3730- (!((x) >> 24) ? 2 : 3 ))))
3731-
3732- next_instr -= 1 + EXTENDED_ARG_OFFSET (oparg );
3733-
3734- stackless_call :
3735- /*
3736- * keep the reference to the frame to be called.
3737- */
3738- f -> f_stacktop = stack_pointer ;
3739-
3740- /* Set f->f_lasti to the instruction before the current one or to the
3741- * first instruction (-1). See "f->f_lasti refers to ..." above.
3742- */
3743- f -> f_lasti = INSTR_OFFSET () != 0 ?
3744- assert (INSTR_OFFSET () >= sizeof (_Py_CODEUNIT )),
3745- (int )(INSTR_OFFSET () - sizeof (_Py_CODEUNIT )) : -1 ;
3746- if (SLP_PEEK_NEXT_FRAME (tstate )-> f_back != f )
3747- return retval ;
3748- STACKLESS_UNPACK (tstate , retval );
3749- {
3750- PyFrameObject * f2 = SLP_CLAIM_NEXT_FRAME (tstate );
3751- retval = CALL_FRAME_FUNCTION (f2 , 0 , retval );
3752- Py_DECREF (f2 );
3753- if (SLP_PEEK_NEXT_FRAME (tstate ) != f ) {
3754- assert (f -> f_execute == slp_eval_frame_value || f -> f_execute == slp_eval_frame_noval ||
3755- f -> f_execute == slp_eval_frame_setup_with || f -> f_execute == slp_eval_frame_with_cleanup );
3756- if (f -> f_execute == slp_eval_frame_noval )
3757- f -> f_execute = slp_eval_frame_value ;
3758- return retval ;
3759- }
3760- f2 = SLP_CLAIM_NEXT_FRAME (tstate );
3761- assert (f == f2 );
3762- Py_DECREF (f2 );
3763- }
3764- if (STACKLESS_UNWINDING (retval ))
3765- STACKLESS_UNPACK (tstate , retval );
3766-
3767- f -> f_stacktop = NULL ;
3768- if (f -> f_execute == slp_eval_frame_iter ) {
3769- next_instr += 1 + EXTENDED_ARG_OFFSET (oparg );;
3770- f -> f_execute = slp_eval_frame_value ;
3771- goto stackless_iter_return ;
3772- }
3773- else if (f -> f_execute == slp_eval_frame_setup_with ) {
3774- next_instr += 1 + EXTENDED_ARG_OFFSET (oparg );
3775- f -> f_execute = slp_eval_frame_value ;
3776- goto stackless_setup_with_return ;
3777- }
3778- else if (f -> f_execute == slp_eval_frame_with_cleanup ) {
3779- f -> f_execute = slp_eval_frame_value ;
3780- goto stackless_with_cleanup_return ;
3781- }
3782-
3783- goto stackless_call_return ;
37843756
37853757stackless_interrupt_call :
37863758 /* interrupted during unwinding */
0 commit comments