summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/descrobject.c34
-rw-r--r--Objects/typeobject.c68
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