diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-08-24 23:04:14 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-08-24 23:04:14 (GMT) |
commit | 3f1057a4b62d8c94ae77f34f950b74a45499b218 (patch) | |
tree | cb4815a4176534216b519be17cfe84b10ce74b54 /Objects/abstract.c | |
parent | f7507dd3e8ec84fe025c0ba82a9150275e2af9d9 (diff) | |
download | cpython-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.c | 39 |
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) { |