diff --git a/Python/specialize.c b/Python/specialize.c index cd09b188b7fa97e..1d0b8a533dbb243 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -383,26 +383,26 @@ _PyCode_Quicken(PyCodeObject *code) #define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9 #define SPEC_FAIL_CALL_CO_NOT_OPTIMIZED 10 /* SPEC_FAIL_METHOD defined as 11 above */ - -#define SPEC_FAIL_CALL_INSTANCE_METHOD 11 -#define SPEC_FAIL_CALL_CMETHOD 12 -#define SPEC_FAIL_CALL_PYCFUNCTION 13 -#define SPEC_FAIL_CALL_PYCFUNCTION_WITH_KEYWORDS 14 -#define SPEC_FAIL_CALL_PYCFUNCTION_FAST_WITH_KEYWORDS 15 -#define SPEC_FAIL_CALL_PYCFUNCTION_NOARGS 16 -#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 17 -#define SPEC_FAIL_CALL_CLASS 18 -#define SPEC_FAIL_CALL_PYTHON_CLASS 19 -#define SPEC_FAIL_CALL_METHOD_DESCRIPTOR 20 -#define SPEC_FAIL_CALL_BOUND_METHOD 21 -#define SPEC_FAIL_CALL_STR 22 -#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 23 -#define SPEC_FAIL_CALL_CLASS_MUTABLE 24 -#define SPEC_FAIL_CALL_KWNAMES 25 -#define SPEC_FAIL_CALL_METHOD_WRAPPER 26 -#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 27 -#define SPEC_FAIL_CALL_PYFUNCTION 28 -#define SPEC_FAIL_CALL_PEP_523 29 +/* code flag kind */ +#define SPEC_FAIL_CALL_CFUNCTION_FLAG_NOARGS 11 +#define SPEC_FAIL_CALL_CFUNCTION_FLAG_VARARGS 12 +#define SPEC_FAIL_CALL_CFUNCTION_FLAG_VARARGS_KW 13 +#define SPEC_FAIL_CALL_FLAG_VARARGS 14 +#define SPEC_FAIL_CALL_FLAG_VARARGS_KW 15 +#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 16 +/* callable type kind */ +#define SPEC_FAIL_CALL_INSTANCE_METHOD 17 +#define SPEC_FAIL_CALL_CMETHOD 18 +#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 19 +#define SPEC_FAIL_CALL_METHOD_WRAPPER 20 +/* unsupported cases */ +#define SPEC_FAIL_CALL_PYTHON_CLASS 21 +#define SPEC_FAIL_CALL_BOUND_METHOD 22 +#define SPEC_FAIL_CALL_STR 23 +#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 24 +#define SPEC_FAIL_CALL_CLASS_MUTABLE 25 +#define SPEC_FAIL_CALL_KWNAMES 26 +#define SPEC_FAIL_CALL_PEP_523 27 /* COMPARE_OP */ #define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12 @@ -1470,18 +1470,17 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, #ifdef Py_STATS static int -builtin_call_fail_kind(int ml_flags) +code_flag_fail_kind(int co_flags, bool is_cfunc) { - switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | + switch (co_flags & + (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + return is_cfunc ? SPEC_FAIL_CALL_CFUNCTION_FLAG_NOARGS : SPEC_FAIL_CALL_BAD_CALL_FLAGS; case METH_VARARGS: - return SPEC_FAIL_CALL_PYCFUNCTION; + return is_cfunc ? SPEC_FAIL_CALL_CFUNCTION_FLAG_VARARGS : SPEC_FAIL_CALL_FLAG_VARARGS; case METH_VARARGS | METH_KEYWORDS: - return SPEC_FAIL_CALL_PYCFUNCTION_WITH_KEYWORDS; - case METH_FASTCALL | METH_KEYWORDS: - return SPEC_FAIL_CALL_PYCFUNCTION_FAST_WITH_KEYWORDS; - case METH_NOARGS: - return SPEC_FAIL_CALL_PYCFUNCTION_NOARGS; + return is_cfunc ? SPEC_FAIL_CALL_CFUNCTION_FLAG_VARARGS_KW : SPEC_FAIL_CALL_FLAG_VARARGS_KW; /* This case should never happen with PyCFunctionObject -- only PyMethodObject. See zlib.compressobj()'s methods for an example. */ @@ -1538,7 +1537,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, return 0; } } - SPECIALIZATION_FAIL(CALL, builtin_call_fail_kind(descr->d_method->ml_flags)); + SPECIALIZATION_FAIL(CALL, code_flag_fail_kind(descr->d_method->ml_flags, false)); return -1; } @@ -1646,8 +1645,7 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, return 0; } default: - SPECIALIZATION_FAIL(CALL, - builtin_call_fail_kind(PyCFunction_GET_FLAGS(callable))); + SPECIALIZATION_FAIL(CALL, code_flag_fail_kind(PyCFunction_GET_FLAGS(callable), true)); return 1; } } @@ -1656,37 +1654,17 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, static int call_fail_kind(PyObject *callable) { - if (PyCFunction_CheckExact(callable)) { - return SPEC_FAIL_CALL_PYCFUNCTION; - } - else if (PyFunction_Check(callable)) { - return SPEC_FAIL_CALL_PYFUNCTION; - } - else if (PyInstanceMethod_Check(callable)) { + if (PyInstanceMethod_Check(callable)) { return SPEC_FAIL_CALL_INSTANCE_METHOD; } - else if (PyMethod_Check(callable)) { - return SPEC_FAIL_CALL_BOUND_METHOD; - } // builtin method else if (PyCMethod_Check(callable)) { return SPEC_FAIL_CALL_CMETHOD; } - else if (PyType_Check(callable)) { - if (((PyTypeObject *)callable)->tp_new == PyBaseObject_Type.tp_new) { - return SPEC_FAIL_CALL_PYTHON_CLASS; - } - else { - return SPEC_FAIL_CALL_CLASS; - } - } - else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { - return SPEC_FAIL_CALL_METHOD_DESCRIPTOR; - } - else if (Py_TYPE(callable) == &PyWrapperDescr_Type) { + else if (Py_IS_TYPE(callable, &PyWrapperDescr_Type)) { return SPEC_FAIL_CALL_OPERATOR_WRAPPER; } - else if (Py_TYPE(callable) == &_PyMethodWrapper_Type) { + else if (Py_IS_TYPE(callable, &_PyMethodWrapper_Type)) { return SPEC_FAIL_CALL_METHOD_WRAPPER; } return SPEC_FAIL_OTHER; @@ -1718,7 +1696,7 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, fail = specialize_method_descriptor((PyMethodDescrObject *)callable, instr, nargs, kwnames); } - else if (Py_TYPE(callable) == &PyMethod_Type) { + else if (Py_IS_TYPE(callable, &PyMethod_Type)) { PyObject *func = ((PyMethodObject *)callable)->im_func; if (PyFunction_Check(func)) { fail = specialize_py_call((PyFunctionObject *)func,