diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-08-31 19:23:01 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-08-31 19:23:01 (GMT) |
commit | ee5adfbae6df9a4ae8d73bccc4f3a55b7f382d11 (patch) | |
tree | ecbac10d7a319d2d655ad1ddffcfdb9b75c9c70b /Python | |
parent | c88b99ce060e37a9098708483b7e3c8b5db87fbd (diff) | |
download | cpython-ee5adfbae6df9a4ae8d73bccc4f3a55b7f382d11.zip cpython-ee5adfbae6df9a4ae8d73bccc4f3a55b7f382d11.tar.gz cpython-ee5adfbae6df9a4ae8d73bccc4f3a55b7f382d11.tar.bz2 |
add user-modifiable recursion_limit
ceval.c:
define recurion_limit (static), default value is 2500
define Py_GetRecursionLimit and Py_SetRecursionLimit
raise RuntimeError if limit is exceeded
PC/config.h:
remove plat-specific definition
sysmodule.c:
add sys.(get|set)recursionlimit
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 20 | ||||
-rw-r--r-- | Python/sysmodule.c | 54 |
2 files changed, 66 insertions, 8 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index b399b63..7e11250 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -298,6 +298,20 @@ Py_MakePendingCalls(void) } +/* The interpreter's recursion limit */ + +static int recursion_limit = 2500; + +int Py_GetRecursionLimit(void) +{ + return recursion_limit; +} + +void Py_SetRecursionLimit(int new_limit) +{ + recursion_limit = new_limit; +} + /* Status code for main loop (reason for stack unwind) */ enum why_code { @@ -326,10 +340,6 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) /* Interpreter main loop */ -#ifndef MAX_RECURSION_DEPTH -#define MAX_RECURSION_DEPTH 10000 -#endif - static PyObject * eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, @@ -565,7 +575,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, } } - if (++tstate->recursion_depth > MAX_RECURSION_DEPTH) { + if (++tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; PyErr_SetString(PyExc_RuntimeError, "Maximum recursion depth exceeded"); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index d500a36..31d7abf 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -199,6 +199,45 @@ static char setcheckinterval_doc[] = Tell the Python interpreter to check for asynchronous events every\n\ n instructions. This also affects how often thread switches occur."; +static PyObject * +sys_setrecursionlimit(PyObject *self, PyObject *args) +{ + int new_limit; + if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit)) + return NULL; + if (new_limit <= 0) { + PyErr_SetString(PyExc_ValueError, + "recursion limit must be positive"); + return NULL; + } + Py_SetRecursionLimit(new_limit); + Py_INCREF(Py_None); + return Py_None; +} + +static char setrecursionlimit_doc[] = +"setrecursionlimit(n)\n\ +\n\ +Set the maximum depth of the Python interpreter stack to n. This\n\ +limit prevents infinite recursion from causing an overflow of the C\n\ +stack and crashing Python. The highest possible limit is platform-\n\ +dependent."; + +static PyObject * +sys_getrecursionlimit(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getrecursionlimit")) + return NULL; + return PyInt_FromLong(Py_GetRecursionLimit()); +} + +static char getrecursionlimit_doc[] = +"getrecursionlimit()\n\ +\n\ +Return the current value of the recursion limit, the maximum depth\n\ +of the Python interpreter stack. This limit prevents infinite\n\ +recursion from causing an overflow of the C stack and crashing Python."; + #ifdef USE_MALLOPT /* Link with -lmalloc (or -lmpc) on an SGI */ #include <malloc.h> @@ -268,7 +307,8 @@ static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ {"exc_info", sys_exc_info, 1, exc_info_doc}, {"exit", sys_exit, 0, exit_doc}, - {"getdefaultencoding", sys_getdefaultencoding, 1, getdefaultencoding_doc}, + {"getdefaultencoding", sys_getdefaultencoding, 1, + getdefaultencoding_doc}, #ifdef COUNT_ALLOCS {"getcounts", sys_getcounts, 1}, #endif @@ -280,12 +320,18 @@ static PyMethodDef sys_methods[] = { {"gettotalrefcount", sys_gettotalrefcount, 1}, #endif {"getrefcount", sys_getrefcount, 1, getrefcount_doc}, + {"getrecursionlimit", sys_getrecursionlimit, 1, + getrecursionlimit_doc}, #ifdef USE_MALLOPT {"mdebug", sys_mdebug, 1}, #endif - {"setdefaultencoding", sys_setdefaultencoding, 1, setdefaultencoding_doc}, - {"setcheckinterval", sys_setcheckinterval, 1, setcheckinterval_doc}, + {"setdefaultencoding", sys_setdefaultencoding, 1, + setdefaultencoding_doc}, + {"setcheckinterval", sys_setcheckinterval, 1, + setcheckinterval_doc}, {"setprofile", sys_setprofile, 0, setprofile_doc}, + {"setrecursionlimit", sys_setrecursionlimit, 1, + setrecursionlimit_doc}, {"settrace", sys_settrace, 0, settrace_doc}, {NULL, NULL} /* sentinel */ }; @@ -376,8 +422,10 @@ Functions:\n\ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ getrefcount() -- return the reference count for an object (plus one :-)\n\ +getrecursionlimit() -- return the max recursion depth for the interpreter\n\ setcheckinterval() -- control how often the interpreter checks for events\n\ setprofile() -- set the global profiling function\n\ +setrecursionlimit() -- set the max recursion depth for the interpreter\n\ settrace() -- set the global debug tracing function\n\ " #endif |