diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-08-24 22:29:32 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-08-24 22:29:32 (GMT) |
commit | 577e1f8cb41b76ea763910a47abf42a1952ddec3 (patch) | |
tree | c813887a0af4c5b7312b2e835677546584c067ea /Python | |
parent | 53868aaabb154c11bf666b31662bb4ae8bc6ec79 (diff) | |
download | cpython-577e1f8cb41b76ea763910a47abf42a1952ddec3.zip cpython-577e1f8cb41b76ea763910a47abf42a1952ddec3.tar.gz cpython-577e1f8cb41b76ea763910a47abf42a1952ddec3.tar.bz2 |
Add _PyObject_FastCallKeywords()
Issue #27830: Similar to _PyObject_FastCallDict(), but keyword arguments are
also passed in the same C array than positional arguments, rather than being
passed as a Python dict.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index b082760..266b987 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -113,7 +113,6 @@ static PyObject * call_function(PyObject ***, int, uint64*, uint64*); #else static PyObject * call_function(PyObject ***, int); #endif -static PyObject * fast_function(PyObject *, PyObject **, Py_ssize_t, Py_ssize_t); static PyObject * do_call(PyObject *, PyObject ***, Py_ssize_t, Py_ssize_t); static PyObject * ext_do_call(PyObject *, PyObject ***, int, Py_ssize_t, Py_ssize_t); static PyObject * update_keyword_args(PyObject *, Py_ssize_t, PyObject ***, @@ -4767,7 +4766,7 @@ call_function(PyObject ***pp_stack, int oparg } READ_TIMESTAMP(*pintr0); if (PyFunction_Check(func)) { - x = fast_function(func, (*pp_stack) - n, nargs, nkwargs); + x = _PyFunction_FastCallKeywords(func, (*pp_stack) - n, nargs, nkwargs); } else { x = do_call(func, pp_stack, nargs, nkwargs); @@ -4780,7 +4779,7 @@ call_function(PyObject ***pp_stack, int oparg /* Clear the stack of the function object. Also removes the arguments in case they weren't consumed already - (fast_function() and err_args() leave them on the stack). + (_PyFunction_FastCallKeywords() and err_args() leave them on the stack). */ while ((*pp_stack) > pfunc) { w = EXT_POP(*pp_stack); @@ -4792,7 +4791,7 @@ call_function(PyObject ***pp_stack, int oparg return x; } -/* The fast_function() function optimize calls for which no argument +/* The _PyFunction_FastCallKeywords() function optimize calls for which no argument tuple is necessary; the objects are passed directly from the stack. For the simplest case -- a function that takes only positional arguments and is called with only positional arguments -- it @@ -4840,8 +4839,9 @@ _PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t nargs, /* Similar to _PyFunction_FastCall() but keywords are passed a (key, value) pairs in stack */ -static PyObject * -fast_function(PyObject *func, PyObject **stack, Py_ssize_t nargs, Py_ssize_t nkwargs) +PyObject * +_PyFunction_FastCallKeywords(PyObject *func, PyObject **stack, + Py_ssize_t nargs, Py_ssize_t nkwargs) { PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); @@ -4850,6 +4850,11 @@ fast_function(PyObject *func, PyObject **stack, Py_ssize_t nargs, Py_ssize_t nkw PyObject **d; int nd; + assert(func != NULL); + assert(nargs >= 0); + assert(nkwargs >= 0); + assert((nargs == 0 && nkwargs == 0) || stack != NULL); + PCALL(PCALL_FUNCTION); PCALL(PCALL_FAST_FUNCTION); @@ -4902,14 +4907,14 @@ _PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, Py_ssize_t nd, nk; PyObject *result; - PCALL(PCALL_FUNCTION); - PCALL(PCALL_FAST_FUNCTION); - assert(func != NULL); assert(nargs >= 0); assert(nargs == 0 || args != NULL); assert(kwargs == NULL || PyDict_Check(kwargs)); + PCALL(PCALL_FUNCTION); + PCALL(PCALL_FAST_FUNCTION); + if (co->co_kwonlyargcount == 0 && (kwargs == NULL || PyDict_Size(kwargs) == 0) && co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) |