summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-10-27 14:26:22 (GMT)
committerGitHub <noreply@github.com>2021-10-27 14:26:22 (GMT)
commit4776b07d178b2800374f5c15da182f1215756205 (patch)
tree1f1c6e6c64d1666e83dde5ee3caec8254ff6fe36 /Python/ceval.c
parentbcee6aa31550cfecdc3acecbd0e4447bb0051887 (diff)
downloadcpython-4776b07d178b2800374f5c15da182f1215756205.zip
cpython-4776b07d178b2800374f5c15da182f1215756205.tar.gz
cpython-4776b07d178b2800374f5c15da182f1215756205.tar.bz2
Don't make a call at the C level when calling bound-methods from Python code. (GH-29238)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index a0f4c80..bd01e81 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4607,8 +4607,21 @@ check_eval_breaker:
kwnames = NULL;
postcall_shrink = 1;
call_function:
- // Check if the call can be inlined or not
function = PEEK(oparg + 1);
+ if (Py_TYPE(function) == &PyMethod_Type) {
+ PyObject *meth = ((PyMethodObject *)function)->im_func;
+ PyObject *self = ((PyMethodObject *)function)->im_self;
+ Py_INCREF(meth);
+ Py_INCREF(self);
+ PEEK(oparg + 1) = self;
+ Py_DECREF(function);
+ function = meth;
+ oparg++;
+ nargs++;
+ assert(postcall_shrink >= 1);
+ postcall_shrink--;
+ }
+ // Check if the call can be inlined or not
if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL) {
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags;
int is_generator = code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);