gh-122313: Clean up deep recursion guarding code in the compiler (GH-… · python/cpython@efcd65c

GitHub

@@ -15,6 +15,19 @@ typedef struct {

1515intrecursion_limit; /* recursion limit */

1616} _PyASTOptimizeState;

171718+#defineENTER_RECURSIVE(ST) \

19+ do { \

20+ if (++(ST)->recursion_depth > (ST)->recursion_limit) { \

21+ PyErr_SetString(PyExc_RecursionError, \

22+ "maximum recursion depth exceeded during compilation"); \

23+ return 0; \

24+ } \

25+ } while(0)

26+27+#defineLEAVE_RECURSIVE(ST) \

28+ do { \

29+ --(ST)->recursion_depth; \

30+ } while(0)

18311932staticint

2033make_const(expr_tynode, PyObject*val, PyArena*arena)

@@ -708,11 +721,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

708721staticint

709722astfold_expr(expr_tynode_, PyArena*ctx_, _PyASTOptimizeState*state)

710723{

711-if (++state->recursion_depth>state->recursion_limit) {

712-PyErr_SetString(PyExc_RecursionError,

713-"maximum recursion depth exceeded during compilation");

714-return0;

715- }

724+ENTER_RECURSIVE(state);

716725switch (node_->kind) {

717726caseBoolOp_kind:

718727CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);

@@ -811,7 +820,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

811820caseName_kind:

812821if (node_->v.Name.ctx==Load&&

813822_PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {

814-state->recursion_depth--;

823+LEAVE_RECURSIVE(state);

815824returnmake_const(node_, PyBool_FromLong(!state->optimize), ctx_);

816825 }

817826break;

@@ -824,7 +833,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

824833// No default case, so the compiler will emit a warning if new expression

825834// kinds are added without being handled here

826835 }

827-state->recursion_depth--;

836+LEAVE_RECURSIVE(state);;

828837return1;

829838}

830839@@ -871,11 +880,7 @@ astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

871880staticint

872881astfold_stmt(stmt_tynode_, PyArena*ctx_, _PyASTOptimizeState*state)

873882{

874-if (++state->recursion_depth>state->recursion_limit) {

875-PyErr_SetString(PyExc_RecursionError,

876-"maximum recursion depth exceeded during compilation");

877-return0;

878- }

883+ENTER_RECURSIVE(state);

879884switch (node_->kind) {

880885caseFunctionDef_kind:

881886CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params);

@@ -999,7 +1004,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

9991004// No default case, so the compiler will emit a warning if new statement

10001005// kinds are added without being handled here

10011006 }

1002-state->recursion_depth--;

1007+LEAVE_RECURSIVE(state);

10031008return1;

10041009}

10051010@@ -1031,11 +1036,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

10311036// Currently, this is really only used to form complex/negative numeric

10321037// constants in MatchValue and MatchMapping nodes

10331038// We still recurse into all subexpressions and subpatterns anyway

1034-if (++state->recursion_depth>state->recursion_limit) {

1035-PyErr_SetString(PyExc_RecursionError,

1036-"maximum recursion depth exceeded during compilation");

1037-return0;

1038- }

1039+ENTER_RECURSIVE(state);

10391040switch (node_->kind) {

10401041caseMatchValue_kind:

10411042CALL(astfold_expr, expr_ty, node_->v.MatchValue.value);

@@ -1067,7 +1068,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)

10671068// No default case, so the compiler will emit a warning if new pattern

10681069// kinds are added without being handled here

10691070 }

1070-state->recursion_depth--;

1071+LEAVE_RECURSIVE(state);

10711072return1;

10721073}

10731074