SF bug #1053819:  Segfault in tuple_of_constants

Peepholer could be fooled into misidentifying a tuple_of_constants.
Added code to count consecutive occurrences of LOAD_CONST.
Use the count to weed out the misidentified cases.
Added a unittest.
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 913f805..934b57c 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -83,6 +83,23 @@
             self.assert_(elem in asm)
             self.assert_('BUILD_TUPLE' not in asm)
 
+        # Bug 1053819:  Tuple of constants misidentified when presented with:
+        # . . . opcode_with_arg 100   unary_opcode   BUILD_TUPLE 1  . . .
+        # The following would segfault upon compilation
+        def crater():
+            (~[
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+                0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+            ],)
+
     def test_elim_extra_return(self):
         # RETURN LOAD_CONST None RETURN  -->  RETURN
         def f(x):
diff --git a/Python/compile.c b/Python/compile.c
index dfb94d3..37793ca 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -419,15 +419,16 @@
 	newconst = PyTuple_New(n);
 	if (newconst == NULL)
 		return 0;
+	len_consts = PyList_GET_SIZE(consts);
 	for (i=0 ; i<n ; i++) {
 		arg = GETARG(codestr, (i*3));
+		assert(arg < len_consts);
 		constant = PyList_GET_ITEM(consts, arg);
 		Py_INCREF(constant);
 		PyTuple_SET_ITEM(newconst, i, constant);
 	}
 
 	/* Append folded constant onto consts */
-	len_consts = PyList_GET_SIZE(consts);
 	if (PyList_Append(consts, newconst)) {
 		Py_DECREF(newconst);
 		return 0;
@@ -501,6 +502,7 @@
 	unsigned char *lineno;
 	int *addrmap = NULL;
 	int new_line, cum_orig_line, last_line, tabsiz;
+	int cumlc=0, lastlc=0;	/* Count runs of consecutive LOAD_CONST codes */
 	unsigned int *blocks;
 	char *name;
 
@@ -536,6 +538,10 @@
 	for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
 		addrmap[i] = i - nops;
 		opcode = codestr[i];
+
+		lastlc = cumlc;
+		cumlc = 0;
+
 		switch (opcode) {
 
 		/* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with 
@@ -589,6 +595,7 @@
 
 		/* Skip over LOAD_CONST trueconst  JUMP_IF_FALSE xx  POP_TOP */
 		case LOAD_CONST:
+			cumlc = lastlc + 1;
 			j = GETARG(codestr, i);
 			if (codestr[i+3] != JUMP_IF_FALSE  ||
 			    codestr[i+6] != POP_TOP  ||
@@ -607,6 +614,7 @@
 			j = GETARG(codestr, i);
 			h = i - 3 * j;
 			if (h >= 0  &&
+			    j == lastlc  &&
 			    codestr[h] == LOAD_CONST  && 
 			    ISBASICBLOCK(blocks, h, 3*(j+1))  &&
 			    tuple_of_constants(&codestr[h], j, consts)) {