@@ -71,14 +71,15 @@ do { \
7171
7272#define inst (name , ...) case name:
7373#define super (name ) static int SUPER_##name
74- #define family (name ) static int family_##name
74+ #define family (name , ... ) static int family_##name
7575
7676#define NAME_ERROR_MSG \
7777 "name '%.200s' is not defined"
7878
7979// Dummy variables for stack effects.
8080static PyObject * value , * value1 , * value2 , * left , * right , * res , * sum , * prod , * sub ;
8181static PyObject * container , * start , * stop , * v , * lhs , * rhs ;
82+ static PyObject * list , * tuple , * dict ;
8283
8384static PyObject *
8485dummy_func (
@@ -322,7 +323,15 @@ dummy_func(
322323 ERROR_IF (sum == NULL , error );
323324 }
324325
325- inst (BINARY_SUBSCR , (container , sub -- res )) {
326+ family (binary_subscr , INLINE_CACHE_ENTRIES_BINARY_SUBSCR ) = {
327+ BINARY_SUBSCR ,
328+ BINARY_SUBSCR_DICT ,
329+ BINARY_SUBSCR_GETITEM ,
330+ BINARY_SUBSCR_LIST_INT ,
331+ BINARY_SUBSCR_TUPLE_INT ,
332+ };
333+
334+ inst (BINARY_SUBSCR , (container , sub , unused /4 -- res )) {
326335 _PyBinarySubscrCache * cache = (_PyBinarySubscrCache * )next_instr ;
327336 if (ADAPTIVE_COUNTER_IS_ZERO (cache -> counter )) {
328337 assert (cframe .use_tracing == 0 );
@@ -336,7 +345,6 @@ dummy_func(
336345 Py_DECREF (container );
337346 Py_DECREF (sub );
338347 ERROR_IF (res == NULL , error );
339- JUMPBY (INLINE_CACHE_ENTRIES_BINARY_SUBSCR );
340348 }
341349
342350 inst (BINARY_SLICE , (container , start , stop -- res )) {
@@ -369,11 +377,8 @@ dummy_func(
369377 ERROR_IF (err , error );
370378 }
371379
372- // stack effect: (__0 -- )
373- inst (BINARY_SUBSCR_LIST_INT ) {
380+ inst (BINARY_SUBSCR_LIST_INT , (list , sub , unused /4 -- res )) {
374381 assert (cframe .use_tracing == 0 );
375- PyObject * sub = TOP ();
376- PyObject * list = SECOND ();
377382 DEOPT_IF (!PyLong_CheckExact (sub ), BINARY_SUBSCR );
378383 DEOPT_IF (!PyList_CheckExact (list ), BINARY_SUBSCR );
379384
@@ -384,21 +389,15 @@ dummy_func(
384389 Py_ssize_t index = ((PyLongObject * )sub )-> ob_digit [0 ];
385390 DEOPT_IF (index >= PyList_GET_SIZE (list ), BINARY_SUBSCR );
386391 STAT_INC (BINARY_SUBSCR , hit );
387- PyObject * res = PyList_GET_ITEM (list , index );
392+ res = PyList_GET_ITEM (list , index );
388393 assert (res != NULL );
389394 Py_INCREF (res );
390- STACK_SHRINK (1 );
391395 _Py_DECREF_SPECIALIZED (sub , (destructor )PyObject_Free );
392- SET_TOP (res );
393396 Py_DECREF (list );
394- JUMPBY (INLINE_CACHE_ENTRIES_BINARY_SUBSCR );
395397 }
396398
397- // stack effect: (__0 -- )
398- inst (BINARY_SUBSCR_TUPLE_INT ) {
399+ inst (BINARY_SUBSCR_TUPLE_INT , (tuple , sub , unused /4 -- res )) {
399400 assert (cframe .use_tracing == 0 );
400- PyObject * sub = TOP ();
401- PyObject * tuple = SECOND ();
402401 DEOPT_IF (!PyLong_CheckExact (sub ), BINARY_SUBSCR );
403402 DEOPT_IF (!PyTuple_CheckExact (tuple ), BINARY_SUBSCR );
404403
@@ -409,51 +408,39 @@ dummy_func(
409408 Py_ssize_t index = ((PyLongObject * )sub )-> ob_digit [0 ];
410409 DEOPT_IF (index >= PyTuple_GET_SIZE (tuple ), BINARY_SUBSCR );
411410 STAT_INC (BINARY_SUBSCR , hit );
412- PyObject * res = PyTuple_GET_ITEM (tuple , index );
411+ res = PyTuple_GET_ITEM (tuple , index );
413412 assert (res != NULL );
414413 Py_INCREF (res );
415- STACK_SHRINK (1 );
416414 _Py_DECREF_SPECIALIZED (sub , (destructor )PyObject_Free );
417- SET_TOP (res );
418415 Py_DECREF (tuple );
419- JUMPBY (INLINE_CACHE_ENTRIES_BINARY_SUBSCR );
420416 }
421417
422- // stack effect: (__0 -- )
423- inst (BINARY_SUBSCR_DICT ) {
418+ inst (BINARY_SUBSCR_DICT , (dict , sub , unused /4 -- res )) {
424419 assert (cframe .use_tracing == 0 );
425- PyObject * dict = SECOND ();
426- DEOPT_IF (!PyDict_CheckExact (SECOND ()), BINARY_SUBSCR );
420+ DEOPT_IF (!PyDict_CheckExact (dict ), BINARY_SUBSCR );
427421 STAT_INC (BINARY_SUBSCR , hit );
428- PyObject * sub = TOP ();
429- PyObject * res = PyDict_GetItemWithError (dict , sub );
422+ res = PyDict_GetItemWithError (dict , sub );
430423 if (res == NULL ) {
431424 if (!_PyErr_Occurred (tstate )) {
432425 _PyErr_SetKeyError (sub );
433426 }
434- goto error ;
427+ Py_DECREF (dict );
428+ Py_DECREF (sub );
429+ ERROR_IF (1 , error );
435430 }
436- Py_INCREF (res );
437- STACK_SHRINK (1 );
438- Py_DECREF (sub );
439- SET_TOP (res );
431+ Py_INCREF (res ); // Do this before DECREF'ing dict, sub
440432 Py_DECREF (dict );
441- JUMPBY ( INLINE_CACHE_ENTRIES_BINARY_SUBSCR );
433+ Py_DECREF ( sub );
442434 }
443435
444- // stack effect: (__0 -- )
445- inst (BINARY_SUBSCR_GETITEM ) {
446- PyObject * sub = TOP ();
447- PyObject * container = SECOND ();
448- _PyBinarySubscrCache * cache = (_PyBinarySubscrCache * )next_instr ;
449- uint32_t type_version = read_u32 (cache -> type_version );
436+ inst (BINARY_SUBSCR_GETITEM , (container , sub , unused /1 , type_version /2 , func_version /1 -- unused )) {
450437 PyTypeObject * tp = Py_TYPE (container );
451438 DEOPT_IF (tp -> tp_version_tag != type_version , BINARY_SUBSCR );
452439 assert (tp -> tp_flags & Py_TPFLAGS_HEAPTYPE );
453440 PyObject * cached = ((PyHeapTypeObject * )tp )-> _spec_cache .getitem ;
454441 assert (PyFunction_Check (cached ));
455442 PyFunctionObject * getitem = (PyFunctionObject * )cached ;
456- DEOPT_IF (getitem -> func_version != cache -> func_version , BINARY_SUBSCR );
443+ DEOPT_IF (getitem -> func_version != func_version , BINARY_SUBSCR );
457444 PyCodeObject * code = (PyCodeObject * )getitem -> func_code ;
458445 assert (code -> co_argcount == 2 );
459446 DEOPT_IF (!_PyThreadState_HasStackSpace (tstate , code -> co_framesize ), BINARY_SUBSCR );
0 commit comments