Index: Python/import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.227 diff -u -r2.227 import.c --- Python/import.c 23 Mar 2004 16:28:13 -0000 2.227 +++ Python/import.c 25 Mar 2004 12:30:39 -0000 @@ -53,6 +53,9 @@ magic number *back* to 62011. This should get the snake-farm to throw away its old .pyc files, amongst others. + MvL, 2004-03-24: Added TYPE_INTERNED and TYPE_STRINGREF types to + marshal. + Known values: Python 1.5: 20121 Python 1.5.1: 20121 @@ -66,8 +69,9 @@ Python 2.3a0: 62011 Python 2.3a0: 62021 Python 2.3a0: 62011 (!) + Python 2.4a0: 62013 */ -#define MAGIC (62011 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62013 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the Index: Python/marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.75 diff -u -r1.75 marshal.c --- Python/marshal.c 4 Sep 2003 11:59:50 -0000 1.75 +++ Python/marshal.c 25 Mar 2004 12:30:40 -0000 @@ -27,6 +27,8 @@ #define TYPE_COMPLEX 'x' #define TYPE_LONG 'l' #define TYPE_STRING 's' +#define TYPE_INTERNED 't' +#define TYPE_STRINGREF 'R' #define TYPE_TUPLE '(' #define TYPE_LIST '[' #define TYPE_DICT '{' @@ -42,6 +44,7 @@ PyObject *str; char *ptr; char *end; + PyObject *strings; /* dict on marshal, list on unmarshal */ } WFILE; #define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \ @@ -189,7 +192,24 @@ } #endif else if (PyString_Check(v)) { - w_byte(TYPE_STRING, p); + if (PyString_CHECK_INTERNED(v)) { + PyObject *o = PyDict_GetItem(p->strings, v); + if (o) { + long w = PyInt_AsLong(o); + w_byte(TYPE_STRINGREF, p); + w_long(w, p); + goto exit; + } + else { + o = PyInt_FromLong(PyDict_Size(p->strings)); + PyDict_SetItem(p->strings, v, o); + Py_DECREF(o); + w_byte(TYPE_INTERNED, p); + } + } + else { + w_byte(TYPE_STRING, p); + } n = PyString_GET_SIZE(v); w_long((long)n, p); w_string(PyString_AS_STRING(v), n, p); @@ -269,7 +289,7 @@ w_byte(TYPE_UNKNOWN, p); p->error = 1; } - + exit: p->depth--; } @@ -280,6 +300,7 @@ wf.fp = fp; wf.error = 0; wf.depth = 0; + wf.strings = NULL; w_long(x, &wf); } @@ -290,7 +311,9 @@ wf.fp = fp; wf.error = 0; wf.depth = 0; + wf.strings = PyDict_New(); w_object(x, &wf); + Py_DECREF(wf.strings); } typedef WFILE RFILE; /* Same struct with different invariants */ @@ -481,6 +504,7 @@ } #endif + case TYPE_INTERNED: case TYPE_STRING: n = r_long(p); if (n < 0) { @@ -496,6 +520,16 @@ "EOF read where object expected"); } } + if (type == TYPE_INTERNED) { + PyString_InternInPlace(&v); + PyList_Append(p->strings, v); + } + return v; + + case TYPE_STRINGREF: + n = r_long(p); + v = PyList_GET_ITEM(p->strings, n); + Py_INCREF(v); return v; #ifdef Py_USING_UNICODE @@ -652,6 +686,7 @@ { RFILE rf; rf.fp = fp; + rf.strings = NULL; return r_short(&rf); } @@ -660,6 +695,7 @@ { RFILE rf; rf.fp = fp; + rf.strings = NULL; return r_long(&rf); } @@ -730,18 +766,23 @@ PyMarshal_ReadObjectFromFile(FILE *fp) { RFILE rf; + PyObject *result; if (PyErr_Occurred()) { fprintf(stderr, "XXX rd_object called with exception set\n"); return NULL; } rf.fp = fp; - return r_object(&rf); + rf.strings = PyList_New(0); + result = r_object(&rf); + Py_DECREF(rf.strings); + return result; } PyObject * PyMarshal_ReadObjectFromString(char *str, int len) { RFILE rf; + PyObject *result; if (PyErr_Occurred()) { fprintf(stderr, "XXX rds_object called with exception set\n"); return NULL; @@ -750,7 +791,10 @@ rf.str = NULL; rf.ptr = str; rf.end = str + len; - return r_object(&rf); + rf.strings = PyList_New(0); + result = r_object(&rf); + Py_DECREF(rf.strings); + return result; } PyObject * @@ -765,7 +809,9 @@ wf.end = wf.ptr + PyString_Size(wf.str); wf.error = 0; wf.depth = 0; + wf.strings = PyDict_New(); w_object(x, &wf); + Py_DECREF(wf.strings); if (wf.str != NULL) _PyString_Resize(&wf.str, (int) (wf.ptr - @@ -800,7 +846,9 @@ wf.ptr = wf.end = NULL; wf.error = 0; wf.depth = 0; + wf.strings = PyDict_New(); w_object(x, &wf); + Py_DECREF(wf.strings); if (wf.error) { PyErr_SetString(PyExc_ValueError, (wf.error==1)?"unmarshallable object" @@ -827,12 +875,14 @@ rf.fp = PyFile_AsFile(f); rf.str = NULL; rf.ptr = rf.end = NULL; + rf.strings = PyList_New(0); PyErr_Clear(); v = r_object(&rf); if (PyErr_Occurred()) { Py_XDECREF(v); v = NULL; } + Py_DECREF(rf.strings); return v; } @@ -858,8 +908,10 @@ rf.str = args; rf.ptr = s; rf.end = s + n; + rf.strings = PyList_New(0); PyErr_Clear(); v = r_object(&rf); + Py_DECREF(rf.strings); if (PyErr_Occurred()) { Py_XDECREF(v); v = NULL;