@@ -591,6 +591,7 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
591591#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES 30
592592#define SPEC_FAIL_BINARY_OP_XOR_INT 31
593593#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES 32
594+ #define SPEC_FAIL_BINARY_OP_SUBSCR 33
594595
595596/* Calls */
596597
@@ -1835,102 +1836,6 @@ function_get_version(PyObject *o, int opcode)
18351836 return version ;
18361837}
18371838
1838- static int
1839- specialize_binary_op_subscr (
1840- PyObject * container , PyObject * sub , _Py_CODEUNIT * instr )
1841- {
1842- PyTypeObject * container_type = Py_TYPE (container );
1843- uint8_t specialized_op ;
1844- if (container_type == & PyList_Type ) {
1845- if (PyLong_CheckExact (sub )) {
1846- if (_PyLong_IsNonNegativeCompact ((PyLongObject * )sub )) {
1847- specialized_op = BINARY_OP_SUBSCR_LIST_INT ;
1848- goto success ;
1849- }
1850- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_OUT_OF_RANGE );
1851- goto fail ;
1852- }
1853- SPECIALIZATION_FAIL (BINARY_OP ,
1854- PySlice_Check (sub ) ? SPEC_FAIL_SUBSCR_LIST_SLICE : SPEC_FAIL_OTHER );
1855- goto fail ;
1856- }
1857- if (container_type == & PyTuple_Type ) {
1858- if (PyLong_CheckExact (sub )) {
1859- if (_PyLong_IsNonNegativeCompact ((PyLongObject * )sub )) {
1860- specialized_op = BINARY_OP_SUBSCR_TUPLE_INT ;
1861- goto success ;
1862- }
1863- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_OUT_OF_RANGE );
1864- goto fail ;
1865- }
1866- SPECIALIZATION_FAIL (BINARY_OP ,
1867- PySlice_Check (sub ) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER );
1868- goto fail ;
1869- }
1870- if (container_type == & PyUnicode_Type ) {
1871- if (PyLong_CheckExact (sub )) {
1872- if (_PyLong_IsNonNegativeCompact ((PyLongObject * )sub )) {
1873- specialized_op = BINARY_OP_SUBSCR_STR_INT ;
1874- goto success ;
1875- }
1876- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_OUT_OF_RANGE );
1877- goto fail ;
1878- }
1879- SPECIALIZATION_FAIL (BINARY_OP ,
1880- PySlice_Check (sub ) ? SPEC_FAIL_SUBSCR_STRING_SLICE : SPEC_FAIL_OTHER );
1881- goto fail ;
1882- }
1883- if (container_type == & PyDict_Type ) {
1884- specialized_op = BINARY_OP_SUBSCR_DICT ;
1885- goto success ;
1886- }
1887- unsigned int tp_version ;
1888- PyObject * descriptor = _PyType_LookupRefAndVersion (container_type , & _Py_ID (__getitem__ ), & tp_version );
1889- if (descriptor && Py_TYPE (descriptor ) == & PyFunction_Type ) {
1890- if (!(container_type -> tp_flags & Py_TPFLAGS_HEAPTYPE )) {
1891- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE );
1892- Py_DECREF (descriptor );
1893- goto fail ;
1894- }
1895- PyFunctionObject * func = (PyFunctionObject * )descriptor ;
1896- PyCodeObject * fcode = (PyCodeObject * )func -> func_code ;
1897- int kind = function_kind (fcode );
1898- if (kind != SIMPLE_FUNCTION ) {
1899- SPECIALIZATION_FAIL (BINARY_OP , kind );
1900- Py_DECREF (descriptor );
1901- goto fail ;
1902- }
1903- if (fcode -> co_argcount != 2 ) {
1904- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_WRONG_NUMBER_ARGUMENTS );
1905- Py_DECREF (descriptor );
1906- goto fail ;
1907- }
1908-
1909- PyHeapTypeObject * ht = (PyHeapTypeObject * )container_type ;
1910- /* Don't specialize if PEP 523 is active */
1911- if (_PyInterpreterState_GET ()-> eval_frame ) {
1912- SPECIALIZATION_FAIL (BINARY_OP , SPEC_FAIL_OTHER );
1913- Py_DECREF (descriptor );
1914- goto fail ;
1915- }
1916- if (_PyType_CacheGetItemForSpecialization (ht , descriptor , (uint32_t )tp_version )) {
1917- specialized_op = BINARY_OP_SUBSCR_GETITEM ;
1918- Py_DECREF (descriptor );
1919- goto success ;
1920- }
1921- }
1922- Py_XDECREF (descriptor );
1923- SPECIALIZATION_FAIL (BINARY_OP ,
1924- binary_subscr_fail_kind (container_type , sub ));
1925- fail :
1926- unspecialize (instr );
1927- return 0 ;
1928- success :
1929- specialize (instr , specialized_op );
1930- return 1 ;
1931- }
1932-
1933-
19341839#ifdef Py_STATS
19351840static int
19361841store_subscr_fail_kind (PyObject * container , PyObject * sub )
@@ -2424,6 +2329,59 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
24242329 return SPEC_FAIL_BINARY_OP_XOR_INT ;
24252330 }
24262331 return SPEC_FAIL_BINARY_OP_XOR ;
2332+ case NB_SUBSCR :
2333+ if (PyList_CheckExact (lhs )) {
2334+ if (PyLong_CheckExact (rhs ) && !_PyLong_IsNonNegativeCompact ((PyLongObject * )rhs )) {
2335+ return SPEC_FAIL_OUT_OF_RANGE ;
2336+ }
2337+ if (PySlice_Check (rhs )) {
2338+ return SPEC_FAIL_SUBSCR_LIST_SLICE ;
2339+ }
2340+ }
2341+ if (PyTuple_CheckExact (lhs )) {
2342+ if (PyLong_CheckExact (rhs ) && !_PyLong_IsNonNegativeCompact ((PyLongObject * )rhs )) {
2343+ return SPEC_FAIL_OUT_OF_RANGE ;
2344+ }
2345+ if (PySlice_Check (rhs )) {
2346+ return SPEC_FAIL_SUBSCR_TUPLE_SLICE ;
2347+ }
2348+ }
2349+ if (PyUnicode_CheckExact (lhs )) {
2350+ if (PyLong_CheckExact (rhs ) && !_PyLong_IsNonNegativeCompact ((PyLongObject * )rhs )) {
2351+ return SPEC_FAIL_OUT_OF_RANGE ;
2352+ }
2353+ if (PySlice_Check (rhs )) {
2354+ return SPEC_FAIL_SUBSCR_STRING_SLICE ;
2355+ }
2356+ }
2357+ unsigned int tp_version ;
2358+ PyTypeObject * container_type = Py_TYPE (lhs );
2359+ PyObject * descriptor = _PyType_LookupRefAndVersion (container_type , & _Py_ID (__getitem__ ), & tp_version );
2360+ if (descriptor && Py_TYPE (descriptor ) == & PyFunction_Type ) {
2361+ if (!(container_type -> tp_flags & Py_TPFLAGS_HEAPTYPE )) {
2362+ Py_DECREF (descriptor );
2363+ return SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE ;
2364+ }
2365+ PyFunctionObject * func = (PyFunctionObject * )descriptor ;
2366+ PyCodeObject * fcode = (PyCodeObject * )func -> func_code ;
2367+ int kind = function_kind (fcode );
2368+ if (kind != SIMPLE_FUNCTION ) {
2369+ Py_DECREF (descriptor );
2370+ return kind ;
2371+ }
2372+ if (fcode -> co_argcount != 2 ) {
2373+ Py_DECREF (descriptor );
2374+ return SPEC_FAIL_WRONG_NUMBER_ARGUMENTS ;
2375+ }
2376+
2377+ if (_PyInterpreterState_GET ()-> eval_frame ) {
2378+ /* Don't specialize if PEP 523 is active */
2379+ Py_DECREF (descriptor );
2380+ return SPEC_FAIL_OTHER ;
2381+ }
2382+ }
2383+ Py_XDECREF (descriptor );
2384+ return SPEC_FAIL_BINARY_OP_SUBSCR ;
24272385 }
24282386 Py_UNREACHABLE ();
24292387}
@@ -2634,10 +2592,46 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
26342592 }
26352593 break ;
26362594 case NB_SUBSCR :
2637- if (specialize_binary_op_subscr (lhs , rhs , instr )) {
2595+ if (PyLong_CheckExact (rhs ) && _PyLong_IsNonNegativeCompact ((PyLongObject * )rhs )) {
2596+ if (PyList_CheckExact (lhs )) {
2597+ specialize (instr , BINARY_OP_SUBSCR_LIST_INT );
2598+ return ;
2599+ }
2600+ if (PyTuple_CheckExact (lhs )) {
2601+ specialize (instr , BINARY_OP_SUBSCR_TUPLE_INT );
2602+ return ;
2603+ }
2604+ if (PyUnicode_CheckExact (lhs )) {
2605+ specialize (instr , BINARY_OP_SUBSCR_STR_INT );
2606+ return ;
2607+ }
2608+ }
2609+ if (PyDict_CheckExact (lhs )) {
2610+ specialize (instr , BINARY_OP_SUBSCR_DICT );
26382611 return ;
26392612 }
2640- return ;
2613+ unsigned int tp_version ;
2614+ PyTypeObject * container_type = Py_TYPE (lhs );
2615+ PyObject * descriptor = _PyType_LookupRefAndVersion (container_type , & _Py_ID (__getitem__ ), & tp_version );
2616+ if (descriptor && Py_TYPE (descriptor ) == & PyFunction_Type &&
2617+ container_type -> tp_flags & Py_TPFLAGS_HEAPTYPE )
2618+ {
2619+ PyFunctionObject * func = (PyFunctionObject * )descriptor ;
2620+ PyCodeObject * fcode = (PyCodeObject * )func -> func_code ;
2621+ int kind = function_kind (fcode );
2622+ PyHeapTypeObject * ht = (PyHeapTypeObject * )container_type ;
2623+ if (kind == SIMPLE_FUNCTION &&
2624+ fcode -> co_argcount == 2 &&
2625+ !_PyInterpreterState_GET ()-> eval_frame && /* Don't specialize if PEP 523 is active */
2626+ _PyType_CacheGetItemForSpecialization (ht , descriptor , (uint32_t )tp_version ))
2627+ {
2628+ specialize (instr , BINARY_OP_SUBSCR_GETITEM );
2629+ Py_DECREF (descriptor );
2630+ return ;
2631+ }
2632+ }
2633+ Py_XDECREF (descriptor );
2634+ break ;
26412635 }
26422636
26432637 _PyBinaryOpSpecializationDescr * descr ;
0 commit comments