diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/descrobject.c | 34 | ||||
-rw-r--r-- | Objects/typeobject.c | 68 |
2 files changed, 62 insertions, 40 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 3a65902..1d525da 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -3,38 +3,6 @@ #include "Python.h" #include "structmember.h" /* Why is this not included in Python.h? */ -/* Various kinds of descriptor objects */ - -#define COMMON \ - PyObject_HEAD \ - PyTypeObject *d_type; \ - PyObject *d_name - -typedef struct { - COMMON; -} PyDescrObject; - -typedef struct { - COMMON; - PyMethodDef *d_method; -} PyMethodDescrObject; - -typedef struct { - COMMON; - PyMemberDef *d_member; -} PyMemberDescrObject; - -typedef struct { - COMMON; - PyGetSetDef *d_getset; -} PyGetSetDescrObject; - -typedef struct { - COMMON; - struct wrapperbase *d_base; - void *d_wrapped; /* This can be any function pointer */ -} PyWrapperDescrObject; - static void descr_dealloc(PyDescrObject *descr) { @@ -481,7 +449,7 @@ static PyTypeObject PyGetSetDescr_Type = { (descrsetfunc)getset_set, /* tp_descr_set */ }; -static PyTypeObject PyWrapperDescr_Type = { +PyTypeObject PyWrapperDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "wrapper_descriptor", diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a681d33..d976945 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2113,12 +2113,16 @@ wrap_sq_item(PyObject *self, PyObject *args, void *wrapped) PyObject *arg; int i; - if (!PyArg_ParseTuple(args, "O", &arg)) - return NULL; - i = getindex(self, arg); - if (i == -1 && PyErr_Occurred()) - return NULL; - return (*func)(self, i); + if (PyTuple_GET_SIZE(args) == 1) { + arg = PyTuple_GET_ITEM(args, 0); + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) + return NULL; + return (*func)(self, i); + } + PyArg_ParseTuple(args, "O", &arg); + assert(PyErr_Occurred()); + return NULL; } static struct wrapperbase tab_getitem_int[] = { @@ -2825,7 +2829,57 @@ slot_sq_length(PyObject *self) SLOT1(slot_sq_concat, "__add__", PyObject *, "O") SLOT1(slot_sq_repeat, "__mul__", int, "i") -SLOT1(slot_sq_item, "__getitem__", int, "i") + +/* Super-optimized version of slot_sq_item. + Other slots could do the same... */ +static PyObject * +slot_sq_item(PyObject *self, int i) +{ + static PyObject *getitem_str; + PyObject *func, *args = NULL, *ival = NULL, *retval = NULL; + descrgetfunc f; + + if (getitem_str == NULL) { + getitem_str = PyString_InternFromString("__getitem__"); + if (getitem_str == NULL) + return NULL; + } + func = _PyType_Lookup(self->ob_type, getitem_str); + if (func != NULL) { + if (func->ob_type == &PyWrapperDescr_Type) { + PyWrapperDescrObject *wrapper = + (PyWrapperDescrObject *)func; + if (wrapper->d_base->wrapper == wrap_sq_item) { + intargfunc f; + f = (intargfunc)(wrapper->d_wrapped); + return f(self, i); + } + } + if ((f = func->ob_type->tp_descr_get) == NULL) + Py_INCREF(func); + else + func = f(func, self, (PyObject *)(self->ob_type)); + ival = PyInt_FromLong(i); + if (ival != NULL) { + args = PyTuple_New(1); + if (args != NULL) { + PyTuple_SET_ITEM(args, 0, ival); + retval = PyObject_Call(func, args, NULL); + Py_XDECREF(args); + Py_XDECREF(func); + return retval; + } + } + } + else { + PyErr_SetObject(PyExc_AttributeError, getitem_str); + } + Py_XDECREF(args); + Py_XDECREF(ival); + Py_XDECREF(func); + return NULL; +} + SLOT2(slot_sq_slice, "__getslice__", int, int, "ii") static int |