[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