diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 48 | ||||
-rw-r--r-- | Python/errors.c | 2 |
2 files changed, 29 insertions, 21 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index e6b7424..59054a6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -510,6 +510,29 @@ Py_SetRecursionLimit(int new_limit) recursion_limit = new_limit; } +int +_Py_CheckRecursiveCall(char *where) +{ + PyThreadState *tstate = PyThreadState_GET(); + +#ifdef USE_STACKCHECK + if (PyOS_CheckStack()) { + --tstate->recursion_depth; + PyErr_SetString(PyExc_MemoryError, "Stack overflow"); + return -1; + } +#endif + if (tstate->recursion_depth > recursion_limit) { + --tstate->recursion_depth; + PyErr_Format(PyExc_RuntimeError, + "maximum recursion depth exceeded%s", + where); + return -1; + } + return 0; +} + + /* Status code for main loop (reason for stack unwind) */ enum why_code { @@ -674,21 +697,9 @@ eval_frame(PyFrameObject *f) if (f == NULL) return NULL; -#ifdef USE_STACKCHECK - if (tstate->recursion_depth%10 == 0 && PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "Stack overflow"); - return NULL; - } -#endif - /* push frame */ - if (++tstate->recursion_depth > recursion_limit) { - --tstate->recursion_depth; - PyErr_SetString(PyExc_RuntimeError, - "maximum recursion depth exceeded"); - tstate->frame = f->f_back; + if (Py_EnterRecursiveCall("")) return NULL; - } tstate->frame = f; @@ -710,9 +721,7 @@ eval_frame(PyFrameObject *f) if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, f, PyTrace_CALL, Py_None)) { /* Trace function raised an error */ - --tstate->recursion_depth; - tstate->frame = f->f_back; - return NULL; + goto exit_eval_frame; } } if (tstate->c_profilefunc != NULL) { @@ -722,9 +731,7 @@ eval_frame(PyFrameObject *f) tstate->c_profileobj, f, PyTrace_CALL, Py_None)) { /* Profile function raised an error */ - --tstate->recursion_depth; - tstate->frame = f->f_back; - return NULL; + goto exit_eval_frame; } } } @@ -2428,7 +2435,8 @@ eval_frame(PyFrameObject *f) reset_exc_info(tstate); /* pop frame */ - --tstate->recursion_depth; + exit_eval_frame: + Py_LeaveRecursiveCall(); tstate->frame = f->f_back; return retval; diff --git a/Python/errors.c b/Python/errors.c index 1788cdd..4d88d2d 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -599,7 +599,7 @@ PyErr_WriteUnraisable(PyObject *obj) Py_XDECREF(tb); } -extern PyObject *PyModule_GetWarningsModule(); +extern PyObject *PyModule_GetWarningsModule(void); /* Function to issue a warning message; may raise an exception. */ int |