summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-08-24 23:04:14 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-08-24 23:04:14 (GMT)
commit3f1057a4b62d8c94ae77f34f950b74a45499b218 (patch)
treecb4815a4176534216b519be17cfe84b10ce74b54 /Objects/abstract.c
parentf7507dd3e8ec84fe025c0ba82a9150275e2af9d9 (diff)
downloadcpython-3f1057a4b62d8c94ae77f34f950b74a45499b218.zip
cpython-3f1057a4b62d8c94ae77f34f950b74a45499b218.tar.gz
cpython-3f1057a4b62d8c94ae77f34f950b74a45499b218.tar.bz2
method_call() and slot_tp_new() now uses fast call
Issue #27841: Add _PyObject_Call_Prepend() helper function to prepend an argument to existing arguments to call a function. This helper uses fast calls. Modify method_call() and slot_tp_new() to use _PyObject_Call_Prepend().
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index c41fe11..9e5405d 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2388,6 +2388,45 @@ _PyObject_FastCallKeywords(PyObject *func, PyObject **stack, Py_ssize_t nargs,
return result;
}
+/* Positional arguments are obj followed args. */
+PyObject *
+_PyObject_Call_Prepend(PyObject *func,
+ PyObject *obj, PyObject *args, PyObject *kwargs)
+{
+ PyObject *small_stack[8];
+ PyObject **stack;
+ Py_ssize_t argcount;
+ PyObject *result;
+
+ assert(PyTuple_Check(args));
+
+ argcount = PyTuple_GET_SIZE(args);
+ if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
+ stack = small_stack;
+ }
+ else {
+ stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *));
+ if (stack == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ }
+
+ /* use borrowed references */
+ stack[0] = obj;
+ Py_MEMCPY(&stack[1],
+ &PyTuple_GET_ITEM(args, 0),
+ argcount * sizeof(PyObject *));
+
+ result = _PyObject_FastCallDict(func,
+ stack, argcount + 1,
+ kwargs);
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
+ return result;
+}
+
static PyObject*
call_function_tail(PyObject *callable, PyObject *args)
{