[Python-checkins] python/dist/src/Modules cPickle.c,2.121,2.122
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Mon, 03 Feb 2003 21:06:20 -0800
Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv29814/Modules
Modified Files:
cPickle.c
Log Message:
cPickle can load pickles using proto 2 EXT[124] now, but can't yet
generate these opcodes.
Index: cPickle.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v
retrieving revision 2.121
retrieving revision 2.122
diff -C2 -d -r2.121 -r2.122
*** cPickle.c 4 Feb 2003 01:54:49 -0000 2.121
--- cPickle.c 4 Feb 2003 05:06:17 -0000 2.122
***************
*** 3734,3737 ****
--- 3734,3805 ----
}
+ /* Push an object from the extension registry (EXT[124]). nbytes is
+ * the number of bytes following the opcode, holding the index (code) value.
+ */
+ static int
+ load_extension(Unpicklerobject *self, int nbytes)
+ {
+ char *codebytes; /* the nbytes bytes after the opcode */
+ long code; /* calc_binint returns long */
+ PyObject *py_code; /* code as a Python int */
+ PyObject *obj; /* the object to push */
+ PyObject *pair; /* (module_name, class_name) */
+ PyObject *module_name, *class_name;
+
+ assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+ if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+ code = calc_binint(codebytes, nbytes);
+ if (code <= 0) { /* note that 0 is forbidden */
+ /* Corrupt or hostile pickle. */
+ PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
+ return -1;
+ }
+
+ /* Look for the code in the cache. */
+ py_code = PyInt_FromLong(code);
+ if (py_code == NULL) return -1;
+ obj = PyDict_GetItem(extension_cache, py_code);
+ if (obj != NULL) {
+ /* Bingo. */
+ Py_DECREF(py_code);
+ PDATA_APPEND(self->stack, obj, -1);
+ return 0;
+ }
+
+ /* Look up the (module_name, class_name) pair. */
+ pair = PyDict_GetItem(inverted_registry, py_code);
+ if (pair == NULL) {
+ Py_DECREF(py_code);
+ PyErr_Format(PyExc_ValueError, "unregistered extension "
+ "code %ld", code);
+ return -1;
+ }
+ /* Since the extension registry is manipulable via Python code,
+ * confirm that obj is really a 2-tuple of strings.
+ */
+ if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
+ !PyString_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
+ !PyString_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
+ Py_DECREF(py_code);
+ PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
+ "isn't a 2-tuple of strings", code);
+ return -1;
+ }
+ /* Load the object. */
+ obj = find_class(module_name, class_name, self->find_class);
+ if (obj == NULL) {
+ Py_DECREF(py_code);
+ return -1;
+ }
+ /* Cache code -> obj. */
+ code = PyDict_SetItem(extension_cache, py_code, obj);
+ Py_DECREF(py_code);
+ if (code < 0) {
+ Py_DECREF(obj);
+ return -1;
+ }
+ PDATA_PUSH(self->stack, obj, -1);
+ return 0;
+ }
static int
***************
*** 4215,4218 ****
--- 4283,4300 ----
continue;
+ case EXT1:
+ if (load_extension(self, 1) < 0)
+ break;
+ continue;
+
+ case EXT2:
+ if (load_extension(self, 2) < 0)
+ break;
+ continue;
+
+ case EXT4:
+ if (load_extension(self, 4) < 0)
+ break;
+ continue;
case MARK:
if (load_mark(self) < 0)
***************
*** 4371,4374 ****
--- 4453,4467 ----
}
+ static int
+ noload_extension(Unpicklerobject *self, int nbytes)
+ {
+ char *codebytes;
+
+ assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+ if (self->read_func(self, &codebytes, nbytes) < 0) return -1;
+ PDATA_APPEND(self->stack, Py_None, -1);
+ return 0;
+ }
+
static PyObject *
***************
*** 4555,4558 ****
--- 4648,4666 ----
case GET:
if (load_get(self) < 0)
+ break;
+ continue;
+
+ case EXT1:
+ if (noload_extension(self, 1) < 0)
+ break;
+ continue;
+
+ case EXT2:
+ if (noload_extension(self, 2) < 0)
+ break;
+ continue;
+
+ case EXT4:
+ if (noload_extension(self, 4) < 0)
break;
continue;