diff Python/ceval.c @ 3839:22e29b1747e1 legacy-trunk

Changes for slice and ellipses
author Guido van Rossum <guido@python.org>
date Tue, 30 Jul 1996 16:49:37 +0000
parents 581f073f071d
children 4566a19c3438
line wrap: on
line diff
--- a/Python/ceval.c	Tue Jul 30 16:48:31 1996 +0000
+++ b/Python/ceval.c	Tue Jul 30 16:49:37 1996 +0000
@@ -87,6 +87,7 @@
 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 @@
    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 @@
 	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 @@
 {
 	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 @@
 		pendingfirst = (i + 1) % NPENDINGCALLS;
 		if (func(arg) < 0) {
 			busy = 0;
+			ticker = 0; /* We're not done yet */
 			return -1;
 		}
 	}
@@ -281,6 +290,12 @@
 
 /* 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 @@
 #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 @@
 		}
 	}
 
+	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 @@
 	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 @@
 			}
 			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 @@
 
 	current_frame = f->f_back;
 	DECREF(f);
+	--recursion_depth;
 	
 	return retval;
 }
@@ -2549,6 +2596,13 @@
 }
 
 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;
 {