summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1996-07-30 16:49:37 (GMT)
committerGuido van Rossum <guido@python.org>1996-07-30 16:49:37 (GMT)
commit8861b74445560c078d11ff6800a3ce20a869ea93 (patch)
tree67426f7e9173e2c4a0f0040f1f97ed7c3270dbc2 /Python/ceval.c
parent3ecebf17324b138a9d10ad429c0ad55ab5de1682 (diff)
downloadcpython-8861b74445560c078d11ff6800a3ce20a869ea93.zip
cpython-8861b74445560c078d11ff6800a3ce20a869ea93.tar.gz
cpython-8861b74445560c078d11ff6800a3ce20a869ea93.tar.bz2
Changes for slice and ellipses
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index ec26792..d526095 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -87,6 +87,7 @@ static object *apply_subscript PROTO((object *, object *));
static object *loop_subscript PROTO((object *, object *));
static int slice_index PROTO((object *, int, int *));
static object *apply_slice PROTO((object *, object *, object *));
+static object *build_slice PROTO((object *, object *, object *));
static int assign_subscript PROTO((object *, object *, object *));
static int assign_slice PROTO((object *, object *, object *, object *));
static int cmp_exception PROTO((object *, object *));
@@ -187,6 +188,8 @@ restore_thread(x)
thread (the main thread) ever takes things out of the queue.
*/
+static int ticker = 0; /* main loop counter to do periodic things */
+
#define NPENDINGCALLS 32
static struct {
int (*func) PROTO((ANY *));
@@ -215,6 +218,7 @@ Py_AddPendingCall(func, arg)
pendingcalls[i].func = func;
pendingcalls[i].arg = arg;
pendinglast = j;
+ ticker = 0; /* Signal main loop */
busy = 0;
/* XXX End critical section */
return 0;
@@ -225,11 +229,15 @@ Py_MakePendingCalls()
{
static int busy = 0;
#ifdef WITH_THREAD
- if (get_thread_ident() != main_thread)
+ if (get_thread_ident() != main_thread) {
+ ticker = 0; /* We're not done yet */
return 0;
+ }
#endif
- if (busy)
+ if (busy) {
+ ticker = 0; /* We're not done yet */
return 0;
+ }
busy = 1;
for (;;) {
int i;
@@ -243,6 +251,7 @@ Py_MakePendingCalls()
pendingfirst = (i + 1) % NPENDINGCALLS;
if (func(arg) < 0) {
busy = 0;
+ ticker = 0; /* We're not done yet */
return -1;
}
}
@@ -281,6 +290,12 @@ eval_code(co, globals, locals)
/* Interpreter main loop */
+#ifndef MAX_RECURSION_DEPTH
+#define MAX_RECURSION_DEPTH 10000
+#endif
+
+static int recursion_depth = 0;
+
static object *
eval_code2(co, globals, locals,
args, argcount, kws, kwcount, defs, defcount, owner)
@@ -355,6 +370,13 @@ eval_code2(co, globals, locals,
#define SETLOCAL(i, value) do { XDECREF(GETLOCAL(i)); \
GETLOCAL(i) = value; } while (0)
+#ifdef USE_STACKCHECK
+ if (recursion_depth%10 == 0 && PyOS_CheckStack()) {
+ err_setstr(MemoryError, "Stack overflow");
+ return NULL;
+ }
+#endif
+
if (globals == NULL) {
err_setstr(SystemError, "eval_code2: NULL globals");
return NULL;
@@ -514,6 +536,14 @@ eval_code2(co, globals, locals,
}
}
+ if (++recursion_depth > MAX_RECURSION_DEPTH) {
+ --recursion_depth;
+ err_setstr(RuntimeError, "Maximum recursion depth exceeded");
+ current_frame = f->f_back;
+ DECREF(f);
+ return NULL;
+ }
+
next_instr = GETUSTRINGVALUE(f->f_code->co_code);
stack_pointer = f->f_valuestack;
@@ -522,22 +552,23 @@ eval_code2(co, globals, locals,
x = None; /* Not a reference, just anything non-NULL */
for (;;) {
- static int ticker;
-
/* Do periodic things.
Doing this every time through the loop would add
too much overhead (a function call per instruction).
- So we do it only every Nth instruction. */
-
- if (pendingfirst != pendinglast) {
- if (Py_MakePendingCalls() < 0) {
- why = WHY_EXCEPTION;
- goto on_error;
- }
- }
+ So we do it only every Nth instruction.
+
+ The ticker is reset to zero if there are pending
+ calls (see Py_AddPendingCalls() and
+ Py_MakePendingCalls() above). */
if (--ticker < 0) {
ticker = sys_checkinterval;
+ if (pendingfirst != pendinglast) {
+ if (Py_MakePendingCalls() < 0) {
+ why = WHY_EXCEPTION;
+ goto on_error;
+ }
+ }
if (sigcheck()) {
why = WHY_EXCEPTION;
goto on_error;
@@ -1630,7 +1661,22 @@ eval_code2(co, globals, locals,
}
PUSH(x);
break;
-
+
+ case BUILD_SLICE:
+ if (oparg == 3)
+ w = POP();
+ else
+ w = NULL;
+ v = POP();
+ u = POP();
+ x = build_slice(u,v,w);
+ DECREF(u);
+ DECREF(v);
+ XDECREF(w);
+ PUSH(x);
+ break;
+
+
default:
fprintf(stderr,
"XXX lineno: %d, opcode: %d\n",
@@ -1793,6 +1839,7 @@ eval_code2(co, globals, locals,
current_frame = f->f_back;
DECREF(f);
+ --recursion_depth;
return retval;
}
@@ -2549,6 +2596,13 @@ slice_index(v, isize, pi)
}
static object *
+build_slice(u, v, w) /* u:v:w */
+ object *u, *v, *w;
+{
+ return PySlice_New(u,v,w);
+}
+
+static object *
apply_slice(u, v, w) /* return u[v:w] */
object *u, *v, *w;
{