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

Unified Diff: Objects/methodobject.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Patch Set: Created 2 years, 12 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
--- a/Objects/methodobject.c Wed Jan 25 23:33:27 2017 +0100
+++ b/Objects/methodobject.c Thu Jan 26 02:43:18 2017 +0100
@@ -87,26 +87,30 @@ PyCFunction_Call(PyObject *func, PyObjec
}
PyObject *
-_PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **args,
- Py_ssize_t nargs, PyObject *kwargs)
+_PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs,
+ PyObject *kwargs)
{
+ PyCFunctionObject *func = (PyCFunctionObject*)func_obj;
PyCFunction meth;
- PyObject *result;
+ PyObject *self, *result;
int flags;
PyObject *argstuple;
- /* _PyMethodDef_RawFastCallDict() must not be called with an exception set,
- because it can clear it (directly or indirectly) and so the
+ /* _PyCFunction_FastCallDict() must not be called with an exception set,
+ because it may clear it (directly or indirectly) and so the
caller loses its exception */
assert(!PyErr_Occurred());
- assert(method != NULL);
+ assert(PyCFunction_Check(func_obj));
+ assert(func_obj != NULL);
haypo 2017/01/26 03:35:21 assertions in the wrong order.
assert(nargs >= 0);
assert(nargs == 0 || args != NULL);
assert(kwargs == NULL || PyDict_Check(kwargs));
- meth = method->ml_meth;
- flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
+ func = (PyCFunctionObject*)func_obj;
+ meth = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
switch (flags)
{
@@ -114,7 +118,7 @@ PyObject *
if (nargs != 0) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)",
- method->ml_name, nargs);
+ func->m_ml->ml_name, nargs);
return NULL;
}
@@ -129,7 +133,7 @@ PyObject *
if (nargs != 1) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes exactly one argument (%zd given)",
- method->ml_name, nargs);
+ func->m_ml->ml_name, nargs);
return NULL;
}
@@ -165,19 +169,8 @@ PyObject *
case METH_FASTCALL:
{
- PyObject **stack;
- PyObject *kwnames;
- _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
-
- if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
- return NULL;
- }
-
- result = (*fastmeth) (self, stack, nargs, kwnames);
- if (stack != args) {
- PyMem_Free(stack);
- }
- Py_XDECREF(kwnames);
+ result = _Py_RawFastCallDict(self, (fastternaryfunc)meth,
+ args, nargs, kwargs);
break;
}
@@ -188,44 +181,27 @@ PyObject *
return NULL;
}
+ result = _Py_CheckFunctionResult(func_obj, result, NULL);
+
return result;
no_keyword_error:
PyErr_Format(PyExc_TypeError,
"%.200s() takes no keyword arguments",
- method->ml_name, nargs);
-
+ func->m_ml->ml_name, nargs);
return NULL;
}
PyObject *
-_PyCFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
- PyObject *kwargs)
+_PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self,
+ PyObject **args, Py_ssize_t nargs,
+ PyObject *kwnames)
{
+ PyCFunction meth;
PyObject *result;
-
- assert(func != NULL);
- assert(PyCFunction_Check(func));
-
- result = _PyMethodDef_RawFastCallDict(((PyCFunctionObject*)func)->m_ml,
- PyCFunction_GET_SELF(func),
- args, nargs, kwargs);
- result = _Py_CheckFunctionResult(func, result, NULL);
- return result;
-}
-
-PyObject *
-_PyCFunction_FastCallKeywords(PyObject *func_obj, PyObject **args,
- Py_ssize_t nargs, PyObject *kwnames)
-{
- PyCFunctionObject *func;
- PyCFunction meth;
- PyObject *self, *result;
Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
int flags;
- assert(func_obj != NULL);
- assert(PyCFunction_Check(func_obj));
assert(nargs >= 0);
haypo 2017/01/26 03:35:21 assert(method != NULL);
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
assert((nargs == 0 && nkwargs == 0) || args != NULL);
@@ -237,10 +213,8 @@ PyObject *
loses its exception */
assert(!PyErr_Occurred());
- func = (PyCFunctionObject*)func_obj;
- meth = PyCFunction_GET_FUNCTION(func);
- self = PyCFunction_GET_SELF(func);
- flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
+ meth = method->ml_meth;
+ flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
switch (flags)
{
@@ -248,7 +222,7 @@ PyObject *
if (nargs != 0) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)",
- func->m_ml->ml_name, nargs);
+ method->ml_name, nargs);
return NULL;
}
@@ -263,7 +237,7 @@ PyObject *
if (nargs != 1) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes exactly one argument (%zd given)",
- func->m_ml->ml_name, nargs);
+ method->ml_name, nargs);
return NULL;
}
@@ -276,7 +250,7 @@ PyObject *
case METH_FASTCALL:
/* Fast-path: avoid temporary dict to pass keyword arguments */
- result = ((_PyCFunctionFast)meth) (self, args, nargs, kwnames);
+ result = ((fastternaryfunc)meth) (self, args, nargs, kwnames);
break;
case METH_VARARGS:
@@ -326,16 +300,31 @@ PyObject *
return NULL;
}
- result = _Py_CheckFunctionResult(func_obj, result, NULL);
return result;
no_keyword_error:
PyErr_Format(PyExc_TypeError,
"%.200s() takes no keyword arguments",
- func->m_ml->ml_name);
+ method->ml_name);
return NULL;
}
+PyObject *
+_PyCFunction_FastCallKeywords(PyObject *func, PyObject **args,
+ Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *result;
+
+ assert(func != NULL);
+ assert(PyCFunction_Check(func));
+
+ result = _PyMethodDef_RawFastCallKeywords(((PyCFunctionObject*)func)->m_ml,
+ PyCFunction_GET_SELF(func),
+ args, nargs, kwnames);
+ result = _Py_CheckFunctionResult(func, result, NULL);
+ return result;
+}
+
/* Methods (the standard built-in methods, that is) */
static void
@@ -556,8 +545,8 @@ PyTypeObject PyCFunction_Type = {
meth_methods, /* tp_methods */
meth_members, /* tp_members */
meth_getsets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
+
+ .tp_fastcall = _PyCFunction_FastCallKeywords,
};
/* Clear out the free list */

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