[Python-3000-checkins] r60477 - in python/branches/py3k: Misc/NEWS Objects/longobject.c

christian.heimes python-3000-checkins at python.org
Thu Jan 31 16:16:39 CET 2008


Author: christian.heimes
Date: Thu Jan 31 16:16:38 2008
New Revision: 60477

Modified:
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/longobject.c
Log:
Fixed multiple reinitialization of the Python interpreter. The small int list in longobject.c has caused a seg fault during the third finalization.

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jan 31 16:16:38 2008
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Fixed multiple reinitialization of the Python interpreter. The small int
+  list in longobject.c has caused a seg fault during the third finalization.
+
 - Issue #1973: bytes.fromhex('') raises SystemError
 
 - Issue #1771: remove cmp parameter from sorted() and list.sort()

Modified: python/branches/py3k/Objects/longobject.c
==============================================================================
--- python/branches/py3k/Objects/longobject.c	(original)
+++ python/branches/py3k/Objects/longobject.c	Thu Jan 31 16:16:38 2008
@@ -3705,17 +3705,34 @@
 _PyLong_Init(void)
 {
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
-	int ival;
+	int ival, size;
 	PyLongObject *v = small_ints;
-	for (ival = -NSMALLNEGINTS; ival < 0; ival++, v++) {
-		PyObject_INIT(v, &PyLong_Type);
-		Py_SIZE(v) = -1;
-		v->ob_digit[0] = -ival;
-	}
-	for (; ival < NSMALLPOSINTS; ival++, v++) {
-		PyObject_INIT(v, &PyLong_Type);
-		Py_SIZE(v) = ival ? 1 : 0;
-		v->ob_digit[0] = ival;
+
+	for (ival = -NSMALLNEGINTS; ival <  NSMALLPOSINTS; ival++, v++) {
+		size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
+		if (Py_TYPE(v) == &PyLong_Type) {
+			/* The element is already initialized, most likely
+			 * the Python interpreter was initialized before.
+			 */
+			/* _Py_NewReference((PyObject*)v);
+			 *  XXX: It sets the ref count to 1 but it may be
+			 * larger. Emulate new reference w/o setting refcnt
+			 * to 1.
+			 */
+			PyObject* op = (PyObject*)v;
+			_Py_INC_REFTOTAL;
+			op->ob_refcnt = (op->ob_refcnt < 1) ? 1 : op->ob_refcnt;
+			_Py_AddToAllObjects(op, 1);
+			_Py_INC_TPALLOCS(op);
+
+			assert(Py_SIZE(op) == size);
+			assert(v->ob_digit[0] == abs(ival));
+		}
+		else {
+			PyObject_INIT(v, &PyLong_Type);
+		}
+		Py_SIZE(v) = size;
+		v->ob_digit[0] = abs(ival);
 	}
 #endif
 	return 1;
@@ -3724,19 +3741,15 @@
 void
 PyLong_Fini(void)
 {
-#if 0
-	int i;
-	/* This is currently not needed; the small integers
-	   are statically allocated */
+	/* Integers are currently statically allocated. Py_DECREF is not
+	   needed, but Python must forget about the reference or multiple
+	   reinitializations will fail. */
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
-        PyIntObject **q;
-
-        i = NSMALLNEGINTS + NSMALLPOSINTS;
-        q = small_ints;
-        while (--i >= 0) {
-                Py_XDECREF(*q);
-                *q++ = NULL;
-        }
-#endif
+	int i;
+	PyLongObject *v = small_ints;
+	for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) {
+		_Py_DEC_REFTOTAL;
+		_Py_ForgetReference((PyObject*)v);
+	}
 #endif
 }


More information about the Python-3000-checkins mailing list