diff options
author | Armin Rigo <arigo@tunes.org> | 2003-10-28 12:05:48 (GMT) |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2003-10-28 12:05:48 (GMT) |
commit | 2b3eb4062c5e50abf854f7e68038243ca7c07217 (patch) | |
tree | fc5a73861c6e4feb4f4bc497165fa28d9c81d79f /Python | |
parent | 0e4f76405d79e95abfdda21b9dfc10c7f32340e8 (diff) | |
download | cpython-2b3eb4062c5e50abf854f7e68038243ca7c07217.zip cpython-2b3eb4062c5e50abf854f7e68038243ca7c07217.tar.gz cpython-2b3eb4062c5e50abf854f7e68038243ca7c07217.tar.bz2 |
Deleting cyclic object comparison.
SF patch 825639
http://mail.python.org/pipermail/python-dev/2003-October/039445.html
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index e6b7424..fe8aca5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -497,6 +497,7 @@ Py_MakePendingCalls(void) /* The interpreter's recursion limit */ static int recursion_limit = 1000; +int _Py_CheckRecursionLimit = 1000; int Py_GetRecursionLimit(void) @@ -508,8 +509,38 @@ void Py_SetRecursionLimit(int new_limit) { recursion_limit = new_limit; + _Py_CheckRecursionLimit = recursion_limit; } +/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() + if the recursion_depth reaches _Py_CheckRecursionLimit. + If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit + to guarantee that _Py_CheckRecursiveCall() is regularly called. + Without USE_STACKCHECK, there is no need for this. */ +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; + } + _Py_CheckRecursionLimit = recursion_limit; + return 0; +} + + /* Status code for main loop (reason for stack unwind) */ enum why_code { @@ -674,21 +705,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 +729,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 +739,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 +2443,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; |