@@ -548,6 +548,64 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
548
548
return tstate -> interp -> eval_frame (f , throwflag );
549
549
}
550
550
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
+
551
609
PyObject * _Py_HOT_FUNCTION
552
610
#ifdef STACKLESS
553
611
slp_eval_frame_value (PyFrameObject * f , int throwflag , PyObject * retval )
@@ -2945,10 +3003,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
2945
3003
STACKLESS_ASSERT ();
2946
3004
}
2947
3005
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 );
2952
3007
iter = TOP ();
2953
3008
}
2954
3009
#else
@@ -3056,10 +3111,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3056
3111
Py_DECREF (enter );
3057
3112
#ifdef STACKLESS
3058
3113
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 );
3063
3115
}
3064
3116
#endif
3065
3117
if (res == NULL )
@@ -3158,10 +3210,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3158
3210
Py_DECREF (exit_func );
3159
3211
#ifdef STACKLESS
3160
3212
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 );
3165
3214
/* recompute exc after the goto */
3166
3215
exc = TOP ();
3167
3216
if (PyLong_Check (exc ))
@@ -3283,8 +3332,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3283
3332
}
3284
3333
#ifdef STACKLESS
3285
3334
if (STACKLESS_UNWINDING (res )) {
3286
- retval = res ;
3287
- goto stackless_call ;
3335
+ HANDLE_UNWINDING (NULL , 0 , res );
3288
3336
}
3289
3337
#endif
3290
3338
@@ -3302,10 +3350,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3302
3350
stack_pointer = sp ;
3303
3351
#ifdef STACKLESS
3304
3352
if (STACKLESS_UNWINDING (res )) {
3305
- retval = res ;
3306
- goto stackless_call ;
3307
- stackless_call_return :
3308
- res = retval ;
3353
+ HANDLE_UNWINDING (NULL , 0 , res );
3309
3354
}
3310
3355
#endif
3311
3356
PUSH (res );
@@ -3326,8 +3371,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3326
3371
Py_DECREF (names );
3327
3372
#ifdef STACKLESS
3328
3373
if (STACKLESS_UNWINDING (res )) {
3329
- retval = res ;
3330
- goto stackless_call ;
3374
+ HANDLE_UNWINDING (NULL , 0 , res );
3331
3375
}
3332
3376
#endif
3333
3377
PUSH (res );
@@ -3387,12 +3431,11 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3387
3431
Py_XDECREF (kwargs );
3388
3432
#ifdef STACKLESS
3389
3433
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
3394
3438
#endif
3395
-
3396
3439
SET_TOP (result );
3397
3440
if (result == NULL ) {
3398
3441
goto error ;
@@ -3710,77 +3753,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3710
3753
3711
3754
return _Py_CheckFunctionResult (NULL , retval , "PyEval_EvalFrameEx" );
3712
3755
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 ;
3784
3756
3785
3757
stackless_interrupt_call :
3786
3758
/* interrupted during unwinding */
0 commit comments