From fc910a355198973988cb73fb2bae94604c84800d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 10 Feb 2025 16:31:05 +0000 Subject: [PATCH 01/41] Hide that C recursion protection is implemented with a counter. There is an imbalance in the AST somewhere. --- Include/ceval.h | 4 + Include/cpython/object.h | 8 +- Include/internal/pycore_ceval.h | 8 +- Include/internal/pycore_symtable.h | 2 - Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_capi/test_misc.py | 2 +- Objects/object.c | 5 +- Parser/asdl_c.py | 63 +-- Python/Python-ast.c | 733 ++++++++++++----------------- Python/ast.c | 392 +++++++-------- Python/ast_opt.c | 56 +-- Python/bytecodes.c | 14 +- Python/ceval.c | 41 +- Python/executor_cases.c.h | 6 +- Python/generated_cases.c.h | 14 +- Python/pythonrun.c | 25 +- Python/symtable.c | 47 +- Tools/cases_generator/analyzer.py | 1 + 18 files changed, 618 insertions(+), 805 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index 32ab38972e548f..23afbb6441ed5d 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -60,6 +60,10 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); +PyAPI_FUNC(int) Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count); +PyAPI_FUNC(void) _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate); +PyAPI_FUNC(void) Py_LeaveRecursiveCallTstate(PyThreadState *tstate); + PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 71bd01884426ad..c3d5bcc6f3031a 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -490,15 +490,15 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate); #define Py_TRASHCAN_BEGIN(op, dealloc) \ do { \ PyThreadState *tstate = PyThreadState_Get(); \ - if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ + if (Py_ReachedRecursionLimit(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ _PyTrash_thread_deposit_object(tstate, (PyObject *)op); \ break; \ } \ - tstate->c_recursion_remaining--; + _Py_EnterRecursiveCallUnchecked(tstate); /* The body of the deallocator is here. */ #define Py_TRASHCAN_END \ - tstate->c_recursion_remaining++; \ - if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \ + Py_LeaveRecursiveCallTstate(tstate); \ + if (tstate->delete_later && !Py_ReachedRecursionLimit(tstate, 2)) { \ _PyTrash_thread_destroy_chain(tstate); \ } \ } while (0); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index fea8665ae39ab5..cc5c07fff4794a 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -221,7 +221,7 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, } static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) { - assert(tstate->c_recursion_remaining > 0); + assert(tstate->c_recursion_remaining >= -2); // Allow a bit of wiggle room tstate->c_recursion_remaining--; } @@ -234,6 +234,12 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { tstate->c_recursion_remaining++; } +#define Py_RECURSION_LIMIT_MARGIN_MULTIPLIER 50 + +static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { + return tstate->c_recursion_remaining <= margin_count * Py_RECURSION_LIMIT_MARGIN_MULTIPLIER; +} + static inline void _Py_LeaveRecursiveCall(void) { PyThreadState *tstate = _PyThreadState_GET(); _Py_LeaveRecursiveCallTstate(tstate); diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index b7e274296112aa..3b87a7f869c4d7 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -82,8 +82,6 @@ struct symtable { PyObject *st_private; /* name of current class or NULL */ _PyFutureFeatures *st_future; /* module's future features that affect the symbol table */ - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ }; typedef struct _symtable_entry { diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index a438c8e81e4fd1..c95a27e9be5d0b 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -749,7 +749,7 @@ def next(self): def test_ast_recursion_limit(self): fail_depth = support.exceeds_recursion_limit() crash_depth = 100_000 - success_depth = int(support.get_c_recursion_limit() * 0.8) + success_depth = int(support.get_c_recursion_limit() * 0.6) if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() success_depth = min(success_depth, remaining) diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index b218f72f1bbce0..52d67baa8e88a0 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -408,7 +408,7 @@ def test_trashcan_subclass(self): # activated when its tp_dealloc is being called by a subclass from _testcapi import MyList L = None - for i in range(1000): + for i in range(support.get_c_recursion_limit()): L = MyList((L,)) @support.requires_resource('cpu') diff --git a/Objects/object.c b/Objects/object.c index f3c7fa6d906ad6..f1db80d0cb9bd6 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2910,8 +2910,7 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate) tups = [(tup,) for tup in tups] del tups */ - assert(tstate->c_recursion_remaining > Py_TRASHCAN_HEADROOM); - tstate->c_recursion_remaining--; + _Py_EnterRecursiveCallTstateUnchecked(tstate); while (tstate->delete_later) { PyObject *op = tstate->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; @@ -2933,7 +2932,7 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate) _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); } - tstate->c_recursion_remaining++; + _Py_LeaveRecursiveCallTstate(tstate); } void _Py_NO_RETURN diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 7b2df738119115..15bf8d9b3df783 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -738,7 +738,7 @@ def emit_sequence_constructor(self, name, type): class PyTypesDeclareVisitor(PickleVisitor): def visitProduct(self, prod, name): - self.emit("static PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, void*);" % name, 0) + self.emit("static PyObject* ast2obj_%s(struct ast_state *state, void*);" % name, 0) if prod.attributes: self.emit("static const char * const %s_attributes[] = {" % name, 0) for a in prod.attributes: @@ -759,7 +759,7 @@ def visitSum(self, sum, name): ptype = "void*" if is_simple(sum): ptype = get_c_type(name) - self.emit("static PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, %s);" % (name, ptype), 0) + self.emit("static PyObject* ast2obj_%s(struct ast_state *state, %s);" % (name, ptype), 0) for t in sum.types: self.visitConstructor(t, name) @@ -1734,8 +1734,8 @@ def visitModule(self, mod): /* Conversion AST -> Python */ -static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, asdl_seq *seq, - PyObject* (*func)(struct ast_state *state, struct validator *vstate, void*)) +static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, + PyObject* (*func)(struct ast_state *state, void*)) { Py_ssize_t i, n = asdl_seq_LEN(seq); PyObject *result = PyList_New(n); @@ -1743,7 +1743,7 @@ def visitModule(self, mod): if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, vstate, asdl_seq_GET_UNTYPED(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -1753,7 +1753,7 @@ def visitModule(self, mod): return result; } -static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), void *o) +static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { PyObject *op = (PyObject*)o; if (!op) { @@ -1765,7 +1765,7 @@ def visitModule(self, mod): #define ast2obj_identifier ast2obj_object #define ast2obj_string ast2obj_object -static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), long b) +static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) { return PyLong_FromLong(b); } @@ -2014,7 +2014,7 @@ class ObjVisitor(PickleVisitor): def func_begin(self, name): ctype = get_c_type(name) self.emit("PyObject*", 0) - self.emit("ast2obj_%s(struct ast_state *state, struct validator *vstate, void* _o)" % (name), 0) + self.emit("ast2obj_%s(struct ast_state *state, void* _o)" % (name), 0) self.emit("{", 0) self.emit("%s o = (%s)_o;" % (ctype, ctype), 1) self.emit("PyObject *result = NULL, *value = NULL;", 1) @@ -2022,17 +2022,15 @@ def func_begin(self, name): self.emit('if (!o) {', 1) self.emit("Py_RETURN_NONE;", 2) self.emit("}", 1) - self.emit("if (++vstate->recursion_depth > vstate->recursion_limit) {", 1) - self.emit("PyErr_SetString(PyExc_RecursionError,", 2) - self.emit('"maximum recursion depth exceeded during ast construction");', 3) + self.emit('if (Py_EnterRecursiveCall("during ast construction")) {', 1) self.emit("return NULL;", 2) self.emit("}", 1) def func_end(self): - self.emit("vstate->recursion_depth--;", 1) + self.emit("Py_LeaveRecursiveCall();", 1) self.emit("return result;", 1) self.emit("failed:", 0) - self.emit("vstate->recursion_depth--;", 1) + self.emit("Py_LeaveRecursiveCall();", 1) self.emit("Py_XDECREF(value);", 1) self.emit("Py_XDECREF(result);", 1) self.emit("return NULL;", 1) @@ -2050,7 +2048,7 @@ def visitSum(self, sum, name): self.visitConstructor(t, i + 1, name) self.emit("}", 1) for a in sum.attributes: - self.emit("value = ast2obj_%s(state, vstate, o->%s);" % (a.type, a.name), 1) + self.emit("value = ast2obj_%s(state, o->%s);" % (a.type, a.name), 1) self.emit("if (!value) goto failed;", 1) self.emit('if (PyObject_SetAttr(result, state->%s, value) < 0)' % a.name, 1) self.emit('goto failed;', 2) @@ -2058,7 +2056,7 @@ def visitSum(self, sum, name): self.func_end() def simpleSum(self, sum, name): - self.emit("PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, %s_ty o)" % (name, name), 0) + self.emit("PyObject* ast2obj_%s(struct ast_state *state, %s_ty o)" % (name, name), 0) self.emit("{", 0) self.emit("switch(o) {", 1) for t in sum.types: @@ -2076,7 +2074,7 @@ def visitProduct(self, prod, name): for field in prod.fields: self.visitField(field, name, 1, True) for a in prod.attributes: - self.emit("value = ast2obj_%s(state, vstate, o->%s);" % (a.type, a.name), 1) + self.emit("value = ast2obj_%s(state, o->%s);" % (a.type, a.name), 1) self.emit("if (!value) goto failed;", 1) self.emit("if (PyObject_SetAttr(result, state->%s, value) < 0)" % a.name, 1) self.emit('goto failed;', 2) @@ -2117,7 +2115,7 @@ def set(self, field, value, depth): self.emit("for(i = 0; i < n; i++)", depth+1) # This cannot fail, so no need for error handling self.emit( - "PyList_SET_ITEM(value, i, ast2obj_{0}(state, vstate, ({0}_ty)asdl_seq_GET({1}, i)));".format( + "PyList_SET_ITEM(value, i, ast2obj_{0}(state, ({0}_ty)asdl_seq_GET({1}, i)));".format( field.type, value ), @@ -2126,9 +2124,9 @@ def set(self, field, value, depth): ) self.emit("}", depth) else: - self.emit("value = ast2obj_list(state, vstate, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) + self.emit("value = ast2obj_list(state, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) else: - self.emit("value = ast2obj_%s(state, vstate, %s);" % (field.type, value), depth, reflow=False) + self.emit("value = ast2obj_%s(state, %s);" % (field.type, value), depth, reflow=False) class PartingShots(StaticVisitor): @@ -2140,28 +2138,8 @@ class PartingShots(StaticVisitor): if (state == NULL) { return NULL; } + PyObject *result = ast2obj_mod(state, t); - int starting_recursion_depth; - /* Be careful here to prevent overflow. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return NULL; - } - struct validator vstate; - vstate.recursion_limit = Py_C_RECURSION_LIMIT; - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - vstate.recursion_depth = starting_recursion_depth; - - PyObject *result = ast2obj_mod(state, &vstate, t); - - /* Check that the recursion depth counting balanced correctly */ - if (result && vstate.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST constructor recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, vstate.recursion_depth); - return NULL; - } return result; } @@ -2293,11 +2271,6 @@ def generate_module_def(mod, metadata, f, internal_h): #include "structmember.h" #include - struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ - }; - // Forward declaration static int init_types(void *arg); diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 7038e3c92ab8f0..95a9987e2223e1 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -13,11 +13,6 @@ #include "structmember.h" #include -struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - // Forward declaration static int init_types(void *arg); @@ -392,8 +387,7 @@ GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(type_param, type_param_ty) -static PyObject* ast2obj_mod(struct ast_state *state, struct validator *vstate, - void*); +static PyObject* ast2obj_mod(struct ast_state *state, void*); static const char * const Module_fields[]={ "body", "type_ignores", @@ -414,8 +408,7 @@ static const char * const stmt_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_stmt(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_stmt(struct ast_state *state, void*); static const char * const FunctionDef_fields[]={ "name", "args", @@ -550,8 +543,7 @@ static const char * const expr_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_expr(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_expr(struct ast_state *state, void*); static const char * const BoolOp_fields[]={ "op", "values", @@ -664,18 +656,12 @@ static const char * const Slice_fields[]={ "upper", "step", }; -static PyObject* ast2obj_expr_context(struct ast_state *state, struct validator - *vstate, expr_context_ty); -static PyObject* ast2obj_boolop(struct ast_state *state, struct validator - *vstate, boolop_ty); -static PyObject* ast2obj_operator(struct ast_state *state, struct validator - *vstate, operator_ty); -static PyObject* ast2obj_unaryop(struct ast_state *state, struct validator - *vstate, unaryop_ty); -static PyObject* ast2obj_cmpop(struct ast_state *state, struct validator - *vstate, cmpop_ty); -static PyObject* ast2obj_comprehension(struct ast_state *state, struct - validator *vstate, void*); +static PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty); +static PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty); +static PyObject* ast2obj_operator(struct ast_state *state, operator_ty); +static PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty); +static PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty); +static PyObject* ast2obj_comprehension(struct ast_state *state, void*); static const char * const comprehension_fields[]={ "target", "iter", @@ -688,15 +674,13 @@ static const char * const excepthandler_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_excepthandler(struct ast_state *state, struct - validator *vstate, void*); +static PyObject* ast2obj_excepthandler(struct ast_state *state, void*); static const char * const ExceptHandler_fields[]={ "type", "name", "body", }; -static PyObject* ast2obj_arguments(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_arguments(struct ast_state *state, void*); static const char * const arguments_fields[]={ "posonlyargs", "args", @@ -706,8 +690,7 @@ static const char * const arguments_fields[]={ "kwarg", "defaults", }; -static PyObject* ast2obj_arg(struct ast_state *state, struct validator *vstate, - void*); +static PyObject* ast2obj_arg(struct ast_state *state, void*); static const char * const arg_attributes[] = { "lineno", "col_offset", @@ -719,8 +702,7 @@ static const char * const arg_fields[]={ "annotation", "type_comment", }; -static PyObject* ast2obj_keyword(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_keyword(struct ast_state *state, void*); static const char * const keyword_attributes[] = { "lineno", "col_offset", @@ -731,8 +713,7 @@ static const char * const keyword_fields[]={ "arg", "value", }; -static PyObject* ast2obj_alias(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_alias(struct ast_state *state, void*); static const char * const alias_attributes[] = { "lineno", "col_offset", @@ -743,14 +724,12 @@ static const char * const alias_fields[]={ "name", "asname", }; -static PyObject* ast2obj_withitem(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_withitem(struct ast_state *state, void*); static const char * const withitem_fields[]={ "context_expr", "optional_vars", }; -static PyObject* ast2obj_match_case(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_match_case(struct ast_state *state, void*); static const char * const match_case_fields[]={ "pattern", "guard", @@ -762,8 +741,7 @@ static const char * const pattern_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_pattern(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_pattern(struct ast_state *state, void*); static const char * const MatchValue_fields[]={ "value", }; @@ -794,8 +772,7 @@ static const char * const MatchAs_fields[]={ static const char * const MatchOr_fields[]={ "patterns", }; -static PyObject* ast2obj_type_ignore(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_type_ignore(struct ast_state *state, void*); static const char * const TypeIgnore_fields[]={ "lineno", "tag", @@ -806,8 +783,7 @@ static const char * const type_param_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_type_param(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_type_param(struct ast_state *state, void*); static const char * const TypeVar_fields[]={ "name", "bound", @@ -5933,8 +5909,8 @@ add_attributes(struct ast_state *state, PyObject *type, const char * const *attr /* Conversion AST -> Python */ -static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, asdl_seq *seq, - PyObject* (*func)(struct ast_state *state, struct validator *vstate, void*)) +static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, + PyObject* (*func)(struct ast_state *state, void*)) { Py_ssize_t i, n = asdl_seq_LEN(seq); PyObject *result = PyList_New(n); @@ -5942,7 +5918,7 @@ static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, vstate, asdl_seq_GET_UNTYPED(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -5952,7 +5928,7 @@ static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, return result; } -static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), void *o) +static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { PyObject *op = (PyObject*)o; if (!op) { @@ -5964,7 +5940,7 @@ static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct valid #define ast2obj_identifier ast2obj_object #define ast2obj_string ast2obj_object -static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), long b) +static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) { return PyLong_FromLong(b); } @@ -8712,7 +8688,7 @@ _PyAST_TypeVarTuple(identifier name, expr_ty default_value, int lineno, int PyObject* -ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_mod(struct ast_state *state, void* _o) { mod_ty o = (mod_ty)_o; PyObject *result = NULL, *value = NULL; @@ -8720,9 +8696,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -8730,14 +8704,12 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Module_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Module.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.Module.type_ignores, + value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores, ast2obj_type_ignore); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_ignores, value) == -1) @@ -8748,7 +8720,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Interactive_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Interactive.body, + value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) @@ -8759,7 +8731,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Expression_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Expression.body); + value = ast2obj_expr(state, o->v.Expression.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -8769,31 +8741,30 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FunctionType_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionType.argtypes, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->argtypes, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FunctionType.returns); + value = ast2obj_expr(state, o->v.FunctionType.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); break; } - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_stmt(struct ast_state *state, void* _o) { stmt_ty o = (stmt_ty)_o; PyObject *result = NULL, *value = NULL; @@ -8801,9 +8772,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -8811,41 +8780,39 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FunctionDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.FunctionDef.name); + value = ast2obj_identifier(state, o->v.FunctionDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arguments(state, vstate, o->v.FunctionDef.args); + value = ast2obj_arguments(state, o->v.FunctionDef.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.FunctionDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FunctionDef.returns); + value = ast2obj_expr(state, o->v.FunctionDef.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.FunctionDef.type_comment); + value = ast2obj_string(state, o->v.FunctionDef.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionDef.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) @@ -8856,41 +8823,40 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncFunctionDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.AsyncFunctionDef.name); + value = ast2obj_identifier(state, o->v.AsyncFunctionDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arguments(state, vstate, o->v.AsyncFunctionDef.args); + value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.AsyncFunctionDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AsyncFunctionDef.returns); + value = ast2obj_expr(state, o->v.AsyncFunctionDef.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncFunctionDef.type_comment); + value = ast2obj_string(state, o->v.AsyncFunctionDef.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.type_params, ast2obj_type_param); if (!value) goto failed; @@ -8902,38 +8868,36 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ClassDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ClassDef.name); + value = ast2obj_identifier(state, o->v.ClassDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.bases, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->bases, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.keywords, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords, ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ClassDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ClassDef.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) @@ -8944,7 +8908,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Return_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Return.value); + value = ast2obj_expr(state, o->v.Return.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -8954,7 +8918,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Delete_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Delete.targets, + value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) @@ -8965,18 +8929,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Assign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Assign.targets, + value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Assign.value); + value = ast2obj_expr(state, o->v.Assign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.Assign.type_comment); + value = ast2obj_string(state, o->v.Assign.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -8986,19 +8950,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeAlias_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.TypeAlias.name); + value = ast2obj_expr(state, o->v.TypeAlias.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.TypeAlias.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.TypeAlias.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeAlias.value); + value = ast2obj_expr(state, o->v.TypeAlias.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9008,17 +8971,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AugAssign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AugAssign.target); + value = ast2obj_expr(state, o->v.AugAssign.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_operator(state, vstate, o->v.AugAssign.op); + value = ast2obj_operator(state, o->v.AugAssign.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AugAssign.value); + value = ast2obj_expr(state, o->v.AugAssign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9028,22 +8991,22 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AnnAssign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AnnAssign.target); + value = ast2obj_expr(state, o->v.AnnAssign.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AnnAssign.annotation); + value = ast2obj_expr(state, o->v.AnnAssign.annotation); if (!value) goto failed; if (PyObject_SetAttr(result, state->annotation, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AnnAssign.value); + value = ast2obj_expr(state, o->v.AnnAssign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.AnnAssign.simple); + value = ast2obj_int(state, o->v.AnnAssign.simple); if (!value) goto failed; if (PyObject_SetAttr(result, state->simple, value) == -1) goto failed; @@ -9053,29 +9016,27 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->For_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.For.target); + value = ast2obj_expr(state, o->v.For.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.For.iter); + value = ast2obj_expr(state, o->v.For.iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.For.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.For.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.For.type_comment); + value = ast2obj_string(state, o->v.For.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9085,29 +9046,29 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncFor_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AsyncFor.target); + value = ast2obj_expr(state, o->v.AsyncFor.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AsyncFor.iter); + value = ast2obj_expr(state, o->v.AsyncFor.iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncFor.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncFor.orelse, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncFor.type_comment); + value = ast2obj_string(state, o->v.AsyncFor.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9117,19 +9078,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->While_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.While.test); + value = ast2obj_expr(state, o->v.While.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.While.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.While.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9139,19 +9098,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->If_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.If.test); + value = ast2obj_expr(state, o->v.If.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.If.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.If.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9161,19 +9118,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->With_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.With.items, + value = ast2obj_list(state, (asdl_seq*)o->v.With.items, ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.With.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.With.type_comment); + value = ast2obj_string(state, o->v.With.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9183,19 +9139,19 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncWith_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncWith.items, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items, ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncWith.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncWith.type_comment); + value = ast2obj_string(state, o->v.AsyncWith.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9205,12 +9161,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Match_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Match.subject); + value = ast2obj_expr(state, o->v.Match.subject); if (!value) goto failed; if (PyObject_SetAttr(result, state->subject, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Match.cases, + value = ast2obj_list(state, (asdl_seq*)o->v.Match.cases, ast2obj_match_case); if (!value) goto failed; if (PyObject_SetAttr(result, state->cases, value) == -1) @@ -9221,12 +9177,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Raise_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Raise.exc); + value = ast2obj_expr(state, o->v.Raise.exc); if (!value) goto failed; if (PyObject_SetAttr(result, state->exc, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Raise.cause); + value = ast2obj_expr(state, o->v.Raise.cause); if (!value) goto failed; if (PyObject_SetAttr(result, state->cause, value) == -1) goto failed; @@ -9236,25 +9192,23 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Try_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.handlers, + value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers, ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.finalbody, + value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) @@ -9265,25 +9219,24 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TryStar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.handlers, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.handlers, ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.orelse, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.finalbody, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.finalbody, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) @@ -9294,12 +9247,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Assert_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Assert.test); + value = ast2obj_expr(state, o->v.Assert.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Assert.msg); + value = ast2obj_expr(state, o->v.Assert.msg); if (!value) goto failed; if (PyObject_SetAttr(result, state->msg, value) == -1) goto failed; @@ -9309,7 +9262,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Import_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Import.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Import.names, ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9320,18 +9273,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ImportFrom_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ImportFrom.module); + value = ast2obj_identifier(state, o->v.ImportFrom.module); if (!value) goto failed; if (PyObject_SetAttr(result, state->module, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ImportFrom.names, + value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names, ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.ImportFrom.level); + value = ast2obj_int(state, o->v.ImportFrom.level); if (!value) goto failed; if (PyObject_SetAttr(result, state->level, value) == -1) goto failed; @@ -9341,7 +9294,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Global_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Global.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Global.names, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9352,7 +9305,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Nonlocal_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Nonlocal.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9363,7 +9316,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Expr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Expr.value); + value = ast2obj_expr(state, o->v.Expr.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9385,37 +9338,37 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) if (!result) goto failed; break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_expr(struct ast_state *state, void* _o) { expr_ty o = (expr_ty)_o; PyObject *result = NULL, *value = NULL; @@ -9423,9 +9376,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -9433,12 +9384,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->BoolOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_boolop(state, vstate, o->v.BoolOp.op); + value = ast2obj_boolop(state, o->v.BoolOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.BoolOp.values, + value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) @@ -9449,12 +9400,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->NamedExpr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.NamedExpr.target); + value = ast2obj_expr(state, o->v.NamedExpr.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.NamedExpr.value); + value = ast2obj_expr(state, o->v.NamedExpr.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9464,17 +9415,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->BinOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.BinOp.left); + value = ast2obj_expr(state, o->v.BinOp.left); if (!value) goto failed; if (PyObject_SetAttr(result, state->left, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_operator(state, vstate, o->v.BinOp.op); + value = ast2obj_operator(state, o->v.BinOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.BinOp.right); + value = ast2obj_expr(state, o->v.BinOp.right); if (!value) goto failed; if (PyObject_SetAttr(result, state->right, value) == -1) goto failed; @@ -9484,12 +9435,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->UnaryOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_unaryop(state, vstate, o->v.UnaryOp.op); + value = ast2obj_unaryop(state, o->v.UnaryOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.UnaryOp.operand); + value = ast2obj_expr(state, o->v.UnaryOp.operand); if (!value) goto failed; if (PyObject_SetAttr(result, state->operand, value) == -1) goto failed; @@ -9499,12 +9450,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Lambda_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_arguments(state, vstate, o->v.Lambda.args); + value = ast2obj_arguments(state, o->v.Lambda.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Lambda.body); + value = ast2obj_expr(state, o->v.Lambda.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -9514,17 +9465,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->IfExp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.IfExp.test); + value = ast2obj_expr(state, o->v.IfExp.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.IfExp.body); + value = ast2obj_expr(state, o->v.IfExp.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.IfExp.orelse); + value = ast2obj_expr(state, o->v.IfExp.orelse); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9534,14 +9485,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Dict_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Dict.keys, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Dict.values, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -9551,8 +9500,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Set_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Set.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -9562,13 +9510,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ListComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.ListComp.elt); + value = ast2obj_expr(state, o->v.ListComp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ListComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9579,12 +9526,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->SetComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.SetComp.elt); + value = ast2obj_expr(state, o->v.SetComp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.SetComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9595,18 +9542,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->DictComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.DictComp.key); + value = ast2obj_expr(state, o->v.DictComp.key); if (!value) goto failed; if (PyObject_SetAttr(result, state->key, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.DictComp.value); + value = ast2obj_expr(state, o->v.DictComp.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.DictComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9617,13 +9563,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->GeneratorExp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.GeneratorExp.elt); + value = ast2obj_expr(state, o->v.GeneratorExp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.GeneratorExp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9634,7 +9579,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Await_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Await.value); + value = ast2obj_expr(state, o->v.Await.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9644,7 +9589,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Yield_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Yield.value); + value = ast2obj_expr(state, o->v.Yield.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9654,7 +9599,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->YieldFrom_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.YieldFrom.value); + value = ast2obj_expr(state, o->v.YieldFrom.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9664,7 +9609,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Compare_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Compare.left); + value = ast2obj_expr(state, o->v.Compare.left); if (!value) goto failed; if (PyObject_SetAttr(result, state->left, value) == -1) goto failed; @@ -9674,14 +9619,14 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) value = PyList_New(n); if (!value) goto failed; for(i = 0; i < n; i++) - PyList_SET_ITEM(value, i, ast2obj_cmpop(state, vstate, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); + PyList_SET_ITEM(value, i, ast2obj_cmpop(state, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); } if (!value) goto failed; if (PyObject_SetAttr(result, state->ops, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.Compare.comparators, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->comparators, value) == -1) goto failed; @@ -9691,18 +9636,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Call_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Call.func); + value = ast2obj_expr(state, o->v.Call.func); if (!value) goto failed; if (PyObject_SetAttr(result, state->func, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Call.args, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Call.keywords, + value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords, ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) @@ -9713,17 +9657,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FormattedValue_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.FormattedValue.value); + value = ast2obj_expr(state, o->v.FormattedValue.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.FormattedValue.conversion); + value = ast2obj_int(state, o->v.FormattedValue.conversion); if (!value) goto failed; if (PyObject_SetAttr(result, state->conversion, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FormattedValue.format_spec); + value = ast2obj_expr(state, o->v.FormattedValue.format_spec); if (!value) goto failed; if (PyObject_SetAttr(result, state->format_spec, value) == -1) goto failed; @@ -9733,7 +9677,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->JoinedStr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.JoinedStr.values, + value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) @@ -9744,12 +9688,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Constant_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_constant(state, vstate, o->v.Constant.value); + value = ast2obj_constant(state, o->v.Constant.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.Constant.kind); + value = ast2obj_string(state, o->v.Constant.kind); if (!value) goto failed; if (PyObject_SetAttr(result, state->kind, value) == -1) goto failed; @@ -9759,17 +9703,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Attribute_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Attribute.value); + value = ast2obj_expr(state, o->v.Attribute.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.Attribute.attr); + value = ast2obj_identifier(state, o->v.Attribute.attr); if (!value) goto failed; if (PyObject_SetAttr(result, state->attr, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Attribute.ctx); + value = ast2obj_expr_context(state, o->v.Attribute.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9779,17 +9723,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Subscript_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Subscript.value); + value = ast2obj_expr(state, o->v.Subscript.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Subscript.slice); + value = ast2obj_expr(state, o->v.Subscript.slice); if (!value) goto failed; if (PyObject_SetAttr(result, state->slice, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Subscript.ctx); + value = ast2obj_expr_context(state, o->v.Subscript.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9799,12 +9743,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Starred_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Starred.value); + value = ast2obj_expr(state, o->v.Starred.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Starred.ctx); + value = ast2obj_expr_context(state, o->v.Starred.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9814,12 +9758,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Name_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.Name.id); + value = ast2obj_identifier(state, o->v.Name.id); if (!value) goto failed; if (PyObject_SetAttr(result, state->id, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Name.ctx); + value = ast2obj_expr_context(state, o->v.Name.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9829,13 +9773,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->List_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.List.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.List.ctx); + value = ast2obj_expr_context(state, o->v.List.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9845,13 +9788,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Tuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Tuple.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Tuple.ctx); + value = ast2obj_expr_context(state, o->v.Tuple.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9861,54 +9803,53 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Slice_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Slice.lower); + value = ast2obj_expr(state, o->v.Slice.lower); if (!value) goto failed; if (PyObject_SetAttr(result, state->lower, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Slice.upper); + value = ast2obj_expr(state, o->v.Slice.upper); if (!value) goto failed; if (PyObject_SetAttr(result, state->upper, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Slice.step); + value = ast2obj_expr(state, o->v.Slice.step); if (!value) goto failed; if (PyObject_SetAttr(result, state->step, value) == -1) goto failed; Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } -PyObject* ast2obj_expr_context(struct ast_state *state, struct validator - *vstate, expr_context_ty o) +PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) { switch(o) { case Load: @@ -9920,8 +9861,7 @@ PyObject* ast2obj_expr_context(struct ast_state *state, struct validator } Py_UNREACHABLE(); } -PyObject* ast2obj_boolop(struct ast_state *state, struct validator *vstate, - boolop_ty o) +PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) { switch(o) { case And: @@ -9931,8 +9871,7 @@ PyObject* ast2obj_boolop(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_operator(struct ast_state *state, struct validator *vstate, - operator_ty o) +PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) { switch(o) { case Add: @@ -9964,8 +9903,7 @@ PyObject* ast2obj_operator(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_unaryop(struct ast_state *state, struct validator *vstate, - unaryop_ty o) +PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) { switch(o) { case Invert: @@ -9979,8 +9917,7 @@ PyObject* ast2obj_unaryop(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_cmpop(struct ast_state *state, struct validator *vstate, - cmpop_ty o) +PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) { switch(o) { case Eq: @@ -10007,8 +9944,7 @@ PyObject* ast2obj_cmpop(struct ast_state *state, struct validator *vstate, Py_UNREACHABLE(); } PyObject* -ast2obj_comprehension(struct ast_state *state, struct validator *vstate, void* - _o) +ast2obj_comprehension(struct ast_state *state, void* _o) { comprehension_ty o = (comprehension_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10016,46 +9952,43 @@ ast2obj_comprehension(struct ast_state *state, struct validator *vstate, void* if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->comprehension_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_expr(state, vstate, o->target); + value = ast2obj_expr(state, o->target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->iter); + value = ast2obj_expr(state, o->iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->ifs, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->ifs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->is_async); + value = ast2obj_int(state, o->is_async); if (!value) goto failed; if (PyObject_SetAttr(result, state->is_async, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* - _o) +ast2obj_excepthandler(struct ast_state *state, void* _o) { excepthandler_ty o = (excepthandler_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10063,9 +9996,7 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10073,17 +10004,17 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* tp = (PyTypeObject *)state->ExceptHandler_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.ExceptHandler.type); + value = ast2obj_expr(state, o->v.ExceptHandler.type); if (!value) goto failed; if (PyObject_SetAttr(result, state->type, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.ExceptHandler.name); + value = ast2obj_identifier(state, o->v.ExceptHandler.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ExceptHandler.body, + value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) @@ -10091,37 +10022,37 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_arguments(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_arguments(struct ast_state *state, void* _o) { arguments_ty o = (arguments_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10129,61 +10060,58 @@ ast2obj_arguments(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_list(state, vstate, (asdl_seq*)o->posonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->posonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->args, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arg(state, vstate, o->vararg); + value = ast2obj_arg(state, o->vararg); if (!value) goto failed; if (PyObject_SetAttr(result, state->vararg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->kwonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->kw_defaults, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->kw_defaults, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arg(state, vstate, o->kwarg); + value = ast2obj_arg(state, o->kwarg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwarg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->defaults, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_arg(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_arg(struct ast_state *state, void* _o) { arg_ty o = (arg_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10191,60 +10119,58 @@ ast2obj_arg(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->arg_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->arg); + value = ast2obj_identifier(state, o->arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->arg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->annotation); + value = ast2obj_expr(state, o->annotation); if (!value) goto failed; if (PyObject_SetAttr(result, state->annotation, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->type_comment); + value = ast2obj_string(state, o->type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_keyword(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_keyword(struct ast_state *state, void* _o) { keyword_ty o = (keyword_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10252,55 +10178,53 @@ ast2obj_keyword(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->keyword_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->arg); + value = ast2obj_identifier(state, o->arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->arg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->value); + value = ast2obj_expr(state, o->value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_alias(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_alias(struct ast_state *state, void* _o) { alias_ty o = (alias_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10308,55 +10232,53 @@ ast2obj_alias(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->alias_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->name); + value = ast2obj_identifier(state, o->name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->asname); + value = ast2obj_identifier(state, o->asname); if (!value) goto failed; if (PyObject_SetAttr(result, state->asname, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_withitem(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_withitem(struct ast_state *state, void* _o) { withitem_ty o = (withitem_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10364,35 +10286,33 @@ ast2obj_withitem(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->withitem_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_expr(state, vstate, o->context_expr); + value = ast2obj_expr(state, o->context_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->context_expr, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->optional_vars); + value = ast2obj_expr(state, o->optional_vars); if (!value) goto failed; if (PyObject_SetAttr(result, state->optional_vars, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_match_case(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_match_case(struct ast_state *state, void* _o) { match_case_ty o = (match_case_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10400,40 +10320,38 @@ ast2obj_match_case(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->match_case_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_pattern(state, vstate, o->pattern); + value = ast2obj_pattern(state, o->pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->pattern, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->guard); + value = ast2obj_expr(state, o->guard); if (!value) goto failed; if (PyObject_SetAttr(result, state->guard, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_pattern(struct ast_state *state, void* _o) { pattern_ty o = (pattern_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10441,9 +10359,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10451,7 +10367,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchValue_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.MatchValue.value); + value = ast2obj_expr(state, o->v.MatchValue.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -10461,7 +10377,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchSingleton_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_constant(state, vstate, o->v.MatchSingleton.value); + value = ast2obj_constant(state, o->v.MatchSingleton.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -10471,8 +10387,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchSequence_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchSequence.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchSequence.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) @@ -10483,20 +10398,19 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchMapping_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.MatchMapping.keys, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchMapping.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.MatchMapping.rest); + value = ast2obj_identifier(state, o->v.MatchMapping.rest); if (!value) goto failed; if (PyObject_SetAttr(result, state->rest, value) == -1) goto failed; @@ -10506,27 +10420,24 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchClass_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.MatchClass.cls); + value = ast2obj_expr(state, o->v.MatchClass.cls); if (!value) goto failed; if (PyObject_SetAttr(result, state->cls, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.kwd_attrs, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_attrs, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwd_attrs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.kwd_patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwd_patterns, value) == -1) @@ -10537,7 +10448,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchStar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.MatchStar.name); + value = ast2obj_identifier(state, o->v.MatchStar.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; @@ -10547,12 +10458,12 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchAs_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_pattern(state, vstate, o->v.MatchAs.pattern); + value = ast2obj_pattern(state, o->v.MatchAs.pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->pattern, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.MatchAs.name); + value = ast2obj_identifier(state, o->v.MatchAs.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; @@ -10562,7 +10473,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchOr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.MatchOr.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchOr.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) @@ -10570,37 +10481,37 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_type_ignore(struct ast_state *state, void* _o) { type_ignore_ty o = (type_ignore_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10608,9 +10519,7 @@ ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10618,29 +10527,29 @@ ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeIgnore_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_int(state, vstate, o->v.TypeIgnore.lineno); + value = ast2obj_int(state, o->v.TypeIgnore.lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.TypeIgnore.tag); + value = ast2obj_string(state, o->v.TypeIgnore.tag); if (!value) goto failed; if (PyObject_SetAttr(result, state->tag, value) == -1) goto failed; Py_DECREF(value); break; } - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_type_param(struct ast_state *state, void* _o) { type_param_ty o = (type_param_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10648,9 +10557,7 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10658,17 +10565,17 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeVar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.TypeVar.name); + value = ast2obj_identifier(state, o->v.TypeVar.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVar.bound); + value = ast2obj_expr(state, o->v.TypeVar.bound); if (!value) goto failed; if (PyObject_SetAttr(result, state->bound, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVar.default_value); + value = ast2obj_expr(state, o->v.TypeVar.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; @@ -10678,12 +10585,12 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ParamSpec_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ParamSpec.name); + value = ast2obj_identifier(state, o->v.ParamSpec.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.ParamSpec.default_value); + value = ast2obj_expr(state, o->v.ParamSpec.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; @@ -10693,42 +10600,42 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeVarTuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.TypeVarTuple.name); + value = ast2obj_identifier(state, o->v.TypeVarTuple.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVarTuple.default_value); + value = ast2obj_expr(state, o->v.TypeVarTuple.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -18135,28 +18042,8 @@ PyObject* PyAST_mod2obj(mod_ty t) if (state == NULL) { return NULL; } + PyObject *result = ast2obj_mod(state, t); - int starting_recursion_depth; - /* Be careful here to prevent overflow. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return NULL; - } - struct validator vstate; - vstate.recursion_limit = Py_C_RECURSION_LIMIT; - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - vstate.recursion_depth = starting_recursion_depth; - - PyObject *result = ast2obj_mod(state, &vstate, t); - - /* Check that the recursion depth counting balanced correctly */ - if (result && vstate.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST constructor recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, vstate.recursion_depth); - return NULL; - } return result; } diff --git a/Python/ast.c b/Python/ast.c index bf1ff5f3ec18ba..597df5b63b5f39 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -9,34 +9,22 @@ #include #include -struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); -static int validate_stmts(struct validator *, asdl_stmt_seq *); -static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int); -static int validate_patterns(struct validator *, asdl_pattern_seq *, int); -static int validate_type_params(struct validator *, asdl_type_param_seq *); +static int validate_stmts(asdl_stmt_seq *); +static int validate_exprs(asdl_expr_seq *, expr_context_ty, int); +static int validate_patterns(asdl_pattern_seq *, int); +static int validate_type_params(asdl_type_param_seq *); static int _validate_nonempty_seq(asdl_seq *, const char *, const char *); -static int validate_stmt(struct validator *, stmt_ty); -static int validate_expr(struct validator *, expr_ty, expr_context_ty); -static int validate_pattern(struct validator *, pattern_ty, int); -static int validate_typeparam(struct validator *, type_param_ty); +static int validate_stmt(stmt_ty); +static int validate_expr(expr_ty, expr_context_ty); +static int validate_pattern(pattern_ty, int); +static int validate_typeparam(type_param_ty); #define VALIDATE_POSITIONS(node) \ if (node->lineno > node->end_lineno) { \ @@ -80,7 +68,7 @@ validate_name(PyObject *name) } static int -validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) +validate_comprehension(asdl_comprehension_seq *gens) { assert(!PyErr_Occurred()); if (!asdl_seq_LEN(gens)) { @@ -89,32 +77,32 @@ validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) } for (Py_ssize_t i = 0; i < asdl_seq_LEN(gens); i++) { comprehension_ty comp = asdl_seq_GET(gens, i); - if (!validate_expr(state, comp->target, Store) || - !validate_expr(state, comp->iter, Load) || - !validate_exprs(state, comp->ifs, Load, 0)) + if (!validate_expr(comp->target, Store) || + !validate_expr(comp->iter, Load) || + !validate_exprs(comp->ifs, Load, 0)) return 0; } return 1; } static int -validate_keywords(struct validator *state, asdl_keyword_seq *keywords) +validate_keywords(asdl_keyword_seq *keywords) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++) - if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load)) + if (!validate_expr((asdl_seq_GET(keywords, i))->value, Load)) return 0; return 1; } static int -validate_args(struct validator *state, asdl_arg_seq *args) +validate_args(asdl_arg_seq *args) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = asdl_seq_GET(args, i); VALIDATE_POSITIONS(arg); - if (arg->annotation && !validate_expr(state, arg->annotation, Load)) + if (arg->annotation && !validate_expr(arg->annotation, Load)) return 0; } return 1; @@ -136,20 +124,20 @@ expr_context_name(expr_context_ty ctx) } static int -validate_arguments(struct validator *state, arguments_ty args) +validate_arguments(arguments_ty args) { assert(!PyErr_Occurred()); - if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) { + if (!validate_args(args->posonlyargs) || !validate_args(args->args)) { return 0; } if (args->vararg && args->vararg->annotation - && !validate_expr(state, args->vararg->annotation, Load)) { + && !validate_expr(args->vararg->annotation, Load)) { return 0; } - if (!validate_args(state, args->kwonlyargs)) + if (!validate_args(args->kwonlyargs)) return 0; if (args->kwarg && args->kwarg->annotation - && !validate_expr(state, args->kwarg->annotation, Load)) { + && !validate_expr(args->kwarg->annotation, Load)) { return 0; } if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { @@ -161,11 +149,11 @@ validate_arguments(struct validator *state, arguments_ty args) "kw_defaults on arguments"); return 0; } - return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1); + return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1); } static int -validate_constant(struct validator *state, PyObject *value) +validate_constant(PyObject *value) { assert(!PyErr_Occurred()); if (value == Py_None || value == Py_Ellipsis) @@ -180,7 +168,7 @@ validate_constant(struct validator *state, PyObject *value) return 1; if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); PyObject *it = PyObject_GetIter(value); if (it == NULL) @@ -196,7 +184,7 @@ validate_constant(struct validator *state, PyObject *value) break; } - if (!validate_constant(state, item)) { + if (!validate_constant(item)) { Py_DECREF(it); Py_DECREF(item); return 0; @@ -205,7 +193,7 @@ validate_constant(struct validator *state, PyObject *value) } Py_DECREF(it); - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -218,12 +206,12 @@ validate_constant(struct validator *state, PyObject *value) } static int -validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) +validate_expr(expr_ty exp, expr_context_ty ctx) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(exp); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); int check_ctx = 1; expr_context_ty actual_ctx; @@ -273,23 +261,23 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); return 0; } - ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0); + ret = validate_exprs(exp->v.BoolOp.values, Load, 0); break; case BinOp_kind: - ret = validate_expr(state, exp->v.BinOp.left, Load) && - validate_expr(state, exp->v.BinOp.right, Load); + ret = validate_expr(exp->v.BinOp.left, Load) && + validate_expr(exp->v.BinOp.right, Load); break; case UnaryOp_kind: - ret = validate_expr(state, exp->v.UnaryOp.operand, Load); + ret = validate_expr(exp->v.UnaryOp.operand, Load); break; case Lambda_kind: - ret = validate_arguments(state, exp->v.Lambda.args) && - validate_expr(state, exp->v.Lambda.body, Load); + ret = validate_arguments(exp->v.Lambda.args) && + validate_expr(exp->v.Lambda.body, Load); break; case IfExp_kind: - ret = validate_expr(state, exp->v.IfExp.test, Load) && - validate_expr(state, exp->v.IfExp.body, Load) && - validate_expr(state, exp->v.IfExp.orelse, Load); + ret = validate_expr(exp->v.IfExp.test, Load) && + validate_expr(exp->v.IfExp.body, Load) && + validate_expr(exp->v.IfExp.orelse, Load); break; case Dict_kind: if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { @@ -299,34 +287,34 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) } /* null_ok=1 for keys expressions to allow dict unpacking to work in dict literals, i.e. ``{**{a:b}}`` */ - ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) && - validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0); + ret = validate_exprs(exp->v.Dict.keys, Load, /*null_ok=*/ 1) && + validate_exprs(exp->v.Dict.values, Load, /*null_ok=*/ 0); break; case Set_kind: - ret = validate_exprs(state, exp->v.Set.elts, Load, 0); + ret = validate_exprs(exp->v.Set.elts, Load, 0); break; #define COMP(NAME) \ case NAME ## _kind: \ - ret = validate_comprehension(state, exp->v.NAME.generators) && \ - validate_expr(state, exp->v.NAME.elt, Load); \ + ret = validate_comprehension(exp->v.NAME.generators) && \ + validate_expr(exp->v.NAME.elt, Load); \ break; COMP(ListComp) COMP(SetComp) COMP(GeneratorExp) #undef COMP case DictComp_kind: - ret = validate_comprehension(state, exp->v.DictComp.generators) && - validate_expr(state, exp->v.DictComp.key, Load) && - validate_expr(state, exp->v.DictComp.value, Load); + ret = validate_comprehension(exp->v.DictComp.generators) && + validate_expr(exp->v.DictComp.key, Load) && + validate_expr(exp->v.DictComp.value, Load); break; case Yield_kind: - ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load); + ret = !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load); break; case YieldFrom_kind: - ret = validate_expr(state, exp->v.YieldFrom.value, Load); + ret = validate_expr(exp->v.YieldFrom.value, Load); break; case Await_kind: - ret = validate_expr(state, exp->v.Await.value, Load); + ret = validate_expr(exp->v.Await.value, Load); break; case Compare_kind: if (!asdl_seq_LEN(exp->v.Compare.comparators)) { @@ -339,52 +327,52 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) "of comparators and operands"); return 0; } - ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) && - validate_expr(state, exp->v.Compare.left, Load); + ret = validate_exprs(exp->v.Compare.comparators, Load, 0) && + validate_expr(exp->v.Compare.left, Load); break; case Call_kind: - ret = validate_expr(state, exp->v.Call.func, Load) && - validate_exprs(state, exp->v.Call.args, Load, 0) && - validate_keywords(state, exp->v.Call.keywords); + ret = validate_expr(exp->v.Call.func, Load) && + validate_exprs(exp->v.Call.args, Load, 0) && + validate_keywords(exp->v.Call.keywords); break; case Constant_kind: - if (!validate_constant(state, exp->v.Constant.value)) { + if (!validate_constant(exp->v.Constant.value)) { return 0; } ret = 1; break; case JoinedStr_kind: - ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0); + ret = validate_exprs(exp->v.JoinedStr.values, Load, 0); break; case FormattedValue_kind: - if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0) + if (validate_expr(exp->v.FormattedValue.value, Load) == 0) return 0; if (exp->v.FormattedValue.format_spec) { - ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load); + ret = validate_expr(exp->v.FormattedValue.format_spec, Load); break; } ret = 1; break; case Attribute_kind: - ret = validate_expr(state, exp->v.Attribute.value, Load); + ret = validate_expr(exp->v.Attribute.value, Load); break; case Subscript_kind: - ret = validate_expr(state, exp->v.Subscript.slice, Load) && - validate_expr(state, exp->v.Subscript.value, Load); + ret = validate_expr(exp->v.Subscript.slice, Load) && + validate_expr(exp->v.Subscript.value, Load); break; case Starred_kind: - ret = validate_expr(state, exp->v.Starred.value, ctx); + ret = validate_expr(exp->v.Starred.value, ctx); break; case Slice_kind: - ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) && - (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) && - (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load)); + ret = (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) && + (!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) && + (!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load)); break; case List_kind: - ret = validate_exprs(state, exp->v.List.elts, ctx, 0); + ret = validate_exprs(exp->v.List.elts, ctx, 0); break; case Tuple_kind: - ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); + ret = validate_exprs(exp->v.Tuple.elts, ctx, 0); break; case NamedExpr_kind: if (exp->v.NamedExpr.target->kind != Name_kind) { @@ -392,7 +380,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) "NamedExpr target must be a Name"); return 0; } - ret = validate_expr(state, exp->v.NamedExpr.value, Load); + ret = validate_expr(exp->v.NamedExpr.value, Load); break; /* This last case doesn't have any checking. */ case Name_kind: @@ -404,7 +392,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) PyErr_SetString(PyExc_SystemError, "unexpected expression"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } @@ -480,10 +468,10 @@ ensure_literal_complex(expr_ty exp) } static int -validate_pattern_match_value(struct validator *state, expr_ty exp) +validate_pattern_match_value(expr_ty exp) { assert(!PyErr_Occurred()); - if (!validate_expr(state, exp, Load)) { + if (!validate_expr(exp, Load)) { return 0; } @@ -493,7 +481,7 @@ validate_pattern_match_value(struct validator *state, expr_ty exp) /* Ellipsis and immutable sequences are not allowed. For True, False and None, MatchSingleton() should be used */ - if (!validate_expr(state, exp, Load)) { + if (!validate_expr(exp, Load)) { return 0; } PyObject *literal = exp->v.Constant.value; @@ -545,15 +533,15 @@ validate_capture(PyObject *name) } static int -validate_pattern(struct validator *state, pattern_ty p, int star_ok) +validate_pattern(pattern_ty p, int star_ok) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(p); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (p->kind) { case MatchValue_kind: - ret = validate_pattern_match_value(state, p->v.MatchValue.value); + ret = validate_pattern_match_value(p->v.MatchValue.value); break; case MatchSingleton_kind: ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value); @@ -563,7 +551,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) } break; case MatchSequence_kind: - ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1); + ret = validate_patterns(p->v.MatchSequence.patterns, /*star_ok=*/1); break; case MatchMapping_kind: if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) { @@ -591,7 +579,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) continue; } } - if (!validate_pattern_match_value(state, key)) { + if (!validate_pattern_match_value(key)) { ret = 0; break; } @@ -599,7 +587,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) if (ret == 0) { break; } - ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchMapping.patterns, /*star_ok=*/0); break; case MatchClass_kind: if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) { @@ -608,7 +596,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; break; } - if (!validate_expr(state, p->v.MatchClass.cls, Load)) { + if (!validate_expr(p->v.MatchClass.cls, Load)) { ret = 0; break; } @@ -644,12 +632,12 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) break; } - if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) { + if (!validate_patterns(p->v.MatchClass.patterns, /*star_ok=*/0)) { ret = 0; break; } - ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchClass.kwd_patterns, /*star_ok=*/0); break; case MatchStar_kind: if (!star_ok) { @@ -673,7 +661,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; } else { - ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0); + ret = validate_pattern(p->v.MatchAs.pattern, /*star_ok=*/0); } break; case MatchOr_kind: @@ -683,7 +671,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; break; } - ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchOr.patterns, /*star_ok=*/0); break; // No default case, so the compiler will emit a warning if new pattern // kinds are added without being handled here @@ -692,7 +680,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) PyErr_SetString(PyExc_SystemError, "unexpected pattern"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } @@ -707,56 +695,56 @@ _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) #define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner) static int -validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx) +validate_assignlist(asdl_expr_seq *targets, expr_context_ty ctx) { assert(!PyErr_Occurred()); return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && - validate_exprs(state, targets, ctx, 0); + validate_exprs(targets, ctx, 0); } static int -validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) +validate_body(asdl_stmt_seq *body, const char *owner) { assert(!PyErr_Occurred()); - return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body); + return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); } static int -validate_stmt(struct validator *state, stmt_ty stmt) +validate_stmt(stmt_ty stmt) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(stmt); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (stmt->kind) { case FunctionDef_kind: - ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && - validate_type_params(state, stmt->v.FunctionDef.type_params) && - validate_arguments(state, stmt->v.FunctionDef.args) && - validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) && + ret = validate_body(stmt->v.FunctionDef.body, "FunctionDef") && + validate_type_params(stmt->v.FunctionDef.type_params) && + validate_arguments(stmt->v.FunctionDef.args) && + validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && (!stmt->v.FunctionDef.returns || - validate_expr(state, stmt->v.FunctionDef.returns, Load)); + validate_expr(stmt->v.FunctionDef.returns, Load)); break; case ClassDef_kind: - ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") && - validate_type_params(state, stmt->v.ClassDef.type_params) && - validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) && - validate_keywords(state, stmt->v.ClassDef.keywords) && - validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0); + ret = validate_body(stmt->v.ClassDef.body, "ClassDef") && + validate_type_params(stmt->v.ClassDef.type_params) && + validate_exprs(stmt->v.ClassDef.bases, Load, 0) && + validate_keywords(stmt->v.ClassDef.keywords) && + validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); break; case Return_kind: - ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load); + ret = !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); break; case Delete_kind: - ret = validate_assignlist(state, stmt->v.Delete.targets, Del); + ret = validate_assignlist(stmt->v.Delete.targets, Del); break; case Assign_kind: - ret = validate_assignlist(state, stmt->v.Assign.targets, Store) && - validate_expr(state, stmt->v.Assign.value, Load); + ret = validate_assignlist(stmt->v.Assign.targets, Store) && + validate_expr(stmt->v.Assign.value, Load); break; case AugAssign_kind: - ret = validate_expr(state, stmt->v.AugAssign.target, Store) && - validate_expr(state, stmt->v.AugAssign.value, Load); + ret = validate_expr(stmt->v.AugAssign.target, Store) && + validate_expr(stmt->v.AugAssign.value, Load); break; case AnnAssign_kind: if (stmt->v.AnnAssign.target->kind != Name_kind && @@ -765,10 +753,10 @@ validate_stmt(struct validator *state, stmt_ty stmt) "AnnAssign with simple non-Name target"); return 0; } - ret = validate_expr(state, stmt->v.AnnAssign.target, Store) && + ret = validate_expr(stmt->v.AnnAssign.target, Store) && (!stmt->v.AnnAssign.value || - validate_expr(state, stmt->v.AnnAssign.value, Load)) && - validate_expr(state, stmt->v.AnnAssign.annotation, Load); + validate_expr(stmt->v.AnnAssign.value, Load)) && + validate_expr(stmt->v.AnnAssign.annotation, Load); break; case TypeAlias_kind: if (stmt->v.TypeAlias.name->kind != Name_kind) { @@ -776,64 +764,64 @@ validate_stmt(struct validator *state, stmt_ty stmt) "TypeAlias with non-Name name"); return 0; } - ret = validate_expr(state, stmt->v.TypeAlias.name, Store) && - validate_type_params(state, stmt->v.TypeAlias.type_params) && - validate_expr(state, stmt->v.TypeAlias.value, Load); + ret = validate_expr(stmt->v.TypeAlias.name, Store) && + validate_type_params(stmt->v.TypeAlias.type_params) && + validate_expr(stmt->v.TypeAlias.value, Load); break; case For_kind: - ret = validate_expr(state, stmt->v.For.target, Store) && - validate_expr(state, stmt->v.For.iter, Load) && - validate_body(state, stmt->v.For.body, "For") && - validate_stmts(state, stmt->v.For.orelse); + ret = validate_expr(stmt->v.For.target, Store) && + validate_expr(stmt->v.For.iter, Load) && + validate_body(stmt->v.For.body, "For") && + validate_stmts(stmt->v.For.orelse); break; case AsyncFor_kind: - ret = validate_expr(state, stmt->v.AsyncFor.target, Store) && - validate_expr(state, stmt->v.AsyncFor.iter, Load) && - validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") && - validate_stmts(state, stmt->v.AsyncFor.orelse); + ret = validate_expr(stmt->v.AsyncFor.target, Store) && + validate_expr(stmt->v.AsyncFor.iter, Load) && + validate_body(stmt->v.AsyncFor.body, "AsyncFor") && + validate_stmts(stmt->v.AsyncFor.orelse); break; case While_kind: - ret = validate_expr(state, stmt->v.While.test, Load) && - validate_body(state, stmt->v.While.body, "While") && - validate_stmts(state, stmt->v.While.orelse); + ret = validate_expr(stmt->v.While.test, Load) && + validate_body(stmt->v.While.body, "While") && + validate_stmts(stmt->v.While.orelse); break; case If_kind: - ret = validate_expr(state, stmt->v.If.test, Load) && - validate_body(state, stmt->v.If.body, "If") && - validate_stmts(state, stmt->v.If.orelse); + ret = validate_expr(stmt->v.If.test, Load) && + validate_body(stmt->v.If.body, "If") && + validate_stmts(stmt->v.If.orelse); break; case With_kind: if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) return 0; for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) return 0; } - ret = validate_body(state, stmt->v.With.body, "With"); + ret = validate_body(stmt->v.With.body, "With"); break; case AsyncWith_kind: if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) return 0; for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) return 0; } - ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith"); + ret = validate_body(stmt->v.AsyncWith.body, "AsyncWith"); break; case Match_kind: - if (!validate_expr(state, stmt->v.Match.subject, Load) + if (!validate_expr(stmt->v.Match.subject, Load) || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) { return 0; } for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) { match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i); - if (!validate_pattern(state, m->pattern, /*star_ok=*/0) - || (m->guard && !validate_expr(state, m->guard, Load)) - || !validate_body(state, m->body, "match_case")) { + if (!validate_pattern(m->pattern, /*star_ok=*/0) + || (m->guard && !validate_expr(m->guard, Load)) + || !validate_body(m->body, "match_case")) { return 0; } } @@ -841,8 +829,8 @@ validate_stmt(struct validator *state, stmt_ty stmt) break; case Raise_kind: if (stmt->v.Raise.exc) { - ret = validate_expr(state, stmt->v.Raise.exc, Load) && - (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load)); + ret = validate_expr(stmt->v.Raise.exc, Load) && + (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load)); break; } if (stmt->v.Raise.cause) { @@ -852,7 +840,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) ret = 1; break; case Try_kind: - if (!validate_body(state, stmt->v.Try.body, "Try")) + if (!validate_body(stmt->v.Try.body, "Try")) return 0; if (!asdl_seq_LEN(stmt->v.Try.handlers) && !asdl_seq_LEN(stmt->v.Try.finalbody)) { @@ -868,17 +856,17 @@ validate_stmt(struct validator *state, stmt_ty stmt) excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); VALIDATE_POSITIONS(handler); if ((handler->v.ExceptHandler.type && - !validate_expr(state, handler->v.ExceptHandler.type, Load)) || - !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) + !validate_expr(handler->v.ExceptHandler.type, Load)) || + !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) return 0; } ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) || - validate_stmts(state, stmt->v.Try.finalbody)) && + validate_stmts(stmt->v.Try.finalbody)) && (!asdl_seq_LEN(stmt->v.Try.orelse) || - validate_stmts(state, stmt->v.Try.orelse)); + validate_stmts(stmt->v.Try.orelse)); break; case TryStar_kind: - if (!validate_body(state, stmt->v.TryStar.body, "TryStar")) + if (!validate_body(stmt->v.TryStar.body, "TryStar")) return 0; if (!asdl_seq_LEN(stmt->v.TryStar.handlers) && !asdl_seq_LEN(stmt->v.TryStar.finalbody)) { @@ -893,18 +881,18 @@ validate_stmt(struct validator *state, stmt_ty stmt) for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i); if ((handler->v.ExceptHandler.type && - !validate_expr(state, handler->v.ExceptHandler.type, Load)) || - !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) + !validate_expr(handler->v.ExceptHandler.type, Load)) || + !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) return 0; } ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) || - validate_stmts(state, stmt->v.TryStar.finalbody)) && + validate_stmts(stmt->v.TryStar.finalbody)) && (!asdl_seq_LEN(stmt->v.TryStar.orelse) || - validate_stmts(state, stmt->v.TryStar.orelse)); + validate_stmts(stmt->v.TryStar.orelse)); break; case Assert_kind: - ret = validate_expr(state, stmt->v.Assert.test, Load) && - (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load)); + ret = validate_expr(stmt->v.Assert.test, Load) && + (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load)); break; case Import_kind: ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); @@ -923,15 +911,15 @@ validate_stmt(struct validator *state, stmt_ty stmt) ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); break; case Expr_kind: - ret = validate_expr(state, stmt->v.Expr.value, Load); + ret = validate_expr(stmt->v.Expr.value, Load); break; case AsyncFunctionDef_kind: - ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && - validate_type_params(state, stmt->v.AsyncFunctionDef.type_params) && - validate_arguments(state, stmt->v.AsyncFunctionDef.args) && - validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && + ret = validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && + validate_type_params(stmt->v.AsyncFunctionDef.type_params) && + validate_arguments(stmt->v.AsyncFunctionDef.args) && + validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && (!stmt->v.AsyncFunctionDef.returns || - validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load)); + validate_expr(stmt->v.AsyncFunctionDef.returns, Load)); break; case Pass_kind: case Break_kind: @@ -944,18 +932,18 @@ validate_stmt(struct validator *state, stmt_ty stmt) PyErr_SetString(PyExc_SystemError, "unexpected statement"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } static int -validate_stmts(struct validator *state, asdl_stmt_seq *seq) +validate_stmts(asdl_stmt_seq *seq) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) { stmt_ty stmt = asdl_seq_GET(seq, i); if (stmt) { - if (!validate_stmt(state, stmt)) + if (!validate_stmt(stmt)) return 0; } else { @@ -968,13 +956,13 @@ validate_stmts(struct validator *state, asdl_stmt_seq *seq) } static int -validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) +validate_exprs(asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) { expr_ty expr = asdl_seq_GET(exprs, i); if (expr) { - if (!validate_expr(state, expr, ctx)) + if (!validate_expr(expr, ctx)) return 0; } else if (!null_ok) { @@ -988,12 +976,12 @@ validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ct } static int -validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok) +validate_patterns(asdl_pattern_seq *patterns, int star_ok) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) { pattern_ty pattern = asdl_seq_GET(patterns, i); - if (!validate_pattern(state, pattern, star_ok)) { + if (!validate_pattern(pattern, star_ok)) { return 0; } } @@ -1001,7 +989,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ } static int -validate_typeparam(struct validator *state, type_param_ty tp) +validate_typeparam(type_param_ty tp) { VALIDATE_POSITIONS(tp); int ret = -1; @@ -1009,32 +997,32 @@ validate_typeparam(struct validator *state, type_param_ty tp) case TypeVar_kind: ret = validate_name(tp->v.TypeVar.name) && (!tp->v.TypeVar.bound || - validate_expr(state, tp->v.TypeVar.bound, Load)) && + validate_expr(tp->v.TypeVar.bound, Load)) && (!tp->v.TypeVar.default_value || - validate_expr(state, tp->v.TypeVar.default_value, Load)); + validate_expr(tp->v.TypeVar.default_value, Load)); break; case ParamSpec_kind: ret = validate_name(tp->v.ParamSpec.name) && (!tp->v.ParamSpec.default_value || - validate_expr(state, tp->v.ParamSpec.default_value, Load)); + validate_expr(tp->v.ParamSpec.default_value, Load)); break; case TypeVarTuple_kind: ret = validate_name(tp->v.TypeVarTuple.name) && (!tp->v.TypeVarTuple.default_value || - validate_expr(state, tp->v.TypeVarTuple.default_value, Load)); + validate_expr(tp->v.TypeVarTuple.default_value, Load)); break; } return ret; } static int -validate_type_params(struct validator *state, asdl_type_param_seq *tps) +validate_type_params(asdl_type_param_seq *tps) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(tps); i++) { type_param_ty tp = asdl_seq_GET(tps, i); if (tp) { - if (!validate_typeparam(state, tp)) + if (!validate_typeparam(tp)) return 0; } } @@ -1046,34 +1034,20 @@ _PyAST_Validate(mod_ty mod) { assert(!PyErr_Occurred()); int res = -1; - struct validator state; - PyThreadState *tstate; - int starting_recursion_depth; - - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - state.recursion_depth = starting_recursion_depth; - state.recursion_limit = Py_C_RECURSION_LIMIT; switch (mod->kind) { case Module_kind: - res = validate_stmts(&state, mod->v.Module.body); + res = validate_stmts(mod->v.Module.body); break; case Interactive_kind: - res = validate_stmts(&state, mod->v.Interactive.body); + res = validate_stmts(mod->v.Interactive.body); break; case Expression_kind: - res = validate_expr(&state, mod->v.Expression.body, Load); + res = validate_expr(mod->v.Expression.body, Load); break; case FunctionType_kind: - res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && - validate_expr(&state, mod->v.FunctionType.returns, Load); + res = validate_exprs(mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && + validate_expr(mod->v.FunctionType.returns, Load); break; // No default case so compiler emits warning for unhandled cases } @@ -1082,14 +1056,6 @@ _PyAST_Validate(mod_ty mod) PyErr_SetString(PyExc_SystemError, "impossible module node"); return 0; } - - /* Check that the recursion depth counting balanced correctly */ - if (res && state.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST validator recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state.recursion_depth); - return 0; - } return res; } diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 78d84002d593fb..18c8b02e2fb1b4 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -10,24 +10,14 @@ typedef struct { int optimize; int ff_features; - - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ } _PyASTOptimizeState; -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); static int make_const(expr_ty node, PyObject *val, PyArena *arena) @@ -724,7 +714,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case BoolOp_kind: CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); @@ -822,7 +812,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case Name_kind: if (node_->v.Name.ctx == Load && _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); } break; @@ -835,7 +825,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new expression // kinds are added without being handled here } - LEAVE_RECURSIVE(state);; + LEAVE_RECURSIVE(); return 1; } @@ -882,7 +872,7 @@ astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case FunctionDef_kind: CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params); @@ -1006,7 +996,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new statement // kinds are added without being handled here } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -1038,7 +1028,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // Currently, this is really only used to form complex/negative numeric // constants in MatchValue and MatchMapping nodes // We still recurse into all subexpressions and subpatterns anyway - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case MatchValue_kind: CALL(astfold_expr, expr_ty, node_->v.MatchValue.value); @@ -1070,7 +1060,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new pattern // kinds are added without being handled here } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -1108,34 +1098,12 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat int _PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features) { - PyThreadState *tstate; - int starting_recursion_depth; - _PyASTOptimizeState state; state.optimize = optimize; state.ff_features = ff_features; - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - state.recursion_depth = starting_recursion_depth; - state.recursion_limit = Py_C_RECURSION_LIMIT; - int ret = astfold_mod(mod, arena, &state); assert(ret || PyErr_Occurred()); - /* Check that the recursion depth counting balanced correctly */ - if (ret && state.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST optimizer recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state.recursion_depth); - return 0; - } - return ret; } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 703d7ec61ebab3..ae46215d3f3b18 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1083,7 +1083,9 @@ dummy_func( /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); PyObject *result = PyStackRef_AsPyObjectSteal(retval); SYNC_SP(); /* Not strictly necessary, but prevents warnings */ return result; @@ -3974,7 +3976,7 @@ dummy_func( EXIT_IF(!PyCFunction_CheckExact(callable_o)); EXIT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; @@ -4168,7 +4170,7 @@ dummy_func( PyMethodDef *meth = method->d_method; EXIT_IF(meth->ml_flags != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); _PyStackRef arg_stackref = arguments[1]; _PyStackRef self_stackref = arguments[0]; EXIT_IF(!Py_IS_TYPE(PyStackRef_AsPyObjectBorrow(self_stackref), @@ -4250,7 +4252,7 @@ dummy_func( EXIT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); EXIT_IF(meth->ml_flags != METH_NOARGS); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; _Py_EnterRecursiveCallTstateUnchecked(tstate); @@ -5253,7 +5255,9 @@ dummy_func( if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return NULL; } next_instr = frame->instr_ptr; diff --git a/Python/ceval.c b/Python/ceval.c index 1e4f1f3af20aca..46e693fd1edad6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -302,6 +302,27 @@ Py_SetRecursionLimit(int new_limit) _PyEval_StartTheWorld(interp); } +int +Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) +{ + return _Py_ReachedRecursionLimit(tstate, margin_count); +} + +void +_Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) +{ + tstate->c_recursion_remaining--; + if (tstate->c_recursion_remaining < -50) { + Py_FatalError("Unchecked stack overflow."); + } +} + +void +Py_LeaveRecursiveCallTstate(PyThreadState *tstate) +{ + _Py_LeaveRecursiveCallTstate(tstate); +} + /* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches recursion_limit. */ int @@ -759,11 +780,6 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch) } -/* _PyEval_EvalFrameDefault() is a *big* function, - * so consume 3 units of C stack */ -#define PY_EVAL_C_STACK_UNITS 2 - - #ifdef Py_TAIL_CALL_INTERP #include "opcode_targets.h" #include "generated_cases.c.h" @@ -822,7 +838,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int frame->previous = &entry_frame; tstate->current_frame = frame; - tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1); + // PyEval_EvalDefault is a big function, so count it twice + _Py_EnterRecursiveCallTstateUnchecked(tstate); /* support for generator.throw() */ if (throwflag) { @@ -982,7 +999,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(frame->owner == FRAME_OWNED_BY_INTERPRETER); /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return NULL; } @@ -1542,11 +1561,11 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) // _PyThreadState_PopFrame, since f_code is already cleared at that point: assert((PyObject **)frame + _PyFrame_GetCode(frame)->co_framesize == tstate->datastack_top); - tstate->c_recursion_remaining--; + _Py_EnterRecursiveCallTstateUnchecked(tstate); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); PyStackRef_CLEAR(frame->f_executable); - tstate->c_recursion_remaining++; + _Py_LeaveRecursiveCallTstate(tstate); _PyThreadState_PopFrame(tstate, frame); } @@ -1559,11 +1578,11 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) assert(tstate->exc_info == &gen->gi_exc_state); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; - tstate->c_recursion_remaining--; + _Py_EnterRecursiveCallTstateUnchecked(tstate); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); _PyErr_ClearExcState(&gen->gi_exc_state); - tstate->c_recursion_remaining++; + _Py_LeaveRecursiveCallTstate(tstate); frame->previous = NULL; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 96b7386bd24846..36a7027f38120e 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5099,7 +5099,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -5442,7 +5442,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -5586,7 +5586,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index f02e13f5e3fbce..a296294372338a 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2078,7 +2078,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3354,7 +3354,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3451,7 +3451,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -6823,7 +6823,9 @@ /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); PyObject *result = PyStackRef_AsPyObjectSteal(retval); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -11387,7 +11389,9 @@ JUMP_TO_LABEL(error); if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return NULL; } next_instr = frame->instr_ptr; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ae0df9685ac159..328bc773c4acaf 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1552,20 +1552,17 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp #include #include -/* - * Return non-zero when we run out of memory on the stack; zero otherwise. - */ -int -PyOS_CheckStack(void) +int _PyOS_CheckStack(int words) { - __try { + __try + { /* alloca throws a stack overflow exception if there's not enough space left on the stack */ - alloca(PYOS_STACK_MARGIN * sizeof(void*)); + alloca(words * sizeof(void *)); return 0; - } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH) { + } + __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { int errcode = _resetstkoflw(); if (errcode == 0) { @@ -1575,6 +1572,14 @@ PyOS_CheckStack(void) return 1; } +/* + * Return non-zero when we run out of memory on the stack; zero otherwise. + */ +int PyOS_CheckStack(void) +{ + return _PyOS_CheckStack(PYOS_STACK_MARGIN); +} + #endif /* WIN32 && _MSC_VER */ /* Alternate implementations can be added here... */ diff --git a/Python/symtable.c b/Python/symtable.c index 49bd01ba68ac9e..873576183314e6 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -406,7 +406,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) asdl_stmt_seq *seq; Py_ssize_t i; PyThreadState *tstate; - int starting_recursion_depth; if (st == NULL) return NULL; @@ -423,11 +422,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - st->recursion_depth = starting_recursion_depth; - st->recursion_limit = Py_C_RECURSION_LIMIT; /* Make the initial symbol information gathering pass */ @@ -469,14 +463,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - /* Check that the recursion depth counting balanced correctly */ - if (st->recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "symtable analysis recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, st->recursion_depth); - _PySymtable_Free(st); - return NULL; - } /* Make the second symbol analysis pass */ if (symtable_analyze(st)) { #if _PY_DUMP_SYMTABLE @@ -1736,19 +1722,12 @@ symtable_enter_type_param_block(struct symtable *st, identifier name, } \ } while(0) -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); static int @@ -1823,7 +1802,7 @@ maybe_set_ste_coroutine_for_module(struct symtable *st, stmt_ty s) static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (s->kind) { case FunctionDef_kind: { if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) @@ -2235,7 +2214,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } @@ -2358,7 +2337,7 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e) static int symtable_visit_expr(struct symtable *st, expr_ty e) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (e->kind) { case NamedExpr_kind: if (!symtable_raise_if_annotation_block(st, "named expression", e)) { @@ -2529,7 +2508,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_SEQ(st, expr, e->v.Tuple.elts); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } @@ -2563,7 +2542,7 @@ symtable_visit_type_param_bound_or_default( static int symtable_visit_type_param(struct symtable *st, type_param_ty tp) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch(tp->kind) { case TypeVar_kind: if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) @@ -2612,14 +2591,14 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp) } break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } static int symtable_visit_pattern(struct symtable *st, pattern_ty p) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (p->kind) { case MatchValue_kind: VISIT(st, expr, p->v.MatchValue.value); @@ -2668,7 +2647,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) VISIT_SEQ(st, pattern, p->v.MatchOr.patterns); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index c127d0334d9cf8..fed7aec746a7b7 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -678,6 +678,7 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "initial_temperature_backoff_counter", "JUMP_TO_LABEL", "restart_backoff_counter", + "_Py_ReachedRecursionLimit", ) def find_stmt_start(node: parser.CodeDef, idx: int) -> lexer.Token: From afeb8666d3574f1a04b6961fdea4ccabb1bc48db Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 15:32:49 +0000 Subject: [PATCH 02/41] Implement C recursion protection with limit pointers --- Include/ceval.h | 1 - Include/cpython/object.h | 4 +- Include/cpython/pystate.h | 44 ++++++++++++++-------- Include/internal/pycore_ceval.h | 26 +++---------- Include/pythonrun.h | 1 + Lib/test/list_tests.py | 2 +- Lib/test/mapping_tests.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_compile.py | 10 ++--- Lib/test/test_dict.py | 2 +- Lib/test/test_dictviews.py | 2 +- Lib/test/test_exception_group.py | 2 +- Modules/_testinternalcapi.c | 4 +- Objects/object.c | 13 ------- Python/bytecodes.c | 3 -- Python/ceval.c | 62 +++++++++++++++++-------------- Python/executor_cases.c.h | 3 -- Python/generated_cases.c.h | 3 -- Python/pystate.c | 7 ++-- Tools/cases_generator/analyzer.py | 1 - 20 files changed, 87 insertions(+), 107 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index 23afbb6441ed5d..09460a7757ded0 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -61,7 +61,6 @@ PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); PyAPI_FUNC(int) Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count); -PyAPI_FUNC(void) _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate); PyAPI_FUNC(void) Py_LeaveRecursiveCallTstate(PyThreadState *tstate); PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index c3d5bcc6f3031a..9035d8b3c18705 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -493,11 +493,9 @@ do { \ if (Py_ReachedRecursionLimit(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ _PyTrash_thread_deposit_object(tstate, (PyObject *)op); \ break; \ - } \ - _Py_EnterRecursiveCallUnchecked(tstate); + } /* The body of the deallocator is here. */ #define Py_TRASHCAN_END \ - Py_LeaveRecursiveCallTstate(tstate); \ if (tstate->delete_later && !Py_ReachedRecursionLimit(tstate, 2)) { \ _PyTrash_thread_destroy_chain(tstate); \ } \ diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index cd6d9582496850..44f11c01212451 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -112,7 +112,8 @@ struct _ts { int py_recursion_remaining; int py_recursion_limit; - int c_recursion_remaining; + char *c_stack_soft_limit; + char *c_stack_hard_limit; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. @@ -202,34 +203,45 @@ struct _ts { PyObject *threading_local_sentinel; }; -#ifdef Py_DEBUG - // A debug build is likely built with low optimization level which implies - // higher stack memory usage than a release build: use a lower limit. -# define Py_C_RECURSION_LIMIT 500 -#elif defined(__s390x__) -# define Py_C_RECURSION_LIMIT 800 + +#if defined(__s390x__) +# define Py_C_STACK_SIZE 320000 #elif defined(_WIN32) && defined(_M_ARM64) -# define Py_C_RECURSION_LIMIT 1000 +# define Py_C_STACK_SIZE 400000 #elif defined(_WIN32) -# define Py_C_RECURSION_LIMIT 3000 +# define Py_C_STACK_SIZE 1200000 #elif defined(__ANDROID__) // On an ARM64 emulator, API level 34 was OK with 10000, but API level 21 // crashed in test_compiler_recursion_limit. -# define Py_C_RECURSION_LIMIT 3000 -#elif defined(_Py_ADDRESS_SANITIZER) -# define Py_C_RECURSION_LIMIT 4000 +# define Py_C_STACK_SIZE 1200000 #elif defined(__sparc__) // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. -# define Py_C_RECURSION_LIMIT 4000 +# define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) // Based on wasmtime 16. -# define Py_C_RECURSION_LIMIT 5000 +# define Py_C_STACK_SIZE 2000000 #elif defined(__hppa__) || defined(__powerpc64__) // test_descr crashed with >8000 but let's keep a margin of error. -# define Py_C_RECURSION_LIMIT 5000 +# define Py_C_STACK_SIZE 2000000 #else // This value is duplicated in Lib/test/support/__init__.py -# define Py_C_RECURSION_LIMIT 10000 +# define Py_C_STACK_SIZE 5000000 +#endif + + +#ifdef Py_DEBUG + // A debug build is likely built with low optimization level which implies + // higher stack memory usage than a release build: use a lower limit. +# if defined(__has_feature) /* Clang */ + // Clang debug builds use a lot of stack space +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 2000) +# else +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 1000) +# endif +#elif defined(_Py_ADDRESS_SANITIZER) +# define Py_C_STACK_SIZE (Py_C_STACK_SIZE / 600) +#else +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 300) #endif diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index cc5c07fff4794a..ec2f5cc4f26478 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,18 +193,10 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -#ifdef USE_STACKCHECK -/* With USE_STACKCHECK macro defined, trigger stack checks in - _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return (tstate->c_recursion_remaining-- < 0 - || (tstate->c_recursion_remaining & 63) == 0); + char here; + return &here < tstate->c_stack_soft_limit; } -#else -static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return tstate->c_recursion_remaining-- < 0; -} -#endif // Export for '_json' shared extension, used via _Py_EnterRecursiveCall() // static inline function. @@ -220,29 +212,21 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); } -static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) { - assert(tstate->c_recursion_remaining >= -2); // Allow a bit of wiggle room - tstate->c_recursion_remaining--; -} - static inline int _Py_EnterRecursiveCall(const char *where) { PyThreadState *tstate = _PyThreadState_GET(); return _Py_EnterRecursiveCallTstate(tstate, where); } static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { - tstate->c_recursion_remaining++; + (void)tstate; } -#define Py_RECURSION_LIMIT_MARGIN_MULTIPLIER 50 - static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { - return tstate->c_recursion_remaining <= margin_count * Py_RECURSION_LIMIT_MARGIN_MULTIPLIER; + char here; + return &here <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } static inline void _Py_LeaveRecursiveCall(void) { - PyThreadState *tstate = _PyThreadState_GET(); - _Py_LeaveRecursiveCallTstate(tstate); } extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 154c7450cb934f..f78f8b2a190090 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -25,6 +25,7 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); on 64-bit platforms). On a 32-bit platform, this translates to an 8k margin. */ #define PYOS_STACK_MARGIN 2048 +#define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *)) #if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 /* Enable stack checking under Microsoft C */ diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index dbd9f27872962d..d8426dfb3fdca2 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -62,7 +62,7 @@ def test_repr(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) - for i in range(get_c_recursion_limit() + 1): + for i in range(get_c_recursion_limit() * 10): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index f249f0021e9c1c..04236330dd04a8 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -625,7 +625,7 @@ def __repr__(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): d = self._empty_mapping() - for i in range(get_c_recursion_limit() + 1): + for i in range(get_c_recursion_limit() * 5): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index f31d98bf731d67..c743f23f15f506 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2634,7 +2634,7 @@ def get_c_recursion_limit(): def exceeds_recursion_limit(): """For recursion tests, easily exceeds default recursion limit.""" - return get_c_recursion_limit() * 3 + return get_c_recursion_limit() * 20 # Windows doesn't have os.uname() but it doesn't support s390x. diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6c3de2091c451d..a8a803cdd92cb0 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -712,11 +712,11 @@ def test_yet_more_evil_still_undecodable(self): @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): - # Expected limit is Py_C_RECURSION_LIMIT - limit = get_c_recursion_limit() - fail_depth = limit + 1 - crash_depth = limit * 100 - success_depth = int(limit * 0.8) + # Compiler frames are small + limit = get_c_recursion_limit() * 3 // 2 + fail_depth = limit * 10 + crash_depth = limit * 50 + success_depth = limit def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 86b2f22dee5347..d3fa65df5f6017 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -597,7 +597,7 @@ def __repr__(self): @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = {} - for i in range(get_c_recursion_limit() + 1): + for i in range(get_c_recursion_limit() * 10): d = {1: d} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index d6bf00eeeb0013..5118db98be439a 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -280,7 +280,7 @@ def test_recursive_repr(self): @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} - for i in range(get_c_recursion_limit()//2 + 100): + for i in range(get_c_recursion_limit() * 2): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 53212529c27e28..b9af1e503d1406 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -460,7 +460,7 @@ def test_basics_split_by_predicate__match(self): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(get_c_recursion_limit() + 1): + for i in range(get_c_recursion_limit() * 10): e = ExceptionGroup('eg', [e]) return e diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index e44b629897c58a..0073a265509323 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -115,7 +115,9 @@ static PyObject* get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); - return PyLong_FromLong(tstate->c_recursion_remaining); + char here; + int remaining = (int)((&here - tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); + return PyLong_FromLong(remaining); } diff --git a/Objects/object.c b/Objects/object.c index f1db80d0cb9bd6..7d5ff759ac83d6 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2899,18 +2899,6 @@ _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op) void _PyTrash_thread_destroy_chain(PyThreadState *tstate) { - /* We need to increase c_recursion_remaining here, otherwise, - _PyTrash_thread_destroy_chain will be called recursively - and then possibly crash. An example that may crash without - increase: - N = 500000 # need to be large enough - ob = object() - tups = [(ob,) for i in range(N)] - for i in range(49): - tups = [(tup,) for tup in tups] - del tups - */ - _Py_EnterRecursiveCallTstateUnchecked(tstate); while (tstate->delete_later) { PyObject *op = tstate->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; @@ -2932,7 +2920,6 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate) _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); } - _Py_LeaveRecursiveCallTstate(tstate); } void _Py_NO_RETURN diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ae46215d3f3b18..9cacf61071ceda 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3980,7 +3980,6 @@ dummy_func( STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); _Py_LeaveRecursiveCallTstate(tstate); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -4177,7 +4176,6 @@ dummy_func( method->d_common.d_type)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), PyStackRef_AsPyObjectBorrow(arg_stackref)); @@ -4255,7 +4253,6 @@ dummy_func( EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); _Py_LeaveRecursiveCallTstate(tstate); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); diff --git a/Python/ceval.c b/Python/ceval.c index 46e693fd1edad6..fbf78d7c1adcbd 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -311,8 +311,8 @@ Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) void _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) { - tstate->c_recursion_remaining--; - if (tstate->c_recursion_remaining < -50) { + char here; + if (&here < tstate->c_stack_hard_limit) { Py_FatalError("Unchecked stack overflow."); } } @@ -328,31 +328,44 @@ Py_LeaveRecursiveCallTstate(PyThreadState *tstate) int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { + char here; + assert(tstate->c_stack_soft_limit != NULL); + if (tstate->c_stack_hard_limit == NULL) { #ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - ++tstate->c_recursion_remaining; - _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); - return -1; - } + assert(_PyOS_CheckStack(PYOS_STACK_MARGIN)); + if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { + tstate->c_stack_soft_limit = &here - PYOS_STACK_MARGIN_BYTES; + return 0; + } + else { + assert(tstate->c_stack_soft_limit != (char*)UINTPTR_MAX); + tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; + }F +#else + assert(tstate->c_stack_soft_limit == (char*)UINTPTR_MAX); + tstate->c_stack_soft_limit = &here - Py_C_STACK_SIZE; + tstate->c_stack_hard_limit = &here - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); #endif + } + if (&here >= tstate->c_stack_soft_limit) { + return 0; + } + assert(tstate->c_stack_hard_limit != NULL); + if (&here < tstate->c_stack_hard_limit) { + /* Overflowing while handling an overflow. Give up. */ + Py_FatalError("Cannot recover from stack overflow."); + } if (tstate->recursion_headroom) { - if (tstate->c_recursion_remaining < -50) { - /* Overflowing while handling an overflow. Give up. */ - Py_FatalError("Cannot recover from stack overflow."); - } + return 0; } else { - if (tstate->c_recursion_remaining <= 0) { - tstate->recursion_headroom++; - _PyErr_Format(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); - tstate->recursion_headroom--; - ++tstate->c_recursion_remaining; - return -1; - } + tstate->recursion_headroom++; + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded%s", + where); + tstate->recursion_headroom--; + return -1; } - return 0; } @@ -838,9 +851,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int frame->previous = &entry_frame; tstate->current_frame = frame; - // PyEval_EvalDefault is a big function, so count it twice - _Py_EnterRecursiveCallTstateUnchecked(tstate); - /* support for generator.throw() */ if (throwflag) { if (_Py_EnterRecursivePy(tstate)) { @@ -1561,11 +1571,9 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) // _PyThreadState_PopFrame, since f_code is already cleared at that point: assert((PyObject **)frame + _PyFrame_GetCode(frame)->co_framesize == tstate->datastack_top); - _Py_EnterRecursiveCallTstateUnchecked(tstate); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); PyStackRef_CLEAR(frame->f_executable); - _Py_LeaveRecursiveCallTstate(tstate); _PyThreadState_PopFrame(tstate, frame); } @@ -1578,11 +1586,9 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) assert(tstate->exc_info == &gen->gi_exc_state); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; - _Py_EnterRecursiveCallTstateUnchecked(tstate); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); _PyErr_ClearExcState(&gen->gi_exc_state); - _Py_LeaveRecursiveCallTstate(tstate); frame->previous = NULL; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 36a7027f38120e..6cb99ca8175795 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5106,7 +5106,6 @@ STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -5455,7 +5454,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), @@ -5592,7 +5590,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a296294372338a..aef5b0c6f4d3db 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2086,7 +2086,6 @@ STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -3361,7 +3360,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -3466,7 +3464,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), diff --git a/Python/pystate.c b/Python/pystate.c index 89a652850e9363..8184ec10cf614d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1490,9 +1490,10 @@ init_threadstate(_PyThreadStateImpl *_tstate, // thread_id and native_thread_id are set in bind_tstate(). - tstate->py_recursion_limit = interp->ceval.recursion_limit, - tstate->py_recursion_remaining = interp->ceval.recursion_limit, - tstate->c_recursion_remaining = Py_C_RECURSION_LIMIT; + tstate->py_recursion_limit = interp->ceval.recursion_limit; + tstate->py_recursion_remaining = interp->ceval.recursion_limit; + tstate->c_stack_soft_limit = (char *)UINTPTR_MAX; + tstate->c_stack_hard_limit = NULL; tstate->exc_info = &tstate->exc_state; diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index fed7aec746a7b7..258855fd0b44b0 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -658,7 +658,6 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "_PyUnicode_JoinArray", "_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY", "_Py_DECREF_NO_DEALLOC", - "_Py_EnterRecursiveCallTstateUnchecked", "_Py_ID", "_Py_IsImmortal", "_Py_LeaveRecursiveCallPy", From 22ca16925834a8cc5c0f3e3dd2db7b31c05f69a8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 15:46:13 +0000 Subject: [PATCH 03/41] Use uintptr_t instead of char * to avoid warnings and UB --- Include/cpython/pystate.h | 5 +++-- Include/internal/pycore_ceval.h | 6 ++++-- Modules/_testinternalcapi.c | 3 ++- Python/ceval.c | 26 ++++++++++++++------------ Python/pystate.c | 4 ++-- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 44f11c01212451..666a295ffdf8a0 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -112,8 +112,9 @@ struct _ts { int py_recursion_remaining; int py_recursion_limit; - char *c_stack_soft_limit; - char *c_stack_hard_limit; + // These are addresses, but we need to convert to ints to avoid UB. + uintptr_t c_stack_soft_limit; + uintptr_t c_stack_hard_limit; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index ec2f5cc4f26478..727ba8ad85533d 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -195,7 +195,8 @@ extern void _PyEval_DeactivateOpCache(void); static inline int _Py_MakeRecCheck(PyThreadState *tstate) { char here; - return &here < tstate->c_stack_soft_limit; + uintptr_t here_addr = (uintptr_t)&here; + return here_addr < tstate->c_stack_soft_limit; } // Export for '_json' shared extension, used via _Py_EnterRecursiveCall() @@ -223,7 +224,8 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { char here; - return &here <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; + uintptr_t here_addr = (uintptr_t)&here; + return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } static inline void _Py_LeaveRecursiveCall(void) { diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 0073a265509323..5bfc7d1fc12087 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -116,7 +116,8 @@ get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); char here; - int remaining = (int)((&here - tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); + uintptr_t here_addr = (uintptr_t)&here; + int remaining = (int)((here_addr - tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); return PyLong_FromLong(remaining); } diff --git a/Python/ceval.c b/Python/ceval.c index fbf78d7c1adcbd..c044a76bb3872b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -312,7 +312,8 @@ void _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) { char here; - if (&here < tstate->c_stack_hard_limit) { + uintptr_t here_addr = (uintptr_t)&here; + if (here_addr < tstate->c_stack_hard_limit) { Py_FatalError("Unchecked stack overflow."); } } @@ -329,29 +330,30 @@ int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { char here; - assert(tstate->c_stack_soft_limit != NULL); - if (tstate->c_stack_hard_limit == NULL) { + uintptr_t here_addr = (uintptr_t)&here; + assert(tstate->c_stack_soft_limit != 0); + if (tstate->c_stack_hard_limit == 0) { #ifdef USE_STACKCHECK assert(_PyOS_CheckStack(PYOS_STACK_MARGIN)); if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { - tstate->c_stack_soft_limit = &here - PYOS_STACK_MARGIN_BYTES; + tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; return 0; } else { - assert(tstate->c_stack_soft_limit != (char*)UINTPTR_MAX); + assert(tstate->c_stack_soft_limit != UINTPTR_MAX); tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; - }F + } #else - assert(tstate->c_stack_soft_limit == (char*)UINTPTR_MAX); - tstate->c_stack_soft_limit = &here - Py_C_STACK_SIZE; - tstate->c_stack_hard_limit = &here - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); + assert(tstate->c_stack_soft_limit == UINTPTR_MAX); + tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE; + tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); #endif } - if (&here >= tstate->c_stack_soft_limit) { + if (here_addr >= tstate->c_stack_soft_limit) { return 0; } - assert(tstate->c_stack_hard_limit != NULL); - if (&here < tstate->c_stack_hard_limit) { + assert(tstate->c_stack_hard_limit != 0); + if (here_addr < tstate->c_stack_hard_limit) { /* Overflowing while handling an overflow. Give up. */ Py_FatalError("Cannot recover from stack overflow."); } diff --git a/Python/pystate.c b/Python/pystate.c index 8184ec10cf614d..9aa5b995619192 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1492,8 +1492,8 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->py_recursion_limit = interp->ceval.recursion_limit; tstate->py_recursion_remaining = interp->ceval.recursion_limit; - tstate->c_stack_soft_limit = (char *)UINTPTR_MAX; - tstate->c_stack_hard_limit = NULL; + tstate->c_stack_soft_limit = UINTPTR_MAX; + tstate->c_stack_hard_limit = 0; tstate->exc_info = &tstate->exc_state; From b3638a5e8c82db148c877eb88d34a059c8ee1a91 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 16:18:12 +0000 Subject: [PATCH 04/41] Fix typo and update stable ABI --- Doc/data/stable_abi.dat | 1 + Include/ceval.h | 1 - Include/cpython/pystate.h | 2 +- Include/internal/pycore_ceval.h | 2 +- Lib/test/test_stable_abi_ctypes.py | 1 + Misc/stable_abi.toml | 2 ++ PC/python3dll.c | 1 + Python/ceval.c | 6 ------ 8 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 59e7a31bc2ef06..db2e72b6090e6f 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -885,6 +885,7 @@ func,Py_NewRef,3.10,, func,Py_PACK_FULL_VERSION,3.14,, func,Py_PACK_VERSION,3.14,, func,Py_REFCNT,3.14,, +func,Py_ReachedRecursionLimit,3.14,, func,Py_ReprEnter,3.2,, func,Py_ReprLeave,3.2,, func,Py_SetProgramName,3.2,, diff --git a/Include/ceval.h b/Include/ceval.h index 09460a7757ded0..6e5e91d9cf73f1 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -61,7 +61,6 @@ PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); PyAPI_FUNC(int) Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count); -PyAPI_FUNC(void) Py_LeaveRecursiveCallTstate(PyThreadState *tstate); PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 666a295ffdf8a0..791eca9177dcbd 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -240,7 +240,7 @@ struct _ts { # define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 1000) # endif #elif defined(_Py_ADDRESS_SANITIZER) -# define Py_C_STACK_SIZE (Py_C_STACK_SIZE / 600) +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 600) #else # define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 300) #endif diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 727ba8ad85533d..f12b19f0fdca4a 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -218,7 +218,7 @@ static inline int _Py_EnterRecursiveCall(const char *where) { return _Py_EnterRecursiveCallTstate(tstate, where); } -static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { +static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { (void)tstate; } diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index f3724ce6d4d15a..793dbcc3f9a4cb 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -904,6 +904,7 @@ def test_windows_feature_macros(self): "Py_PACK_FULL_VERSION", "Py_PACK_VERSION", "Py_REFCNT", + "Py_ReachedRecursionLimit", "Py_ReprEnter", "Py_ReprLeave", "Py_SetPath", diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 9317be605f0065..51e88dfd60441e 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2545,3 +2545,5 @@ added = '3.14' [function.Py_PACK_VERSION] added = '3.14' +[function.Py_ReachedRecursionLimit] + added = '3.14' diff --git a/PC/python3dll.c b/PC/python3dll.c index 84b3c735240b73..dd282ca1013bd4 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -83,6 +83,7 @@ EXPORT_FUNC(Py_NewInterpreter) EXPORT_FUNC(Py_NewRef) EXPORT_FUNC(Py_PACK_FULL_VERSION) EXPORT_FUNC(Py_PACK_VERSION) +EXPORT_FUNC(Py_ReachedRecursionLimit) EXPORT_FUNC(Py_REFCNT) EXPORT_FUNC(Py_ReprEnter) EXPORT_FUNC(Py_ReprLeave) diff --git a/Python/ceval.c b/Python/ceval.c index 7e7687e8471f81..4b5668738429c8 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -318,12 +318,6 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) } } -void -Py_LeaveRecursiveCallTstate(PyThreadState *tstate) -{ - _Py_LeaveRecursiveCallTstate(tstate); -} - /* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches recursion_limit. */ int From 774efb530e2111d04a33ed3e84a4b79bb14e32f6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 16:23:36 +0000 Subject: [PATCH 05/41] Tweak AST test numbers --- Lib/test/test_ast/test_ast.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index c95a27e9be5d0b..af9f199e6b8942 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -747,9 +747,9 @@ def next(self): @support.cpython_only @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - fail_depth = support.exceeds_recursion_limit() - crash_depth = 100_000 - success_depth = int(support.get_c_recursion_limit() * 0.6) + fail_depth = support.exceeds_recursion_limit() * 2 + crash_depth = 200_000 + success_depth = support.get_c_recursion_limit() if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() success_depth = min(success_depth, remaining) From 151c88f2a45b2ee5add540274728837a9f907f68 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 16:47:37 +0000 Subject: [PATCH 06/41] Improve logic handling trial C stack overflow --- Python/ceval.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 4b5668738429c8..5f704f436a6c33 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -328,15 +328,17 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) assert(tstate->c_stack_soft_limit != 0); if (tstate->c_stack_hard_limit == 0) { #ifdef USE_STACKCHECK - assert(_PyOS_CheckStack(PYOS_STACK_MARGIN)); if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; return 0; } - else { - assert(tstate->c_stack_soft_limit != UINTPTR_MAX); - tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; + assert(tstate->c_stack_soft_limit != UINTPTR_MAX); + int margin = PYOS_STACK_MARGIN*3/2; + while (margin > 0 && _PyOS_CheckStack(margin)) { + margin -= PYOS_STACK_MARGIN/2; } + tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *); + tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else assert(tstate->c_stack_soft_limit == UINTPTR_MAX); tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE; From 350f8eccbd8a17b6fc471f54968874cf70f42303 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 16:51:35 +0000 Subject: [PATCH 07/41] Remove calls to PyOS_CheckStack --- Objects/object.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/Objects/object.c b/Objects/object.c index 7d5ff759ac83d6..d07a33a91237d9 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -612,12 +612,9 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) int write_error = 0; if (PyErr_CheckSignals()) return -1; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); + if (_Py_EnterRecursiveCall(" printing an object")) { return -1; } -#endif clearerr(fp); /* Clear any previous error condition */ if (op == NULL) { Py_BEGIN_ALLOW_THREADS @@ -738,12 +735,6 @@ PyObject_Repr(PyObject *v) PyObject *res; if (PyErr_CheckSignals()) return NULL; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } -#endif if (v == NULL) return PyUnicode_FromString(""); if (Py_TYPE(v)->tp_repr == NULL) @@ -786,12 +777,6 @@ PyObject_Str(PyObject *v) PyObject *res; if (PyErr_CheckSignals()) return NULL; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } -#endif if (v == NULL) return PyUnicode_FromString(""); if (PyUnicode_CheckExact(v)) { From 428c46ad6aecc073d75a157f7f9789537102454a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 11 Feb 2025 17:05:51 +0000 Subject: [PATCH 08/41] Up the limits for recursion tests --- Lib/test/list_tests.py | 2 +- Lib/test/mapping_tests.py | 2 +- Lib/test/test_compile.py | 4 ++-- Lib/test/test_dict.py | 2 +- Lib/test/test_exception_group.py | 2 +- Lib/test/test_isinstance.py | 11 +++++------ Lib/test/test_userdict.py | 6 +----- Lib/test/test_userlist.py | 4 +--- 8 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index d8426dfb3fdca2..1ec646a7ce8e19 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -62,7 +62,7 @@ def test_repr(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) - for i in range(get_c_recursion_limit() * 10): + for i in range(100_000): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 04236330dd04a8..02a0f2ebabaeab 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -625,7 +625,7 @@ def __repr__(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): d = self._empty_mapping() - for i in range(get_c_recursion_limit() * 5): + for i in range(100_000): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index a8a803cdd92cb0..646844122fb8c1 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -714,8 +714,8 @@ def test_yet_more_evil_still_undecodable(self): def test_compiler_recursion_limit(self): # Compiler frames are small limit = get_c_recursion_limit() * 3 // 2 - fail_depth = limit * 10 - crash_depth = limit * 50 + fail_depth = limit * 50 + crash_depth = limit * 200 success_depth = limit def check_limit(prefix, repeated, mode="single"): diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index d3fa65df5f6017..c2d2825ac1811c 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -597,7 +597,7 @@ def __repr__(self): @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = {} - for i in range(get_c_recursion_limit() * 10): + for i in range(100_000): d = {1: d} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index b9af1e503d1406..7d6d961bd74e9b 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -460,7 +460,7 @@ def test_basics_split_by_predicate__match(self): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(get_c_recursion_limit() * 10): + for i in range(100_000): e = ExceptionGroup('eg', [e]) return e diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index abc75c82375d98..115e26c5541526 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -267,15 +267,13 @@ def test_subclass_tuple(self): def test_subclass_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown - with support.infinite_recursion(): - self.assertRaises(RecursionError, blowstack, issubclass, str, str) + self.assertRaises(RecursionError, blowstack, issubclass, str, str) @support.skip_emscripten_stack_overflow() def test_isinstance_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown - with support.infinite_recursion(): - self.assertRaises(RecursionError, blowstack, isinstance, '', str) + self.assertRaises(RecursionError, blowstack, isinstance, '', str) def test_subclass_with_union(self): self.assertTrue(issubclass(int, int | float | int)) @@ -355,8 +353,9 @@ def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. tuple_arg = (compare_to,) - for cnt in range(support.exceeds_recursion_limit()): - tuple_arg = (tuple_arg,) + while True: + for _ in range(100): + tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py index 61e79f553e8ec9..9bd842eda5b49c 100644 --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -213,11 +213,7 @@ class G(collections.UserDict): else: self.fail("g[42] didn't raise KeyError") - # Decorate existing test with recursion limit, because - # the test is for C structure, but `UserDict` is a Python structure. - test_repr_deep = support.infinite_recursion(25)( - mapping_tests.TestHashMappingProtocol.test_repr_deep, - ) + test_repr_deep = mapping_tests.TestHashMappingProtocol.test_repr_deep if __name__ == "__main__": diff --git a/Lib/test/test_userlist.py b/Lib/test/test_userlist.py index 312702c8e398b9..e82e88f3f3ed1d 100644 --- a/Lib/test/test_userlist.py +++ b/Lib/test/test_userlist.py @@ -69,9 +69,7 @@ def test_userlist_copy(self): # Decorate existing test with recursion limit, because # the test is for C structure, but `UserList` is a Python structure. - test_repr_deep = support.infinite_recursion(25)( - list_tests.CommonTest.test_repr_deep, - ) + test_repr_deep = list_tests.CommonTest.test_repr_deep if __name__ == "__main__": unittest.main() From a9be14169915b7055e3944e3fbbb4b8d41a9e0c3 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 09:35:43 +0000 Subject: [PATCH 09/41] Use deeper stack for test --- Lib/test/test_dictviews.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 5118db98be439a..b420361773d3b2 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -2,7 +2,7 @@ import copy import pickle import unittest -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import exceeds_recursion_limit, skip_emscripten_stack_overflow class DictSetTest(unittest.TestCase): @@ -280,7 +280,7 @@ def test_recursive_repr(self): @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} - for i in range(get_c_recursion_limit() * 2): + for i in range(exceeds_recursion_limit() * 2): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) From 03fc52e146e81cb3c200cbc7c50f0adc14b92f9b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 10:45:34 +0000 Subject: [PATCH 10/41] Remove exceeds_recursion_limit and get_c_recursion_limit. Use platform independent constants --- Include/cpython/pystate.h | 4 ++-- Lib/test/list_tests.py | 2 +- Lib/test/mapping_tests.py | 2 +- Lib/test/support/__init__.py | 16 +--------------- Lib/test/test_ast/test_ast.py | 4 ++-- Lib/test/test_capi/test_misc.py | 2 +- Lib/test/test_collections.py | 2 +- Lib/test/test_compile.py | 6 +++--- Lib/test/test_dict.py | 2 +- Lib/test/test_dictviews.py | 4 ++-- Lib/test/test_exception_group.py | 2 +- Lib/test/test_exceptions.py | 2 +- Lib/test/test_functools.py | 8 +++----- Lib/test/test_marshal.py | 3 +-- Lib/test/test_sys_settrace.py | 2 +- 15 files changed, 22 insertions(+), 39 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 791eca9177dcbd..2a9008f0f134df 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -235,9 +235,9 @@ struct _ts { // higher stack memory usage than a release build: use a lower limit. # if defined(__has_feature) /* Clang */ // Clang debug builds use a lot of stack space -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 2000) +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 4000) # else -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 1000) +# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 2000) # endif #elif defined(_Py_ADDRESS_SANITIZER) # define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 600) diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 1ec646a7ce8e19..1e8c4310c8481f 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -6,7 +6,7 @@ from functools import cmp_to_key from test import seq_tests -from test.support import ALWAYS_EQ, NEVER_EQ, get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import ALWAYS_EQ, NEVER_EQ, skip_emscripten_stack_overflow class CommonTest(seq_tests.CommonTest): diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 02a0f2ebabaeab..fa41a4305e812e 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow class BasicTestMappingProtocol(unittest.TestCase): diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c743f23f15f506..7bbc75a6e1a280 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -56,7 +56,7 @@ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", - "Py_DEBUG", "exceeds_recursion_limit", "get_c_recursion_limit", + "Py_DEBUG" "skip_on_s390x", "requires_jit_enabled", "requires_jit_disabled", @@ -2623,20 +2623,6 @@ def adjust_int_max_str_digits(max_digits): finally: sys.set_int_max_str_digits(current) - -def get_c_recursion_limit(): - try: - import _testcapi - return _testcapi.Py_C_RECURSION_LIMIT - except ImportError: - raise unittest.SkipTest('requires _testcapi') - - -def exceeds_recursion_limit(): - """For recursion tests, easily exceeds default recursion limit.""" - return get_c_recursion_limit() * 20 - - # Windows doesn't have os.uname() but it doesn't support s390x. is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x' skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x') diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index af9f199e6b8942..bbc1446fc4fe48 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -747,9 +747,9 @@ def next(self): @support.cpython_only @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - fail_depth = support.exceeds_recursion_limit() * 2 + fail_depth = 20_000 crash_depth = 200_000 - success_depth = support.get_c_recursion_limit() + success_depth = 200 if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() success_depth = min(success_depth, remaining) diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 52d67baa8e88a0..6c4cf5bd6598bc 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -408,7 +408,7 @@ def test_trashcan_subclass(self): # activated when its tp_dealloc is being called by a subclass from _testcapi import MyList L = None - for i in range(support.get_c_recursion_limit()): + for i in range(100): L = MyList((L,)) @support.requires_resource('cpu') diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 1e93530398be79..999449c78f0df8 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -542,7 +542,7 @@ def test_odd_sizes(self): self.assertEqual(Dot(1)._replace(d=999), (999,)) self.assertEqual(Dot(1)._fields, ('d',)) - n = support.exceeds_recursion_limit() + n = 100_000 names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 646844122fb8c1..644469d1fdf4ba 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -21,7 +21,7 @@ from test import support from test.support import (script_helper, requires_debug_ranges, run_code, - requires_specialization, get_c_recursion_limit) + requires_specialization) from test.support.bytecode_helper import instructions_with_positions from test.support.os_helper import FakePath @@ -123,7 +123,7 @@ def __getitem__(self, key): @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.skip_emscripten_stack_overflow() def test_extended_arg(self): - repeat = int(get_c_recursion_limit() * 0.9) + repeat = 100 longexpr = 'x = x or ' + '-x' * repeat g = {} code = textwrap.dedent(''' @@ -713,7 +713,7 @@ def test_yet_more_evil_still_undecodable(self): @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): # Compiler frames are small - limit = get_c_recursion_limit() * 3 // 2 + limit = 100 fail_depth = limit * 50 crash_depth = limit * 200 success_depth = limit diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index c2d2825ac1811c..ed485a74372de4 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -8,7 +8,7 @@ import unittest import weakref from test import support -from test.support import import_helper, get_c_recursion_limit +from test.support import import_helper class DictTest(unittest.TestCase): diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index b420361773d3b2..d09eba0019ac19 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -2,7 +2,7 @@ import copy import pickle import unittest -from test.support import exceeds_recursion_limit, skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow class DictSetTest(unittest.TestCase): @@ -280,7 +280,7 @@ def test_recursive_repr(self): @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} - for i in range(exceeds_recursion_limit() * 2): + for i in range(100_000): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 7d6d961bd74e9b..c9dbf94ca16ce5 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,7 +1,7 @@ import collections.abc import types import unittest -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 3838eb5b27c9e6..58c68a5cde4f6b 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1451,7 +1451,7 @@ def gen(): next(generator) recursionlimit = sys.getrecursionlimit() try: - recurse(support.exceeds_recursion_limit()) + recurse(100_000) finally: sys.setrecursionlimit(recursionlimit) print('Done.') diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 1b7a76bec839bf..34d403424fe0a8 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2077,15 +2077,13 @@ def fib(n): return n return fib(n-1) + fib(n-2) - if not support.Py_DEBUG: - depth = support.get_c_recursion_limit()*2//7 - with support.infinite_recursion(): - fib(depth) + with support.infinite_recursion(): + fib(100) if self.module == c_functools: fib.cache_clear() with support.infinite_recursion(): with self.assertRaises(RecursionError): - fib(10000) + fib(100_000) @py_functools.lru_cache() diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 4ed9f1fc1b8020..8b1fb0eba1f8b6 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -125,8 +125,7 @@ def test_code(self): def test_many_codeobjects(self): # Issue2957: bad recursion count on code objects # more than MAX_MARSHAL_STACK_DEPTH - count = support.exceeds_recursion_limit() - codes = (ExceptionTestCase.test_exceptions.__code__,) * count + codes = (ExceptionTestCase.test_exceptions.__code__,) * 10_000 marshal.loads(marshal.dumps(codes)) def test_different_filenames(self): diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 28c2c681babe18..e2fe7861415cef 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -3035,7 +3035,7 @@ def test_trace_unpack_long_sequence(self): def test_trace_lots_of_globals(self): - count = min(1000, int(support.get_c_recursion_limit() * 0.8)) + count = 1000 code = """if 1: def f(): From afac1e635be23e9710e99300ed0c462dbf4e81a5 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 11:07:59 +0000 Subject: [PATCH 11/41] Do fewer probes when growing stack limit --- Include/internal/pycore_ceval.h | 1 + Python/ceval.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index f12b19f0fdca4a..6101111119e721 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -223,6 +223,7 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { } static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { + assert(tstate->c_stack_soft_limit != UINTPTR_MAX); char here; uintptr_t here_addr = (uintptr_t)&here; return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; diff --git a/Python/ceval.c b/Python/ceval.c index 5f704f436a6c33..90deb9c3cfd05d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -332,10 +332,15 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; return 0; } + int margin = PYOS_STACK_MARGIN; assert(tstate->c_stack_soft_limit != UINTPTR_MAX); - int margin = PYOS_STACK_MARGIN*3/2; - while (margin > 0 && _PyOS_CheckStack(margin)) { - margin -= PYOS_STACK_MARGIN/2; + if (_PyOS_CheckStack(margin)) { + margin = PYOS_STACK_MARGIN/2; + } + else { + if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) { + margin = PYOS_STACK_MARGIN*3/2; + } } tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *); tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; From 9da904da9feb64cf7a933266e4c882eeee546631 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 11:12:48 +0000 Subject: [PATCH 12/41] Tweak depths --- Lib/test/support/__init__.py | 3 +-- Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_compile.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 7bbc75a6e1a280..7aacd187981373 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -56,8 +56,7 @@ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", - "Py_DEBUG" - "skip_on_s390x", + "Py_DEBUG", "skip_on_s390x", "requires_jit_enabled", "requires_jit_disabled", "force_not_colorized", diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index bbc1446fc4fe48..d1ef5f190a6c05 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -747,7 +747,7 @@ def next(self): @support.cpython_only @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - fail_depth = 20_000 + fail_depth = 100_000 crash_depth = 200_000 success_depth = 200 if _testinternalcapi is not None: diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 644469d1fdf4ba..bef00ff4b6e0a8 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -714,8 +714,8 @@ def test_yet_more_evil_still_undecodable(self): def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - fail_depth = limit * 50 - crash_depth = limit * 200 + fail_depth = limit * 500 + crash_depth = limit * 2000 success_depth = limit def check_limit(prefix, repeated, mode="single"): From dbcf6f02685ef4473cb2292daeaec051fc94dc0b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 12:19:13 +0000 Subject: [PATCH 13/41] Perform lazy initialization of c recursion check --- Include/internal/pycore_ceval.h | 10 ++++++- Python/ceval.c | 52 +++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 6101111119e721..4c01b07365e275 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -222,11 +222,19 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { (void)tstate; } +PyAPI_FUNC(void) _Py_InitializeRecursionCheck(PyThreadState *tstate); + static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { assert(tstate->c_stack_soft_limit != UINTPTR_MAX); char here; uintptr_t here_addr = (uintptr_t)&here; - return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; + if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { + return 0; + } + if (tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionCheck(tstate); + } + return here_addr <= stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } static inline void _Py_LeaveRecursiveCall(void) { diff --git a/Python/ceval.c b/Python/ceval.c index d369e210cd7b20..aacb8379c09002 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -318,6 +318,35 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) } } +void +_Py_InitializeRecursionCheck(PyThreadState *tstate) +{ + char here; + uintptr_t here_addr = (uintptr_t)&here; +#ifdef USE_STACKCHECK + if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { + tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; + return 0; + } + int margin = PYOS_STACK_MARGIN; + assert(tstate->c_stack_soft_limit != UINTPTR_MAX); + if (_PyOS_CheckStack(margin)) { + margin = PYOS_STACK_MARGIN/2; + } + else { + if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) { + margin = PYOS_STACK_MARGIN*3/2; + } + } + tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *); + tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; +#else + assert(tstate->c_stack_soft_limit == UINTPTR_MAX); + tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE; + tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); +#endif +} + /* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches recursion_limit. */ int @@ -327,28 +356,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) uintptr_t here_addr = (uintptr_t)&here; assert(tstate->c_stack_soft_limit != 0); if (tstate->c_stack_hard_limit == 0) { -#ifdef USE_STACKCHECK - if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { - tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; - return 0; - } - int margin = PYOS_STACK_MARGIN; - assert(tstate->c_stack_soft_limit != UINTPTR_MAX); - if (_PyOS_CheckStack(margin)) { - margin = PYOS_STACK_MARGIN/2; - } - else { - if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) { - margin = PYOS_STACK_MARGIN*3/2; - } - } - tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *); - tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; -#else - assert(tstate->c_stack_soft_limit == UINTPTR_MAX); - tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE; - tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); -#endif + _Py_InitializeRecursionCheck(tstate); } if (here_addr >= tstate->c_stack_soft_limit) { return 0; From 2cc3287b540cc4d3c38f1f6672c165a531efaf80 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 12:21:54 +0000 Subject: [PATCH 14/41] Post merge fixup --- Include/internal/pycore_ceval.h | 3 +- Python/generated_cases.c.h | 1586 +++++++++---------------------- 2 files changed, 448 insertions(+), 1141 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 4c01b07365e275..8feec04954ea3f 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -225,7 +225,6 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { PyAPI_FUNC(void) _Py_InitializeRecursionCheck(PyThreadState *tstate); static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { - assert(tstate->c_stack_soft_limit != UINTPTR_MAX); char here; uintptr_t here_addr = (uintptr_t)&here; if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { @@ -234,7 +233,7 @@ static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_co if (tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionCheck(tstate); } - return here_addr <= stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; + return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } static inline void _Py_LeaveRecursiveCall(void) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 771e6bf6deb433..aef5b0c6f4d3db 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -61,23 +61,16 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyEval_BinaryOps[oparg](lhs_o, rhs_o); stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(lhs); + PyStackRef_CLOSE(rhs); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } res = PyStackRef_FromPyObjectSteal(res_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = lhs; - lhs = res; - stack_pointer[-2] = lhs; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(rhs); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = res; } + stack_pointer[-2] = res; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -286,21 +279,13 @@ STAT_INC(BINARY_OP, hit); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = d->action(left_o, right_o); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); res = PyStackRef_FromPyObjectSteal(res_o); } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2] = res; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -339,7 +324,7 @@ // _BINARY_OP_INPLACE_ADD_UNICODE { PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); - PyObject *right_o = PyStackRef_AsPyObjectSteal(right); + PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); assert(PyUnicode_CheckExact(left_o)); assert(PyUnicode_CheckExact(right_o)); int next_oparg; @@ -370,17 +355,11 @@ assert(Py_REFCNT(left_o) >= 2); PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc); PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyUnicode_Append(&temp, right_o); - stack_pointer = _PyFrame_GetStackPointer(frame); *target_local = PyStackRef_FromPyObjectSteal(temp); - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(right_o); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc); if (PyStackRef_IsNull(*target_local)) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } #if TIER_ONE // The STORE_FAST is already done. This is done here in tier one, @@ -389,6 +368,8 @@ SKIP_OVER(1); #endif } + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -533,25 +514,15 @@ _PyErr_SetKeyError(sub); stack_pointer = _PyFrame_GetStackPointer(frame); } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = sub_st; - sub_st = PyStackRef_NULL; - stack_pointer[-1] = sub_st; - PyStackRef_CLOSE(tmp); - tmp = dict_st; - dict_st = PyStackRef_NULL; - stack_pointer[-2] = dict_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(dict_st); + PyStackRef_CLOSE(sub_st); if (rc <= 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } // not found or error res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2] = res; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1033,14 +1004,9 @@ values = &stack_pointer[-oparg*2]; STACKREFS_TO_PYOBJECTS(values, oparg*2, values_o); if (CONVERSION_FAILED(values_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg*2; --_i >= 0;) { - tmp = values[_i]; - values[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(values[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -oparg*2; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -1052,22 +1018,17 @@ oparg); stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(values_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg*2; --_i >= 0;) { - tmp = values[_i]; - values[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(values[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -oparg*2; - assert(WITHIN_STACK_BOUNDS()); if (map_o == NULL) { + stack_pointer += -oparg*2; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } map = PyStackRef_FromPyObjectSteal(map_o); - stack_pointer[0] = map; - stack_pointer += 1; + stack_pointer[-oparg*2] = map; + stack_pointer += 1 - oparg*2; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1087,14 +1048,9 @@ PyObject *set_o = PySet_New(NULL); stack_pointer = _PyFrame_GetStackPointer(frame); if (set_o == NULL) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg; --_i >= 0;) { - tmp = values[_i]; - values[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(values[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -1107,25 +1063,20 @@ stack_pointer = _PyFrame_GetStackPointer(frame); } } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg; --_i >= 0;) { - tmp = values[_i]; - values[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(values[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -oparg; - assert(WITHIN_STACK_BOUNDS()); if (err != 0) { + stack_pointer += -oparg; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); Py_DECREF(set_o); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } set = PyStackRef_FromPyObjectSteal(set_o); - stack_pointer[0] = set; - stack_pointer += 1; + stack_pointer[-oparg] = set; + stack_pointer += 1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1145,22 +1096,17 @@ PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]); PyObject *step_o = oparg == 3 ? PyStackRef_AsPyObjectBorrow(args[2]) : NULL; PyObject *slice_o = PySlice_New(start_o, stop_o, step_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -oparg; - assert(WITHIN_STACK_BOUNDS()); if (slice_o == NULL) { + stack_pointer += -oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } slice = PyStackRef_FromPyObjectSteal(slice_o); - stack_pointer[0] = slice; - stack_pointer += 1; + stack_pointer[-oparg] = slice; + stack_pointer += 1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1178,36 +1124,26 @@ pieces = &stack_pointer[-oparg]; STACKREFS_TO_PYOBJECTS(pieces, oparg, pieces_o); if (CONVERSION_FAILED(pieces_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg; --_i >= 0;) { - tmp = pieces[_i]; - pieces[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(pieces[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } PyObject *str_o = _PyUnicode_JoinArray(&_Py_STR(empty), pieces_o, oparg); STACKREFS_TO_PYOBJECTS_CLEANUP(pieces_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; for (int _i = oparg; --_i >= 0;) { - tmp = pieces[_i]; - pieces[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(pieces[_i]); } - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -oparg; - assert(WITHIN_STACK_BOUNDS()); if (str_o == NULL) { + stack_pointer += -oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } str = PyStackRef_FromPyObjectSteal(str_o); - stack_pointer[0] = str; - stack_pointer += 1; + stack_pointer[-oparg] = str; + stack_pointer += 1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1343,20 +1279,11 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -1392,23 +1319,14 @@ } } assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -1418,8 +1336,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -1427,12 +1345,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1536,9 +1454,7 @@ stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); if (temp == NULL) { - _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FrameClearAndPop(tstate, shim); - stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } init_frame = temp; @@ -1871,20 +1787,11 @@ STAT_INC(CALL, hit); STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -1893,23 +1800,14 @@ PyObject *res_o = tp->tp_vectorcall((PyObject *)tp, args_o, total_args, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -1919,8 +1817,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -1928,12 +1826,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -1983,20 +1881,11 @@ /* res = func(self, args, nargs) */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -2009,23 +1898,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -2035,8 +1915,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -2044,12 +1924,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -2103,20 +1983,11 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -2126,23 +1997,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -2152,8 +2014,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -2161,12 +2023,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -2216,7 +2078,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -2224,7 +2086,6 @@ STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -2474,18 +2335,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, PyStackRef_AsPyObjectBorrow(value)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = res; DISPATCH(); } @@ -2507,23 +2362,15 @@ PyObject *value2 = PyStackRef_AsPyObjectBorrow(value2_st); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); - _PyStackRef tmp = value1_st; - value1_st = PyStackRef_NULL; - stack_pointer[-1] = value1_st; - PyStackRef_CLOSE(tmp); - tmp = value2_st; - value2_st = PyStackRef_NULL; - stack_pointer[-2] = value2_st; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(value2_st); + PyStackRef_CLOSE(value1_st); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2] = res; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -2578,19 +2425,11 @@ } res = retval ? PyStackRef_True : PyStackRef_False; assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = callable[0]; - callable[0] = res; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); @@ -2708,24 +2547,12 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - stack_pointer[-1] = kwnames; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = kwnames; - kwnames = PyStackRef_NULL; - stack_pointer[-1] = kwnames; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(kwnames); stack_pointer += -3 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -2761,32 +2588,21 @@ } } } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = kwnames; - kwnames = PyStackRef_NULL; - stack_pointer[-1] = kwnames; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } + PyStackRef_CLOSE(kwnames); if (res_o == NULL) { + stack_pointer += -3 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-3 - oparg] = res; + stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -2976,23 +2792,12 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = kwnames; - kwnames = PyStackRef_NULL; - stack_pointer[-1] = kwnames; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(kwnames); stack_pointer += -3 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -3012,23 +2817,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -3038,8 +2834,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -3047,12 +2843,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -3347,20 +3143,11 @@ int nargs = total_args - 1; STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -3372,23 +3159,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -3398,8 +3176,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -3407,12 +3185,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -3469,20 +3247,11 @@ int nargs = total_args - 1; STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -3494,23 +3263,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -3520,8 +3280,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -3529,12 +3289,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -3593,14 +3353,13 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -3690,7 +3449,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate, 0)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3705,7 +3464,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), @@ -3713,23 +3471,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); _Py_LeaveRecursiveCallTstate(tstate); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -3739,8 +3488,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -3748,12 +3497,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -3808,20 +3557,11 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -3834,23 +3574,14 @@ stack_pointer = _PyFrame_GetStackPointer(frame); STACKREFS_TO_PYOBJECTS_CLEANUP(args_o); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -3860,8 +3591,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -3869,12 +3600,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -4296,54 +4027,38 @@ int err = _PyEval_CheckExceptStarTypeValid(tstate, match_type); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = match_type_st; - match_type_st = PyStackRef_NULL; - stack_pointer[-1] = match_type_st; - PyStackRef_CLOSE(tmp); - tmp = exc_value_st; - exc_value_st = PyStackRef_NULL; - stack_pointer[-2] = exc_value_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); - JUMP_TO_LABEL(error); + PyStackRef_CLOSE(exc_value_st); + PyStackRef_CLOSE(match_type_st); + JUMP_TO_LABEL(pop_2_error); } PyObject *match_o = NULL; PyObject *rest_o = NULL; _PyFrame_SetStackPointer(frame, stack_pointer); int res = _PyEval_ExceptionGroupMatch(frame, exc_value, match_type, &match_o, &rest_o); - _PyStackRef tmp = match_type_st; - match_type_st = PyStackRef_NULL; - stack_pointer[-1] = match_type_st; - PyStackRef_CLOSE(tmp); - tmp = exc_value_st; - exc_value_st = PyStackRef_NULL; - stack_pointer[-2] = exc_value_st; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(exc_value_st); + PyStackRef_CLOSE(match_type_st); if (res < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } assert((match_o == NULL) == (rest_o == NULL)); if (match_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } if (!Py_IsNone(match_o)) { + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyErr_SetHandledException(match_o); stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += 2; + assert(WITHIN_STACK_BOUNDS()); } rest = PyStackRef_FromPyObjectSteal(rest_o); match = PyStackRef_FromPyObjectSteal(match_o); - stack_pointer[0] = rest; - stack_pointer[1] = match; - stack_pointer += 2; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-2] = rest; + stack_pointer[-1] = match; DISPATCH(); } @@ -4367,20 +4082,15 @@ int err = _PyEval_CheckExceptTypeValid(tstate, right_o); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { - JUMP_TO_LABEL(error); + PyStackRef_CLOSE(right); + JUMP_TO_LABEL(pop_1_error); } _PyFrame_SetStackPointer(frame, stack_pointer); int res = PyErr_GivenExceptionMatches(left_o, right_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(right); - stack_pointer = _PyFrame_GetStackPointer(frame); b = res ? PyStackRef_True : PyStackRef_False; - stack_pointer[0] = b; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = b; DISPATCH(); } @@ -4394,14 +4104,14 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(CLEANUP_THROW); - _PyStackRef sub_iter; - _PyStackRef last_sent_val; + _PyStackRef sub_iter_st; + _PyStackRef last_sent_val_st; _PyStackRef exc_value_st; _PyStackRef none; _PyStackRef value; exc_value_st = stack_pointer[-1]; - last_sent_val = stack_pointer[-2]; - sub_iter = stack_pointer[-3]; + last_sent_val_st = stack_pointer[-2]; + sub_iter_st = stack_pointer[-3]; PyObject *exc_value = PyStackRef_AsPyObjectBorrow(exc_value_st); #ifndef Py_TAIL_CALL_INTERP assert(throwflag); @@ -4411,34 +4121,23 @@ int matches = PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration); stack_pointer = _PyFrame_GetStackPointer(frame); if (matches) { - value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = sub_iter; - sub_iter = value; - stack_pointer[-3] = sub_iter; - PyStackRef_CLOSE(tmp); - tmp = exc_value_st; - exc_value_st = PyStackRef_NULL; - stack_pointer[-1] = exc_value_st; - PyStackRef_CLOSE(tmp); - tmp = last_sent_val; - last_sent_val = PyStackRef_NULL; - stack_pointer[-2] = last_sent_val; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); none = PyStackRef_None; + value = PyStackRef_FromPyObjectNew(((PyStopIterationObject *)exc_value)->value); + PyStackRef_CLOSE(sub_iter_st); + PyStackRef_CLOSE(last_sent_val_st); + PyStackRef_CLOSE(exc_value_st); } else { _PyFrame_SetStackPointer(frame, stack_pointer); _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); monitor_reraise(tstate, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); JUMP_TO_LABEL(exception_unwind); } - stack_pointer[0] = none; - stack_pointer[1] = value; - stack_pointer += 2; + stack_pointer[-3] = none; + stack_pointer[-2] = value; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -4482,21 +4181,15 @@ assert((oparg >> 5) <= Py_GE); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PyObject_RichCompare(left_o, right_o, oparg >> 5); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } if (oparg & 16) { + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int res_bool = PyObject_IsTrue(res_o); Py_DECREF(res_o); @@ -4508,6 +4201,8 @@ } else { res = PyStackRef_FromPyObjectSteal(res_o); + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); } } stack_pointer[0] = res; @@ -4619,8 +4314,7 @@ _PyLong_DigitCount((PyLongObject *)right_o) <= 1); Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left_o); Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o); - // 2 if <, 4 if > - , 8 if ==; this matches the low 4 bits of the oparg + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg int sign_ish = COMPARISON_BIT(ileft, iright); PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc); PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc); @@ -4724,24 +4418,16 @@ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); _PyFrame_SetStackPointer(frame, stack_pointer); int res = PySequence_Contains(right_o, left_o); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); if (res < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False; } - stack_pointer[0] = b; - stack_pointer += 1; + stack_pointer[-2] = b; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -4773,23 +4459,15 @@ STAT_INC(CONTAINS_OP, hit); _PyFrame_SetStackPointer(frame, stack_pointer); int res = PyDict_Contains(right_o, left_o); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); if (res < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False; - stack_pointer[0] = b; - stack_pointer += 1; + stack_pointer[-2] = b; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -4822,23 +4500,15 @@ // Note: both set and frozenset use the same seq_contains method! _PyFrame_SetStackPointer(frame, stack_pointer); int res = _PySet_Contains((PySetObject *)right_o, left_o); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); if (res < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } b = (res ^ oparg) ? PyStackRef_True : PyStackRef_False; - stack_pointer[0] = b; - stack_pointer += 1; + stack_pointer[-2] = b; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -4930,14 +4600,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyObject_DelAttr(PyStackRef_AsPyObjectBorrow(owner), name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -5066,20 +4734,14 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyObject_DelItem(PyStackRef_AsPyObjectBorrow(container), PyStackRef_AsPyObjectBorrow(sub)); - _PyStackRef tmp = sub; - sub = PyStackRef_NULL; - stack_pointer[-1] = sub; - PyStackRef_CLOSE(tmp); - tmp = container; - container = PyStackRef_NULL; - stack_pointer[-2] = container; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(container); + PyStackRef_CLOSE(sub); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -5107,18 +4769,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatKwargsError(tstate, callable_o, update_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(update); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + PyStackRef_CLOSE(update); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(update); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -5150,18 +4806,12 @@ Py_TYPE(update_o)->tp_name); stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(update); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + PyStackRef_CLOSE(update); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(update); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -5185,26 +4835,20 @@ int matches = PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration); stack_pointer = _PyFrame_GetStackPointer(frame); if (matches) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = exc_st; - exc_st = PyStackRef_NULL; - stack_pointer[-1] = exc_st; - PyStackRef_CLOSE(tmp); - tmp = awaitable_st; - awaitable_st = PyStackRef_NULL; - stack_pointer[-2] = awaitable_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(awaitable_st); + PyStackRef_CLOSE(exc_st); } else { Py_INCREF(exc); _PyFrame_SetStackPointer(frame, stack_pointer); _PyErr_SetRaisedException(tstate, exc); monitor_reraise(tstate, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); JUMP_TO_LABEL(exception_unwind); } + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -5245,12 +4889,10 @@ receiver = stack_pointer[-2]; (void)receiver; val = value; + PyStackRef_CLOSE(receiver); stack_pointer[-2] = val; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(receiver); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -5387,23 +5029,15 @@ value = stack_pointer[-2]; _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PyObject_Format(PyStackRef_AsPyObjectBorrow(value), PyStackRef_AsPyObjectBorrow(fmt_spec)); - _PyStackRef tmp = fmt_spec; - fmt_spec = PyStackRef_NULL; - stack_pointer[-1] = fmt_spec; - PyStackRef_CLOSE(tmp); - tmp = value; - value = PyStackRef_NULL; - stack_pointer[-2] = value; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(value); + PyStackRef_CLOSE(fmt_spec); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2] = res; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -5739,26 +5373,20 @@ "__aiter__ method, got %.100s", type->tp_name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(obj); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } _PyFrame_SetStackPointer(frame, stack_pointer); iter_o = (*getter)(obj_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(obj); - stack_pointer = _PyFrame_GetStackPointer(frame); if (iter_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } if (Py_TYPE(iter_o)->tp_as_async == NULL || Py_TYPE(iter_o)->tp_as_async->am_anext == NULL) { + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); _PyErr_Format(tstate, PyExc_TypeError, "'async for' received an object from __aiter__ " @@ -5769,9 +5397,7 @@ JUMP_TO_LABEL(error); } iter = PyStackRef_FromPyObjectSteal(iter_o); - stack_pointer[0] = iter; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = iter; DISPATCH(); } @@ -5813,18 +5439,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *iter_o = _PyEval_GetAwaitable(PyStackRef_AsPyObjectBorrow(iterable), oparg); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(iterable); - stack_pointer = _PyFrame_GetStackPointer(frame); if (iter_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } iter = PyStackRef_FromPyObjectSteal(iter_o); - stack_pointer[0] = iter; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = iter; DISPATCH(); } @@ -5843,18 +5463,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *iter_o = PyObject_GetIter(PyStackRef_AsPyObjectBorrow(iterable)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(iterable); - stack_pointer = _PyFrame_GetStackPointer(frame); if (iter_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } iter = PyStackRef_FromPyObjectSteal(iter_o); - stack_pointer[0] = iter; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = iter; DISPATCH(); } @@ -5927,13 +5541,7 @@ JUMP_TO_LABEL(error); } iter = PyStackRef_FromPyObjectSteal(iter_o); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = iterable; - iterable = iter; - stack_pointer[-1] = iterable; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = iter; + PyStackRef_CLOSE(iterable); } } stack_pointer[-1] = iter; @@ -5983,23 +5591,15 @@ PyObject *res_o = _PyEval_ImportName(tstate, frame, name, PyStackRef_AsPyObjectBorrow(fromlist), PyStackRef_AsPyObjectBorrow(level)); - _PyStackRef tmp = fromlist; - fromlist = PyStackRef_NULL; - stack_pointer[-1] = fromlist; - PyStackRef_CLOSE(tmp); - tmp = level; - level = PyStackRef_NULL; - stack_pointer[-2] = level; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(level); + PyStackRef_CLOSE(fromlist); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2] = res; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -6111,20 +5711,11 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -6160,23 +5751,14 @@ } } assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp; + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } if (res_o == NULL) { + stack_pointer += -2 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); @@ -6186,8 +5768,8 @@ _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); @@ -6195,12 +5777,12 @@ if (err != 0) { JUMP_TO_LABEL(error); } - stack_pointer += -1; + stack_pointer += 1 + oparg; assert(WITHIN_STACK_BOUNDS()); } } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -6517,24 +6099,12 @@ /* Callable is not a normal Python function */ STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o); if (CONVERSION_FAILED(args_o)) { - stack_pointer[-1] = kwnames; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = kwnames; - kwnames = PyStackRef_NULL; - stack_pointer[-1] = kwnames; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(args[_i]); } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(kwnames); stack_pointer += -3 - oparg; assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); @@ -6570,32 +6140,21 @@ } } } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = kwnames; - kwnames = PyStackRef_NULL; - stack_pointer[-1] = kwnames; - PyStackRef_CLOSE(tmp); + PyStackRef_CLOSE(callable[0]); + PyStackRef_XCLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { - tmp = args[_i]; - args[_i] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - } - tmp = self_or_null[0]; - self_or_null[0] = PyStackRef_NULL; - PyStackRef_XCLOSE(tmp); - tmp = callable[0]; - callable[0] = PyStackRef_NULL; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3 - oparg; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(args[_i]); + } + PyStackRef_CLOSE(kwnames); if (res_o == NULL) { + stack_pointer += -3 - oparg; + assert(WITHIN_STACK_BOUNDS()); JUMP_TO_LABEL(error); } res = PyStackRef_FromPyObjectSteal(res_o); } - stack_pointer[0] = res; - stack_pointer += 1; + stack_pointer[-3 - oparg] = res; + stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -6623,11 +6182,9 @@ JUMP_TO_LABEL(error); } } + PyStackRef_CLOSE(value); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -6854,23 +6411,10 @@ frame, this_instr, global_super, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = self_st; - self_st = PyStackRef_NULL; - stack_pointer[-1] = self_st; - PyStackRef_CLOSE(tmp); - tmp = class_st; - class_st = PyStackRef_NULL; - stack_pointer[-2] = class_st; - PyStackRef_CLOSE(tmp); - tmp = global_super_st; - global_super_st = PyStackRef_NULL; - stack_pointer[-3] = global_super_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); - JUMP_TO_LABEL(error); + PyStackRef_CLOSE(global_super_st); + PyStackRef_CLOSE(class_st); + PyStackRef_CLOSE(self_st); + JUMP_TO_LABEL(pop_3_error); } } // we make no attempt to optimize here; specializations should @@ -6901,26 +6445,15 @@ } } } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = self_st; - self_st = PyStackRef_NULL; - stack_pointer[-1] = self_st; - PyStackRef_CLOSE(tmp); - tmp = class_st; - class_st = PyStackRef_NULL; - stack_pointer[-2] = class_st; - PyStackRef_CLOSE(tmp); - tmp = global_super_st; - global_super_st = PyStackRef_NULL; - stack_pointer[-3] = global_super_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(global_super_st); + PyStackRef_CLOSE(class_st); + PyStackRef_CLOSE(self_st); if (super == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_3_error); } PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + stack_pointer += -3; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *attr_o = PyObject_GetAttr(super, name); Py_DECREF(super); @@ -7287,7 +6820,9 @@ /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); PyObject *result = PyStackRef_AsPyObjectSteal(retval); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -7309,21 +6844,11 @@ right = stack_pointer[-1]; left = stack_pointer[-2]; int res = Py_Is(PyStackRef_AsPyObjectBorrow(left), PyStackRef_AsPyObjectBorrow(right)) ^ oparg; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = right; - right = PyStackRef_NULL; - stack_pointer[-1] = right; - PyStackRef_CLOSE(tmp); - tmp = left; - left = PyStackRef_NULL; - stack_pointer[-2] = left; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(left); + PyStackRef_CLOSE(right); b = res ? PyStackRef_True : PyStackRef_False; - stack_pointer[0] = b; - stack_pointer += 1; + stack_pointer[-2] = b; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -7569,19 +7094,13 @@ Py_TYPE(iterable)->tp_name); stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(iterable_st); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } assert(Py_IsNone(none_val)); + PyStackRef_CLOSE(iterable_st); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(iterable_st); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -7644,17 +7163,11 @@ CALL that it's not a method call. meth | NULL | arg1 | ... | argN */ - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); if (attr_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } self_or_null[0] = PyStackRef_NULL; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); } } else { @@ -7662,16 +7175,10 @@ _PyFrame_SetStackPointer(frame, stack_pointer); attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(owner); if (attr_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); } attr = PyStackRef_FromPyObjectSteal(attr_o); } @@ -7720,18 +7227,13 @@ STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); attr = PyStackRef_FromPyObjectNew(descr); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = owner; - owner = attr; - stack_pointer[-1] = owner; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = attr; + PyStackRef_CLOSE(owner); } // _PUSH_NULL_CONDITIONAL { null = PyStackRef_NULL; } + stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = null; stack_pointer += (oparg & 1); assert(WITHIN_STACK_BOUNDS()); @@ -7787,18 +7289,13 @@ STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); attr = PyStackRef_FromPyObjectNew(descr); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = owner; - owner = attr; - stack_pointer[-1] = owner; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = attr; + PyStackRef_CLOSE(owner); } // _PUSH_NULL_CONDITIONAL { null = PyStackRef_NULL; } + stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = null; stack_pointer += (oparg & 1); assert(WITHIN_STACK_BOUNDS()); @@ -8224,16 +7721,10 @@ assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); attr = PyStackRef_FromPyObjectNew(descr); } - stack_pointer[0] = attr; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = attr; DISPATCH(); } @@ -8292,16 +7783,10 @@ assert((oparg & 1) == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(owner); - stack_pointer = _PyFrame_GetStackPointer(frame); attr = PyStackRef_FromPyObjectNew(descr); } - stack_pointer[0] = attr; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = attr; DISPATCH(); } @@ -8449,19 +7934,14 @@ attr = PyStackRef_FromPyObjectNew(attr_o); #endif STAT_INC(LOAD_ATTR, hit); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = owner; - owner = attr; - stack_pointer[-1] = owner; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = attr; + PyStackRef_CLOSE(owner); } /* Skip 5 cache entries */ // _PUSH_NULL_CONDITIONAL { null = PyStackRef_NULL; } + stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = null; stack_pointer += (oparg & 1); assert(WITHIN_STACK_BOUNDS()); @@ -8558,19 +8038,14 @@ STAT_INC(LOAD_ATTR, hit); attr = PyStackRef_FromPyObjectNew(attr_o); UNLOCK_OBJECT(dict); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = owner; - owner = attr; - stack_pointer[-1] = owner; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = attr; + PyStackRef_CLOSE(owner); } /* Skip 5 cache entries */ // _PUSH_NULL_CONDITIONAL { null = PyStackRef_NULL; } + stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = null; stack_pointer += (oparg & 1); assert(WITHIN_STACK_BOUNDS()); @@ -8873,18 +8348,16 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(mod_or_class_dict); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } if (v_o == NULL) { if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); v_o = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), (PyDictObject *)BUILTINS(), @@ -8905,6 +8378,8 @@ else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -8929,11 +8404,11 @@ } } } + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); } v = PyStackRef_FromPyObjectSteal(v_o); - stack_pointer[0] = v; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = v; DISPATCH(); } @@ -9299,23 +8774,10 @@ frame, this_instr, global_super, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = self_st; - self_st = PyStackRef_NULL; - stack_pointer[-1] = self_st; - PyStackRef_CLOSE(tmp); - tmp = class_st; - class_st = PyStackRef_NULL; - stack_pointer[-2] = class_st; - PyStackRef_CLOSE(tmp); - tmp = global_super_st; - global_super_st = PyStackRef_NULL; - stack_pointer[-3] = global_super_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); - JUMP_TO_LABEL(error); + PyStackRef_CLOSE(global_super_st); + PyStackRef_CLOSE(class_st); + PyStackRef_CLOSE(self_st); + JUMP_TO_LABEL(pop_3_error); } } // we make no attempt to optimize here; specializations should @@ -9346,26 +8808,15 @@ } } } - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = self_st; - self_st = PyStackRef_NULL; - stack_pointer[-1] = self_st; - PyStackRef_CLOSE(tmp); - tmp = class_st; - class_st = PyStackRef_NULL; - stack_pointer[-2] = class_st; - PyStackRef_CLOSE(tmp); - tmp = global_super_st; - global_super_st = PyStackRef_NULL; - stack_pointer[-3] = global_super_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(global_super_st); + PyStackRef_CLOSE(class_st); + PyStackRef_CLOSE(self_st); if (super == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_3_error); } PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + stack_pointer += -3; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *attr_o = PyObject_GetAttr(super, name); Py_DECREF(super); @@ -9423,27 +8874,16 @@ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); - _PyStackRef tmp = self_st; - self_st = PyStackRef_NULL; - stack_pointer[-1] = self_st; - PyStackRef_CLOSE(tmp); - tmp = class_st; - class_st = PyStackRef_NULL; - stack_pointer[-2] = class_st; - PyStackRef_CLOSE(tmp); - tmp = global_super_st; - global_super_st = PyStackRef_NULL; - stack_pointer[-3] = global_super_st; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(global_super_st); + PyStackRef_CLOSE(class_st); + PyStackRef_CLOSE(self_st); if (attr == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_3_error); } attr_st = PyStackRef_FromPyObjectSteal(attr); - stack_pointer[0] = attr_st; - stack_pointer += 1; + stack_pointer[-3] = attr_st; + stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -9505,25 +8945,12 @@ stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); } - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = global_super_st; - global_super_st = self_or_null; - stack_pointer[-2] = global_super_st; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(global_super_st); PyStackRef_CLOSE(class_st); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); attr = PyStackRef_FromPyObjectSteal(attr_o); - stack_pointer[0] = attr; - stack_pointer[1] = self_or_null; - stack_pointer += 2; + stack_pointer[-3] = attr; + stack_pointer[-2] = self_or_null; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -9640,34 +9067,23 @@ PyStackRef_AsPyObjectBorrow(subject), PyStackRef_AsPyObjectBorrow(type), oparg, PyStackRef_AsPyObjectBorrow(names)); - _PyStackRef tmp = names; - names = PyStackRef_NULL; - stack_pointer[-1] = names; - PyStackRef_CLOSE(tmp); - tmp = type; - type = PyStackRef_NULL; - stack_pointer[-2] = type; - PyStackRef_CLOSE(tmp); - tmp = subject; - subject = PyStackRef_NULL; - stack_pointer[-3] = subject; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(subject); + PyStackRef_CLOSE(type); + PyStackRef_CLOSE(names); if (attrs_o) { assert(PyTuple_CheckExact(attrs_o)); // Success! attrs = PyStackRef_FromPyObjectSteal(attrs_o); } else { if (_PyErr_Occurred(tstate)) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_3_error); } // Error! attrs = PyStackRef_None; // Failure! } - stack_pointer[0] = attrs; - stack_pointer += 1; + stack_pointer[-3] = attrs; + stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -9791,11 +9207,9 @@ INSTRUCTION_STATS(POP_ITER); _PyStackRef value; value = stack_pointer[-1]; + PyStackRef_CLOSE(value); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -9843,13 +9257,7 @@ } else { b = PyStackRef_False; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = value; - value = b; - stack_pointer[-1] = value; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = b; + PyStackRef_CLOSE(value); } } // _POP_JUMP_IF_TRUE @@ -9887,13 +9295,7 @@ } else { b = PyStackRef_False; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = value; - value = b; - stack_pointer[-1] = value; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer[-1] = b; + PyStackRef_CLOSE(value); } } // _POP_JUMP_IF_FALSE @@ -9941,11 +9343,9 @@ INSTRUCTION_STATS(POP_TOP); _PyStackRef value; value = stack_pointer[-1]; + PyStackRef_CLOSE(value); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -10018,6 +9418,8 @@ assert(oparg == 0); _PyFrame_SetStackPointer(frame, stack_pointer); monitor_reraise(tstate, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); JUMP_TO_LABEL(exception_unwind); } JUMP_TO_LABEL(error); @@ -10061,6 +9463,8 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyErr_SetRaisedException(tstate, exc); monitor_reraise(tstate, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); JUMP_TO_LABEL(exception_unwind); } @@ -10345,12 +9749,8 @@ JUMPBY(oparg); } else { - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(v); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } } stack_pointer += -1; @@ -10499,14 +9899,12 @@ int err = PySet_Add(PyStackRef_AsPyObjectBorrow(set), PyStackRef_AsPyObjectBorrow(v)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(v); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -10554,14 +9952,12 @@ int err = _PySet_Update(PyStackRef_AsPyObjectBorrow(set), PyStackRef_AsPyObjectBorrow(iterable)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(iterable); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -10604,21 +10000,15 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyObject_SetAttr(PyStackRef_AsPyObjectBorrow(owner), name, PyStackRef_AsPyObjectBorrow(v)); - _PyStackRef tmp = owner; - owner = PyStackRef_NULL; - stack_pointer[-1] = owner; - PyStackRef_CLOSE(tmp); - tmp = v; - v = PyStackRef_NULL; - stack_pointer[-2] = v; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(v); + PyStackRef_CLOSE(owner); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_2_error); } } + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -10956,14 +10346,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyDict_SetItem(GLOBALS(), name, PyStackRef_AsPyObjectBorrow(v)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(v); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -10985,12 +10373,8 @@ _PyErr_Format(tstate, PyExc_SystemError, "no locals found when storing %R", name); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(v); - stack_pointer = _PyFrame_GetStackPointer(frame); - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } if (PyDict_CheckExact(ns)) { _PyFrame_SetStackPointer(frame, stack_pointer); @@ -11002,14 +10386,12 @@ err = PyObject_SetItem(ns, name, PyStackRef_AsPyObjectBorrow(v)); stack_pointer = _PyFrame_GetStackPointer(frame); } - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(v); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11056,24 +10438,14 @@ stack_pointer += 2; assert(WITHIN_STACK_BOUNDS()); } - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = container; - container = PyStackRef_NULL; - stack_pointer[-1] = container; - PyStackRef_CLOSE(tmp); - tmp = v; - v = PyStackRef_NULL; - stack_pointer[-2] = v; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(v); + PyStackRef_CLOSE(container); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_4_error); } } + stack_pointer += -4; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11115,25 +10487,16 @@ /* container[sub] = v */ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyObject_SetItem(PyStackRef_AsPyObjectBorrow(container), PyStackRef_AsPyObjectBorrow(sub), PyStackRef_AsPyObjectBorrow(v)); - _PyStackRef tmp = sub; - sub = PyStackRef_NULL; - stack_pointer[-1] = sub; - PyStackRef_CLOSE(tmp); - tmp = container; - container = PyStackRef_NULL; - stack_pointer[-2] = container; - PyStackRef_CLOSE(tmp); - tmp = v; - v = PyStackRef_NULL; - stack_pointer[-3] = v; - PyStackRef_CLOSE(tmp); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -3; - assert(WITHIN_STACK_BOUNDS()); + PyStackRef_CLOSE(v); + PyStackRef_CLOSE(container); + PyStackRef_CLOSE(sub); if (err) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_3_error); } } + stack_pointer += -3; + assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11299,19 +10662,13 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyObject_IsTrue(PyStackRef_AsPyObjectBorrow(value)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } res = err ? PyStackRef_True : PyStackRef_False; } - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = res; DISPATCH(); } @@ -11345,16 +10702,10 @@ // _REPLACE_WITH_TRUE { value = owner; - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_True; } - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = res; DISPATCH(); } @@ -11410,14 +10761,8 @@ res = PyStackRef_False; } else { - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_True; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); } stack_pointer[-1] = res; DISPATCH(); @@ -11447,12 +10792,7 @@ } STAT_INC(TO_BOOL, hit); res = PyList_GET_SIZE(value_o) ? PyStackRef_True : PyStackRef_False; - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyStackRef tmp = value; - value = res; - stack_pointer[-1] = value; - PyStackRef_CLOSE(tmp); - stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(value); stack_pointer[-1] = res; DISPATCH(); } @@ -11514,14 +10854,8 @@ } else { assert(Py_SIZE(value_o)); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_True; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); } stack_pointer[-1] = res; DISPATCH(); @@ -11541,18 +10875,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PyNumber_Invert(PyStackRef_AsPyObjectBorrow(value)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = res; DISPATCH(); } @@ -11570,18 +10898,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = PyNumber_Negative(PyStackRef_AsPyObjectBorrow(value)); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(value); - stack_pointer = _PyFrame_GetStackPointer(frame); if (res_o == NULL) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); + stack_pointer[-1] = res; DISPATCH(); } @@ -11612,20 +10934,18 @@ next_instr += 1; INSTRUCTION_STATS(UNPACK_EX); _PyStackRef seq; - _PyStackRef *top; + _PyStackRef *right; seq = stack_pointer[-1]; - top = &stack_pointer[(oparg & 0xFF) + (oparg >> 8)]; - PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); + right = &stack_pointer[(oparg & 0xFF)]; + _PyStackRef *top = right + (oparg >> 8); _PyFrame_SetStackPointer(frame, stack_pointer); - int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg & 0xFF, oparg >> 8, top); - Py_DECREF(seq_o); + int res = _PyEval_UnpackIterableStackRef(tstate, seq, oparg & 0xFF, oparg >> 8, top); stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(seq); if (res == 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } - stack_pointer += 1 + (oparg & 0xFF) + (oparg >> 8); + stack_pointer += (oparg & 0xFF) + (oparg >> 8); assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11642,7 +10962,7 @@ _Py_CODEUNIT* const this_instr = next_instr - 2; (void)this_instr; _PyStackRef seq; - _PyStackRef *top; + _PyStackRef *output; // _SPECIALIZE_UNPACK_SEQUENCE { seq = stack_pointer[-1]; @@ -11664,19 +10984,17 @@ } // _UNPACK_SEQUENCE { - top = &stack_pointer[-1 + oparg]; - PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); + output = &stack_pointer[-1]; + _PyStackRef *top = output + oparg; _PyFrame_SetStackPointer(frame, stack_pointer); - int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top); - Py_DECREF(seq_o); + int res = _PyEval_UnpackIterableStackRef(tstate, seq, oparg, -1, top); stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(seq); if (res == 0) { - JUMP_TO_LABEL(error); + JUMP_TO_LABEL(pop_1_error); } } - stack_pointer += oparg; + stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11722,12 +11040,8 @@ *values++ = PyStackRef_FromPyObjectNew(items[i]); } UNLOCK_OBJECT(seq_o); - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(seq); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += oparg; + stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11764,12 +11078,8 @@ for (int i = oparg; --i >= 0; ) { *values++ = PyStackRef_FromPyObjectNew(items[i]); } - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(seq); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += oparg; + stack_pointer += -1 + oparg; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); } @@ -11805,13 +11115,11 @@ STAT_INC(UNPACK_SEQUENCE, hit); val0 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 0)); val1 = PyStackRef_FromPyObjectNew(PyTuple_GET_ITEM(seq_o, 1)); + PyStackRef_CLOSE(seq); stack_pointer[-1] = val1; stack_pointer[0] = val0; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(seq); - stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -12001,6 +11309,8 @@ JUMP_TO_LABEL(error); } _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_MonitorRaise(tstate, frame, next_instr-1); + stack_pointer = _PyFrame_GetStackPointer(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); JUMP_TO_LABEL(exception_unwind); } @@ -12076,7 +11386,9 @@ JUMP_TO_LABEL(error); if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + // PyEval_EvalDefault is a big function, so count it twice + _Py_LeaveRecursiveCallTstate(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return NULL; } next_instr = frame->instr_ptr; @@ -12092,12 +11404,8 @@ JUMP_TO_LABEL(error); JUMP_TO_LABEL(exit_unwind); } next_instr = frame->instr_ptr; + LLTRACE_RESUME_FRAME(); #ifdef Py_DEBUG - int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); - if (lltrace < 0) { - JUMP_TO_LABEL(exit_unwind); - } - frame->lltrace = lltrace; /* _PyEval_EvalFrameDefault() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ From e6979264547b1aa936ac0c5fba0a233452ce432f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 12:25:25 +0000 Subject: [PATCH 15/41] Up depth again --- Lib/test/test_compile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index bef00ff4b6e0a8..b8b32cb8c36a44 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -714,7 +714,7 @@ def test_yet_more_evil_still_undecodable(self): def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - fail_depth = limit * 500 + fail_depth = limit * 1000 crash_depth = limit * 2000 success_depth = limit From f8a9143ecd08ddab8426834faae02b3979d3c928 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 12:40:12 +0000 Subject: [PATCH 16/41] Drop 'failing' depth --- Lib/test/test_ast/test_ast.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index d1ef5f190a6c05..f1459d8d27200a 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -747,7 +747,6 @@ def next(self): @support.cpython_only @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - fail_depth = 100_000 crash_depth = 200_000 success_depth = 200 if _testinternalcapi is not None: @@ -757,13 +756,13 @@ def test_ast_recursion_limit(self): def check_limit(prefix, repeated): expect_ok = prefix + repeated * success_depth ast.parse(expect_ok) - for depth in (fail_depth, crash_depth): - broken = prefix + repeated * depth - details = "Compiling ({!r} + {!r} * {})".format( - prefix, repeated, depth) - with self.assertRaises(RecursionError, msg=details): - with support.infinite_recursion(): - ast.parse(broken) + + broken = prefix + repeated * crash_depth + details = "Compiling ({!r} + {!r} * {})".format( + prefix, repeated, crash_depth) + with self.assertRaises(RecursionError, msg=details): + with support.infinite_recursion(): + ast.parse(broken) check_limit("a", "()") check_limit("a", ".b") From 7d6d77f5e89fd2014631141a061fc86251ffa9fb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 12:44:58 +0000 Subject: [PATCH 17/41] Add news --- .../2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst new file mode 100644 index 00000000000000..e592a7d4d4d37a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst @@ -0,0 +1,3 @@ +Change C stack overflow protection to consider the amount of stack consumed, +rather than a counter. This allows deeper recursion in many cases, but +remains safe. From 31a83dc29189702755225dacce33837ccf600c9a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 13:42:36 +0000 Subject: [PATCH 18/41] Increase headroom --- Include/internal/pycore_ceval.h | 1 + Include/pythonrun.h | 4 ++-- Python/bytecodes.c | 6 ------ Python/ceval.c | 5 +---- Python/generated_cases.c.h | 6 ------ 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 8feec04954ea3f..fa76f8eb03b3df 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -327,6 +327,7 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit); PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value); +extern int _PyOS_CheckStack(int words); #ifdef __cplusplus } diff --git a/Include/pythonrun.h b/Include/pythonrun.h index f78f8b2a190090..e4d184905db945 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -23,8 +23,8 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); /* Stack size, in "pointers" (so we get extra safety margins on 64-bit platforms). On a 32-bit platform, this translates - to an 8k margin. */ -#define PYOS_STACK_MARGIN 2048 + to an 16k margin. */ +#define PYOS_STACK_MARGIN 4096 #define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *)) #if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 9cacf61071ceda..2d7461b6fb5b1b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1083,9 +1083,6 @@ dummy_func( /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - // PyEval_EvalDefault is a big function, so count it twice - _Py_LeaveRecursiveCallTstate(tstate); - _Py_LeaveRecursiveCallTstate(tstate); PyObject *result = PyStackRef_AsPyObjectSteal(retval); SYNC_SP(); /* Not strictly necessary, but prevents warnings */ return result; @@ -5252,9 +5249,6 @@ dummy_func( if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - // PyEval_EvalDefault is a big function, so count it twice - _Py_LeaveRecursiveCallTstate(tstate); - _Py_LeaveRecursiveCallTstate(tstate); return NULL; } next_instr = frame->instr_ptr; diff --git a/Python/ceval.c b/Python/ceval.c index aacb8379c09002..13ed12994f2a8e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -326,7 +326,7 @@ _Py_InitializeRecursionCheck(PyThreadState *tstate) #ifdef USE_STACKCHECK if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; - return 0; + return; } int margin = PYOS_STACK_MARGIN; assert(tstate->c_stack_soft_limit != UINTPTR_MAX); @@ -1033,9 +1033,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(frame->owner == FRAME_OWNED_BY_INTERPRETER); /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - // PyEval_EvalDefault is a big function, so count it twice - _Py_LeaveRecursiveCallTstate(tstate); - _Py_LeaveRecursiveCallTstate(tstate); return NULL; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index aef5b0c6f4d3db..e37f80f7b36f1e 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6820,9 +6820,6 @@ /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - // PyEval_EvalDefault is a big function, so count it twice - _Py_LeaveRecursiveCallTstate(tstate); - _Py_LeaveRecursiveCallTstate(tstate); PyObject *result = PyStackRef_AsPyObjectSteal(retval); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -11386,9 +11383,6 @@ JUMP_TO_LABEL(error); if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - // PyEval_EvalDefault is a big function, so count it twice - _Py_LeaveRecursiveCallTstate(tstate); - _Py_LeaveRecursiveCallTstate(tstate); return NULL; } next_instr = frame->instr_ptr; From 47c50aa18d66a8372b2e3bb27b21b9c73bbd99a6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 14:53:43 +0000 Subject: [PATCH 19/41] Update test --- Lib/test/test_fstring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 1d96b7a2c2459b..572a17a12a0e50 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -627,7 +627,8 @@ def test_mismatched_parens(self): r"does not match opening parenthesis '\('", ["f'{a(4}'", ]) - self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'") + self.assertRaises(SyntaxError, eval, "f'{" + "("*100 + "}'") + self.assertRaises(MemoryError, eval, "f'{" + "("*500 + "}'") @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_fstring_nested_too_deeply(self): From 495c4ea72a63217cef11ed439a907e48a7cce904 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 12 Feb 2025 18:47:02 +0000 Subject: [PATCH 20/41] Tweak some more thresholds and tests --- Lib/test/test_call.py | 4 ++-- Lib/test/test_fstring.py | 1 - Lib/test/test_functools.py | 4 +++- Tools/peg_generator/pegen/c_generator.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 9d73d0e690ed58..a9a842ab82b2d0 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1064,10 +1064,10 @@ def c_py_recurse(m): recurse(90_000) with self.assertRaises(RecursionError): recurse(101_000) - c_recurse(100) + c_recurse(50) with self.assertRaises(RecursionError): c_recurse(90_000) - c_py_recurse(90) + c_py_recurse(50) with self.assertRaises(RecursionError): c_py_recurse(100_000) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 572a17a12a0e50..323e9d12b0131b 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -628,7 +628,6 @@ def test_mismatched_parens(self): ["f'{a(4}'", ]) self.assertRaises(SyntaxError, eval, "f'{" + "("*100 + "}'") - self.assertRaises(MemoryError, eval, "f'{" + "("*500 + "}'") @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_fstring_nested_too_deeply(self): diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 34d403424fe0a8..9ae6a8f8ad2232 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2077,8 +2077,10 @@ def fib(n): return n return fib(n-1) + fib(n-2) - with support.infinite_recursion(): + try: fib(100) + except RecursionError: + fib(50) if self.module == c_functools: fib.cache_clear() with support.infinite_recursion(): diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index a4951d05e80ebd..0d85ca989448b2 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -44,7 +44,7 @@ # define MAXSTACK 4000 # endif #else -# define MAXSTACK 6000 +# define MAXSTACK 4000 #endif """ From 9e0cc670cbea5a39676fa6fb5109e1769ccc8c1b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 14:30:47 +0000 Subject: [PATCH 21/41] Add stack protection to parser --- Parser/parser.c | 864 +++++++++++------------ Tools/peg_generator/pegen/c_generator.py | 2 +- 2 files changed, 433 insertions(+), 433 deletions(-) diff --git a/Parser/parser.c b/Parser/parser.c index 9ff58ab7e7bfd5..7a63ff18465bbb 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -935,7 +935,7 @@ static void *_tmp_169_rule(Parser *p); static mod_ty file_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -981,7 +981,7 @@ file_rule(Parser *p) static mod_ty interactive_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1024,7 +1024,7 @@ interactive_rule(Parser *p) static mod_ty eval_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1073,7 +1073,7 @@ eval_rule(Parser *p) static mod_ty func_type_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1134,7 +1134,7 @@ func_type_rule(Parser *p) static asdl_stmt_seq* statements_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1177,7 +1177,7 @@ statements_rule(Parser *p) static asdl_stmt_seq* statement_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1244,7 +1244,7 @@ statement_rule(Parser *p) static asdl_stmt_seq* statement_newline_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1375,7 +1375,7 @@ statement_newline_rule(Parser *p) static asdl_stmt_seq* simple_stmts_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1468,7 +1468,7 @@ simple_stmts_rule(Parser *p) static stmt_ty simple_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1849,7 +1849,7 @@ simple_stmt_rule(Parser *p) static stmt_ty compound_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2039,7 +2039,7 @@ compound_stmt_rule(Parser *p) static stmt_ty assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2257,7 +2257,7 @@ assignment_rule(Parser *p) static expr_ty annotated_rhs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2327,7 +2327,7 @@ annotated_rhs_rule(Parser *p) static AugOperator* augassign_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2658,7 +2658,7 @@ augassign_rule(Parser *p) static stmt_ty return_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2722,7 +2722,7 @@ return_stmt_rule(Parser *p) static stmt_ty raise_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2822,7 +2822,7 @@ raise_stmt_rule(Parser *p) static stmt_ty global_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2886,7 +2886,7 @@ global_stmt_rule(Parser *p) static stmt_ty nonlocal_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2950,7 +2950,7 @@ nonlocal_stmt_rule(Parser *p) static stmt_ty del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3035,7 +3035,7 @@ del_stmt_rule(Parser *p) static stmt_ty yield_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3096,7 +3096,7 @@ yield_stmt_rule(Parser *p) static stmt_ty assert_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3163,7 +3163,7 @@ assert_stmt_rule(Parser *p) static stmt_ty import_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3239,7 +3239,7 @@ import_stmt_rule(Parser *p) static stmt_ty import_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3305,7 +3305,7 @@ import_name_rule(Parser *p) static stmt_ty import_from_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3424,7 +3424,7 @@ import_from_rule(Parser *p) static asdl_alias_seq* import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3559,7 +3559,7 @@ import_from_targets_rule(Parser *p) static asdl_alias_seq* import_from_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3602,7 +3602,7 @@ import_from_as_names_rule(Parser *p) static alias_ty import_from_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3666,7 +3666,7 @@ import_from_as_name_rule(Parser *p) static asdl_alias_seq* dotted_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3709,7 +3709,7 @@ dotted_as_names_rule(Parser *p) static alias_ty dotted_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3775,7 +3775,7 @@ static expr_ty dotted_name_raw(Parser *); static expr_ty dotted_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -3809,7 +3809,7 @@ dotted_name_rule(Parser *p) static expr_ty dotted_name_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3877,7 +3877,7 @@ dotted_name_raw(Parser *p) static asdl_stmt_seq* block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3972,7 +3972,7 @@ block_rule(Parser *p) static asdl_expr_seq* decorators_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4015,7 +4015,7 @@ decorators_rule(Parser *p) static stmt_ty class_def_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4082,7 +4082,7 @@ class_def_rule(Parser *p) static stmt_ty class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4177,7 +4177,7 @@ class_def_raw_rule(Parser *p) static stmt_ty function_def_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4245,7 +4245,7 @@ function_def_rule(Parser *p) static stmt_ty function_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4415,7 +4415,7 @@ function_def_raw_rule(Parser *p) static arguments_ty params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4477,7 +4477,7 @@ params_rule(Parser *p) static arguments_ty parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4640,7 +4640,7 @@ parameters_rule(Parser *p) static asdl_arg_seq* slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4720,7 +4720,7 @@ slash_no_default_rule(Parser *p) static SlashWithDefault* slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4809,7 +4809,7 @@ slash_with_default_rule(Parser *p) static StarEtc* star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4970,7 +4970,7 @@ star_etc_rule(Parser *p) static arg_ty kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5035,7 +5035,7 @@ kwds_rule(Parser *p) static arg_ty param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5115,7 +5115,7 @@ param_no_default_rule(Parser *p) static arg_ty param_no_default_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5193,7 +5193,7 @@ param_no_default_star_annotation_rule(Parser *p) static NameDefaultPair* param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5279,7 +5279,7 @@ param_with_default_rule(Parser *p) static NameDefaultPair* param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5363,7 +5363,7 @@ param_maybe_default_rule(Parser *p) static arg_ty param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5427,7 +5427,7 @@ param_rule(Parser *p) static arg_ty param_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5491,7 +5491,7 @@ param_star_annotation_rule(Parser *p) static expr_ty annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5537,7 +5537,7 @@ annotation_rule(Parser *p) static expr_ty star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5583,7 +5583,7 @@ star_annotation_rule(Parser *p) static expr_ty default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5651,7 +5651,7 @@ default_rule(Parser *p) static stmt_ty if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5791,7 +5791,7 @@ if_stmt_rule(Parser *p) static stmt_ty elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5928,7 +5928,7 @@ elif_stmt_rule(Parser *p) static asdl_stmt_seq* else_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5996,7 +5996,7 @@ else_block_rule(Parser *p) static stmt_ty while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6092,7 +6092,7 @@ while_stmt_rule(Parser *p) static stmt_ty for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6289,7 +6289,7 @@ for_stmt_rule(Parser *p) static stmt_ty with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6561,7 +6561,7 @@ with_stmt_rule(Parser *p) static withitem_ty with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6659,7 +6659,7 @@ with_item_rule(Parser *p) static stmt_ty try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6848,7 +6848,7 @@ try_stmt_rule(Parser *p) static excepthandler_ty except_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7001,7 +7001,7 @@ except_block_rule(Parser *p) static excepthandler_ty except_star_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7115,7 +7115,7 @@ except_star_block_rule(Parser *p) static asdl_stmt_seq* finally_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7185,7 +7185,7 @@ finally_block_rule(Parser *p) static stmt_ty match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7283,7 +7283,7 @@ match_stmt_rule(Parser *p) static expr_ty subject_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7369,7 +7369,7 @@ subject_expr_rule(Parser *p) static match_case_ty case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7443,7 +7443,7 @@ case_block_rule(Parser *p) static expr_ty guard_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7489,7 +7489,7 @@ guard_rule(Parser *p) static pattern_ty patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7569,7 +7569,7 @@ patterns_rule(Parser *p) static pattern_ty pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7626,7 +7626,7 @@ pattern_rule(Parser *p) static pattern_ty as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7712,7 +7712,7 @@ as_pattern_rule(Parser *p) static pattern_ty or_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7781,7 +7781,7 @@ or_pattern_rule(Parser *p) static pattern_ty closed_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7963,7 +7963,7 @@ closed_pattern_rule(Parser *p) static pattern_ty literal_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8197,7 +8197,7 @@ literal_pattern_rule(Parser *p) static expr_ty literal_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8385,7 +8385,7 @@ literal_expr_rule(Parser *p) static expr_ty complex_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8491,7 +8491,7 @@ complex_number_rule(Parser *p) static expr_ty signed_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8574,7 +8574,7 @@ signed_number_rule(Parser *p) static expr_ty signed_real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8657,7 +8657,7 @@ signed_real_number_rule(Parser *p) static expr_ty real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8700,7 +8700,7 @@ real_number_rule(Parser *p) static expr_ty imaginary_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8743,7 +8743,7 @@ imaginary_number_rule(Parser *p) static pattern_ty capture_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8804,7 +8804,7 @@ capture_pattern_rule(Parser *p) static expr_ty pattern_capture_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8851,7 +8851,7 @@ pattern_capture_target_rule(Parser *p) static pattern_ty wildcard_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8912,7 +8912,7 @@ wildcard_pattern_rule(Parser *p) static pattern_ty value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8977,7 +8977,7 @@ static expr_ty attr_raw(Parser *); static expr_ty attr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -9011,7 +9011,7 @@ attr_rule(Parser *p) static expr_ty attr_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9079,7 +9079,7 @@ attr_raw(Parser *p) static expr_ty name_or_attr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9136,7 +9136,7 @@ name_or_attr_rule(Parser *p) static pattern_ty group_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9185,7 +9185,7 @@ group_pattern_rule(Parser *p) static pattern_ty sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9291,7 +9291,7 @@ sequence_pattern_rule(Parser *p) static asdl_seq* open_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9340,7 +9340,7 @@ open_sequence_pattern_rule(Parser *p) static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9387,7 +9387,7 @@ maybe_sequence_pattern_rule(Parser *p) static pattern_ty maybe_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9444,7 +9444,7 @@ maybe_star_pattern_rule(Parser *p) static pattern_ty star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9553,7 +9553,7 @@ star_pattern_rule(Parser *p) static pattern_ty mapping_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9752,7 +9752,7 @@ mapping_pattern_rule(Parser *p) static asdl_seq* items_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9790,7 +9790,7 @@ items_pattern_rule(Parser *p) static KeyPatternPair* key_value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9839,7 +9839,7 @@ key_value_pattern_rule(Parser *p) static expr_ty double_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9890,7 +9890,7 @@ double_star_pattern_rule(Parser *p) static pattern_ty class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10120,7 +10120,7 @@ class_pattern_rule(Parser *p) static asdl_pattern_seq* positional_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10163,7 +10163,7 @@ positional_patterns_rule(Parser *p) static asdl_seq* keyword_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10201,7 +10201,7 @@ keyword_patterns_rule(Parser *p) static KeyPatternPair* keyword_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10250,7 +10250,7 @@ keyword_pattern_rule(Parser *p) static stmt_ty type_alias_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10323,7 +10323,7 @@ type_alias_rule(Parser *p) static asdl_type_param_seq* type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10391,7 +10391,7 @@ type_params_rule(Parser *p) static asdl_type_param_seq* type_param_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10442,7 +10442,7 @@ type_param_seq_rule(Parser *p) static type_param_ty type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10611,7 +10611,7 @@ type_param_rule(Parser *p) static expr_ty type_param_bound_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10657,7 +10657,7 @@ type_param_bound_rule(Parser *p) static expr_ty type_param_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10703,7 +10703,7 @@ type_param_default_rule(Parser *p) static expr_ty type_param_starred_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10749,7 +10749,7 @@ type_param_starred_default_rule(Parser *p) static expr_ty expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10877,7 +10877,7 @@ expressions_rule(Parser *p) static expr_ty expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11031,7 +11031,7 @@ expression_rule(Parser *p) static expr_ty yield_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11137,7 +11137,7 @@ yield_expr_rule(Parser *p) static expr_ty star_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11260,7 +11260,7 @@ star_expressions_rule(Parser *p) static expr_ty star_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11348,7 +11348,7 @@ star_expression_rule(Parser *p) static asdl_expr_seq* star_named_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11395,7 +11395,7 @@ star_named_expressions_rule(Parser *p) static expr_ty star_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11478,7 +11478,7 @@ star_named_expression_rule(Parser *p) static expr_ty assignment_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11552,7 +11552,7 @@ assignment_expression_rule(Parser *p) static expr_ty named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11630,7 +11630,7 @@ named_expression_rule(Parser *p) static expr_ty disjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11718,7 +11718,7 @@ disjunction_rule(Parser *p) static expr_ty conjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11806,7 +11806,7 @@ conjunction_rule(Parser *p) static expr_ty inversion_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11894,7 +11894,7 @@ inversion_rule(Parser *p) static expr_ty comparison_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11987,7 +11987,7 @@ comparison_rule(Parser *p) static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12196,7 +12196,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12242,7 +12242,7 @@ eq_bitwise_or_rule(Parser *p) static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12288,7 +12288,7 @@ noteq_bitwise_or_rule(Parser *p) static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12334,7 +12334,7 @@ lte_bitwise_or_rule(Parser *p) static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12380,7 +12380,7 @@ lt_bitwise_or_rule(Parser *p) static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12426,7 +12426,7 @@ gte_bitwise_or_rule(Parser *p) static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12472,7 +12472,7 @@ gt_bitwise_or_rule(Parser *p) static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12521,7 +12521,7 @@ notin_bitwise_or_rule(Parser *p) static CmpopExprPair* in_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12567,7 +12567,7 @@ in_bitwise_or_rule(Parser *p) static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12616,7 +12616,7 @@ isnot_bitwise_or_rule(Parser *p) static CmpopExprPair* is_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12664,7 +12664,7 @@ static expr_ty bitwise_or_raw(Parser *); static expr_ty bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12698,7 +12698,7 @@ bitwise_or_rule(Parser *p) static expr_ty bitwise_or_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12786,7 +12786,7 @@ static expr_ty bitwise_xor_raw(Parser *); static expr_ty bitwise_xor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12820,7 +12820,7 @@ bitwise_xor_rule(Parser *p) static expr_ty bitwise_xor_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12908,7 +12908,7 @@ static expr_ty bitwise_and_raw(Parser *); static expr_ty bitwise_and_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12942,7 +12942,7 @@ bitwise_and_rule(Parser *p) static expr_ty bitwise_and_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13030,7 +13030,7 @@ static expr_ty shift_expr_raw(Parser *); static expr_ty shift_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13064,7 +13064,7 @@ shift_expr_rule(Parser *p) static expr_ty shift_expr_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13210,7 +13210,7 @@ static expr_ty sum_raw(Parser *); static expr_ty sum_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13244,7 +13244,7 @@ sum_rule(Parser *p) static expr_ty sum_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13378,7 +13378,7 @@ static expr_ty term_raw(Parser *); static expr_ty term_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13412,7 +13412,7 @@ term_rule(Parser *p) static expr_ty term_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13673,7 +13673,7 @@ term_raw(Parser *p) static expr_ty factor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13833,7 +13833,7 @@ factor_rule(Parser *p) static expr_ty power_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13919,7 +13919,7 @@ power_rule(Parser *p) static expr_ty await_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14014,7 +14014,7 @@ static expr_ty primary_raw(Parser *); static expr_ty primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -14048,7 +14048,7 @@ primary_rule(Parser *p) static expr_ty primary_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14254,7 +14254,7 @@ primary_raw(Parser *p) static expr_ty slices_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14345,7 +14345,7 @@ slices_rule(Parser *p) static expr_ty slice_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14449,7 +14449,7 @@ slice_rule(Parser *p) static expr_ty atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14731,7 +14731,7 @@ atom_rule(Parser *p) static expr_ty group_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14799,7 +14799,7 @@ group_rule(Parser *p) static expr_ty lambdef_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14869,7 +14869,7 @@ lambdef_rule(Parser *p) static arguments_ty lambda_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14931,7 +14931,7 @@ lambda_params_rule(Parser *p) static arguments_ty lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15096,7 +15096,7 @@ lambda_parameters_rule(Parser *p) static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15176,7 +15176,7 @@ lambda_slash_no_default_rule(Parser *p) static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15264,7 +15264,7 @@ lambda_slash_with_default_rule(Parser *p) static StarEtc* lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15392,7 +15392,7 @@ lambda_star_etc_rule(Parser *p) static arg_ty lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15457,7 +15457,7 @@ lambda_kwds_rule(Parser *p) static arg_ty lambda_param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15529,7 +15529,7 @@ lambda_param_no_default_rule(Parser *p) static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15607,7 +15607,7 @@ lambda_param_with_default_rule(Parser *p) static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15685,7 +15685,7 @@ lambda_param_maybe_default_rule(Parser *p) static arg_ty lambda_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15746,7 +15746,7 @@ lambda_param_rule(Parser *p) static expr_ty fstring_middle_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15810,7 +15810,7 @@ fstring_middle_rule(Parser *p) static expr_ty fstring_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15905,7 +15905,7 @@ fstring_replacement_field_rule(Parser *p) static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15951,7 +15951,7 @@ fstring_conversion_rule(Parser *p) static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16015,7 +16015,7 @@ fstring_full_format_spec_rule(Parser *p) static expr_ty fstring_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16077,7 +16077,7 @@ fstring_format_spec_rule(Parser *p) static expr_ty fstring_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16126,7 +16126,7 @@ fstring_rule(Parser *p) static expr_ty string_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16169,7 +16169,7 @@ string_rule(Parser *p) static expr_ty strings_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16235,7 +16235,7 @@ strings_rule(Parser *p) static expr_ty list_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16302,7 +16302,7 @@ list_rule(Parser *p) static expr_ty tuple_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16369,7 +16369,7 @@ tuple_rule(Parser *p) static expr_ty set_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16436,7 +16436,7 @@ set_rule(Parser *p) static expr_ty dict_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16528,7 +16528,7 @@ dict_rule(Parser *p) static asdl_seq* double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16575,7 +16575,7 @@ double_starred_kvpairs_rule(Parser *p) static KeyValuePair* double_starred_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16640,7 +16640,7 @@ double_starred_kvpair_rule(Parser *p) static KeyValuePair* kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16689,7 +16689,7 @@ kvpair_rule(Parser *p) static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16736,7 +16736,7 @@ for_if_clauses_rule(Parser *p) static comprehension_ty for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16882,7 +16882,7 @@ for_if_clause_rule(Parser *p) static expr_ty listcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16971,7 +16971,7 @@ listcomp_rule(Parser *p) static expr_ty setcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17062,7 +17062,7 @@ setcomp_rule(Parser *p) static expr_ty genexp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17151,7 +17151,7 @@ genexp_rule(Parser *p) static expr_ty dictcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17240,7 +17240,7 @@ dictcomp_rule(Parser *p) static expr_ty arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17315,7 +17315,7 @@ arguments_rule(Parser *p) static expr_ty args_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17415,7 +17415,7 @@ args_rule(Parser *p) static asdl_seq* kwargs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17505,7 +17505,7 @@ kwargs_rule(Parser *p) static expr_ty starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17607,7 +17607,7 @@ starred_expression_rule(Parser *p) static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17717,7 +17717,7 @@ kwarg_or_starred_rule(Parser *p) static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17839,7 +17839,7 @@ kwarg_or_double_starred_rule(Parser *p) static expr_ty star_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17933,7 +17933,7 @@ star_targets_rule(Parser *p) static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17980,7 +17980,7 @@ star_targets_list_seq_rule(Parser *p) static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18057,7 +18057,7 @@ star_targets_tuple_seq_rule(Parser *p) static expr_ty star_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18148,7 +18148,7 @@ star_target_rule(Parser *p) static expr_ty target_with_star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18289,7 +18289,7 @@ target_with_star_atom_rule(Parser *p) static expr_ty star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18449,7 +18449,7 @@ star_atom_rule(Parser *p) static expr_ty single_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18543,7 +18543,7 @@ single_target_rule(Parser *p) static expr_ty single_subscript_attribute_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18663,7 +18663,7 @@ static expr_ty t_primary_raw(Parser *); static expr_ty t_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -18697,7 +18697,7 @@ t_primary_rule(Parser *p) static expr_ty t_primary_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18918,7 +18918,7 @@ t_primary_raw(Parser *p) static void * t_lookahead_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18994,7 +18994,7 @@ t_lookahead_rule(Parser *p) static asdl_expr_seq* del_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19044,7 +19044,7 @@ del_targets_rule(Parser *p) static expr_ty del_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19181,7 +19181,7 @@ del_target_rule(Parser *p) static expr_ty del_t_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19348,7 +19348,7 @@ del_t_atom_rule(Parser *p) static asdl_expr_seq* type_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19592,7 +19592,7 @@ type_expressions_rule(Parser *p) static Token* func_type_comment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19685,7 +19685,7 @@ func_type_comment_rule(Parser *p) static void * invalid_arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19928,7 +19928,7 @@ invalid_arguments_rule(Parser *p) static void * invalid_kwarg_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20074,7 +20074,7 @@ expression_without_invalid_rule(Parser *p) { int _prev_call_invalid = p->call_invalid_rules; p->call_invalid_rules = 0; - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20193,7 +20193,7 @@ expression_without_invalid_rule(Parser *p) static void * invalid_legacy_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20241,7 +20241,7 @@ invalid_legacy_expression_rule(Parser *p) static void * invalid_type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20329,7 +20329,7 @@ invalid_type_param_rule(Parser *p) static void * invalid_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20445,7 +20445,7 @@ invalid_expression_rule(Parser *p) static void * invalid_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20571,7 +20571,7 @@ invalid_named_expression_rule(Parser *p) static void * invalid_assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20776,7 +20776,7 @@ invalid_assignment_rule(Parser *p) static expr_ty invalid_ann_assign_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20863,7 +20863,7 @@ invalid_ann_assign_target_rule(Parser *p) static void * invalid_del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20909,7 +20909,7 @@ invalid_del_stmt_rule(Parser *p) static void * invalid_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20957,7 +20957,7 @@ invalid_block_rule(Parser *p) static void * invalid_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21075,7 +21075,7 @@ invalid_comprehension_rule(Parser *p) static void * invalid_dict_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21136,7 +21136,7 @@ invalid_dict_comprehension_rule(Parser *p) static void * invalid_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21353,7 +21353,7 @@ invalid_parameters_rule(Parser *p) static void * invalid_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21402,7 +21402,7 @@ invalid_default_rule(Parser *p) static void * invalid_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21544,7 +21544,7 @@ invalid_star_etc_rule(Parser *p) static void * invalid_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21659,7 +21659,7 @@ invalid_kwds_rule(Parser *p) static void * invalid_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21727,7 +21727,7 @@ invalid_parameters_helper_rule(Parser *p) static void * invalid_lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21946,7 +21946,7 @@ invalid_lambda_parameters_rule(Parser *p) static void * invalid_lambda_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22011,7 +22011,7 @@ invalid_lambda_parameters_helper_rule(Parser *p) static void * invalid_lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22126,7 +22126,7 @@ invalid_lambda_star_etc_rule(Parser *p) static void * invalid_lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22241,7 +22241,7 @@ invalid_lambda_kwds_rule(Parser *p) static void * invalid_double_type_comments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22296,7 +22296,7 @@ invalid_double_type_comments_rule(Parser *p) static void * invalid_with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22347,7 +22347,7 @@ invalid_with_item_rule(Parser *p) static void * invalid_for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22399,7 +22399,7 @@ invalid_for_if_clause_rule(Parser *p) static void * invalid_for_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22449,7 +22449,7 @@ invalid_for_target_rule(Parser *p) static void * invalid_group_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22531,7 +22531,7 @@ invalid_group_rule(Parser *p) static void * invalid_import_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22610,7 +22610,7 @@ invalid_import_rule(Parser *p) static void * invalid_import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22685,7 +22685,7 @@ invalid_import_from_targets_rule(Parser *p) static void * invalid_with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22784,7 +22784,7 @@ invalid_with_stmt_rule(Parser *p) static void * invalid_with_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22895,7 +22895,7 @@ invalid_with_stmt_indent_rule(Parser *p) static void * invalid_try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23074,7 +23074,7 @@ invalid_try_stmt_rule(Parser *p) static void * invalid_except_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23231,7 +23231,7 @@ invalid_except_stmt_rule(Parser *p) static void * invalid_except_star_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23396,7 +23396,7 @@ invalid_except_star_stmt_rule(Parser *p) static void * invalid_finally_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23449,7 +23449,7 @@ invalid_finally_stmt_rule(Parser *p) static void * invalid_except_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23540,7 +23540,7 @@ invalid_except_stmt_indent_rule(Parser *p) static void * invalid_except_star_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23603,7 +23603,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) static void * invalid_match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23689,7 +23689,7 @@ invalid_match_stmt_rule(Parser *p) static void * invalid_case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23781,7 +23781,7 @@ invalid_case_block_rule(Parser *p) static void * invalid_as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23860,7 +23860,7 @@ invalid_as_pattern_rule(Parser *p) static void * invalid_class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23910,7 +23910,7 @@ invalid_class_pattern_rule(Parser *p) static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23965,7 +23965,7 @@ invalid_class_argument_pattern_rule(Parser *p) static void * invalid_if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24051,7 +24051,7 @@ invalid_if_stmt_rule(Parser *p) static void * invalid_elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24135,7 +24135,7 @@ invalid_elif_stmt_rule(Parser *p) static void * invalid_else_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24188,7 +24188,7 @@ invalid_else_stmt_rule(Parser *p) static void * invalid_while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24274,7 +24274,7 @@ invalid_while_stmt_rule(Parser *p) static void * invalid_for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24380,7 +24380,7 @@ invalid_for_stmt_rule(Parser *p) static void * invalid_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24512,7 +24512,7 @@ invalid_def_raw_rule(Parser *p) static void * invalid_class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24615,7 +24615,7 @@ invalid_class_def_raw_rule(Parser *p) static void * invalid_double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24724,7 +24724,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) static void * invalid_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24831,7 +24831,7 @@ invalid_kvpair_rule(Parser *p) static void * invalid_starred_expression_unpacking_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24883,7 +24883,7 @@ invalid_starred_expression_unpacking_rule(Parser *p) static void * invalid_starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24937,7 +24937,7 @@ invalid_starred_expression_rule(Parser *p) static void * invalid_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25297,7 +25297,7 @@ invalid_replacement_field_rule(Parser *p) static void * invalid_conversion_character_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25368,7 +25368,7 @@ invalid_conversion_character_rule(Parser *p) static void * invalid_arithmetic_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25420,7 +25420,7 @@ invalid_arithmetic_rule(Parser *p) static void * invalid_factor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25469,7 +25469,7 @@ invalid_factor_rule(Parser *p) static void * invalid_type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25515,7 +25515,7 @@ invalid_type_params_rule(Parser *p) static asdl_seq * _loop0_1_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25582,7 +25582,7 @@ _loop0_1_rule(Parser *p) static asdl_seq * _loop1_2_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25654,7 +25654,7 @@ _loop1_2_rule(Parser *p) static asdl_seq * _loop0_3_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25730,7 +25730,7 @@ _loop0_3_rule(Parser *p) static asdl_seq * _gather_4_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25771,7 +25771,7 @@ _gather_4_rule(Parser *p) static void * _tmp_5_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25828,7 +25828,7 @@ _tmp_5_rule(Parser *p) static void * _tmp_6_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25904,7 +25904,7 @@ _tmp_6_rule(Parser *p) static void * _tmp_7_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25961,7 +25961,7 @@ _tmp_7_rule(Parser *p) static void * _tmp_8_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26018,7 +26018,7 @@ _tmp_8_rule(Parser *p) static void * _tmp_9_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26075,7 +26075,7 @@ _tmp_9_rule(Parser *p) static void * _tmp_10_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26121,7 +26121,7 @@ _tmp_10_rule(Parser *p) static void * _tmp_11_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26189,7 +26189,7 @@ _tmp_11_rule(Parser *p) static asdl_seq * _loop1_12_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26261,7 +26261,7 @@ _loop1_12_rule(Parser *p) static void * _tmp_13_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26307,7 +26307,7 @@ _tmp_13_rule(Parser *p) static asdl_seq * _loop0_14_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26383,7 +26383,7 @@ _loop0_14_rule(Parser *p) static asdl_seq * _gather_15_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26424,7 +26424,7 @@ _gather_15_rule(Parser *p) static void * _tmp_16_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26481,7 +26481,7 @@ _tmp_16_rule(Parser *p) static void * _tmp_17_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26527,7 +26527,7 @@ _tmp_17_rule(Parser *p) static asdl_seq * _loop0_18_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26594,7 +26594,7 @@ _loop0_18_rule(Parser *p) static asdl_seq * _loop1_19_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26666,7 +26666,7 @@ _loop1_19_rule(Parser *p) static asdl_seq * _loop0_20_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26742,7 +26742,7 @@ _loop0_20_rule(Parser *p) static asdl_seq * _gather_21_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26783,7 +26783,7 @@ _gather_21_rule(Parser *p) static void * _tmp_22_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26829,7 +26829,7 @@ _tmp_22_rule(Parser *p) static asdl_seq * _loop0_23_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26905,7 +26905,7 @@ _loop0_23_rule(Parser *p) static asdl_seq * _gather_24_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26946,7 +26946,7 @@ _gather_24_rule(Parser *p) static asdl_seq * _loop1_25_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27018,7 +27018,7 @@ _loop1_25_rule(Parser *p) static void * _tmp_26_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27067,7 +27067,7 @@ _tmp_26_rule(Parser *p) static void * _tmp_27_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27113,7 +27113,7 @@ _tmp_27_rule(Parser *p) static asdl_seq * _loop0_28_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27180,7 +27180,7 @@ _loop0_28_rule(Parser *p) static asdl_seq * _loop0_29_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27247,7 +27247,7 @@ _loop0_29_rule(Parser *p) static asdl_seq * _loop1_30_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27319,7 +27319,7 @@ _loop1_30_rule(Parser *p) static asdl_seq * _loop1_31_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27391,7 +27391,7 @@ _loop1_31_rule(Parser *p) static asdl_seq * _loop0_32_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27458,7 +27458,7 @@ _loop0_32_rule(Parser *p) static asdl_seq * _loop1_33_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27530,7 +27530,7 @@ _loop1_33_rule(Parser *p) static asdl_seq * _loop0_34_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27606,7 +27606,7 @@ _loop0_34_rule(Parser *p) static asdl_seq * _gather_35_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27647,7 +27647,7 @@ _gather_35_rule(Parser *p) static void * _tmp_36_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27723,7 +27723,7 @@ _tmp_36_rule(Parser *p) static asdl_seq * _loop1_37_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27795,7 +27795,7 @@ _loop1_37_rule(Parser *p) static asdl_seq * _loop1_38_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27867,7 +27867,7 @@ _loop1_38_rule(Parser *p) static asdl_seq * _loop1_39_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27939,7 +27939,7 @@ _loop1_39_rule(Parser *p) static asdl_seq * _loop0_40_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28015,7 +28015,7 @@ _loop0_40_rule(Parser *p) static asdl_seq * _gather_41_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28056,7 +28056,7 @@ _gather_41_rule(Parser *p) static void * _tmp_42_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28113,7 +28113,7 @@ _tmp_42_rule(Parser *p) static void * _tmp_43_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28189,7 +28189,7 @@ _tmp_43_rule(Parser *p) static asdl_seq * _loop0_44_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28265,7 +28265,7 @@ _loop0_44_rule(Parser *p) static asdl_seq * _gather_45_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28306,7 +28306,7 @@ _gather_45_rule(Parser *p) static asdl_seq * _loop0_46_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28382,7 +28382,7 @@ _loop0_46_rule(Parser *p) static asdl_seq * _gather_47_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28423,7 +28423,7 @@ _gather_47_rule(Parser *p) static void * _tmp_48_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28480,7 +28480,7 @@ _tmp_48_rule(Parser *p) static asdl_seq * _loop0_49_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28556,7 +28556,7 @@ _loop0_49_rule(Parser *p) static asdl_seq * _gather_50_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28597,7 +28597,7 @@ _gather_50_rule(Parser *p) static asdl_seq * _loop0_51_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28673,7 +28673,7 @@ _loop0_51_rule(Parser *p) static asdl_seq * _gather_52_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28714,7 +28714,7 @@ _gather_52_rule(Parser *p) static asdl_seq * _loop0_53_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28790,7 +28790,7 @@ _loop0_53_rule(Parser *p) static asdl_seq * _gather_54_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28831,7 +28831,7 @@ _gather_54_rule(Parser *p) static asdl_seq * _loop1_55_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28903,7 +28903,7 @@ _loop1_55_rule(Parser *p) static asdl_seq * _loop1_56_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28975,7 +28975,7 @@ _loop1_56_rule(Parser *p) static asdl_seq * _loop0_57_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29051,7 +29051,7 @@ _loop0_57_rule(Parser *p) static asdl_seq * _gather_58_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29092,7 +29092,7 @@ _gather_58_rule(Parser *p) static asdl_seq * _loop1_59_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29164,7 +29164,7 @@ _loop1_59_rule(Parser *p) static asdl_seq * _loop1_60_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29236,7 +29236,7 @@ _loop1_60_rule(Parser *p) static asdl_seq * _loop1_61_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29308,7 +29308,7 @@ _loop1_61_rule(Parser *p) static void * _tmp_62_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29351,7 +29351,7 @@ _tmp_62_rule(Parser *p) static asdl_seq * _loop0_63_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29427,7 +29427,7 @@ _loop0_63_rule(Parser *p) static asdl_seq * _gather_64_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29468,7 +29468,7 @@ _gather_64_rule(Parser *p) static void * _tmp_65_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29514,7 +29514,7 @@ _tmp_65_rule(Parser *p) static void * _tmp_66_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29571,7 +29571,7 @@ _tmp_66_rule(Parser *p) static void * _tmp_67_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29647,7 +29647,7 @@ _tmp_67_rule(Parser *p) static void * _tmp_68_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29704,7 +29704,7 @@ _tmp_68_rule(Parser *p) static void * _tmp_69_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29799,7 +29799,7 @@ _tmp_69_rule(Parser *p) static void * _tmp_70_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29856,7 +29856,7 @@ _tmp_70_rule(Parser *p) static asdl_seq * _loop0_71_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29923,7 +29923,7 @@ _loop0_71_rule(Parser *p) static asdl_seq * _loop0_72_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29990,7 +29990,7 @@ _loop0_72_rule(Parser *p) static asdl_seq * _loop1_73_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30062,7 +30062,7 @@ _loop1_73_rule(Parser *p) static asdl_seq * _loop1_74_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30134,7 +30134,7 @@ _loop1_74_rule(Parser *p) static asdl_seq * _loop0_75_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30201,7 +30201,7 @@ _loop0_75_rule(Parser *p) static asdl_seq * _loop1_76_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30273,7 +30273,7 @@ _loop1_76_rule(Parser *p) static asdl_seq * _loop0_77_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30340,7 +30340,7 @@ _loop0_77_rule(Parser *p) static asdl_seq * _loop0_78_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30407,7 +30407,7 @@ _loop0_78_rule(Parser *p) static asdl_seq * _loop1_79_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30479,7 +30479,7 @@ _loop1_79_rule(Parser *p) static void * _tmp_80_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30528,7 +30528,7 @@ _tmp_80_rule(Parser *p) static asdl_seq * _loop0_81_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30604,7 +30604,7 @@ _loop0_81_rule(Parser *p) static asdl_seq * _gather_82_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30645,7 +30645,7 @@ _gather_82_rule(Parser *p) static asdl_seq * _loop1_83_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30717,7 +30717,7 @@ _loop1_83_rule(Parser *p) static asdl_seq * _loop0_84_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30784,7 +30784,7 @@ _loop0_84_rule(Parser *p) static void * _tmp_85_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30843,7 +30843,7 @@ _tmp_85_rule(Parser *p) static asdl_seq * _loop0_86_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30920,7 +30920,7 @@ _loop0_86_rule(Parser *p) static asdl_seq * _gather_87_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30961,7 +30961,7 @@ _gather_87_rule(Parser *p) static void * _tmp_88_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31007,7 +31007,7 @@ _tmp_88_rule(Parser *p) static asdl_seq * _loop0_89_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31083,7 +31083,7 @@ _loop0_89_rule(Parser *p) static asdl_seq * _gather_90_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31124,7 +31124,7 @@ _gather_90_rule(Parser *p) static asdl_seq * _loop0_91_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31200,7 +31200,7 @@ _loop0_91_rule(Parser *p) static asdl_seq * _gather_92_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31241,7 +31241,7 @@ _gather_92_rule(Parser *p) static asdl_seq * _loop0_93_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31308,7 +31308,7 @@ _loop0_93_rule(Parser *p) static asdl_seq * _loop0_94_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31384,7 +31384,7 @@ _loop0_94_rule(Parser *p) static asdl_seq * _gather_95_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31425,7 +31425,7 @@ _gather_95_rule(Parser *p) static asdl_seq * _loop1_96_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31497,7 +31497,7 @@ _loop1_96_rule(Parser *p) static void * _tmp_97_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31537,7 +31537,7 @@ _tmp_97_rule(Parser *p) static asdl_seq * _loop0_98_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31613,7 +31613,7 @@ _loop0_98_rule(Parser *p) static asdl_seq * _gather_99_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31654,7 +31654,7 @@ _gather_99_rule(Parser *p) static asdl_seq * _loop0_100_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31730,7 +31730,7 @@ _loop0_100_rule(Parser *p) static asdl_seq * _gather_101_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31771,7 +31771,7 @@ _gather_101_rule(Parser *p) static void * _tmp_102_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31814,7 +31814,7 @@ _tmp_102_rule(Parser *p) static void * _tmp_103_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31871,7 +31871,7 @@ _tmp_103_rule(Parser *p) static asdl_seq * _loop0_104_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31947,7 +31947,7 @@ _loop0_104_rule(Parser *p) static asdl_seq * _gather_105_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31988,7 +31988,7 @@ _gather_105_rule(Parser *p) static void * _tmp_106_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32048,7 +32048,7 @@ _tmp_106_rule(Parser *p) static void * _tmp_107_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32089,7 +32089,7 @@ _tmp_107_rule(Parser *p) static void * _tmp_108_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32146,7 +32146,7 @@ _tmp_108_rule(Parser *p) static void * _tmp_109_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32222,7 +32222,7 @@ _tmp_109_rule(Parser *p) static void * _tmp_110_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32263,7 +32263,7 @@ _tmp_110_rule(Parser *p) static void * _tmp_111_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32323,7 +32323,7 @@ _tmp_111_rule(Parser *p) static void * _tmp_112_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32380,7 +32380,7 @@ _tmp_112_rule(Parser *p) static void * _tmp_113_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32437,7 +32437,7 @@ _tmp_113_rule(Parser *p) static void * _tmp_114_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32570,7 +32570,7 @@ _tmp_114_rule(Parser *p) static asdl_seq * _loop0_115_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32637,7 +32637,7 @@ _loop0_115_rule(Parser *p) static asdl_seq * _loop0_116_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32704,7 +32704,7 @@ _loop0_116_rule(Parser *p) static void * _tmp_117_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32780,7 +32780,7 @@ _tmp_117_rule(Parser *p) static void * _tmp_118_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32837,7 +32837,7 @@ _tmp_118_rule(Parser *p) static void * _tmp_119_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32894,7 +32894,7 @@ _tmp_119_rule(Parser *p) static void * _tmp_120_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32951,7 +32951,7 @@ _tmp_120_rule(Parser *p) static void * _tmp_121_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33008,7 +33008,7 @@ _tmp_121_rule(Parser *p) static void * _tmp_122_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33068,7 +33068,7 @@ _tmp_122_rule(Parser *p) static void * _tmp_123_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33125,7 +33125,7 @@ _tmp_123_rule(Parser *p) static void * _tmp_124_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33201,7 +33201,7 @@ _tmp_124_rule(Parser *p) static void * _tmp_125_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33258,7 +33258,7 @@ _tmp_125_rule(Parser *p) static asdl_seq * _loop0_126_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33334,7 +33334,7 @@ _loop0_126_rule(Parser *p) static asdl_seq * _gather_127_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33375,7 +33375,7 @@ _gather_127_rule(Parser *p) static void * _tmp_128_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33432,7 +33432,7 @@ _tmp_128_rule(Parser *p) static void * _tmp_129_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33492,7 +33492,7 @@ _tmp_129_rule(Parser *p) static void * _tmp_130_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33549,7 +33549,7 @@ _tmp_130_rule(Parser *p) static void * _tmp_131_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33594,7 +33594,7 @@ _tmp_131_rule(Parser *p) static asdl_seq * _loop0_132_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33670,7 +33670,7 @@ _loop0_132_rule(Parser *p) static asdl_seq * _gather_133_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33711,7 +33711,7 @@ _gather_133_rule(Parser *p) static asdl_seq * _loop0_134_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33787,7 +33787,7 @@ _loop0_134_rule(Parser *p) static asdl_seq * _gather_135_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33828,7 +33828,7 @@ _gather_135_rule(Parser *p) static asdl_seq * _loop0_136_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33904,7 +33904,7 @@ _loop0_136_rule(Parser *p) static asdl_seq * _gather_137_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33945,7 +33945,7 @@ _gather_137_rule(Parser *p) static void * _tmp_138_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34002,7 +34002,7 @@ _tmp_138_rule(Parser *p) static asdl_seq * _loop0_139_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34069,7 +34069,7 @@ _loop0_139_rule(Parser *p) static void * _tmp_140_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34111,7 +34111,7 @@ _tmp_140_rule(Parser *p) static void * _tmp_141_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34168,7 +34168,7 @@ _tmp_141_rule(Parser *p) static void * _tmp_142_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34209,7 +34209,7 @@ _tmp_142_rule(Parser *p) static void * _tmp_143_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34266,7 +34266,7 @@ _tmp_143_rule(Parser *p) static void * _tmp_144_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34361,7 +34361,7 @@ _tmp_144_rule(Parser *p) static void * _tmp_145_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34437,7 +34437,7 @@ _tmp_145_rule(Parser *p) static void * _tmp_146_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34478,7 +34478,7 @@ _tmp_146_rule(Parser *p) static void * _tmp_147_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34535,7 +34535,7 @@ _tmp_147_rule(Parser *p) static void * _tmp_148_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34687,7 +34687,7 @@ _tmp_148_rule(Parser *p) static void * _tmp_149_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34763,7 +34763,7 @@ _tmp_149_rule(Parser *p) static void * _tmp_150_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34809,7 +34809,7 @@ _tmp_150_rule(Parser *p) static void * _tmp_151_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34866,7 +34866,7 @@ _tmp_151_rule(Parser *p) static void * _tmp_152_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34915,7 +34915,7 @@ _tmp_152_rule(Parser *p) static void * _tmp_153_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34961,7 +34961,7 @@ _tmp_153_rule(Parser *p) static void * _tmp_154_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35007,7 +35007,7 @@ _tmp_154_rule(Parser *p) static void * _tmp_155_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35053,7 +35053,7 @@ _tmp_155_rule(Parser *p) static void * _tmp_156_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35110,7 +35110,7 @@ _tmp_156_rule(Parser *p) static void * _tmp_157_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35167,7 +35167,7 @@ _tmp_157_rule(Parser *p) static void * _tmp_158_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35213,7 +35213,7 @@ _tmp_158_rule(Parser *p) static void * _tmp_159_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35272,7 +35272,7 @@ _tmp_159_rule(Parser *p) static void * _tmp_160_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35319,7 +35319,7 @@ _tmp_160_rule(Parser *p) static void * _tmp_161_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35363,7 +35363,7 @@ _tmp_161_rule(Parser *p) static void * _tmp_162_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35403,7 +35403,7 @@ _tmp_162_rule(Parser *p) static void * _tmp_163_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35460,7 +35460,7 @@ _tmp_163_rule(Parser *p) static void * _tmp_164_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35517,7 +35517,7 @@ _tmp_164_rule(Parser *p) static asdl_seq * _loop0_165_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35584,7 +35584,7 @@ _loop0_165_rule(Parser *p) static void * _tmp_166_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35626,7 +35626,7 @@ _tmp_166_rule(Parser *p) static void * _tmp_167_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35668,7 +35668,7 @@ _tmp_167_rule(Parser *p) static void * _tmp_168_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35709,7 +35709,7 @@ _tmp_168_rule(Parser *p) static void * _tmp_169_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index 0d85ca989448b2..c46fbbad3d9eb0 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -380,7 +380,7 @@ def __init__( self.cleanup_statements: List[str] = [] def add_level(self) -> None: - self.print("if (p->level++ == MAXSTACK) {") + self.print("if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) {") with self.indent(): self.print("_Pypegen_stack_overflow(p);") self.print("}") From 857a7bbe51b650273b198f8411d103488ad3cbd4 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 14:31:40 +0000 Subject: [PATCH 22/41] Make tests more robust to low stacks --- Lib/test/pythoninfo.py | 1 - Lib/test/test_exceptions.py | 2 +- Lib/test/test_fstring.py | 24 +++++++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 0b2e4b1c1988c4..38236d82376f37 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -684,7 +684,6 @@ def collect_testcapi(info_add): for name in ( 'LONG_MAX', # always 32-bit on Windows, 64-bit on 64-bit Unix 'PY_SSIZE_T_MAX', - 'Py_C_RECURSION_LIMIT', 'SIZEOF_TIME_T', # 32-bit or 64-bit depending on the platform 'SIZEOF_WCHAR_T', # 16-bit or 32-bit depending on the platform ): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 58c68a5cde4f6b..77873b69a330d6 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1479,7 +1479,7 @@ def test_recursion_normalizing_infinite_exception(self): """ rc, out, err = script_helper.assert_python_failure("-c", code) self.assertEqual(rc, 1) - expected = b'RecursionError: maximum recursion depth exceeded' + expected = b'RecursionError' self.assertTrue(expected in err, msg=f"{expected!r} not found in {err[:3_000]!r}... (truncated)") self.assertIn(b'Done.', out) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 323e9d12b0131b..c8b8c00d88646d 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -627,13 +627,22 @@ def test_mismatched_parens(self): r"does not match opening parenthesis '\('", ["f'{a(4}'", ]) - self.assertRaises(SyntaxError, eval, "f'{" + "("*100 + "}'") + self.assertRaises(SyntaxError, eval, "f'{" + "("*20 + "}'") @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_fstring_nested_too_deeply(self): - self.assertAllRaise(SyntaxError, - "f-string: expressions nested too deeply", - ['f"{1+2:{1+2:{1+1:{1}}}}"']) + def raises_syntax_or_memory_error(txt): + try: + eval(txt) + self.fail("No exception raised") + except SyntaxError: + pass + except MemoryError: + pass + except Exception as ex: + self.fail(f"Should raise SyntaxError or MemoryError, not {type(ex)}") + + raises_syntax_or_memory_error('f"{1+2:{1+2:{1+1:{1}}}}"') def create_nested_fstring(n): if n == 0: @@ -641,9 +650,10 @@ def create_nested_fstring(n): prev = create_nested_fstring(n-1) return f'f"{{{prev}}}"' - self.assertAllRaise(SyntaxError, - "too many nested f-strings", - [create_nested_fstring(160)]) + raises_syntax_or_memory_error(create_nested_fstring(160)) + raises_syntax_or_memory_error("f'{" + "("*100 + "}'") + raises_syntax_or_memory_error("f'{" + "("*1000 + "}'") + raises_syntax_or_memory_error("f'{" + "("*10_000 + "}'") def test_syntax_error_in_nested_fstring(self): # See gh-104016 for more information on this crash From 9c9326a25eac549ce15ffe41e3d09c1f2cfab6d9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 14:32:10 +0000 Subject: [PATCH 23/41] Improve error messages for stack overflow --- Include/cpython/pystate.h | 44 +-------------------------------------- Modules/_testcapimodule.c | 1 - Python/ceval.c | 31 +++++++++++++++++++++++++-- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 2a9008f0f134df..a74934fb6d9cf4 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -113,6 +113,7 @@ struct _ts { int py_recursion_limit; // These are addresses, but we need to convert to ints to avoid UB. + uintptr_t c_stack_top; uintptr_t c_stack_soft_limit; uintptr_t c_stack_hard_limit; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ @@ -204,48 +205,6 @@ struct _ts { PyObject *threading_local_sentinel; }; - -#if defined(__s390x__) -# define Py_C_STACK_SIZE 320000 -#elif defined(_WIN32) && defined(_M_ARM64) -# define Py_C_STACK_SIZE 400000 -#elif defined(_WIN32) -# define Py_C_STACK_SIZE 1200000 -#elif defined(__ANDROID__) - // On an ARM64 emulator, API level 34 was OK with 10000, but API level 21 - // crashed in test_compiler_recursion_limit. -# define Py_C_STACK_SIZE 1200000 -#elif defined(__sparc__) - // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. -# define Py_C_STACK_SIZE 1600000 -#elif defined(__wasi__) - // Based on wasmtime 16. -# define Py_C_STACK_SIZE 2000000 -#elif defined(__hppa__) || defined(__powerpc64__) - // test_descr crashed with >8000 but let's keep a margin of error. -# define Py_C_STACK_SIZE 2000000 -#else - // This value is duplicated in Lib/test/support/__init__.py -# define Py_C_STACK_SIZE 5000000 -#endif - - -#ifdef Py_DEBUG - // A debug build is likely built with low optimization level which implies - // higher stack memory usage than a release build: use a lower limit. -# if defined(__has_feature) /* Clang */ - // Clang debug builds use a lot of stack space -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 4000) -# else -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 2000) -# endif -#elif defined(_Py_ADDRESS_SANITIZER) -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 600) -#else -# define Py_C_RECURSION_LIMIT (Py_C_STACK_SIZE / 300) -#endif - - /* other API */ /* Similar to PyThreadState_Get(), but don't issue a fatal error @@ -259,7 +218,6 @@ _PyThreadState_UncheckedGet(void) return PyThreadState_GetUnchecked(); } - // Disable tracing and profiling. PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c84646ccf03fa7..8a76d43e97237e 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3213,7 +3213,6 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); - PyModule_AddIntMacro(m, Py_C_RECURSION_LIMIT); PyModule_AddObject(m, "INT32_MIN", PyLong_FromInt32(INT32_MIN)); PyModule_AddObject(m, "INT32_MAX", PyLong_FromInt32(INT32_MAX)); PyModule_AddObject(m, "UINT32_MAX", PyLong_FromUInt32(UINT32_MAX)); diff --git a/Python/ceval.c b/Python/ceval.c index 13ed12994f2a8e..74b42df76fc19c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -318,11 +318,33 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) } } +#if defined(__s390x__) +# define Py_C_STACK_SIZE 320000 +#elif defined(_WIN32) && defined(_M_ARM64) +# define Py_C_STACK_SIZE 400000 +#elif defined(_WIN32) +# define Py_C_STACK_SIZE 1200000 +#elif defined(__ANDROID__) +# define Py_C_STACK_SIZE 1200000 +#elif defined(__sparc__) + // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. +# define Py_C_STACK_SIZE 1600000 +#elif defined(__wasi__) + // Based on wasmtime 16. +# define Py_C_STACK_SIZE 2000000 +#elif defined(__hppa__) || defined(__powerpc64__) + // test_descr crashed with >8000 but let's keep a margin of error. +# define Py_C_STACK_SIZE 2000000 +#else +# define Py_C_STACK_SIZE 5000000 +#endif + void _Py_InitializeRecursionCheck(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; + tstate->c_stack_top = here_addr; #ifdef USE_STACKCHECK if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; @@ -364,15 +386,20 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) assert(tstate->c_stack_hard_limit != 0); if (here_addr < tstate->c_stack_hard_limit) { /* Overflowing while handling an overflow. Give up. */ - Py_FatalError("Cannot recover from stack overflow."); + int kbytes_used = (tstate->c_stack_top - here_addr)/1024; + char buffer[80]; + snprintf(buffer, 80, "Unrecoverable stack overflow (used %dkb)%s", kbytes_used, where); + Py_FatalError(buffer); } if (tstate->recursion_headroom) { return 0; } else { + int kbytes_used = (tstate->c_stack_top - here_addr)/1024; tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded%s", + "Stack overflow (used %dkb)S%s", + kbytes_used, where); tstate->recursion_headroom--; return -1; From 3e41b46dbdee8a181540b222cee5979ca7198424 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 16:30:38 +0000 Subject: [PATCH 24/41] Fix formatting --- Python/ceval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index aa9af60d65f33c..e60b8d2b5a131a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -390,7 +390,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) /* Overflowing while handling an overflow. Give up. */ int kbytes_used = (tstate->c_stack_top - here_addr)/1024; char buffer[80]; - snprintf(buffer, 80, "Unrecoverable stack overflow (used %dkb)%s", kbytes_used, where); + snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where); Py_FatalError(buffer); } if (tstate->recursion_headroom) { @@ -400,7 +400,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) int kbytes_used = (tstate->c_stack_top - here_addr)/1024; tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, - "Stack overflow (used %dkb)S%s", + "Stack overflow (used %d kB)%s", kbytes_used, where); tstate->recursion_headroom--; From 158401ae4bd613ffdfe2725d95479ad4f36889e2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 16:49:31 +0000 Subject: [PATCH 25/41] Halve size of WASI stack --- Lib/test/test_functools.py | 5 +---- Python/ceval.c | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 9ae6a8f8ad2232..77ff14c29dac77 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2077,10 +2077,7 @@ def fib(n): return n return fib(n-1) + fib(n-2) - try: - fib(100) - except RecursionError: - fib(50) + fib(100) if self.module == c_functools: fib.cache_clear() with support.infinite_recursion(): diff --git a/Python/ceval.c b/Python/ceval.c index e60b8d2b5a131a..464477b62ea93f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -332,8 +332,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) - // Based on wasmtime 16. -# define Py_C_STACK_SIZE 2000000 +# define Py_C_STACK_SIZE 1000000 #elif defined(__hppa__) || defined(__powerpc64__) // test_descr crashed with >8000 but let's keep a margin of error. # define Py_C_STACK_SIZE 2000000 From c1eb229f7ef76c6ba1ebecf1a44003bb9ffaefd1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 17:05:21 +0000 Subject: [PATCH 26/41] Reduce webassembly 'stack size' by 10 --- Python/ceval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index 464477b62ea93f..5e6e6ac76ce82e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -332,7 +332,8 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) -# define Py_C_STACK_SIZE 1000000 + /* Web assembly has two stacks, so this isn't really the stack depth */ +# define Py_C_STACK_SIZE 100000 #elif defined(__hppa__) || defined(__powerpc64__) // test_descr crashed with >8000 but let's keep a margin of error. # define Py_C_STACK_SIZE 2000000 From 7407d2b9b310cd7fdedebcf33ecdfb43917af89e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 17:13:04 +0000 Subject: [PATCH 27/41] Halve size of WASI stack, again --- Python/ceval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index 5e6e6ac76ce82e..c34c6ccc1e1db7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -333,7 +333,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) /* Web assembly has two stacks, so this isn't really the stack depth */ -# define Py_C_STACK_SIZE 100000 +# define Py_C_STACK_SIZE 50000 #elif defined(__hppa__) || defined(__powerpc64__) // test_descr crashed with >8000 but let's keep a margin of error. # define Py_C_STACK_SIZE 2000000 From 978b5e704879a8478afe0194c41eafea81681b45 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 19:09:36 +0000 Subject: [PATCH 28/41] Change WASI stack back to 100k --- Python/ceval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index c34c6ccc1e1db7..5e6e6ac76ce82e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -333,7 +333,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) /* Web assembly has two stacks, so this isn't really the stack depth */ -# define Py_C_STACK_SIZE 50000 +# define Py_C_STACK_SIZE 100000 #elif defined(__hppa__) || defined(__powerpc64__) // test_descr crashed with >8000 but let's keep a margin of error. # define Py_C_STACK_SIZE 2000000 From 7b36f5913734ff8292430321f99b8bad295b18f9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 13 Feb 2025 19:28:16 +0000 Subject: [PATCH 29/41] Add many skip tests for WASI due to stack issues --- Lib/test/list_tests.py | 4 +++- Lib/test/mapping_tests.py | 3 ++- Lib/test/support/__init__.py | 3 +++ Lib/test/test_ast/test_ast.py | 4 +++- Lib/test/test_dict.py | 1 + Lib/test/test_dictviews.py | 3 ++- Lib/test/test_json/test_recursion.py | 1 + Lib/test/test_sys_settrace.py | 4 ++-- Lib/test/test_tokenize.py | 1 + Lib/test/test_xml_etree_c.py | 1 + 10 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 1e8c4310c8481f..4e63abfc3ce1b3 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -6,7 +6,8 @@ from functools import cmp_to_key from test import seq_tests -from test.support import ALWAYS_EQ, NEVER_EQ, skip_emscripten_stack_overflow +from test.support import ALWAYS_EQ, NEVER_EQ +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow class CommonTest(seq_tests.CommonTest): @@ -59,6 +60,7 @@ def test_repr(self): self.assertEqual(str(a2), "[0, 1, 2, [...], 3]") self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]") + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index fa41a4305e812e..9fb0a7de1982f8 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -from test.support import skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow class BasicTestMappingProtocol(unittest.TestCase): @@ -622,6 +622,7 @@ def __repr__(self): d = self._full_mapping({1: BadRepr()}) self.assertRaises(Exc, repr, d) + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_repr_deep(self): d = self._empty_mapping() diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 7aacd187981373..628c9438910ca2 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -557,6 +557,9 @@ def skip_android_selinux(name): def skip_emscripten_stack_overflow(): return unittest.skipIf(is_emscripten, "Exhausts limited stack on Emscripten") +def skip_wasi_stack_overflow(): + return unittest.skipIf(is_wasi, "Exhausts stack on WASI") + is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"} is_apple = is_apple_mobile or sys.platform == "darwin" diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index dc54988eabd1bc..68f5df96a6338a 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -18,7 +18,8 @@ _testinternalcapi = None from test import support -from test.support import os_helper, script_helper, skip_emscripten_stack_overflow +from test.support import os_helper, script_helper +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow from test.support.ast_helper import ASTTestMixin from test.test_ast.utils import to_tuple from test.test_ast.snippets import ( @@ -745,6 +746,7 @@ def next(self): enum._test_simple_enum(_Precedence, ast._Precedence) @support.cpython_only + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): crash_depth = 200_000 diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index ed485a74372de4..a22394139d25a2 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -594,6 +594,7 @@ def __repr__(self): d = {1: BadRepr()} self.assertRaises(Exc, repr, d) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = {} diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index d09eba0019ac19..11be71d044e3c4 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -2,7 +2,7 @@ import copy import pickle import unittest -from test.support import skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow class DictSetTest(unittest.TestCase): @@ -277,6 +277,7 @@ def test_recursive_repr(self): # Again. self.assertIsInstance(r, str) + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} diff --git a/Lib/test/test_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 663c0643579ac8..700821f8625834 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -82,6 +82,7 @@ def test_highly_nested_objects_decoding(self): with support.infinite_recursion(): self.loads('[' * 100000 + '1' + ']' * 100000) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_highly_nested_objects_encoding(self): # See #12051 diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index e2fe7861415cef..e528c6a9c69d28 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -3042,11 +3042,11 @@ def f(): return ( {} ) - """.format("\n+\n".join(f"var{i}\n" for i in range(count))) + """.format("\n,\n".join(f"var{i}\n" for i in range(count))) ns = {f"var{i}": i for i in range(count)} exec(code, ns) counts = self.count_traces(ns["f"]) - self.assertEqual(counts, {'call': 1, 'line': count * 2, 'return': 1}) + self.assertEqual(counts, {'call': 1, 'line': count * 2 + 1, 'return': 1}) class TestEdgeCases(unittest.TestCase): diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 52d3341975088b..5fa4e0d922ed08 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -3040,6 +3040,7 @@ def get_tokens(string): with self.subTest(case=case): self.assertRaises(tokenize.TokenError, get_tokens, case) + @support.skip_wasi_stack_overflow() def test_max_indent(self): MAXINDENT = 100 diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index db19af419bdeab..9ed0f4096a45e3 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -57,6 +57,7 @@ def test_del_attribute(self): del element.attrib self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @support.skip_wasi_stack_overflow() @unittest.skipIf(support.is_emscripten, "segfaults") def test_trashcan(self): # If this test fails, it will most likely die via segfault. From 5e5db03e7f72497cccfbe15bf16c16b2d73f15cc Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 14 Feb 2025 12:22:15 +0000 Subject: [PATCH 30/41] Probe all pages when extending stack limits --- Include/internal/pycore_ceval.h | 6 ++--- Include/pythonrun.h | 15 +++++++---- Python/ceval.c | 48 +++++++++++++++------------------ Python/pystate.c | 1 + Python/pythonrun.c | 34 ++++++++++++++++++----- 5 files changed, 63 insertions(+), 41 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index a1e99cd32ada9e..def21eb6976d3b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -222,7 +222,7 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { (void)tstate; } -PyAPI_FUNC(void) _Py_InitializeRecursionCheck(PyThreadState *tstate); +PyAPI_FUNC(void) _Py_UpdateRecursionLimits(PyThreadState *tstate); static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { char here; @@ -231,7 +231,7 @@ static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_co return 0; } if (tstate->c_stack_hard_limit == 0) { - _Py_InitializeRecursionCheck(tstate); + _Py_UpdateRecursionLimits(tstate); } return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } @@ -327,7 +327,7 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit); PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value); -extern int _PyOS_CheckStack(int words); +extern void _Py_StackProbe(uintptr_t from, int bytes, int *probed); #ifdef __cplusplus } diff --git a/Include/pythonrun.h b/Include/pythonrun.h index e4d184905db945..97303e0e6adeae 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -21,13 +21,18 @@ PyAPI_FUNC(void) PyErr_DisplayException(PyObject *); /* Stuff with no proper home (yet) */ PyAPI_DATA(int) (*PyOS_InputHook)(void); -/* Stack size, in "pointers" (so we get extra safety margins - on 64-bit platforms). On a 32-bit platform, this translates - to an 16k margin. */ -#define PYOS_STACK_MARGIN 4096 +/* Stack size, in "pointers". This must be large enough, so + * no two calls to check recursion depth are more than this far + * apart. In practice, that means it must be larger than the C + * stack consumption of PyEval_EvalDefault */ +#if defined(Py_DEBUG) && defined(WIN32) +# define PYOS_STACK_MARGIN 3072 +#else +# define PYOS_STACK_MARGIN 2048 +#endif #define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *)) -#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 +#if defined(WIN32) /* Enable stack checking under Microsoft C */ // When changing the platforms, ensure PyOS_CheckStack() docs are still correct #define USE_STACKCHECK diff --git a/Python/ceval.c b/Python/ceval.c index 5e6e6ac76ce82e..400bee392ff3c3 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -322,10 +322,8 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #if defined(__s390x__) # define Py_C_STACK_SIZE 320000 -#elif defined(_WIN32) && defined(_M_ARM64) -# define Py_C_STACK_SIZE 400000 #elif defined(_WIN32) -# define Py_C_STACK_SIZE 1200000 + // Don't define Py_C_STACK_SIZE, use probing instead #elif defined(__ANDROID__) # define Py_C_STACK_SIZE 1200000 #elif defined(__sparc__) @@ -342,32 +340,30 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #endif void -_Py_InitializeRecursionCheck(PyThreadState *tstate) +_Py_UpdateRecursionLimits(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - tstate->c_stack_top = here_addr; + int to_probe = PYOS_STACK_MARGIN_BYTES * 2; #ifdef USE_STACKCHECK - if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) { - tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES; - return; - } - int margin = PYOS_STACK_MARGIN; - assert(tstate->c_stack_soft_limit != UINTPTR_MAX); - if (_PyOS_CheckStack(margin)) { - margin = PYOS_STACK_MARGIN/2; - } - else { - if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) { - margin = PYOS_STACK_MARGIN*3/2; - } + if (tstate->c_stack_top == 0) { + assert(tstate->c_stack_soft_limit == UINTPTR_MAX); + tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); + tstate->c_stack_soft_limit = tstate->c_stack_top; + to_probe = PYOS_STACK_MARGIN_BYTES * 4; + } + int depth; + uintptr_t implicit_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; + _Py_StackProbe(implicit_hard_limit, to_probe, &depth); + tstate->c_stack_soft_limit = implicit_hard_limit - depth + PYOS_STACK_MARGIN_BYTES * 2; + if (depth != to_probe) { + tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; } - tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *); - tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else - assert(tstate->c_stack_soft_limit == UINTPTR_MAX); - tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE; - tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); + assert(tstate->c_stack_top == 0); + tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); + tstate->c_stack_soft_limit = tstate->c_stack_top - Py_C_STACK_SIZE; + tstate->c_stack_hard_limit = tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); #endif } @@ -380,7 +376,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) uintptr_t here_addr = (uintptr_t)&here; assert(tstate->c_stack_soft_limit != 0); if (tstate->c_stack_hard_limit == 0) { - _Py_InitializeRecursionCheck(tstate); + _Py_UpdateRecursionLimits(tstate); } if (here_addr >= tstate->c_stack_soft_limit) { return 0; @@ -388,7 +384,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) assert(tstate->c_stack_hard_limit != 0); if (here_addr < tstate->c_stack_hard_limit) { /* Overflowing while handling an overflow. Give up. */ - int kbytes_used = (tstate->c_stack_top - here_addr)/1024; + int kbytes_used = (int)(tstate->c_stack_top - here_addr)/1024; char buffer[80]; snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where); Py_FatalError(buffer); @@ -397,7 +393,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) return 0; } else { - int kbytes_used = (tstate->c_stack_top - here_addr)/1024; + int kbytes_used = (int)(tstate->c_stack_top - here_addr)/1024; tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, "Stack overflow (used %d kB)%s", diff --git a/Python/pystate.c b/Python/pystate.c index 9aa5b995619192..69558ac5b74a97 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1493,6 +1493,7 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->py_recursion_limit = interp->ceval.recursion_limit; tstate->py_recursion_remaining = interp->ceval.recursion_limit; tstate->c_stack_soft_limit = UINTPTR_MAX; + tstate->c_stack_top = 0; tstate->c_stack_hard_limit = 0; tstate->exc_info = &tstate->exc_state; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 328bc773c4acaf..3f9bc38c45a0d2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1552,14 +1552,24 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp #include #include -int _PyOS_CheckStack(int words) +void _Py_StackProbe(uintptr_t from, int bytes, int *probed) { + assert((bytes & 4095) == 0); + int depth = 4096; + char here; + uintptr_t here_addr = (uintptr_t)&here; __try { - /* alloca throws a stack overflow exception if there's - not enough space left on the stack */ - alloca(words * sizeof(void *)); - return 0; + while (depth <= bytes) { + uintptr_t probe_point = from - depth + 64; + if (probe_point < here_addr) { + /* alloca throws a stack overflow exception if there's + * not enough space left on the stack */ + alloca(here_addr - probe_point); + } + *probed = depth; + depth += 4096; + } } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { @@ -1569,7 +1579,6 @@ int _PyOS_CheckStack(int words) Py_FatalError("Could not reset the stack!"); } } - return 1; } /* @@ -1577,7 +1586,18 @@ int _PyOS_CheckStack(int words) */ int PyOS_CheckStack(void) { - return _PyOS_CheckStack(PYOS_STACK_MARGIN); + char here; + uintptr_t here_addr = (uintptr_t)&here; + uintptr_t from = _Py_SIZE_ROUND_UP(here_addr, 4096); + int depth; + _Py_StackProbe(from, PYOS_STACK_MARGIN_BYTES*2, &depth); + assert(depth <= PYOS_STACK_MARGIN_BYTES*2); + if (depth == PYOS_STACK_MARGIN_BYTES*2) { + return 0; + } + else { + return -1; + } } #endif /* WIN32 && _MSC_VER */ From 82173ed27b2e6818081f6b39cea78849984f74dc Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 14 Feb 2025 12:51:42 +0000 Subject: [PATCH 31/41] Fix compiler warnings --- Include/pythonrun.h | 4 ++-- Python/ceval.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 97303e0e6adeae..0a7255c7cefb81 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -21,8 +21,8 @@ PyAPI_FUNC(void) PyErr_DisplayException(PyObject *); /* Stuff with no proper home (yet) */ PyAPI_DATA(int) (*PyOS_InputHook)(void); -/* Stack size, in "pointers". This must be large enough, so - * no two calls to check recursion depth are more than this far +/* Stack size, in "pointers". This must be large enough, so + * no two calls to check recursion depth are more than this far * apart. In practice, that means it must be larger than the C * stack consumption of PyEval_EvalDefault */ #if defined(Py_DEBUG) && defined(WIN32) diff --git a/Python/ceval.c b/Python/ceval.c index 400bee392ff3c3..7817b038b1ff2c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -344,8 +344,8 @@ _Py_UpdateRecursionLimits(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - int to_probe = PYOS_STACK_MARGIN_BYTES * 2; #ifdef USE_STACKCHECK + int to_probe = PYOS_STACK_MARGIN_BYTES * 2; if (tstate->c_stack_top == 0) { assert(tstate->c_stack_soft_limit == UINTPTR_MAX); tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); @@ -355,7 +355,7 @@ _Py_UpdateRecursionLimits(PyThreadState *tstate) int depth; uintptr_t implicit_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; _Py_StackProbe(implicit_hard_limit, to_probe, &depth); - tstate->c_stack_soft_limit = implicit_hard_limit - depth + PYOS_STACK_MARGIN_BYTES * 2; + tstate->c_stack_soft_limit = implicit_hard_limit - depth + PYOS_STACK_MARGIN_BYTES * 2; if (depth != to_probe) { tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; } From 64cfd861158b5193ce8fc01afee5e960a773c011 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 14 Feb 2025 16:59:50 +0000 Subject: [PATCH 32/41] Use GetCurrentThreadStackLimits instead of probing with alloca --- Python/ceval.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 7817b038b1ff2c..2d0d85db50bfac 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -342,25 +342,17 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) void _Py_UpdateRecursionLimits(PyThreadState *tstate) { +#ifdef WIN32 + ULONG_PTR low, high; + GetCurrentThreadStackLimits(&low, &high); + tstate->c_stack_top = (uintptr_t)high; + ULONG guarantee = 0; + SetThreadStackGuarantee(&guarantee); + tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; + tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; +#else char here; uintptr_t here_addr = (uintptr_t)&here; -#ifdef USE_STACKCHECK - int to_probe = PYOS_STACK_MARGIN_BYTES * 2; - if (tstate->c_stack_top == 0) { - assert(tstate->c_stack_soft_limit == UINTPTR_MAX); - tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); - tstate->c_stack_soft_limit = tstate->c_stack_top; - to_probe = PYOS_STACK_MARGIN_BYTES * 4; - } - int depth; - uintptr_t implicit_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; - _Py_StackProbe(implicit_hard_limit, to_probe, &depth); - tstate->c_stack_soft_limit = implicit_hard_limit - depth + PYOS_STACK_MARGIN_BYTES * 2; - if (depth != to_probe) { - tstate->c_stack_hard_limit = tstate->c_stack_soft_limit - PYOS_STACK_MARGIN_BYTES; - } -#else - assert(tstate->c_stack_top == 0); tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); tstate->c_stack_soft_limit = tstate->c_stack_top - Py_C_STACK_SIZE; tstate->c_stack_hard_limit = tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); From e52137f29d559206a114675a4a0ed257866ef61c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 14 Feb 2025 17:45:47 +0000 Subject: [PATCH 33/41] Refactor a bit --- Include/internal/pycore_ceval.h | 6 ++--- Python/ceval.c | 6 ++--- Python/pythonrun.c | 39 +++++---------------------------- 3 files changed, 10 insertions(+), 41 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index def21eb6976d3b..93377cb08e62e1 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -222,7 +222,7 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { (void)tstate; } -PyAPI_FUNC(void) _Py_UpdateRecursionLimits(PyThreadState *tstate); +PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate); static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { char here; @@ -231,7 +231,7 @@ static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_co return 0; } if (tstate->c_stack_hard_limit == 0) { - _Py_UpdateRecursionLimits(tstate); + _Py_InitializeRecursionLimits(tstate); } return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } @@ -327,8 +327,6 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit); PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value); -extern void _Py_StackProbe(uintptr_t from, int bytes, int *probed); - #ifdef __cplusplus } #endif diff --git a/Python/ceval.c b/Python/ceval.c index 2d0d85db50bfac..958931437cecce 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -323,7 +323,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #if defined(__s390x__) # define Py_C_STACK_SIZE 320000 #elif defined(_WIN32) - // Don't define Py_C_STACK_SIZE, use probing instead + // Don't define Py_C_STACK_SIZE, ask the O/S #elif defined(__ANDROID__) # define Py_C_STACK_SIZE 1200000 #elif defined(__sparc__) @@ -340,7 +340,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #endif void -_Py_UpdateRecursionLimits(PyThreadState *tstate) +_Py_InitializeRecursionLimits(PyThreadState *tstate) { #ifdef WIN32 ULONG_PTR low, high; @@ -368,7 +368,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) uintptr_t here_addr = (uintptr_t)&here; assert(tstate->c_stack_soft_limit != 0); if (tstate->c_stack_hard_limit == 0) { - _Py_UpdateRecursionLimits(tstate); + _Py_InitializeRecursionLimits(tstate); } if (here_addr >= tstate->c_stack_soft_limit) { return 0; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 3f9bc38c45a0d2..08d74721f2512a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1552,35 +1552,6 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp #include #include -void _Py_StackProbe(uintptr_t from, int bytes, int *probed) -{ - assert((bytes & 4095) == 0); - int depth = 4096; - char here; - uintptr_t here_addr = (uintptr_t)&here; - __try - { - while (depth <= bytes) { - uintptr_t probe_point = from - depth + 64; - if (probe_point < here_addr) { - /* alloca throws a stack overflow exception if there's - * not enough space left on the stack */ - alloca(here_addr - probe_point); - } - *probed = depth; - depth += 4096; - } - } - __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - int errcode = _resetstkoflw(); - if (errcode == 0) - { - Py_FatalError("Could not reset the stack!"); - } - } -} - /* * Return non-zero when we run out of memory on the stack; zero otherwise. */ @@ -1588,11 +1559,11 @@ int PyOS_CheckStack(void) { char here; uintptr_t here_addr = (uintptr_t)&here; - uintptr_t from = _Py_SIZE_ROUND_UP(here_addr, 4096); - int depth; - _Py_StackProbe(from, PYOS_STACK_MARGIN_BYTES*2, &depth); - assert(depth <= PYOS_STACK_MARGIN_BYTES*2); - if (depth == PYOS_STACK_MARGIN_BYTES*2) { + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionLimits(tstate); + } + if (here_addr >= tstate->c_stack_soft_limit) { return 0; } else { From 21366c3803b88cfeb882be488d64ca4066f364cb Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 17 Feb 2025 09:44:33 +0000 Subject: [PATCH 34/41] Fix logic error in test --- Lib/test/test_fstring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index d8e44c2b48c937..5974024c170cef 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -635,13 +635,14 @@ def test_fstring_nested_too_deeply(self): def raises_syntax_or_memory_error(txt): try: eval(txt) - self.fail("No exception raised") except SyntaxError: pass except MemoryError: pass except Exception as ex: self.fail(f"Should raise SyntaxError or MemoryError, not {type(ex)}") + else: + self.fail("No exception raised") raises_syntax_or_memory_error('f"{1+2:{1+2:{1+1:{1}}}}"') From 7761d31f2b0904687252058c05d8c0c1243e584d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 17 Feb 2025 16:15:12 +0000 Subject: [PATCH 35/41] Make ABI function needed for Py_TRASHCAN_BEGIN private --- Doc/data/stable_abi.dat | 1 - Include/ceval.h | 2 - Include/cpython/object.h | 7 +- Include/internal/pycore_ceval.h | 6 +- Lib/test/test_stable_abi_ctypes.py | 1 - Misc/stable_abi.toml | 2 - PC/python3dll.c | 1 - Parser/parser.c | 868 +++++++++++------------ Python/bytecodes.c | 6 +- Python/ceval.c | 12 +- Python/executor_cases.c.h | 6 +- Python/generated_cases.c.h | 6 +- Tools/peg_generator/pegen/c_generator.py | 2 +- 13 files changed, 462 insertions(+), 458 deletions(-) diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index db2e72b6090e6f..59e7a31bc2ef06 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -885,7 +885,6 @@ func,Py_NewRef,3.10,, func,Py_PACK_FULL_VERSION,3.14,, func,Py_PACK_VERSION,3.14,, func,Py_REFCNT,3.14,, -func,Py_ReachedRecursionLimit,3.14,, func,Py_ReprEnter,3.2,, func,Py_ReprLeave,3.2,, func,Py_SetProgramName,3.2,, diff --git a/Include/ceval.h b/Include/ceval.h index 6e5e91d9cf73f1..32ab38972e548f 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -60,8 +60,6 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); -PyAPI_FUNC(int) Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count); - PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 9035d8b3c18705..260b90da24c18b 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -487,16 +487,19 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate); * we have headroom above the trigger limit */ #define Py_TRASHCAN_HEADROOM 50 +/* Helper function for Py_TRASHCAN_BEGIN */ +PyAPI_FUNC(int) _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count); + #define Py_TRASHCAN_BEGIN(op, dealloc) \ do { \ PyThreadState *tstate = PyThreadState_Get(); \ - if (Py_ReachedRecursionLimit(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ + if (_Py_ReachedRecursionLimitWithMargin(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ _PyTrash_thread_deposit_object(tstate, (PyObject *)op); \ break; \ } /* The body of the deallocator is here. */ #define Py_TRASHCAN_END \ - if (tstate->delete_later && !Py_ReachedRecursionLimit(tstate, 2)) { \ + if (tstate->delete_later && !_Py_ReachedRecursionLimitWithMargin(tstate, 2)) { \ _PyTrash_thread_destroy_chain(tstate); \ } \ } while (0); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 93377cb08e62e1..4352be994781b4 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -224,16 +224,16 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate); -static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) { +static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { + if (here_addr > tstate->c_stack_soft_limit) { return 0; } if (tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); } - return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; + return here_addr <= tstate->c_stack_soft_limit; } static inline void _Py_LeaveRecursiveCall(void) { diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 793dbcc3f9a4cb..f3724ce6d4d15a 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -904,7 +904,6 @@ def test_windows_feature_macros(self): "Py_PACK_FULL_VERSION", "Py_PACK_VERSION", "Py_REFCNT", - "Py_ReachedRecursionLimit", "Py_ReprEnter", "Py_ReprLeave", "Py_SetPath", diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 51e88dfd60441e..9317be605f0065 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2545,5 +2545,3 @@ added = '3.14' [function.Py_PACK_VERSION] added = '3.14' -[function.Py_ReachedRecursionLimit] - added = '3.14' diff --git a/PC/python3dll.c b/PC/python3dll.c index dd282ca1013bd4..84b3c735240b73 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -83,7 +83,6 @@ EXPORT_FUNC(Py_NewInterpreter) EXPORT_FUNC(Py_NewRef) EXPORT_FUNC(Py_PACK_FULL_VERSION) EXPORT_FUNC(Py_PACK_VERSION) -EXPORT_FUNC(Py_ReachedRecursionLimit) EXPORT_FUNC(Py_REFCNT) EXPORT_FUNC(Py_ReprEnter) EXPORT_FUNC(Py_ReprLeave) diff --git a/Parser/parser.c b/Parser/parser.c index 3ab971a4479624..19b7de3fe57227 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -939,7 +939,7 @@ static void *_tmp_171_rule(Parser *p); static mod_ty file_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -985,7 +985,7 @@ file_rule(Parser *p) static mod_ty interactive_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1028,7 +1028,7 @@ interactive_rule(Parser *p) static mod_ty eval_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1077,7 +1077,7 @@ eval_rule(Parser *p) static mod_ty func_type_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1138,7 +1138,7 @@ func_type_rule(Parser *p) static asdl_stmt_seq* statements_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1181,7 +1181,7 @@ statements_rule(Parser *p) static asdl_stmt_seq* statement_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1248,7 +1248,7 @@ statement_rule(Parser *p) static asdl_stmt_seq* statement_newline_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1379,7 +1379,7 @@ statement_newline_rule(Parser *p) static asdl_stmt_seq* simple_stmts_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1472,7 +1472,7 @@ simple_stmts_rule(Parser *p) static stmt_ty simple_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1853,7 +1853,7 @@ simple_stmt_rule(Parser *p) static stmt_ty compound_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2043,7 +2043,7 @@ compound_stmt_rule(Parser *p) static stmt_ty assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2261,7 +2261,7 @@ assignment_rule(Parser *p) static expr_ty annotated_rhs_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2331,7 +2331,7 @@ annotated_rhs_rule(Parser *p) static AugOperator* augassign_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2662,7 +2662,7 @@ augassign_rule(Parser *p) static stmt_ty return_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2726,7 +2726,7 @@ return_stmt_rule(Parser *p) static stmt_ty raise_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2826,7 +2826,7 @@ raise_stmt_rule(Parser *p) static stmt_ty global_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2890,7 +2890,7 @@ global_stmt_rule(Parser *p) static stmt_ty nonlocal_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2954,7 +2954,7 @@ nonlocal_stmt_rule(Parser *p) static stmt_ty del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3039,7 +3039,7 @@ del_stmt_rule(Parser *p) static stmt_ty yield_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3100,7 +3100,7 @@ yield_stmt_rule(Parser *p) static stmt_ty assert_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3167,7 +3167,7 @@ assert_stmt_rule(Parser *p) static stmt_ty import_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3243,7 +3243,7 @@ import_stmt_rule(Parser *p) static stmt_ty import_name_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3309,7 +3309,7 @@ import_name_rule(Parser *p) static stmt_ty import_from_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3428,7 +3428,7 @@ import_from_rule(Parser *p) static asdl_alias_seq* import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3563,7 +3563,7 @@ import_from_targets_rule(Parser *p) static asdl_alias_seq* import_from_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3606,7 +3606,7 @@ import_from_as_names_rule(Parser *p) static alias_ty import_from_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3670,7 +3670,7 @@ import_from_as_name_rule(Parser *p) static asdl_alias_seq* dotted_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3713,7 +3713,7 @@ dotted_as_names_rule(Parser *p) static alias_ty dotted_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3779,7 +3779,7 @@ static expr_ty dotted_name_raw(Parser *); static expr_ty dotted_name_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -3813,7 +3813,7 @@ dotted_name_rule(Parser *p) static expr_ty dotted_name_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3881,7 +3881,7 @@ dotted_name_raw(Parser *p) static asdl_stmt_seq* block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3976,7 +3976,7 @@ block_rule(Parser *p) static asdl_expr_seq* decorators_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4019,7 +4019,7 @@ decorators_rule(Parser *p) static stmt_ty class_def_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4086,7 +4086,7 @@ class_def_rule(Parser *p) static stmt_ty class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4181,7 +4181,7 @@ class_def_raw_rule(Parser *p) static stmt_ty function_def_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4249,7 +4249,7 @@ function_def_rule(Parser *p) static stmt_ty function_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4419,7 +4419,7 @@ function_def_raw_rule(Parser *p) static arguments_ty params_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4481,7 +4481,7 @@ params_rule(Parser *p) static arguments_ty parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4644,7 +4644,7 @@ parameters_rule(Parser *p) static asdl_arg_seq* slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4724,7 +4724,7 @@ slash_no_default_rule(Parser *p) static SlashWithDefault* slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4813,7 +4813,7 @@ slash_with_default_rule(Parser *p) static StarEtc* star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4974,7 +4974,7 @@ star_etc_rule(Parser *p) static arg_ty kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5039,7 +5039,7 @@ kwds_rule(Parser *p) static arg_ty param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5119,7 +5119,7 @@ param_no_default_rule(Parser *p) static arg_ty param_no_default_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5197,7 +5197,7 @@ param_no_default_star_annotation_rule(Parser *p) static NameDefaultPair* param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5283,7 +5283,7 @@ param_with_default_rule(Parser *p) static NameDefaultPair* param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5367,7 +5367,7 @@ param_maybe_default_rule(Parser *p) static arg_ty param_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5431,7 +5431,7 @@ param_rule(Parser *p) static arg_ty param_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5495,7 +5495,7 @@ param_star_annotation_rule(Parser *p) static expr_ty annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5541,7 +5541,7 @@ annotation_rule(Parser *p) static expr_ty star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5587,7 +5587,7 @@ star_annotation_rule(Parser *p) static expr_ty default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5655,7 +5655,7 @@ default_rule(Parser *p) static stmt_ty if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5795,7 +5795,7 @@ if_stmt_rule(Parser *p) static stmt_ty elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5932,7 +5932,7 @@ elif_stmt_rule(Parser *p) static asdl_stmt_seq* else_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6000,7 +6000,7 @@ else_block_rule(Parser *p) static stmt_ty while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6096,7 +6096,7 @@ while_stmt_rule(Parser *p) static stmt_ty for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6293,7 +6293,7 @@ for_stmt_rule(Parser *p) static stmt_ty with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6565,7 +6565,7 @@ with_stmt_rule(Parser *p) static withitem_ty with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6663,7 +6663,7 @@ with_item_rule(Parser *p) static stmt_ty try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6852,7 +6852,7 @@ try_stmt_rule(Parser *p) static excepthandler_ty except_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7005,7 +7005,7 @@ except_block_rule(Parser *p) static excepthandler_ty except_star_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7119,7 +7119,7 @@ except_star_block_rule(Parser *p) static asdl_stmt_seq* finally_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7189,7 +7189,7 @@ finally_block_rule(Parser *p) static stmt_ty match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7287,7 +7287,7 @@ match_stmt_rule(Parser *p) static expr_ty subject_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7373,7 +7373,7 @@ subject_expr_rule(Parser *p) static match_case_ty case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7447,7 +7447,7 @@ case_block_rule(Parser *p) static expr_ty guard_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7493,7 +7493,7 @@ guard_rule(Parser *p) static pattern_ty patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7573,7 +7573,7 @@ patterns_rule(Parser *p) static pattern_ty pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7630,7 +7630,7 @@ pattern_rule(Parser *p) static pattern_ty as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7716,7 +7716,7 @@ as_pattern_rule(Parser *p) static pattern_ty or_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7785,7 +7785,7 @@ or_pattern_rule(Parser *p) static pattern_ty closed_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7967,7 +7967,7 @@ closed_pattern_rule(Parser *p) static pattern_ty literal_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8201,7 +8201,7 @@ literal_pattern_rule(Parser *p) static expr_ty literal_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8389,7 +8389,7 @@ literal_expr_rule(Parser *p) static expr_ty complex_number_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8495,7 +8495,7 @@ complex_number_rule(Parser *p) static expr_ty signed_number_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8578,7 +8578,7 @@ signed_number_rule(Parser *p) static expr_ty signed_real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8661,7 +8661,7 @@ signed_real_number_rule(Parser *p) static expr_ty real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8704,7 +8704,7 @@ real_number_rule(Parser *p) static expr_ty imaginary_number_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8747,7 +8747,7 @@ imaginary_number_rule(Parser *p) static pattern_ty capture_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8808,7 +8808,7 @@ capture_pattern_rule(Parser *p) static expr_ty pattern_capture_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8855,7 +8855,7 @@ pattern_capture_target_rule(Parser *p) static pattern_ty wildcard_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8916,7 +8916,7 @@ wildcard_pattern_rule(Parser *p) static pattern_ty value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8981,7 +8981,7 @@ static expr_ty attr_raw(Parser *); static expr_ty attr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -9015,7 +9015,7 @@ attr_rule(Parser *p) static expr_ty attr_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9083,7 +9083,7 @@ attr_raw(Parser *p) static expr_ty name_or_attr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9140,7 +9140,7 @@ name_or_attr_rule(Parser *p) static pattern_ty group_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9189,7 +9189,7 @@ group_pattern_rule(Parser *p) static pattern_ty sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9295,7 +9295,7 @@ sequence_pattern_rule(Parser *p) static asdl_seq* open_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9344,7 +9344,7 @@ open_sequence_pattern_rule(Parser *p) static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9391,7 +9391,7 @@ maybe_sequence_pattern_rule(Parser *p) static pattern_ty maybe_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9448,7 +9448,7 @@ maybe_star_pattern_rule(Parser *p) static pattern_ty star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9557,7 +9557,7 @@ star_pattern_rule(Parser *p) static pattern_ty mapping_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9756,7 +9756,7 @@ mapping_pattern_rule(Parser *p) static asdl_seq* items_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9794,7 +9794,7 @@ items_pattern_rule(Parser *p) static KeyPatternPair* key_value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9843,7 +9843,7 @@ key_value_pattern_rule(Parser *p) static expr_ty double_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9894,7 +9894,7 @@ double_star_pattern_rule(Parser *p) static pattern_ty class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10124,7 +10124,7 @@ class_pattern_rule(Parser *p) static asdl_pattern_seq* positional_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10167,7 +10167,7 @@ positional_patterns_rule(Parser *p) static asdl_seq* keyword_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10205,7 +10205,7 @@ keyword_patterns_rule(Parser *p) static KeyPatternPair* keyword_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10254,7 +10254,7 @@ keyword_pattern_rule(Parser *p) static stmt_ty type_alias_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10327,7 +10327,7 @@ type_alias_rule(Parser *p) static asdl_type_param_seq* type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10395,7 +10395,7 @@ type_params_rule(Parser *p) static asdl_type_param_seq* type_param_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10446,7 +10446,7 @@ type_param_seq_rule(Parser *p) static type_param_ty type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10615,7 +10615,7 @@ type_param_rule(Parser *p) static expr_ty type_param_bound_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10661,7 +10661,7 @@ type_param_bound_rule(Parser *p) static expr_ty type_param_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10707,7 +10707,7 @@ type_param_default_rule(Parser *p) static expr_ty type_param_starred_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10753,7 +10753,7 @@ type_param_starred_default_rule(Parser *p) static expr_ty expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10881,7 +10881,7 @@ expressions_rule(Parser *p) static expr_ty expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11035,7 +11035,7 @@ expression_rule(Parser *p) static expr_ty yield_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11141,7 +11141,7 @@ yield_expr_rule(Parser *p) static expr_ty star_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11264,7 +11264,7 @@ star_expressions_rule(Parser *p) static expr_ty star_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11352,7 +11352,7 @@ star_expression_rule(Parser *p) static asdl_expr_seq* star_named_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11399,7 +11399,7 @@ star_named_expressions_rule(Parser *p) static expr_ty star_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11482,7 +11482,7 @@ star_named_expression_rule(Parser *p) static expr_ty assignment_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11556,7 +11556,7 @@ assignment_expression_rule(Parser *p) static expr_ty named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11634,7 +11634,7 @@ named_expression_rule(Parser *p) static expr_ty disjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11722,7 +11722,7 @@ disjunction_rule(Parser *p) static expr_ty conjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11810,7 +11810,7 @@ conjunction_rule(Parser *p) static expr_ty inversion_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11898,7 +11898,7 @@ inversion_rule(Parser *p) static expr_ty comparison_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11991,7 +11991,7 @@ comparison_rule(Parser *p) static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12200,7 +12200,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12246,7 +12246,7 @@ eq_bitwise_or_rule(Parser *p) static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12292,7 +12292,7 @@ noteq_bitwise_or_rule(Parser *p) static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12338,7 +12338,7 @@ lte_bitwise_or_rule(Parser *p) static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12384,7 +12384,7 @@ lt_bitwise_or_rule(Parser *p) static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12430,7 +12430,7 @@ gte_bitwise_or_rule(Parser *p) static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12476,7 +12476,7 @@ gt_bitwise_or_rule(Parser *p) static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12525,7 +12525,7 @@ notin_bitwise_or_rule(Parser *p) static CmpopExprPair* in_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12571,7 +12571,7 @@ in_bitwise_or_rule(Parser *p) static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12620,7 +12620,7 @@ isnot_bitwise_or_rule(Parser *p) static CmpopExprPair* is_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12668,7 +12668,7 @@ static expr_ty bitwise_or_raw(Parser *); static expr_ty bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12702,7 +12702,7 @@ bitwise_or_rule(Parser *p) static expr_ty bitwise_or_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12790,7 +12790,7 @@ static expr_ty bitwise_xor_raw(Parser *); static expr_ty bitwise_xor_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12824,7 +12824,7 @@ bitwise_xor_rule(Parser *p) static expr_ty bitwise_xor_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12912,7 +12912,7 @@ static expr_ty bitwise_and_raw(Parser *); static expr_ty bitwise_and_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12946,7 +12946,7 @@ bitwise_and_rule(Parser *p) static expr_ty bitwise_and_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13034,7 +13034,7 @@ static expr_ty shift_expr_raw(Parser *); static expr_ty shift_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13068,7 +13068,7 @@ shift_expr_rule(Parser *p) static expr_ty shift_expr_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13214,7 +13214,7 @@ static expr_ty sum_raw(Parser *); static expr_ty sum_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13248,7 +13248,7 @@ sum_rule(Parser *p) static expr_ty sum_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13382,7 +13382,7 @@ static expr_ty term_raw(Parser *); static expr_ty term_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13416,7 +13416,7 @@ term_rule(Parser *p) static expr_ty term_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13677,7 +13677,7 @@ term_raw(Parser *p) static expr_ty factor_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13837,7 +13837,7 @@ factor_rule(Parser *p) static expr_ty power_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13923,7 +13923,7 @@ power_rule(Parser *p) static expr_ty await_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14018,7 +14018,7 @@ static expr_ty primary_raw(Parser *); static expr_ty primary_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -14052,7 +14052,7 @@ primary_rule(Parser *p) static expr_ty primary_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14258,7 +14258,7 @@ primary_raw(Parser *p) static expr_ty slices_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14349,7 +14349,7 @@ slices_rule(Parser *p) static expr_ty slice_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14453,7 +14453,7 @@ slice_rule(Parser *p) static expr_ty atom_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14735,7 +14735,7 @@ atom_rule(Parser *p) static expr_ty group_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14803,7 +14803,7 @@ group_rule(Parser *p) static expr_ty lambdef_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14873,7 +14873,7 @@ lambdef_rule(Parser *p) static arguments_ty lambda_params_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14935,7 +14935,7 @@ lambda_params_rule(Parser *p) static arguments_ty lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15100,7 +15100,7 @@ lambda_parameters_rule(Parser *p) static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15180,7 +15180,7 @@ lambda_slash_no_default_rule(Parser *p) static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15268,7 +15268,7 @@ lambda_slash_with_default_rule(Parser *p) static StarEtc* lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15396,7 +15396,7 @@ lambda_star_etc_rule(Parser *p) static arg_ty lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15461,7 +15461,7 @@ lambda_kwds_rule(Parser *p) static arg_ty lambda_param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15533,7 +15533,7 @@ lambda_param_no_default_rule(Parser *p) static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15611,7 +15611,7 @@ lambda_param_with_default_rule(Parser *p) static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15689,7 +15689,7 @@ lambda_param_maybe_default_rule(Parser *p) static arg_ty lambda_param_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15750,7 +15750,7 @@ lambda_param_rule(Parser *p) static expr_ty fstring_middle_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15814,7 +15814,7 @@ fstring_middle_rule(Parser *p) static expr_ty fstring_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15909,7 +15909,7 @@ fstring_replacement_field_rule(Parser *p) static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15955,7 +15955,7 @@ fstring_conversion_rule(Parser *p) static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16019,7 +16019,7 @@ fstring_full_format_spec_rule(Parser *p) static expr_ty fstring_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16081,7 +16081,7 @@ fstring_format_spec_rule(Parser *p) static expr_ty fstring_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16130,7 +16130,7 @@ fstring_rule(Parser *p) static expr_ty string_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16173,7 +16173,7 @@ string_rule(Parser *p) static expr_ty strings_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16239,7 +16239,7 @@ strings_rule(Parser *p) static expr_ty list_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16306,7 +16306,7 @@ list_rule(Parser *p) static expr_ty tuple_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16373,7 +16373,7 @@ tuple_rule(Parser *p) static expr_ty set_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16440,7 +16440,7 @@ set_rule(Parser *p) static expr_ty dict_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16532,7 +16532,7 @@ dict_rule(Parser *p) static asdl_seq* double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16579,7 +16579,7 @@ double_starred_kvpairs_rule(Parser *p) static KeyValuePair* double_starred_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16644,7 +16644,7 @@ double_starred_kvpair_rule(Parser *p) static KeyValuePair* kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16693,7 +16693,7 @@ kvpair_rule(Parser *p) static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16740,7 +16740,7 @@ for_if_clauses_rule(Parser *p) static comprehension_ty for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16886,7 +16886,7 @@ for_if_clause_rule(Parser *p) static expr_ty listcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16975,7 +16975,7 @@ listcomp_rule(Parser *p) static expr_ty setcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17066,7 +17066,7 @@ setcomp_rule(Parser *p) static expr_ty genexp_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17155,7 +17155,7 @@ genexp_rule(Parser *p) static expr_ty dictcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17244,7 +17244,7 @@ dictcomp_rule(Parser *p) static expr_ty arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17319,7 +17319,7 @@ arguments_rule(Parser *p) static expr_ty args_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17419,7 +17419,7 @@ args_rule(Parser *p) static asdl_seq* kwargs_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17509,7 +17509,7 @@ kwargs_rule(Parser *p) static expr_ty starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17611,7 +17611,7 @@ starred_expression_rule(Parser *p) static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17721,7 +17721,7 @@ kwarg_or_starred_rule(Parser *p) static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17843,7 +17843,7 @@ kwarg_or_double_starred_rule(Parser *p) static expr_ty star_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17937,7 +17937,7 @@ star_targets_rule(Parser *p) static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17984,7 +17984,7 @@ star_targets_list_seq_rule(Parser *p) static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18061,7 +18061,7 @@ star_targets_tuple_seq_rule(Parser *p) static expr_ty star_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18152,7 +18152,7 @@ star_target_rule(Parser *p) static expr_ty target_with_star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18293,7 +18293,7 @@ target_with_star_atom_rule(Parser *p) static expr_ty star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18453,7 +18453,7 @@ star_atom_rule(Parser *p) static expr_ty single_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18547,7 +18547,7 @@ single_target_rule(Parser *p) static expr_ty single_subscript_attribute_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18667,7 +18667,7 @@ static expr_ty t_primary_raw(Parser *); static expr_ty t_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -18701,7 +18701,7 @@ t_primary_rule(Parser *p) static expr_ty t_primary_raw(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18922,7 +18922,7 @@ t_primary_raw(Parser *p) static void * t_lookahead_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18998,7 +18998,7 @@ t_lookahead_rule(Parser *p) static asdl_expr_seq* del_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19048,7 +19048,7 @@ del_targets_rule(Parser *p) static expr_ty del_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19185,7 +19185,7 @@ del_target_rule(Parser *p) static expr_ty del_t_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19352,7 +19352,7 @@ del_t_atom_rule(Parser *p) static asdl_expr_seq* type_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19596,7 +19596,7 @@ type_expressions_rule(Parser *p) static Token* func_type_comment_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19689,7 +19689,7 @@ func_type_comment_rule(Parser *p) static void * invalid_arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19932,7 +19932,7 @@ invalid_arguments_rule(Parser *p) static void * invalid_kwarg_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20078,7 +20078,7 @@ expression_without_invalid_rule(Parser *p) { int _prev_call_invalid = p->call_invalid_rules; p->call_invalid_rules = 0; - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20197,7 +20197,7 @@ expression_without_invalid_rule(Parser *p) static void * invalid_legacy_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20245,7 +20245,7 @@ invalid_legacy_expression_rule(Parser *p) static void * invalid_type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20334,7 +20334,7 @@ invalid_type_param_rule(Parser *p) static void * invalid_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20480,7 +20480,7 @@ invalid_expression_rule(Parser *p) static void * invalid_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20606,7 +20606,7 @@ invalid_named_expression_rule(Parser *p) static void * invalid_assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20811,7 +20811,7 @@ invalid_assignment_rule(Parser *p) static expr_ty invalid_ann_assign_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20898,7 +20898,7 @@ invalid_ann_assign_target_rule(Parser *p) static void * invalid_del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20944,7 +20944,7 @@ invalid_del_stmt_rule(Parser *p) static void * invalid_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20992,7 +20992,7 @@ invalid_block_rule(Parser *p) static void * invalid_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21110,7 +21110,7 @@ invalid_comprehension_rule(Parser *p) static void * invalid_dict_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21171,7 +21171,7 @@ invalid_dict_comprehension_rule(Parser *p) static void * invalid_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21388,7 +21388,7 @@ invalid_parameters_rule(Parser *p) static void * invalid_default_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21437,7 +21437,7 @@ invalid_default_rule(Parser *p) static void * invalid_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21579,7 +21579,7 @@ invalid_star_etc_rule(Parser *p) static void * invalid_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21694,7 +21694,7 @@ invalid_kwds_rule(Parser *p) static void * invalid_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21762,7 +21762,7 @@ invalid_parameters_helper_rule(Parser *p) static void * invalid_lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21981,7 +21981,7 @@ invalid_lambda_parameters_rule(Parser *p) static void * invalid_lambda_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22046,7 +22046,7 @@ invalid_lambda_parameters_helper_rule(Parser *p) static void * invalid_lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22161,7 +22161,7 @@ invalid_lambda_star_etc_rule(Parser *p) static void * invalid_lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22276,7 +22276,7 @@ invalid_lambda_kwds_rule(Parser *p) static void * invalid_double_type_comments_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22331,7 +22331,7 @@ invalid_double_type_comments_rule(Parser *p) static void * invalid_with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22382,7 +22382,7 @@ invalid_with_item_rule(Parser *p) static void * invalid_for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22434,7 +22434,7 @@ invalid_for_if_clause_rule(Parser *p) static void * invalid_for_target_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22484,7 +22484,7 @@ invalid_for_target_rule(Parser *p) static void * invalid_group_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22566,7 +22566,7 @@ invalid_group_rule(Parser *p) static void * invalid_import_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22645,7 +22645,7 @@ invalid_import_rule(Parser *p) static void * invalid_import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22720,7 +22720,7 @@ invalid_import_from_targets_rule(Parser *p) static void * invalid_with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22819,7 +22819,7 @@ invalid_with_stmt_rule(Parser *p) static void * invalid_with_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22930,7 +22930,7 @@ invalid_with_stmt_indent_rule(Parser *p) static void * invalid_try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23109,7 +23109,7 @@ invalid_try_stmt_rule(Parser *p) static void * invalid_except_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23266,7 +23266,7 @@ invalid_except_stmt_rule(Parser *p) static void * invalid_except_star_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23431,7 +23431,7 @@ invalid_except_star_stmt_rule(Parser *p) static void * invalid_finally_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23484,7 +23484,7 @@ invalid_finally_stmt_rule(Parser *p) static void * invalid_except_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23575,7 +23575,7 @@ invalid_except_stmt_indent_rule(Parser *p) static void * invalid_except_star_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23638,7 +23638,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) static void * invalid_match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23724,7 +23724,7 @@ invalid_match_stmt_rule(Parser *p) static void * invalid_case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23816,7 +23816,7 @@ invalid_case_block_rule(Parser *p) static void * invalid_as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23895,7 +23895,7 @@ invalid_as_pattern_rule(Parser *p) static void * invalid_class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23945,7 +23945,7 @@ invalid_class_pattern_rule(Parser *p) static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24000,7 +24000,7 @@ invalid_class_argument_pattern_rule(Parser *p) static void * invalid_if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24086,7 +24086,7 @@ invalid_if_stmt_rule(Parser *p) static void * invalid_elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24170,7 +24170,7 @@ invalid_elif_stmt_rule(Parser *p) static void * invalid_else_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24223,7 +24223,7 @@ invalid_else_stmt_rule(Parser *p) static void * invalid_while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24309,7 +24309,7 @@ invalid_while_stmt_rule(Parser *p) static void * invalid_for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24415,7 +24415,7 @@ invalid_for_stmt_rule(Parser *p) static void * invalid_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24547,7 +24547,7 @@ invalid_def_raw_rule(Parser *p) static void * invalid_class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24650,7 +24650,7 @@ invalid_class_def_raw_rule(Parser *p) static void * invalid_double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24759,7 +24759,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) static void * invalid_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24866,7 +24866,7 @@ invalid_kvpair_rule(Parser *p) static void * invalid_starred_expression_unpacking_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24918,7 +24918,7 @@ invalid_starred_expression_unpacking_rule(Parser *p) static void * invalid_starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24972,7 +24972,7 @@ invalid_starred_expression_rule(Parser *p) static void * invalid_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25332,7 +25332,7 @@ invalid_replacement_field_rule(Parser *p) static void * invalid_conversion_character_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25403,7 +25403,7 @@ invalid_conversion_character_rule(Parser *p) static void * invalid_arithmetic_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25455,7 +25455,7 @@ invalid_arithmetic_rule(Parser *p) static void * invalid_factor_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25504,7 +25504,7 @@ invalid_factor_rule(Parser *p) static void * invalid_type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25550,7 +25550,7 @@ invalid_type_params_rule(Parser *p) static asdl_seq * _loop0_1_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25617,7 +25617,7 @@ _loop0_1_rule(Parser *p) static asdl_seq * _loop1_2_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25689,7 +25689,7 @@ _loop1_2_rule(Parser *p) static asdl_seq * _loop0_3_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25765,7 +25765,7 @@ _loop0_3_rule(Parser *p) static asdl_seq * _gather_4_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25806,7 +25806,7 @@ _gather_4_rule(Parser *p) static void * _tmp_5_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25863,7 +25863,7 @@ _tmp_5_rule(Parser *p) static void * _tmp_6_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25939,7 +25939,7 @@ _tmp_6_rule(Parser *p) static void * _tmp_7_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25996,7 +25996,7 @@ _tmp_7_rule(Parser *p) static void * _tmp_8_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26053,7 +26053,7 @@ _tmp_8_rule(Parser *p) static void * _tmp_9_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26110,7 +26110,7 @@ _tmp_9_rule(Parser *p) static void * _tmp_10_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26156,7 +26156,7 @@ _tmp_10_rule(Parser *p) static void * _tmp_11_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26224,7 +26224,7 @@ _tmp_11_rule(Parser *p) static asdl_seq * _loop1_12_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26296,7 +26296,7 @@ _loop1_12_rule(Parser *p) static void * _tmp_13_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26342,7 +26342,7 @@ _tmp_13_rule(Parser *p) static asdl_seq * _loop0_14_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26418,7 +26418,7 @@ _loop0_14_rule(Parser *p) static asdl_seq * _gather_15_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26459,7 +26459,7 @@ _gather_15_rule(Parser *p) static void * _tmp_16_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26516,7 +26516,7 @@ _tmp_16_rule(Parser *p) static void * _tmp_17_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26562,7 +26562,7 @@ _tmp_17_rule(Parser *p) static asdl_seq * _loop0_18_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26629,7 +26629,7 @@ _loop0_18_rule(Parser *p) static asdl_seq * _loop1_19_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26701,7 +26701,7 @@ _loop1_19_rule(Parser *p) static asdl_seq * _loop0_20_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26777,7 +26777,7 @@ _loop0_20_rule(Parser *p) static asdl_seq * _gather_21_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26818,7 +26818,7 @@ _gather_21_rule(Parser *p) static void * _tmp_22_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26864,7 +26864,7 @@ _tmp_22_rule(Parser *p) static asdl_seq * _loop0_23_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26940,7 +26940,7 @@ _loop0_23_rule(Parser *p) static asdl_seq * _gather_24_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26981,7 +26981,7 @@ _gather_24_rule(Parser *p) static asdl_seq * _loop1_25_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27053,7 +27053,7 @@ _loop1_25_rule(Parser *p) static void * _tmp_26_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27102,7 +27102,7 @@ _tmp_26_rule(Parser *p) static void * _tmp_27_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27148,7 +27148,7 @@ _tmp_27_rule(Parser *p) static asdl_seq * _loop0_28_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27215,7 +27215,7 @@ _loop0_28_rule(Parser *p) static asdl_seq * _loop0_29_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27282,7 +27282,7 @@ _loop0_29_rule(Parser *p) static asdl_seq * _loop1_30_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27354,7 +27354,7 @@ _loop1_30_rule(Parser *p) static asdl_seq * _loop1_31_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27426,7 +27426,7 @@ _loop1_31_rule(Parser *p) static asdl_seq * _loop0_32_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27493,7 +27493,7 @@ _loop0_32_rule(Parser *p) static asdl_seq * _loop1_33_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27565,7 +27565,7 @@ _loop1_33_rule(Parser *p) static asdl_seq * _loop0_34_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27641,7 +27641,7 @@ _loop0_34_rule(Parser *p) static asdl_seq * _gather_35_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27682,7 +27682,7 @@ _gather_35_rule(Parser *p) static void * _tmp_36_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27758,7 +27758,7 @@ _tmp_36_rule(Parser *p) static asdl_seq * _loop1_37_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27830,7 +27830,7 @@ _loop1_37_rule(Parser *p) static asdl_seq * _loop1_38_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27902,7 +27902,7 @@ _loop1_38_rule(Parser *p) static asdl_seq * _loop1_39_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27974,7 +27974,7 @@ _loop1_39_rule(Parser *p) static asdl_seq * _loop0_40_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28050,7 +28050,7 @@ _loop0_40_rule(Parser *p) static asdl_seq * _gather_41_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28091,7 +28091,7 @@ _gather_41_rule(Parser *p) static void * _tmp_42_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28148,7 +28148,7 @@ _tmp_42_rule(Parser *p) static void * _tmp_43_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28224,7 +28224,7 @@ _tmp_43_rule(Parser *p) static asdl_seq * _loop0_44_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28300,7 +28300,7 @@ _loop0_44_rule(Parser *p) static asdl_seq * _gather_45_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28341,7 +28341,7 @@ _gather_45_rule(Parser *p) static asdl_seq * _loop0_46_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28417,7 +28417,7 @@ _loop0_46_rule(Parser *p) static asdl_seq * _gather_47_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28458,7 +28458,7 @@ _gather_47_rule(Parser *p) static void * _tmp_48_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28515,7 +28515,7 @@ _tmp_48_rule(Parser *p) static asdl_seq * _loop0_49_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28591,7 +28591,7 @@ _loop0_49_rule(Parser *p) static asdl_seq * _gather_50_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28632,7 +28632,7 @@ _gather_50_rule(Parser *p) static asdl_seq * _loop0_51_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28708,7 +28708,7 @@ _loop0_51_rule(Parser *p) static asdl_seq * _gather_52_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28749,7 +28749,7 @@ _gather_52_rule(Parser *p) static asdl_seq * _loop0_53_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28825,7 +28825,7 @@ _loop0_53_rule(Parser *p) static asdl_seq * _gather_54_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28866,7 +28866,7 @@ _gather_54_rule(Parser *p) static asdl_seq * _loop1_55_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28938,7 +28938,7 @@ _loop1_55_rule(Parser *p) static asdl_seq * _loop1_56_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29010,7 +29010,7 @@ _loop1_56_rule(Parser *p) static asdl_seq * _loop0_57_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29086,7 +29086,7 @@ _loop0_57_rule(Parser *p) static asdl_seq * _gather_58_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29127,7 +29127,7 @@ _gather_58_rule(Parser *p) static asdl_seq * _loop1_59_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29199,7 +29199,7 @@ _loop1_59_rule(Parser *p) static asdl_seq * _loop1_60_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29271,7 +29271,7 @@ _loop1_60_rule(Parser *p) static asdl_seq * _loop1_61_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29343,7 +29343,7 @@ _loop1_61_rule(Parser *p) static void * _tmp_62_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29386,7 +29386,7 @@ _tmp_62_rule(Parser *p) static asdl_seq * _loop0_63_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29462,7 +29462,7 @@ _loop0_63_rule(Parser *p) static asdl_seq * _gather_64_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29503,7 +29503,7 @@ _gather_64_rule(Parser *p) static void * _tmp_65_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29549,7 +29549,7 @@ _tmp_65_rule(Parser *p) static void * _tmp_66_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29606,7 +29606,7 @@ _tmp_66_rule(Parser *p) static void * _tmp_67_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29682,7 +29682,7 @@ _tmp_67_rule(Parser *p) static void * _tmp_68_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29739,7 +29739,7 @@ _tmp_68_rule(Parser *p) static void * _tmp_69_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29834,7 +29834,7 @@ _tmp_69_rule(Parser *p) static void * _tmp_70_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29891,7 +29891,7 @@ _tmp_70_rule(Parser *p) static asdl_seq * _loop0_71_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29958,7 +29958,7 @@ _loop0_71_rule(Parser *p) static asdl_seq * _loop0_72_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30025,7 +30025,7 @@ _loop0_72_rule(Parser *p) static asdl_seq * _loop1_73_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30097,7 +30097,7 @@ _loop1_73_rule(Parser *p) static asdl_seq * _loop1_74_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30169,7 +30169,7 @@ _loop1_74_rule(Parser *p) static asdl_seq * _loop0_75_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30236,7 +30236,7 @@ _loop0_75_rule(Parser *p) static asdl_seq * _loop1_76_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30308,7 +30308,7 @@ _loop1_76_rule(Parser *p) static asdl_seq * _loop0_77_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30375,7 +30375,7 @@ _loop0_77_rule(Parser *p) static asdl_seq * _loop0_78_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30442,7 +30442,7 @@ _loop0_78_rule(Parser *p) static asdl_seq * _loop1_79_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30514,7 +30514,7 @@ _loop1_79_rule(Parser *p) static void * _tmp_80_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30563,7 +30563,7 @@ _tmp_80_rule(Parser *p) static asdl_seq * _loop0_81_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30639,7 +30639,7 @@ _loop0_81_rule(Parser *p) static asdl_seq * _gather_82_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30680,7 +30680,7 @@ _gather_82_rule(Parser *p) static asdl_seq * _loop1_83_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30752,7 +30752,7 @@ _loop1_83_rule(Parser *p) static asdl_seq * _loop0_84_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30819,7 +30819,7 @@ _loop0_84_rule(Parser *p) static void * _tmp_85_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30878,7 +30878,7 @@ _tmp_85_rule(Parser *p) static asdl_seq * _loop0_86_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30955,7 +30955,7 @@ _loop0_86_rule(Parser *p) static asdl_seq * _gather_87_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30996,7 +30996,7 @@ _gather_87_rule(Parser *p) static void * _tmp_88_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31042,7 +31042,7 @@ _tmp_88_rule(Parser *p) static asdl_seq * _loop0_89_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31118,7 +31118,7 @@ _loop0_89_rule(Parser *p) static asdl_seq * _gather_90_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31159,7 +31159,7 @@ _gather_90_rule(Parser *p) static asdl_seq * _loop0_91_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31235,7 +31235,7 @@ _loop0_91_rule(Parser *p) static asdl_seq * _gather_92_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31276,7 +31276,7 @@ _gather_92_rule(Parser *p) static asdl_seq * _loop0_93_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31343,7 +31343,7 @@ _loop0_93_rule(Parser *p) static asdl_seq * _loop0_94_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31419,7 +31419,7 @@ _loop0_94_rule(Parser *p) static asdl_seq * _gather_95_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31460,7 +31460,7 @@ _gather_95_rule(Parser *p) static asdl_seq * _loop1_96_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31532,7 +31532,7 @@ _loop1_96_rule(Parser *p) static void * _tmp_97_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31572,7 +31572,7 @@ _tmp_97_rule(Parser *p) static asdl_seq * _loop0_98_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31648,7 +31648,7 @@ _loop0_98_rule(Parser *p) static asdl_seq * _gather_99_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31689,7 +31689,7 @@ _gather_99_rule(Parser *p) static asdl_seq * _loop0_100_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31765,7 +31765,7 @@ _loop0_100_rule(Parser *p) static asdl_seq * _gather_101_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31806,7 +31806,7 @@ _gather_101_rule(Parser *p) static void * _tmp_102_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31849,7 +31849,7 @@ _tmp_102_rule(Parser *p) static void * _tmp_103_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31906,7 +31906,7 @@ _tmp_103_rule(Parser *p) static asdl_seq * _loop0_104_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31982,7 +31982,7 @@ _loop0_104_rule(Parser *p) static asdl_seq * _gather_105_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32023,7 +32023,7 @@ _gather_105_rule(Parser *p) static void * _tmp_106_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32083,7 +32083,7 @@ _tmp_106_rule(Parser *p) static void * _tmp_107_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32124,7 +32124,7 @@ _tmp_107_rule(Parser *p) static void * _tmp_108_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32181,7 +32181,7 @@ _tmp_108_rule(Parser *p) static void * _tmp_109_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32257,7 +32257,7 @@ _tmp_109_rule(Parser *p) static void * _tmp_110_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32298,7 +32298,7 @@ _tmp_110_rule(Parser *p) static asdl_seq * _loop1_111_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32370,7 +32370,7 @@ _loop1_111_rule(Parser *p) static void * _tmp_112_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32430,7 +32430,7 @@ _tmp_112_rule(Parser *p) static void * _tmp_113_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32487,7 +32487,7 @@ _tmp_113_rule(Parser *p) static void * _tmp_114_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32544,7 +32544,7 @@ _tmp_114_rule(Parser *p) static void * _tmp_115_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32677,7 +32677,7 @@ _tmp_115_rule(Parser *p) static asdl_seq * _loop0_116_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32744,7 +32744,7 @@ _loop0_116_rule(Parser *p) static asdl_seq * _loop0_117_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32811,7 +32811,7 @@ _loop0_117_rule(Parser *p) static void * _tmp_118_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32887,7 +32887,7 @@ _tmp_118_rule(Parser *p) static void * _tmp_119_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32944,7 +32944,7 @@ _tmp_119_rule(Parser *p) static void * _tmp_120_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33001,7 +33001,7 @@ _tmp_120_rule(Parser *p) static void * _tmp_121_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33058,7 +33058,7 @@ _tmp_121_rule(Parser *p) static void * _tmp_122_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33115,7 +33115,7 @@ _tmp_122_rule(Parser *p) static void * _tmp_123_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33175,7 +33175,7 @@ _tmp_123_rule(Parser *p) static void * _tmp_124_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33232,7 +33232,7 @@ _tmp_124_rule(Parser *p) static void * _tmp_125_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33308,7 +33308,7 @@ _tmp_125_rule(Parser *p) static void * _tmp_126_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33365,7 +33365,7 @@ _tmp_126_rule(Parser *p) static asdl_seq * _loop0_127_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33441,7 +33441,7 @@ _loop0_127_rule(Parser *p) static asdl_seq * _gather_128_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33482,7 +33482,7 @@ _gather_128_rule(Parser *p) static void * _tmp_129_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33539,7 +33539,7 @@ _tmp_129_rule(Parser *p) static void * _tmp_130_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33599,7 +33599,7 @@ _tmp_130_rule(Parser *p) static void * _tmp_131_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33656,7 +33656,7 @@ _tmp_131_rule(Parser *p) static void * _tmp_132_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33701,7 +33701,7 @@ _tmp_132_rule(Parser *p) static asdl_seq * _loop0_133_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33777,7 +33777,7 @@ _loop0_133_rule(Parser *p) static asdl_seq * _gather_134_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33818,7 +33818,7 @@ _gather_134_rule(Parser *p) static asdl_seq * _loop0_135_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33894,7 +33894,7 @@ _loop0_135_rule(Parser *p) static asdl_seq * _gather_136_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33935,7 +33935,7 @@ _gather_136_rule(Parser *p) static asdl_seq * _loop0_137_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34011,7 +34011,7 @@ _loop0_137_rule(Parser *p) static asdl_seq * _gather_138_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34052,7 +34052,7 @@ _gather_138_rule(Parser *p) static void * _tmp_139_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34109,7 +34109,7 @@ _tmp_139_rule(Parser *p) static asdl_seq * _loop0_140_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34176,7 +34176,7 @@ _loop0_140_rule(Parser *p) static void * _tmp_141_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34218,7 +34218,7 @@ _tmp_141_rule(Parser *p) static void * _tmp_142_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34275,7 +34275,7 @@ _tmp_142_rule(Parser *p) static void * _tmp_143_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34316,7 +34316,7 @@ _tmp_143_rule(Parser *p) static void * _tmp_144_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34373,7 +34373,7 @@ _tmp_144_rule(Parser *p) static void * _tmp_145_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34468,7 +34468,7 @@ _tmp_145_rule(Parser *p) static void * _tmp_146_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34544,7 +34544,7 @@ _tmp_146_rule(Parser *p) static void * _tmp_147_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34585,7 +34585,7 @@ _tmp_147_rule(Parser *p) static void * _tmp_148_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34642,7 +34642,7 @@ _tmp_148_rule(Parser *p) static void * _tmp_149_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34794,7 +34794,7 @@ _tmp_149_rule(Parser *p) static void * _tmp_150_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34870,7 +34870,7 @@ _tmp_150_rule(Parser *p) static void * _tmp_151_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34916,7 +34916,7 @@ _tmp_151_rule(Parser *p) static void * _tmp_152_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34973,7 +34973,7 @@ _tmp_152_rule(Parser *p) static void * _tmp_153_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35022,7 +35022,7 @@ _tmp_153_rule(Parser *p) static void * _tmp_154_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35068,7 +35068,7 @@ _tmp_154_rule(Parser *p) static void * _tmp_155_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35114,7 +35114,7 @@ _tmp_155_rule(Parser *p) static void * _tmp_156_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35160,7 +35160,7 @@ _tmp_156_rule(Parser *p) static void * _tmp_157_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35217,7 +35217,7 @@ _tmp_157_rule(Parser *p) static void * _tmp_158_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35274,7 +35274,7 @@ _tmp_158_rule(Parser *p) static void * _tmp_159_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35320,7 +35320,7 @@ _tmp_159_rule(Parser *p) static void * _tmp_160_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35379,7 +35379,7 @@ _tmp_160_rule(Parser *p) static void * _tmp_161_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35426,7 +35426,7 @@ _tmp_161_rule(Parser *p) static void * _tmp_162_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35470,7 +35470,7 @@ _tmp_162_rule(Parser *p) static void * _tmp_163_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35510,7 +35510,7 @@ _tmp_163_rule(Parser *p) static void * _tmp_164_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35550,7 +35550,7 @@ _tmp_164_rule(Parser *p) static void * _tmp_165_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35607,7 +35607,7 @@ _tmp_165_rule(Parser *p) static void * _tmp_166_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35664,7 +35664,7 @@ _tmp_166_rule(Parser *p) static asdl_seq * _loop0_167_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35731,7 +35731,7 @@ _loop0_167_rule(Parser *p) static void * _tmp_168_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35773,7 +35773,7 @@ _tmp_168_rule(Parser *p) static void * _tmp_169_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35815,7 +35815,7 @@ _tmp_169_rule(Parser *p) static void * _tmp_170_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35856,7 +35856,7 @@ _tmp_170_rule(Parser *p) static void * _tmp_171_rule(Parser *p) { - if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index b5e5b020a3bf34..fe2b23461cfe0d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3970,7 +3970,7 @@ dummy_func( EXIT_IF(!PyCFunction_CheckExact(callable_o)); EXIT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; @@ -4163,7 +4163,7 @@ dummy_func( PyMethodDef *meth = method->d_method; EXIT_IF(meth->ml_flags != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); _PyStackRef arg_stackref = arguments[1]; _PyStackRef self_stackref = arguments[0]; EXIT_IF(!Py_IS_TYPE(PyStackRef_AsPyObjectBorrow(self_stackref), @@ -4244,7 +4244,7 @@ dummy_func( EXIT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); EXIT_IF(meth->ml_flags != METH_NOARGS); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(_Py_ReachedRecursionLimit(tstate, 0)); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); diff --git a/Python/ceval.c b/Python/ceval.c index 958931437cecce..8078470e0ecd6b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -305,9 +305,17 @@ Py_SetRecursionLimit(int new_limit) } int -Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) +_Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count) { - return _Py_ReachedRecursionLimit(tstate, margin_count); + char here; + uintptr_t here_addr = (uintptr_t)&here; + if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { + return 0; + } + if (tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionLimits(tstate); + } + return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } void diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9f0a9f279640ae..9520bc854dc831 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5426,7 +5426,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -5812,7 +5812,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -5982,7 +5982,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 029146dfaec16d..00dff9fedc0502 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2222,7 +2222,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3598,7 +3598,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3694,7 +3694,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (_Py_ReachedRecursionLimit(tstate, 0)) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index c46fbbad3d9eb0..2be85a163b4043 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -380,7 +380,7 @@ def __init__( self.cleanup_statements: List[str] = [] def add_level(self) -> None: - self.print("if (p->level++ == MAXSTACK || Py_ReachedRecursionLimit(PyThreadState_Get(), 1)) {") + self.print("if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) {") with self.indent(): self.print("_Pypegen_stack_overflow(p);") self.print("}") From b067e3e33f8059a2cde8c6fd0c762e586186f016 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 17 Feb 2025 17:38:18 +0000 Subject: [PATCH 36/41] Move new fields to _PyThreadStateImpl to avoid any potential API breakage --- Include/cpython/pystate.h | 7 +++--- Include/internal/pycore_ceval.h | 10 +++++---- Include/internal/pycore_tstate.h | 5 +++++ Modules/_testinternalcapi.c | 3 ++- Python/ceval.c | 38 ++++++++++++++++++-------------- Python/pystate.c | 9 ++++---- 6 files changed, 42 insertions(+), 30 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index a74934fb6d9cf4..d138c8ca4f1330 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -112,10 +112,7 @@ struct _ts { int py_recursion_remaining; int py_recursion_limit; - // These are addresses, but we need to convert to ints to avoid UB. - uintptr_t c_stack_top; - uintptr_t c_stack_soft_limit; - uintptr_t c_stack_hard_limit; + int c_recursion_remaining; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. @@ -205,6 +202,8 @@ struct _ts { PyObject *threading_local_sentinel; }; +# define Py_C_RECURSION_LIMIT 5000 + /* other API */ /* Similar to PyThreadState_Get(), but don't issue a fatal error diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 4352be994781b4..f9e6a99ce29d2b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -196,7 +196,8 @@ extern void _PyEval_DeactivateOpCache(void); static inline int _Py_MakeRecCheck(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - return here_addr < tstate->c_stack_soft_limit; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + return here_addr < _tstate->c_stack_soft_limit; } // Export for '_json' shared extension, used via _Py_EnterRecursiveCall() @@ -227,13 +228,14 @@ PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate); static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - if (here_addr > tstate->c_stack_soft_limit) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr > _tstate->c_stack_soft_limit) { return 0; } - if (tstate->c_stack_hard_limit == 0) { + if (_tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); } - return here_addr <= tstate->c_stack_soft_limit; + return here_addr <= _tstate->c_stack_soft_limit; } static inline void _Py_LeaveRecursiveCall(void) { diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index 932623f54c4260..624b29e32ed463 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -21,6 +21,11 @@ typedef struct _PyThreadStateImpl { // semi-public fields are in PyThreadState. PyThreadState base; + // These are addresses, but we need to convert to ints to avoid UB. + uintptr_t c_stack_top; + uintptr_t c_stack_soft_limit; + uintptr_t c_stack_hard_limit; + PyObject *asyncio_running_loop; // Strong reference PyObject *asyncio_running_task; // Strong reference diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 5bfc7d1fc12087..67cd96ac55e779 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -117,7 +117,8 @@ get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) PyThreadState *tstate = _PyThreadState_GET(); char here; uintptr_t here_addr = (uintptr_t)&here; - int remaining = (int)((here_addr - tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + int remaining = (int)((here_addr - _tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); return PyLong_FromLong(remaining); } diff --git a/Python/ceval.c b/Python/ceval.c index 8078470e0ecd6b..dacaef4ab4660b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -309,13 +309,14 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count) { char here; uintptr_t here_addr = (uintptr_t)&here; - if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr > _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { return 0; } - if (tstate->c_stack_hard_limit == 0) { + if (_tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); } - return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; + return here_addr <= _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; } void @@ -323,7 +324,8 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) { char here; uintptr_t here_addr = (uintptr_t)&here; - if (here_addr < tstate->c_stack_hard_limit) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr < _tstate->c_stack_hard_limit) { Py_FatalError("Unchecked stack overflow."); } } @@ -350,20 +352,21 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) void _Py_InitializeRecursionLimits(PyThreadState *tstate) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; #ifdef WIN32 ULONG_PTR low, high; GetCurrentThreadStackLimits(&low, &high); - tstate->c_stack_top = (uintptr_t)high; + _tstate->c_stack_top = (uintptr_t)high; ULONG guarantee = 0; SetThreadStackGuarantee(&guarantee); - tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; - tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; + _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; + _tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else char here; uintptr_t here_addr = (uintptr_t)&here; - tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); - tstate->c_stack_soft_limit = tstate->c_stack_top - Py_C_STACK_SIZE; - tstate->c_stack_hard_limit = tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); + _tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); + _tstate->c_stack_soft_limit = _tstate->c_stack_top - Py_C_STACK_SIZE; + _tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); #endif } @@ -372,19 +375,20 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; char here; uintptr_t here_addr = (uintptr_t)&here; - assert(tstate->c_stack_soft_limit != 0); - if (tstate->c_stack_hard_limit == 0) { + assert(_tstate->c_stack_soft_limit != 0); + if (_tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); } - if (here_addr >= tstate->c_stack_soft_limit) { + if (here_addr >= _tstate->c_stack_soft_limit) { return 0; } - assert(tstate->c_stack_hard_limit != 0); - if (here_addr < tstate->c_stack_hard_limit) { + assert(_tstate->c_stack_hard_limit != 0); + if (here_addr < _tstate->c_stack_hard_limit) { /* Overflowing while handling an overflow. Give up. */ - int kbytes_used = (int)(tstate->c_stack_top - here_addr)/1024; + int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024; char buffer[80]; snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where); Py_FatalError(buffer); @@ -393,7 +397,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) return 0; } else { - int kbytes_used = (int)(tstate->c_stack_top - here_addr)/1024; + int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024; tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, "Stack overflow (used %d kB)%s", diff --git a/Python/pystate.c b/Python/pystate.c index 69558ac5b74a97..4caef2260ae58e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1492,10 +1492,7 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->py_recursion_limit = interp->ceval.recursion_limit; tstate->py_recursion_remaining = interp->ceval.recursion_limit; - tstate->c_stack_soft_limit = UINTPTR_MAX; - tstate->c_stack_top = 0; - tstate->c_stack_hard_limit = 0; - + tstate->c_recursion_remaining = 2; tstate->exc_info = &tstate->exc_state; // PyGILState_Release must not try to delete this thread state. @@ -1510,6 +1507,10 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->previous_executor = NULL; tstate->dict_global_version = 0; + _tstate->c_stack_soft_limit = UINTPTR_MAX; + _tstate->c_stack_top = 0; + _tstate->c_stack_hard_limit = 0; + _tstate->asyncio_running_loop = NULL; _tstate->asyncio_running_task = NULL; From b0e695f516aab9a520e14d7bd1b8cf1be1286a62 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 17 Feb 2025 17:42:12 +0000 Subject: [PATCH 37/41] Fix missing cast --- Include/cpython/pystate.h | 2 +- Python/pythonrun.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index d138c8ca4f1330..e0d2ac9bf93ad8 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -112,7 +112,7 @@ struct _ts { int py_recursion_remaining; int py_recursion_limit; - int c_recursion_remaining; + int c_recursion_remaining; /* Retained for backwards compatibility. Do not use */ int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 34dce2f89d1f41..c1382a753fa904 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1543,10 +1543,11 @@ int PyOS_CheckStack(void) char here; uintptr_t here_addr = (uintptr_t)&here; PyThreadState *tstate = _PyThreadState_GET(); - if (tstate->c_stack_hard_limit == 0) { + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (_tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); } - if (here_addr >= tstate->c_stack_soft_limit) { + if (here_addr >= _tstate->c_stack_soft_limit) { return 0; } else { From c4cd68f4d47d98f965a5734a3f1906c351b83bb3 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 17 Feb 2025 17:51:43 +0000 Subject: [PATCH 38/41] yet another missing _ --- Python/ceval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index dacaef4ab4660b..562c9706b64fb9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -360,7 +360,7 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) ULONG guarantee = 0; SetThreadStackGuarantee(&guarantee); _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; - _tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; + _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else char here; uintptr_t here_addr = (uintptr_t)&here; From 9654790e3373b679c3b94a3925b9fc3e84734d8b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 18 Feb 2025 14:38:31 +0000 Subject: [PATCH 39/41] Tidy up a bit --- Doc/c-api/exceptions.rst | 6 +----- Include/pythonrun.h | 2 -- Python/ceval.c | 2 -- Python/pythonrun.c | 22 +++------------------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c1f0bd750361d6..19f6baf9b3dc90 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -921,11 +921,7 @@ because the :ref:`call protocol ` takes care of recursion handling. Marks a point where a recursive C-level call is about to be performed. - If :c:macro:`!USE_STACKCHECK` is defined, this function checks if the OS - stack overflowed using :c:func:`PyOS_CheckStack`. If this is the case, it - sets a :exc:`MemoryError` and returns a nonzero value. - - The function then checks if the recursion limit is reached. If this is the + The function then checks if the stack limit is reached. If this is the case, a :exc:`RecursionError` is set and a nonzero value is returned. Otherwise, zero is returned. diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 0a7255c7cefb81..03b713beb8155f 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -33,8 +33,6 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); #define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *)) #if defined(WIN32) -/* Enable stack checking under Microsoft C */ -// When changing the platforms, ensure PyOS_CheckStack() docs are still correct #define USE_STACKCHECK #endif diff --git a/Python/ceval.c b/Python/ceval.c index 562c9706b64fb9..569f716deccc54 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -337,13 +337,11 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #elif defined(__ANDROID__) # define Py_C_STACK_SIZE 1200000 #elif defined(__sparc__) - // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) /* Web assembly has two stacks, so this isn't really the stack depth */ # define Py_C_STACK_SIZE 100000 #elif defined(__hppa__) || defined(__powerpc64__) - // test_descr crashed with >8000 but let's keep a margin of error. # define Py_C_STACK_SIZE 2000000 #else # define Py_C_STACK_SIZE 5000000 diff --git a/Python/pythonrun.c b/Python/pythonrun.c index c1382a753fa904..88788e9aa82510 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1528,37 +1528,21 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp } #if defined(USE_STACKCHECK) -#if defined(WIN32) && defined(_MSC_VER) -/* Stack checking for Microsoft C */ - -#include -#include +/* Stack checking */ /* * Return non-zero when we run out of memory on the stack; zero otherwise. */ int PyOS_CheckStack(void) { - char here; - uintptr_t here_addr = (uintptr_t)&here; PyThreadState *tstate = _PyThreadState_GET(); - _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; - if (_tstate->c_stack_hard_limit == 0) { - _Py_InitializeRecursionLimits(tstate); - } - if (here_addr >= _tstate->c_stack_soft_limit) { - return 0; - } - else { + if (_Py_ReachedRecursionLimit(tstate)) { return -1; } + return 0; } -#endif /* WIN32 && _MSC_VER */ - -/* Alternate implementations can be added here... */ - #endif /* USE_STACKCHECK */ /* Deprecated C API functions still provided for binary compatibility */ From 2cef96f623026f1f57d5ad1471ecee323dc03db8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 18 Feb 2025 14:51:26 +0000 Subject: [PATCH 40/41] Restore use of exceeds_recursion_limit --- Lib/test/mapping_tests.py | 8 ++++---- Lib/test/support/__init__.py | 8 +++++++- Lib/test/test_call.py | 2 +- Lib/test/test_collections.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_dictviews.py | 4 ++-- Lib/test/test_exception_group.py | 4 ++-- Lib/test/test_exceptions.py | 2 +- Lib/test/test_functools.py | 2 +- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 9fb0a7de1982f8..1a0caa00fcd49e 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow +from test import support class BasicTestMappingProtocol(unittest.TestCase): @@ -622,11 +622,11 @@ def __repr__(self): d = self._full_mapping({1: BadRepr()}) self.assertRaises(Exc, repr, d) - @skip_wasi_stack_overflow() - @skip_emscripten_stack_overflow() + @support.skip_wasi_stack_overflow() + @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = self._empty_mapping() - for i in range(100_000): + for i in range(support.exceeds_recursion_limit()): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 628c9438910ca2..88ac5a56ee928e 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -56,7 +56,7 @@ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", - "Py_DEBUG", "skip_on_s390x", + "Py_DEBUG", "exceeds_recursion_limit", "skip_on_s390x", "requires_jit_enabled", "requires_jit_disabled", "force_not_colorized", @@ -2625,6 +2625,12 @@ def adjust_int_max_str_digits(max_digits): finally: sys.set_int_max_str_digits(current) + +def exceeds_recursion_limit(): + """For recursion tests, easily exceeds default recursion limit.""" + return 100_000 + + # Windows doesn't have os.uname() but it doesn't support s390x. is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x' skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x') diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index a9a842ab82b2d0..95eaf810eea091 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,6 +1,6 @@ import unittest from test.support import (cpython_only, is_wasi, requires_limited_api, Py_DEBUG, - set_recursion_limit, skip_on_s390x, skip_emscripten_stack_overflow, + set_recursion_limit, skip_on_s390x, exceeds_recursion_limit, skip_emscripten_stack_overflow, skip_if_sanitizer, import_helper) try: import _testcapi diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 999449c78f0df8..1e93530398be79 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -542,7 +542,7 @@ def test_odd_sizes(self): self.assertEqual(Dot(1)._replace(d=999), (999,)) self.assertEqual(Dot(1)._fields, ('d',)) - n = 100_000 + n = support.exceeds_recursion_limit() names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index a22394139d25a2..7756c1f995cf2c 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -598,7 +598,7 @@ def __repr__(self): @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = {} - for i in range(100_000): + for i in range(support.exceeds_recursion_limit()): d = {1: d} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 11be71d044e3c4..691fc5dfb5e8ab 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -2,7 +2,7 @@ import copy import pickle import unittest -from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow, exceeds_recursion_limit class DictSetTest(unittest.TestCase): @@ -281,7 +281,7 @@ def test_recursive_repr(self): @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} - for i in range(100_000): + for i in range(exceeds_recursion_limit()): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index c9dbf94ca16ce5..92bbf7917642b0 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,7 +1,7 @@ import collections.abc import types import unittest -from test.support import skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow, exceeds_recursion_limit class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): @@ -460,7 +460,7 @@ def test_basics_split_by_predicate__match(self): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(100_000): + for i in range(exceeds_recursion_limit()): e = ExceptionGroup('eg', [e]) return e diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index ae85d2884d5b1f..bd1053b67fde58 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1451,7 +1451,7 @@ def gen(): next(generator) recursionlimit = sys.getrecursionlimit() try: - recurse(100_000) + recurse(support.exceeds_recursion_limit()) finally: sys.setrecursionlimit(recursionlimit) print('Done.') diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 77ff14c29dac77..d494a162fd7461 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2082,7 +2082,7 @@ def fib(n): fib.cache_clear() with support.infinite_recursion(): with self.assertRaises(RecursionError): - fib(100_000) + fib(support.exceeds_recursion_limit()) @py_functools.lru_cache() From c5d8a401bb90e70bd447a82859385d633d02982e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 18 Feb 2025 15:00:21 +0000 Subject: [PATCH 41/41] Address remaining review comments --- Python/pythonrun.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 88788e9aa82510..36390dac6152f6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1534,13 +1534,11 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp /* * Return non-zero when we run out of memory on the stack; zero otherwise. */ -int PyOS_CheckStack(void) +int +PyOS_CheckStack(void) { PyThreadState *tstate = _PyThreadState_GET(); - if (_Py_ReachedRecursionLimit(tstate)) { - return -1; - } - return 0; + return _Py_ReachedRecursionLimit(tstate); } #endif /* USE_STACKCHECK */