diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 1d2c643..f3329b5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5254,11 +5254,15 @@ handle_eval_breaker: assert(call_shape.kwnames == NULL); int is_meth = is_method(stack_pointer, oparg); int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); DEOPT_IF(total_args != 2, PRECALL); DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; + PyMethodDef *meth = callable->d_method; DEOPT_IF(meth->ml_flags != METH_O, PRECALL); + PyObject *arg = TOP(); + PyObject *self = SECOND(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); STAT_INC(PRECALL, hit); SKIP_CALL(); PyCFunction cfunc = meth->ml_meth; @@ -5267,8 +5271,6 @@ handle_eval_breaker: if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { goto error; } - PyObject *arg = TOP(); - PyObject *self = SECOND(); PyObject *res = cfunc(self, arg); _Py_LeaveRecursiveCall(tstate); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -5287,17 +5289,22 @@ handle_eval_breaker: TARGET(PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { int is_meth = is_method(stack_pointer, oparg); int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; + PyMethodDef *meth = callable->d_method; DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), PRECALL); + PyTypeObject *d_type = callable->d_common.d_type; + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, d_type), PRECALL); STAT_INC(PRECALL, hit); SKIP_CALL(); int nargs = total_args-1; STACK_SHRINK(nargs); - _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; - PyObject *self = TOP(); - PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), call_shape.kwnames); + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), + call_shape.kwnames); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); call_shape.kwnames = NULL; @@ -5322,9 +5329,11 @@ handle_eval_breaker: int is_meth = is_method(stack_pointer, oparg); int total_args = oparg + is_meth; DEOPT_IF(total_args != 1, PRECALL); - PyObject *callable = SECOND(); + PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; + PyMethodDef *meth = callable->d_method; + PyObject *self = TOP(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); DEOPT_IF(meth->ml_flags != METH_NOARGS, PRECALL); STAT_INC(PRECALL, hit); SKIP_CALL(); @@ -5334,7 +5343,6 @@ handle_eval_breaker: if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { goto error; } - PyObject *self = TOP(); PyObject *res = cfunc(self, NULL); _Py_LeaveRecursiveCall(tstate); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -5353,17 +5361,20 @@ handle_eval_breaker: assert(call_shape.kwnames == NULL); int is_meth = is_method(stack_pointer, oparg); int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); /* Builtin METH_FASTCALL methods, without keywords */ DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; + PyMethodDef *meth = callable->d_method; DEOPT_IF(meth->ml_flags != METH_FASTCALL, PRECALL); + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); STAT_INC(PRECALL, hit); SKIP_CALL(); - _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; int nargs = total_args-1; STACK_SHRINK(nargs); - PyObject *self = TOP(); PyObject *res = cfunc(self, stack_pointer, nargs); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); /* Clear the stack of the arguments. */ |