Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Unified Diff: Objects/descrobject.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Objects/classobject.c ('k') | Objects/funcobject.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Objects/descrobject.c Tue Jan 17 20:43:31 2017 -0800
+++ b/Objects/descrobject.c Wed Jan 18 08:45:26 2017 +0100
@@ -210,15 +210,13 @@ getset_set(PyGetSetDescrObject *descr, P
}
static PyObject *
-methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
+methoddescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
+ PyObject *kwnames)
{
- Py_ssize_t argc;
- PyObject *self, *func, *result, **stack;
+ PyObject *self, *func, *result;
/* Make sure that the first argument is acceptable as 'self' */
- assert(PyTuple_Check(args));
- argc = PyTuple_GET_SIZE(args);
- if (argc < 1) {
+ if (nargs < 1) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' of '%.100s' "
"object needs an argument",
@@ -226,7 +224,7 @@ methoddescr_call(PyMethodDescrObject *de
PyDescr_TYPE(descr)->tp_name);
return NULL;
}
- self = PyTuple_GET_ITEM(args, 0);
+ self = args[0];
if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
(PyObject *)PyDescr_TYPE(descr))) {
PyErr_Format(PyExc_TypeError,
@@ -242,23 +240,19 @@ methoddescr_call(PyMethodDescrObject *de
func = PyCFunction_NewEx(descr->d_method, self, NULL);
if (func == NULL)
return NULL;
- stack = &PyTuple_GET_ITEM(args, 1);
- result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
+ result = _PyCFunction_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
Py_DECREF(func);
return result;
}
static PyObject *
-classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
- PyObject *kwds)
+classmethoddescr_call(PyMethodDescrObject *descr, PyObject **args,
+ Py_ssize_t nargs, PyObject *kwnames)
{
- Py_ssize_t argc;
- PyObject *self, *func, *result, **stack;
+ PyObject *self, *func, *result;
/* Make sure that the first argument is acceptable as 'self' */
- assert(PyTuple_Check(args));
- argc = PyTuple_GET_SIZE(args);
- if (argc < 1) {
+ if (nargs < 1) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' of '%.100s' "
"object needs an argument",
@@ -266,7 +260,7 @@ classmethoddescr_call(PyMethodDescrObjec
PyDescr_TYPE(descr)->tp_name);
return NULL;
}
- self = PyTuple_GET_ITEM(args, 0);
+ self = args[0];
if (!PyType_Check(self)) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' requires a type "
@@ -290,22 +284,19 @@ classmethoddescr_call(PyMethodDescrObjec
func = PyCFunction_NewEx(descr->d_method, self, NULL);
if (func == NULL)
return NULL;
- stack = &PyTuple_GET_ITEM(args, 1);
- result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
+ result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
Py_DECREF(func);
return result;
}
static PyObject *
-wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
+wrapperdescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
+ PyObject *kwnames)
{
- Py_ssize_t argc;
- PyObject *self, *func, *result, **stack;
+ PyObject *self, *func, *result;
/* Make sure that the first argument is acceptable as 'self' */
- assert(PyTuple_Check(args));
- argc = PyTuple_GET_SIZE(args);
- if (argc < 1) {
+ if (nargs < 1) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' of '%.100s' "
"object needs an argument",
@@ -313,7 +304,7 @@ wrapperdescr_call(PyWrapperDescrObject *
PyDescr_TYPE(descr)->tp_name);
return NULL;
}
- self = PyTuple_GET_ITEM(args, 0);
+ self = args[0];
if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
(PyObject *)PyDescr_TYPE(descr))) {
PyErr_Format(PyExc_TypeError,
@@ -330,8 +321,7 @@ wrapperdescr_call(PyWrapperDescrObject *
if (func == NULL)
return NULL;
- stack = &PyTuple_GET_ITEM(args, 1);
- result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
+ result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
Py_DECREF(func);
return result;
}
@@ -491,7 +481,7 @@ PyTypeObject PyMethodDescr_Type = {
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
- (ternaryfunc)methoddescr_call, /* tp_call */
+ 0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
@@ -510,7 +500,8 @@ PyTypeObject PyMethodDescr_Type = {
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)method_get, /* tp_descr_get */
- 0, /* tp_descr_set */
+
+ .tp_fastcall = (fastternaryfunc)methoddescr_call,
};
/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
@@ -529,12 +520,12 @@ PyTypeObject PyClassMethodDescr_Type = {
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
- (ternaryfunc)classmethoddescr_call, /* tp_call */
+ 0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
descr_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -548,7 +539,8 @@ PyTypeObject PyClassMethodDescr_Type = {
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)classmethod_get, /* tp_descr_get */
- 0, /* tp_descr_set */
+
+ .tp_fastcall = (fastternaryfunc)classmethoddescr_call,
};
PyTypeObject PyMemberDescr_Type = {
@@ -640,7 +632,7 @@ PyTypeObject PyWrapperDescr_Type = {
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
- (ternaryfunc)wrapperdescr_call, /* tp_call */
+ 0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
@@ -659,7 +651,8 @@ PyTypeObject PyWrapperDescr_Type = {
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)wrapperdescr_get, /* tp_descr_get */
- 0, /* tp_descr_set */
+
+ .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
};
static PyDescrObject *
@@ -1359,10 +1352,8 @@ property_dealloc(PyObject *self)
static PyObject *
property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
- static PyObject * volatile cached_args = NULL;
- PyObject *args;
- PyObject *ret;
propertyobject *gs = (propertyobject *)self;
+ PyObject *args[1];
if (obj == NULL || obj == Py_None) {
Py_INCREF(self);
@@ -1372,29 +1363,9 @@ property_descr_get(PyObject *self, PyObj
PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
return NULL;
}
- args = cached_args;
- cached_args = NULL;
- if (!args) {
- args = PyTuple_New(1);
- if (!args)
- return NULL;
- _PyObject_GC_UNTRACK(args);
- }
- Py_INCREF(obj);
- PyTuple_SET_ITEM(args, 0, obj);
- ret = PyObject_Call(gs->prop_get, args, NULL);
- if (cached_args == NULL && Py_REFCNT(args) == 1) {
- assert(Py_SIZE(args) == 1);
- assert(PyTuple_GET_ITEM(args, 0) == obj);
- cached_args = args;
- Py_DECREF(obj);
- }
- else {
- assert(Py_REFCNT(args) >= 1);
- _PyObject_GC_TRACK(args);
- Py_DECREF(args);
- }
- return ret;
+
+ args[0] = obj;
+ return _PyObject_FastCall(gs->prop_get, args, 1);
}
static int
« no previous file with comments | « Objects/classobject.c ('k') | Objects/funcobject.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+