Commit 46cd02cc authored by Stefan Behnel's avatar Stefan Behnel

support keyword arguments in FastCall code

parent 9d2b6d78
...@@ -5583,7 +5583,7 @@ class PyMethodCallNode(SimpleCallNode): ...@@ -5583,7 +5583,7 @@ class PyMethodCallNode(SimpleCallNode):
len(args)+1, len(args)+1,
self_arg, self_arg,
', '.join(arg.py_result() for arg in args))) ', '.join(arg.py_result() for arg in args)))
code.putln("%s = __Pyx_PyFunction_FastCall(%s, %s+1-%s, %d+%s, NULL); %s" % ( code.putln("%s = __Pyx_PyFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
self.result(), self.result(),
function, function,
Naming.quick_temp_cname, Naming.quick_temp_cname,
......
...@@ -1273,7 +1273,7 @@ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name ...@@ -1273,7 +1273,7 @@ static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(function)) { if (PyFunction_Check(function)) {
PyObject *args[2] = {self, arg}; PyObject *args[2] = {self, arg};
result = __Pyx_PyFunction_FastCall(function, args, 2, NULL); result = __Pyx_PyFunction_FastCall(function, args, 2);
goto done; goto done;
} }
#endif #endif
...@@ -1321,7 +1321,7 @@ static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name ...@@ -1321,7 +1321,7 @@ static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(function)) { if (PyFunction_Check(function)) {
PyObject *args[3] = {self, arg1, arg2}; PyObject *args[3] = {self, arg1, arg2};
result = __Pyx_PyFunction_FastCall(function, args, 3, NULL); result = __Pyx_PyFunction_FastCall(function, args, 3);
goto done; goto done;
} }
#endif #endif
...@@ -1341,7 +1341,7 @@ static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name ...@@ -1341,7 +1341,7 @@ static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(method)) { if (PyFunction_Check(method)) {
PyObject *args[2] = {arg1, arg2}; PyObject *args[2] = {arg1, arg2};
result = __Pyx_PyFunction_FastCall(method, args, 2, NULL); result = __Pyx_PyFunction_FastCall(method, args, 2);
goto done; goto done;
} else } else
#endif #endif
...@@ -1433,11 +1433,14 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject ...@@ -1433,11 +1433,14 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject
/////////////// PyFunctionFastCall.proto /////////////// /////////////// PyFunctionFastCall.proto ///////////////
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
#define __Pyx_PyFunction_FastCall(func, args, nargs) \
__Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
// let's assume that the non-public C-API function might still change during the 3.6 beta phase // let's assume that the non-public C-API function might still change during the 3.6 beta phase
#if 1 || PY_VERSION_HEX < 0x030600B1 #if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwargs); static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs);
#else #else
#define __Pyx_PyFunction_FastCall(func, args, nargs, kwargs) _PyFunction_FastCall(func, args, nargs, kwargs) #define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs)
#endif #endif
#endif #endif
...@@ -1447,8 +1450,8 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int ...@@ -1447,8 +1450,8 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
#include "frameobject.h" #include "frameobject.h"
static PyObject* __Pyx_PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na, static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na,
PyCodeObject *co, PyObject *globals) { PyObject *globals) {
PyFrameObject *f; PyFrameObject *f;
PyThreadState *tstate = PyThreadState_GET(); PyThreadState *tstate = PyThreadState_GET();
PyObject **fastlocals; PyObject **fastlocals;
...@@ -1483,7 +1486,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na, ...@@ -1483,7 +1486,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na,
#if 1 || PY_VERSION_HEX < 0x030600B1 #if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, CYTHON_UNUSED PyObject *kwargs) { static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) {
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
...@@ -1494,18 +1497,60 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int ...@@ -1494,18 +1497,60 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int
//PyObject *name, *qualname; //PyObject *name, *qualname;
//#endif //#endif
#endif #endif
PyObject *kwtuple, **k;
PyObject **d; PyObject **d;
int nd; int nd;
Py_ssize_t nk;
PyObject *result;
assert(kwargs == NULL || PyDict_Check(kwargs));
nk = kwargs ? PyDict_Size(kwargs) : 0;
/* CPython issue #27128: support for keywords will come later */ if (Py_EnterRecursiveCall(" while calling a Python object")) {
assert(kwargs == NULL); return NULL;
}
if (argdefs == NULL && co->co_argcount == nargs && if (
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
co->co_kwonlyargcount == 0 && co->co_kwonlyargcount == 0 &&
#endif #endif
likely(kwargs == NULL || nk == 0) &&
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
return __Pyx_PyFunction_FastCallNoKw(args, nargs, co, globals); /* Fast paths */
if (argdefs == NULL && co->co_argcount == nargs) {
result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals);
goto done;
}
else if (nargs == 0 && argdefs != NULL
&& co->co_argcount == Py_SIZE(argdefs)) {
/* function called with no arguments, but all parameters have
a default value: use default values as arguments .*/
args = &PyTuple_GET_ITEM(argdefs, 0);
result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals);
goto done;
}
}
if (kwargs != NULL) {
Py_ssize_t pos, i;
kwtuple = PyTuple_New(2 * nk);
if (kwtuple == NULL) {
result = NULL;
goto done;
}
k = &PyTuple_GET_ITEM(kwtuple, 0);
pos = i = 0;
while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) {
Py_INCREF(k[i]);
Py_INCREF(k[i+1]);
i += 2;
}
nk = i / 2;
}
else {
kwtuple = NULL;
k = NULL;
} }
closure = PyFunction_GET_CLOSURE(func); closure = PyFunction_GET_CLOSURE(func);
...@@ -1534,16 +1579,21 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int ...@@ -1534,16 +1579,21 @@ static PyObject *__Pyx_PyFunction_FastCall(PyObject *func, PyObject **args, int
// closure, name, qualname); // closure, name, qualname);
//#elif PY_MAJOR_VERSION >= 3 //#elif PY_MAJOR_VERSION >= 3
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
return PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL,
args, nargs, args, nargs,
NULL, 0, k, (int)nk,
d, nd, kwdefs, closure); d, nd, kwdefs, closure);
#else #else
return PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL,
args, nargs, args, nargs,
NULL, 0, k, (int)nk,
d, nd, closure); d, nd, closure);
#endif #endif
Py_XDECREF(kwtuple);
done:
Py_LeaveRecursiveCall();
return result;
} }
#endif // CPython < 3.6 #endif // CPython < 3.6
#endif // CYTHON_FAST_PYCALL #endif // CYTHON_FAST_PYCALL
...@@ -1573,7 +1623,7 @@ static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { ...@@ -1573,7 +1623,7 @@ static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(func)) { if (PyFunction_Check(func)) {
return __Pyx_PyFunction_FastCall(func, &arg, 1, NULL); return __Pyx_PyFunction_FastCall(func, &arg, 1);
} }
#endif #endif
#ifdef __Pyx_CyFunction_USED #ifdef __Pyx_CyFunction_USED
...@@ -1620,7 +1670,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); /*proto ...@@ -1620,7 +1670,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); /*proto
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(func)) { if (PyFunction_Check(func)) {
return __Pyx_PyFunction_FastCall(func, NULL, 0, NULL); return __Pyx_PyFunction_FastCall(func, NULL, 0);
} }
#endif #endif
#ifdef __Pyx_CyFunction_USED #ifdef __Pyx_CyFunction_USED
...@@ -1667,7 +1717,7 @@ static PyObject* __Pyx_PyObject_CallMatrixMethod(PyObject* method, PyObject* arg ...@@ -1667,7 +1717,7 @@ static PyObject* __Pyx_PyObject_CallMatrixMethod(PyObject* method, PyObject* arg
#if CYTHON_FAST_PYCALL #if CYTHON_FAST_PYCALL
if (PyFunction_Check(function)) { if (PyFunction_Check(function)) {
PyObject *args[2] = {self, arg}; PyObject *args[2] = {self, arg};
result = __Pyx_PyFunction_FastCall(function, args, 2, NULL); result = __Pyx_PyFunction_FastCall(function, args, 2);
goto done; goto done;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment