@@ -591,6 +591,7 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, int enable_counters
591
591
#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES 30
592
592
#define SPEC_FAIL_BINARY_OP_XOR_INT 31
593
593
#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES 32
594
+ #define SPEC_FAIL_BINARY_OP_SUBSCR 33
594
595
595
596
/* Calls */
596
597
@@ -1835,102 +1836,6 @@ function_get_version(PyObject *o, int opcode)
1835
1836
return version ;
1836
1837
}
1837
1838
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
-
1934
1839
#ifdef Py_STATS
1935
1840
static int
1936
1841
store_subscr_fail_kind (PyObject * container , PyObject * sub )
@@ -2424,6 +2329,59 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
2424
2329
return SPEC_FAIL_BINARY_OP_XOR_INT ;
2425
2330
}
2426
2331
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 ;
2427
2385
}
2428
2386
Py_UNREACHABLE ();
2429
2387
}
@@ -2634,10 +2592,46 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
2634
2592
}
2635
2593
break ;
2636
2594
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 );
2638
2611
return ;
2639
2612
}
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 ;
2641
2635
}
2642
2636
2643
2637
_PyBinaryOpSpecializationDescr * descr ;
0 commit comments