diff options
author | Guido van Rossum <guido@python.org> | 2001-08-28 18:22:14 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-28 18:22:14 (GMT) |
commit | 2730b132024acd7fbb18110a49b1ea1dbe9e2261 (patch) | |
tree | 747b635b180d56dc2f3b9cab2a244bcfd15f60a4 /Objects | |
parent | b5f17f2dc5b823953868daaacc85cbf3b67e7df7 (diff) | |
download | cpython-2730b132024acd7fbb18110a49b1ea1dbe9e2261.zip cpython-2730b132024acd7fbb18110a49b1ea1dbe9e2261.tar.gz cpython-2730b132024acd7fbb18110a49b1ea1dbe9e2261.tar.bz2 |
Finish the previous checkin: also avoid getattr when calling the method
directly.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 118 |
1 files changed, 93 insertions, 25 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7fb6c8a..476926c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -319,6 +319,55 @@ lookup_method(PyObject *self, char *attrstr, PyObject **attrobj) return res; } +/* A variation of PyObject_CallMethod that uses lookup_method() + instead of PyObject_GetAttrString(). This uses the same convention + as lookup_method to cache the interned name string object. */ + +PyObject * +call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) +{ + va_list va; + PyObject *args, *func = 0, *retval; + PyObject *dummy_str = NULL; + va_start(va, format); + + func = lookup_method(o, name, &dummy_str); + Py_XDECREF(dummy_str); + if (func == NULL) { + va_end(va); + PyErr_SetString(PyExc_AttributeError, name); + return 0; + } + + if (format && *format) + args = Py_VaBuildValue(format, va); + else + args = PyTuple_New(0); + + va_end(va); + + if (!args) + return NULL; + + if (!PyTuple_Check(args)) { + PyObject *a; + + a = PyTuple_New(1); + if (a == NULL) + return NULL; + if (PyTuple_SetItem(a, 0, args) < 0) + return NULL; + args = a; + } + + retval = PyObject_CallObject(func, args); + + Py_DECREF(args); + Py_DECREF(func); + + return retval; +} + /* Method resolution order algorithm from "Putting Metaclasses to Work" by Forman and Danforth (Addison-Wesley 1999). */ @@ -2341,14 +2390,16 @@ add_operators(PyTypeObject *type) static PyObject * \ FUNCNAME(PyObject *self) \ { \ - return PyObject_CallMethod(self, OPSTR, ""); \ + static PyObject cache_str; \ + return call_method(self, OPSTR, &cache_str, ""); \ } #define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ { \ - return PyObject_CallMethod(self, OPSTR, ARGCODES, arg1); \ + static PyObject *cache_str; \ + return call_method(self, OPSTR, &cache_str, ARGCODES, arg1); \ } @@ -2356,11 +2407,12 @@ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ + static PyObject *cache_str, *rcache_str; \ if (self->ob_type->tp_as_number != NULL && \ self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ PyObject *r; \ - r = PyObject_CallMethod( \ - self, OPSTR, "O", other); \ + r = call_method( \ + self, OPSTR, &cache_str, "O", other); \ if (r != Py_NotImplemented || \ other->ob_type == self->ob_type) \ return r; \ @@ -2368,8 +2420,8 @@ FUNCNAME(PyObject *self, PyObject *other) \ } \ if (other->ob_type->tp_as_number != NULL && \ other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ - return PyObject_CallMethod( \ - other, ROPSTR, "O", self); \ + return call_method( \ + other, ROPSTR, &rcache_str, "O", self); \ } \ Py_INCREF(Py_NotImplemented); \ return Py_NotImplemented; \ @@ -2382,13 +2434,15 @@ FUNCNAME(PyObject *self, PyObject *other) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \ { \ - return PyObject_CallMethod(self, OPSTR, ARGCODES, arg1, arg2); \ + static PyObject *cache_str; \ + return call_method(self, OPSTR, &cache_str, ARGCODES, arg1, arg2); \ } static int slot_sq_length(PyObject *self) { - PyObject *res = PyObject_CallMethod(self, "__len__", ""); + static PyObject *len_str; + PyObject *res = call_method(self, "__len__", &len_str, ""); if (res == NULL) return -1; @@ -2404,12 +2458,14 @@ static int slot_sq_ass_item(PyObject *self, int index, PyObject *value) { PyObject *res; + static PyObject *delitem_str, *setitem_str; if (value == NULL) - res = PyObject_CallMethod(self, "__delitem__", "i", index); + res = call_method(self, "__delitem__", &delitem_str, + "i", index); else - res = PyObject_CallMethod(self, "__setitem__", - "iO", index, value); + res = call_method(self, "__setitem__", &setitem_str, + "iO", index, value); if (res == NULL) return -1; Py_DECREF(res); @@ -2420,12 +2476,14 @@ static int slot_sq_ass_slice(PyObject *self, int i, int j, PyObject *value) { PyObject *res; + static PyObject *delslice_str, *setslice_str; if (value == NULL) - res = PyObject_CallMethod(self, "__delslice__", "ii", i, j); + res = call_method(self, "__delslice__", &delslice_str, + "ii", i, j); else - res = PyObject_CallMethod(self, "__setslice__", - "iiO", i, j, value); + res = call_method(self, "__setslice__", &setslice_str, + "iiO", i, j, value); if (res == NULL) return -1; Py_DECREF(res); @@ -2470,12 +2528,14 @@ static int slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { PyObject *res; + static PyObject *delitem_str, *setitem_str; if (value == NULL) - res = PyObject_CallMethod(self, "__delitem__", "O", key); + res = call_method(self, "__delitem__", &delitem_str, + "O", key); else - res = PyObject_CallMethod(self, "__setitem__", - "OO", key, value); + res = call_method(self, "__setitem__", &setitem_str, + "OO", key, value); if (res == NULL) return -1; Py_DECREF(res); @@ -2497,10 +2557,13 @@ SLOT1BINFULL(slot_nb_power_binary, slot_nb_power, static PyObject * slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) { + static PyObject *pow_str; + if (modulus == Py_None) return slot_nb_power_binary(self, other); /* Three-arg power doesn't use __rpow__ */ - return PyObject_CallMethod(self, "__pow__", "OO", other, modulus); + return call_method(self, "__pow__", &pow_str, + "OO", other, modulus); } SLOT0(slot_nb_negative, "__neg__") @@ -2727,12 +2790,14 @@ static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) { PyObject *res; + static PyObject *delattr_str, *setattr_str; if (value == NULL) - res = PyObject_CallMethod(self, "__delattr__", "O", name); + res = call_method(self, "__delattr__", &delattr_str, + "O", name); else - res = PyObject_CallMethod(self, "__setattr__", - "OO", name, value); + res = call_method(self, "__setattr__", &setattr_str, + "OO", name, value); if (res == NULL) return -1; Py_DECREF(res); @@ -2822,7 +2887,8 @@ slot_tp_iter(PyObject *self) static PyObject * slot_tp_iternext(PyObject *self) { - return PyObject_CallMethod(self, "next", ""); + static PyObject *next_str; + return call_method(self, "next", &next_str, ""); } static PyObject * @@ -2856,12 +2922,14 @@ static int slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) { PyObject *res; + static PyObject *del_str, *set_str; if (value == NULL) - res = PyObject_CallMethod(self, "__del__", "O", target); + res = call_method(self, "__del__", &del_str, + "O", target); else - res = PyObject_CallMethod(self, "__set__", - "OO", target, value); + res = call_method(self, "__set__", &set_str, + "OO", target, value); if (res == NULL) return -1; Py_DECREF(res); |