diff options
Diffstat (limited to 'Python/specialize.c')
-rw-r--r-- | Python/specialize.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/Python/specialize.c b/Python/specialize.c index bdcba46ed4..5cf327df47 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -491,8 +491,10 @@ initial_counter_value(void) { #define SPEC_FAIL_PYCFUNCTION_NOARGS 16 #define SPEC_FAIL_BAD_CALL_FLAGS 17 #define SPEC_FAIL_CLASS 18 -#define SPEC_FAIL_C_METHOD_CALL 19 -#define SPEC_FAIL_METHDESCR_NON_METHOD 20 +#define SPEC_FAIL_PYTHON_CLASS 19 +#define SPEC_FAIL_C_METHOD_CALL 20 +#define SPEC_FAIL_METHDESCR_NON_METHOD 21 +#define SPEC_FAIL_METHOD_CALL_CLASS 22 /* COMPARE_OP */ #define SPEC_FAIL_STRING_COMPARE 13 @@ -1263,6 +1265,27 @@ specialize_class_call( PyObject *callable, _Py_CODEUNIT *instr, int nargs, SpecializedCacheEntry *cache) { + assert(PyType_Check(callable)); + PyTypeObject *tp = (PyTypeObject *)callable; + if (_Py_OPCODE(instr[-1]) == PRECALL_METHOD) { + SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_METHOD_CALL_CLASS); + return -1; + } + if (tp->tp_new == PyBaseObject_Type.tp_new) { + SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_PYTHON_CLASS); + return -1; + } + if (nargs == 1) { + if (tp == &PyType_Type) { + *instr = _Py_MAKECODEUNIT(CALL_NO_KW_TYPE_1, _Py_OPARG(*instr)); + return 0; + } + if ((tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) && tp->tp_vectorcall != NULL) { + cache->adaptive.version = tp->tp_version_tag; + *instr = _Py_MAKECODEUNIT(CALL_NO_KW_BUILTIN_CLASS_1, _Py_OPARG(*instr)); + return 0; + } + } SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_CLASS); return -1; } |