55#include  "pycore_long.h"           // _PyLong 
66#include  "pycore_pystate.h"        // _PyThreadState_GET() 
77#include  "pycore_setobject.h"      // _PySet_NextEntry() 
8+ #include  "cpython/code.h"          // CO_MAXBLOCKS 
89
910
1011/* See PEP 765 */ 
@@ -23,7 +24,8 @@ typedef struct {
2324    int  recursion_depth ;            /* current recursion depth */ 
2425    int  recursion_limit ;            /* recursion limit */ 
2526
26-     ControlFlowInFinallyContext  cf_finally ;
27+     int  cf_finally_next ;
28+     ControlFlowInFinallyContext  cf_finally [CO_MAXBLOCKS ];
2729} _PyASTOptimizeState ;
2830
2931#define  ENTER_RECURSIVE (ST ) \
@@ -41,20 +43,27 @@ typedef struct {
4143    } while(0)
4244
4345
44- static  ControlFlowInFinallyContext 
45- overwrite_state (_PyASTOptimizeState  * state , bool  finally , bool  funcdef , bool  loop )
46+ static  int 
47+ push_cf_context (_PyASTOptimizeState  * state ,  stmt_ty   node , bool  finally , bool  funcdef , bool  loop )
4648{
47-     ControlFlowInFinallyContext  saved  =  state -> cf_finally ;
48-     state -> cf_finally .in_finally  =  finally ;
49-     state -> cf_finally .in_funcdef  =  funcdef ;
50-     state -> cf_finally .in_loop  =  loop ;
51-     return  saved ;
49+     if  (state -> cf_finally_next  ==  CO_MAXBLOCKS ) {
50+         PyErr_SetString (PyExc_SyntaxError , "too many statically nested blocks" );
51+         PyErr_RangedSyntaxLocationObject (state -> filename , node -> lineno , node -> col_offset  +  1 ,
52+                                          node -> end_lineno , node -> end_col_offset  +  1 );
53+         return  0 ;
54+     }
55+     ControlFlowInFinallyContext  * ctx  =  & state -> cf_finally [state -> cf_finally_next ++ ];
56+     ctx -> in_finally  =  finally ;
57+     ctx -> in_funcdef  =  funcdef ;
58+     ctx -> in_loop  =  loop ;
59+     return  1 ;
5260}
5361
5462static  void 
55- restore_state (_PyASTOptimizeState  * state ,  ControlFlowInFinallyContext   * saved )
63+ pop_cf_context (_PyASTOptimizeState  * state )
5664{
57-     state -> cf_finally  =  * saved ;
65+     assert (state -> cf_finally_next  >  0 );
66+     state -> cf_finally_next -- ;
5867}
5968
6069static  int 
@@ -74,9 +83,12 @@ control_flow_in_finally_warning(const char *kw, stmt_ty n, _PyASTOptimizeState *
7483static  int 
7584before_return (_PyASTOptimizeState  * state , stmt_ty  node_ )
7685{
77-     if  (state -> cf_finally .in_finally  &&  ! state -> cf_finally .in_funcdef ) {
78-         if  (!control_flow_in_finally_warning ("return" , node_ , state )) {
79-             return  0 ;
86+     if  (state -> cf_finally_next  >  0 ) {
87+         ControlFlowInFinallyContext  * ctx  =  & state -> cf_finally [state -> cf_finally_next  -  1 ];
88+         if  (ctx -> in_finally  &&  ! ctx -> in_funcdef ) {
89+             if  (!control_flow_in_finally_warning ("return" , node_ , state )) {
90+                 return  0 ;
91+             }
8092        }
8193    }
8294    return  1 ;
@@ -85,22 +97,30 @@ before_return(_PyASTOptimizeState *state, stmt_ty node_)
8597static  int 
8698before_loop_exit (_PyASTOptimizeState  * state , stmt_ty  node_ , const  char  * kw )
8799{
88-     if  (state -> cf_finally .in_finally  &&  ! state -> cf_finally .in_loop ) {
89-         if  (!control_flow_in_finally_warning (kw , node_ , state )) {
90-             return  0 ;
100+     if  (state -> cf_finally_next  >  0 ) {
101+         ControlFlowInFinallyContext  * ctx  =  & state -> cf_finally [state -> cf_finally_next  -  1 ];
102+         if  (ctx -> in_finally  &&  ! ctx -> in_loop ) {
103+             if  (!control_flow_in_finally_warning (kw , node_ , state )) {
104+                 return  0 ;
105+             }
91106        }
92107    }
93108    return  1 ;
94109}
95110
96- #define  RESTORE_STATE (S , CFS ) restore_state((S), (CFS))
111+ #define  PUSH_CONTEXT (S , N , FINALLY , FUNCDEF , LOOP ) \
112+     if (!push_cf_context((S), (N), (FINALLY), (FUNCDEF), (LOOP))) { \
113+         return 0; \
114+     }
115+ 
116+ #define  POP_CONTEXT (S ) pop_cf_context(S)
97117
98- #define  BEFORE_FINALLY (S ) overwrite_state ((S), true, false, false)
99- #define  AFTER_FINALLY (S ,  CFS ) RESTORE_STATE((S), (CFS) )
100- #define  BEFORE_FUNC_BODY (S ) overwrite_state ((S), false, true, false)
101- #define  AFTER_FUNC_BODY (S ,  CFS ) RESTORE_STATE((S), (CFS) )
102- #define  BEFORE_LOOP_BODY (S ) overwrite_state ((S), false, false, true)
103- #define  AFTER_LOOP_BODY (S ,  CFS ) RESTORE_STATE((S), (CFS) )
118+ #define  BEFORE_FINALLY (S ,  N )    PUSH_CONTEXT ((S), (N ), true, false, false)
119+ #define  AFTER_FINALLY (S )        POP_CONTEXT(S )
120+ #define  BEFORE_FUNC_BODY (S ,  N )  PUSH_CONTEXT ((S), (N ), false, true, false)
121+ #define  AFTER_FUNC_BODY (S )      POP_CONTEXT(S )
122+ #define  BEFORE_LOOP_BODY (S ,  N )  PUSH_CONTEXT ((S), (N ), false, false, true)
123+ #define  AFTER_LOOP_BODY (S )      POP_CONTEXT(S )
104124
105125#define  BEFORE_RETURN (S , N ) \
106126    if (!before_return((S), (N))) { \
@@ -923,9 +943,9 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
923943    case  FunctionDef_kind : {
924944        CALL_SEQ (astfold_type_param , type_param , node_ -> v .FunctionDef .type_params );
925945        CALL (astfold_arguments , arguments_ty , node_ -> v .FunctionDef .args );
926-         ControlFlowInFinallyContext   saved_context   =   BEFORE_FUNC_BODY (state );
946+         BEFORE_FUNC_BODY (state ,  node_ );
927947        CALL (astfold_body , asdl_seq , node_ -> v .FunctionDef .body );
928-         AFTER_FUNC_BODY (state ,  & saved_context );
948+         AFTER_FUNC_BODY (state );
929949        CALL_SEQ (astfold_expr , expr , node_ -> v .FunctionDef .decorator_list );
930950        if  (!(state -> ff_features  &  CO_FUTURE_ANNOTATIONS )) {
931951            CALL_OPT (astfold_expr , expr_ty , node_ -> v .FunctionDef .returns );
@@ -935,9 +955,9 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
935955    case  AsyncFunctionDef_kind : {
936956        CALL_SEQ (astfold_type_param , type_param , node_ -> v .AsyncFunctionDef .type_params );
937957        CALL (astfold_arguments , arguments_ty , node_ -> v .AsyncFunctionDef .args );
938-         ControlFlowInFinallyContext   saved_context   =   BEFORE_FUNC_BODY (state );
958+         BEFORE_FUNC_BODY (state ,  node_ );
939959        CALL (astfold_body , asdl_seq , node_ -> v .AsyncFunctionDef .body );
940-         AFTER_FUNC_BODY (state ,  & saved_context );
960+         AFTER_FUNC_BODY (state );
941961        CALL_SEQ (astfold_expr , expr , node_ -> v .AsyncFunctionDef .decorator_list );
942962        if  (!(state -> ff_features  &  CO_FUTURE_ANNOTATIONS )) {
943963            CALL_OPT (astfold_expr , expr_ty , node_ -> v .AsyncFunctionDef .returns );
@@ -981,26 +1001,26 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
9811001    case  For_kind : {
9821002        CALL (astfold_expr , expr_ty , node_ -> v .For .target );
9831003        CALL (astfold_expr , expr_ty , node_ -> v .For .iter );
984-         ControlFlowInFinallyContext   saved_context   =   BEFORE_LOOP_BODY (state );
1004+         BEFORE_LOOP_BODY (state ,  node_ );
9851005        CALL_SEQ (astfold_stmt , stmt , node_ -> v .For .body );
986-         AFTER_LOOP_BODY (state ,  & saved_context );
1006+         AFTER_LOOP_BODY (state );
9871007        CALL_SEQ (astfold_stmt , stmt , node_ -> v .For .orelse );
9881008        break ;
9891009    }
9901010    case  AsyncFor_kind : {
9911011        CALL (astfold_expr , expr_ty , node_ -> v .AsyncFor .target );
9921012        CALL (astfold_expr , expr_ty , node_ -> v .AsyncFor .iter );
993-         ControlFlowInFinallyContext   saved_context   =   BEFORE_LOOP_BODY (state );
1013+         BEFORE_LOOP_BODY (state ,  node_ );
9941014        CALL_SEQ (astfold_stmt , stmt , node_ -> v .AsyncFor .body );
995-         AFTER_LOOP_BODY (state ,  & saved_context );
1015+         AFTER_LOOP_BODY (state );
9961016        CALL_SEQ (astfold_stmt , stmt , node_ -> v .AsyncFor .orelse );
9971017        break ;
9981018    }
9991019    case  While_kind : {
10001020        CALL (astfold_expr , expr_ty , node_ -> v .While .test );
1001-         ControlFlowInFinallyContext   saved_context   =   BEFORE_LOOP_BODY (state );
1021+         BEFORE_LOOP_BODY (state ,  node_ );
10021022        CALL_SEQ (astfold_stmt , stmt , node_ -> v .While .body );
1003-         AFTER_LOOP_BODY (state ,  & saved_context );
1023+         AFTER_LOOP_BODY (state );
10041024        CALL_SEQ (astfold_stmt , stmt , node_ -> v .While .orelse );
10051025        break ;
10061026    }
@@ -1025,18 +1045,18 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
10251045        CALL_SEQ (astfold_stmt , stmt , node_ -> v .Try .body );
10261046        CALL_SEQ (astfold_excepthandler , excepthandler , node_ -> v .Try .handlers );
10271047        CALL_SEQ (astfold_stmt , stmt , node_ -> v .Try .orelse );
1028-         ControlFlowInFinallyContext   saved_context   =   BEFORE_FINALLY (state );
1048+         BEFORE_FINALLY (state ,  node_ );
10291049        CALL_SEQ (astfold_stmt , stmt , node_ -> v .Try .finalbody );
1030-         AFTER_FINALLY (state ,  & saved_context );
1050+         AFTER_FINALLY (state );
10311051        break ;
10321052    }
10331053    case  TryStar_kind : {
10341054        CALL_SEQ (astfold_stmt , stmt , node_ -> v .TryStar .body );
10351055        CALL_SEQ (astfold_excepthandler , excepthandler , node_ -> v .TryStar .handlers );
10361056        CALL_SEQ (astfold_stmt , stmt , node_ -> v .TryStar .orelse );
1037-         ControlFlowInFinallyContext   saved_context   =   BEFORE_FINALLY (state );
1057+         BEFORE_FINALLY (state ,  node_ );
10381058        CALL_SEQ (astfold_stmt , stmt , node_ -> v .TryStar .finalbody );
1039-         AFTER_FINALLY (state ,  & saved_context );
1059+         AFTER_FINALLY (state );
10401060        break ;
10411061    }
10421062    case  Assert_kind :
0 commit comments