[Python-checkins] bpo-47186: Replace JUMP_IF_NOT_EXC_MATCH by CHECK_EXC_MATCH + jump (GH-32231)

markshannon webhook-mailer at python.org
Fri Apr 1 08:59:49 EDT 2022


https://github.com/python/cpython/commit/04e07c258f4f2ac85e25355242a113f98a706f04
commit: 04e07c258f4f2ac85e25355242a113f98a706f04
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: markshannon <mark at hotpy.org>
date: 2022-04-01T13:59:38+01:00
summary:

bpo-47186: Replace JUMP_IF_NOT_EXC_MATCH by CHECK_EXC_MATCH + jump (GH-32231)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-04-01-11-53-59.bpo-47186.RBCPk8.rst
M Doc/library/dis.rst
M Doc/whatsnew/3.11.rst
M Include/opcode.h
M Lib/importlib/_bootstrap_external.py
M Lib/opcode.py
M Lib/test/test_dis.py
M Objects/frameobject.c
M Python/ceval.c
M Python/compile.c
M Python/opcode_targets.h

diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index d1a0cecd82841..b364e3f031b3d 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -628,6 +628,12 @@ iterations of the loop.
 
     .. versionadded:: 3.11
 
+.. opcode:: CHECK_EXC_MATCH
+
+   Performs exception matching for ``except``. Tests whether the TOS1 is an exception
+   matching TOS. Pops TOS and pushes the boolean result of the test.
+
+   .. versionadded:: 3.11
 
 .. opcode:: WITH_EXCEPT_START
 
@@ -916,18 +922,6 @@ iterations of the loop.
    .. versionadded:: 3.1
 
 
-.. opcode:: JUMP_IF_NOT_EXC_MATCH (target)
-
-   Performs exception matching for ``except``.
-   Tests whether the second value on the stack is an exception matching TOS,
-   and jumps if it is not. Pops one value from the stack.
-
-   .. versionadded:: 3.9
-
-   .. versionchanged:: 3.11
-      This opcode no longer pops the active exception.
-
-
 .. opcode:: JUMP_IF_NOT_EG_MATCH (target)
 
    Performs exception matching for ``except*``. Applies ``split(TOS)`` on
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 15808679f7fd5..dc2d4b0937c77 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -520,7 +520,8 @@ CPython bytecode changes
 * Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to
   speed up conditional jumps.
 
-* :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception.
+* Replaced :opcode:`JUMP_IF_NOT_EXC_MATCH` by :opcode:`CHECK_EXC_MATCH` which
+  performs the check but does not jump.
 
 * Replaced :opcode:`JUMP_ABSOLUTE` by the relative :opcode:`JUMP_BACKWARD`.
 
diff --git a/Include/opcode.h b/Include/opcode.h
index 3a7db438ede1f..c82d1fd1fae2b 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -21,6 +21,7 @@ extern "C" {
 #define MATCH_SEQUENCE                          32
 #define MATCH_KEYS                              33
 #define PUSH_EXC_INFO                           35
+#define CHECK_EXC_MATCH                         36
 #define WITH_EXCEPT_START                       49
 #define GET_AITER                               50
 #define GET_ANEXT                               51
@@ -74,7 +75,6 @@ extern "C" {
 #define CONTAINS_OP                            118
 #define RERAISE                                119
 #define COPY                                   120
-#define JUMP_IF_NOT_EXC_MATCH                  121
 #define BINARY_OP                              122
 #define SEND                                   123
 #define LOAD_FAST                              124
@@ -136,39 +136,39 @@ extern "C" {
 #define COMPARE_OP_INT_JUMP                     28
 #define COMPARE_OP_STR_JUMP                     29
 #define JUMP_BACKWARD_QUICK                     34
-#define LOAD_ATTR_ADAPTIVE                      36
-#define LOAD_ATTR_INSTANCE_VALUE                37
-#define LOAD_ATTR_MODULE                        38
-#define LOAD_ATTR_SLOT                          39
-#define LOAD_ATTR_WITH_HINT                     40
-#define LOAD_CONST__LOAD_FAST                   41
-#define LOAD_FAST__LOAD_CONST                   42
-#define LOAD_FAST__LOAD_FAST                    43
-#define LOAD_GLOBAL_ADAPTIVE                    44
-#define LOAD_GLOBAL_BUILTIN                     45
-#define LOAD_GLOBAL_MODULE                      46
-#define LOAD_METHOD_ADAPTIVE                    47
-#define LOAD_METHOD_CLASS                       48
-#define LOAD_METHOD_MODULE                      55
-#define LOAD_METHOD_NO_DICT                     56
-#define LOAD_METHOD_WITH_DICT                   57
-#define LOAD_METHOD_WITH_VALUES                 58
-#define PRECALL_ADAPTIVE                        59
-#define PRECALL_BOUND_METHOD                    62
-#define PRECALL_BUILTIN_CLASS                   63
-#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS      64
-#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS  65
-#define PRECALL_NO_KW_BUILTIN_FAST              66
-#define PRECALL_NO_KW_BUILTIN_O                 67
-#define PRECALL_NO_KW_ISINSTANCE                72
-#define PRECALL_NO_KW_LEN                       73
-#define PRECALL_NO_KW_LIST_APPEND               76
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST    77
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS  78
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O       79
-#define PRECALL_NO_KW_STR_1                     80
-#define PRECALL_NO_KW_TUPLE_1                   81
-#define PRECALL_NO_KW_TYPE_1                   113
+#define LOAD_ATTR_ADAPTIVE                      37
+#define LOAD_ATTR_INSTANCE_VALUE                38
+#define LOAD_ATTR_MODULE                        39
+#define LOAD_ATTR_SLOT                          40
+#define LOAD_ATTR_WITH_HINT                     41
+#define LOAD_CONST__LOAD_FAST                   42
+#define LOAD_FAST__LOAD_CONST                   43
+#define LOAD_FAST__LOAD_FAST                    44
+#define LOAD_GLOBAL_ADAPTIVE                    45
+#define LOAD_GLOBAL_BUILTIN                     46
+#define LOAD_GLOBAL_MODULE                      47
+#define LOAD_METHOD_ADAPTIVE                    48
+#define LOAD_METHOD_CLASS                       55
+#define LOAD_METHOD_MODULE                      56
+#define LOAD_METHOD_NO_DICT                     57
+#define LOAD_METHOD_WITH_DICT                   58
+#define LOAD_METHOD_WITH_VALUES                 59
+#define PRECALL_ADAPTIVE                        62
+#define PRECALL_BOUND_METHOD                    63
+#define PRECALL_BUILTIN_CLASS                   64
+#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS      65
+#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS  66
+#define PRECALL_NO_KW_BUILTIN_FAST              67
+#define PRECALL_NO_KW_BUILTIN_O                 72
+#define PRECALL_NO_KW_ISINSTANCE                73
+#define PRECALL_NO_KW_LEN                       76
+#define PRECALL_NO_KW_LIST_APPEND               77
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST    78
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS  79
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O       80
+#define PRECALL_NO_KW_STR_1                     81
+#define PRECALL_NO_KW_TUPLE_1                  113
+#define PRECALL_NO_KW_TYPE_1                   121
 #define PRECALL_PYFUNC                         141
 #define RESUME_QUICK                           143
 #define STORE_ATTR_ADAPTIVE                    150
@@ -205,7 +205,7 @@ static const uint32_t _PyOpcode_Jump[8] = {
     0U,
     0U,
     536870912U,
-    2316156928U,
+    2282602496U,
     4163U,
     0U,
     0U,
@@ -259,6 +259,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
     [CALL_PY_EXACT_ARGS] = CALL,
     [CALL_PY_WITH_DEFAULTS] = CALL,
+    [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
     [COMPARE_OP] = COMPARE_OP,
     [COMPARE_OP_ADAPTIVE] = COMPARE_OP,
     [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP,
@@ -294,7 +295,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [JUMP_FORWARD] = JUMP_FORWARD,
     [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP,
     [JUMP_IF_NOT_EG_MATCH] = JUMP_IF_NOT_EG_MATCH,
-    [JUMP_IF_NOT_EXC_MATCH] = JUMP_IF_NOT_EXC_MATCH,
     [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP,
     [JUMP_NO_INTERRUPT] = JUMP_NO_INTERRUPT,
     [KW_NAMES] = KW_NAMES,
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 744fefd5e21e7..39a348aecef6c 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -397,6 +397,7 @@ def _write_atomic(path, data, mode=0o666):
 #     Python 3.11a6 3487 (Remove the adaptive "oparg counter" mechanism)
 #     Python 3.11a6 3488 (LOAD_GLOBAL can push additional NULL)
 #     Python 3.11a6 3489 (Add JUMP_BACKWARD, remove JUMP_ABSOLUTE)
+#     Python 3.11a6 3490 (remove JUMP_IF_NOT_EXC_MATCH, add CHECK_EXC_MATCH)
 
 #     Python 3.12 will start with magic number 3500
 
@@ -411,7 +412,7 @@ def _write_atomic(path, data, mode=0o666):
 # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
 # in PC/launcher.c must also be updated.
 
-MAGIC_NUMBER = (3489).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3490).to_bytes(2, 'little') + b'\r\n'
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
 _PYCACHE = '__pycache__'
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 6bc64177ac8fc..e993a5c1ff16a 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -76,6 +76,7 @@ def jabs_op(name, op, entries=0):
 def_op('MATCH_KEYS', 33)
 
 def_op('PUSH_EXC_INFO', 35)
+def_op('CHECK_EXC_MATCH', 36)
 
 def_op('WITH_EXCEPT_START', 49)
 def_op('GET_AITER', 50)
@@ -138,7 +139,6 @@ def jabs_op(name, op, entries=0):
 def_op('CONTAINS_OP', 118)
 def_op('RERAISE', 119)
 def_op('COPY', 120)
-jabs_op('JUMP_IF_NOT_EXC_MATCH', 121)
 def_op('BINARY_OP', 122, 1)
 jrel_op('SEND', 123) # Number of bytes to skip
 def_op('LOAD_FAST', 124)        # Local variable number
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 99db8ba0ac3b9..544e1350cb7f9 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -372,7 +372,8 @@ def bug42562():
         >> PUSH_EXC_INFO
 
 %3d        LOAD_GLOBAL              0 (Exception)
-           JUMP_IF_NOT_EXC_MATCH    35 (to 70)
+           CHECK_EXC_MATCH
+           POP_JUMP_IF_FALSE       36 (to 72)
            STORE_FAST               0 (e)
 
 %3d        LOAD_FAST                0 (e)
@@ -683,8 +684,7 @@ def test_boundaries(self):
     def test_widths(self):
         for opcode, opname in enumerate(dis.opname):
             if opname in ('BUILD_MAP_UNPACK_WITH_CALL',
-                          'BUILD_TUPLE_UNPACK_WITH_CALL',
-                          'JUMP_IF_NOT_EXC_MATCH'):
+                          'BUILD_TUPLE_UNPACK_WITH_CALL'):
                 continue
             with self.subTest(opname=opname):
                 width = dis._OPNAME_WIDTH
@@ -1299,47 +1299,48 @@ def _prepare_test_cases():
   Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_FORWARD', opcode=110, arg=30, argval=390, argrepr='to 390', offset=328, starts_line=None, is_jump_target=True, positions=None),
+  Instruction(opname='JUMP_FORWARD', opcode=110, arg=31, argval=392, argrepr='to 392', offset=328, starts_line=None, is_jump_target=True, positions=None),
   Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, starts_line=22, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=191, argval=382, argrepr='to 382', offset=344, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=346, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=348, starts_line=23, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=360, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=366, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_FORWARD', opcode=110, arg=21, argval=424, argrepr='to 424', offset=380, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=382, starts_line=22, is_jump_target=True, positions=None),
-  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=390, starts_line=28, is_jump_target=True, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=402, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=404, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=408, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=420, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=422, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=424, starts_line=23, is_jump_target=True, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=426, starts_line=28, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=438, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=440, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=444, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=454, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=456, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=458, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=460, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=462, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=474, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=476, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=480, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=490, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=492, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=494, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=496, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=498, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=192, argval=384, argrepr='to 384', offset=346, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=350, starts_line=23, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=362, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=364, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=368, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='JUMP_FORWARD', opcode=110, arg=21, argval=426, argrepr='to 426', offset=382, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=384, starts_line=22, is_jump_target=True, positions=None),
+  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=392, starts_line=28, is_jump_target=True, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=404, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=406, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=410, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=422, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=424, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=426, starts_line=23, is_jump_target=True, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=428, starts_line=28, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=440, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=442, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=446, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=456, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=458, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=460, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=462, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=464, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=476, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=478, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=482, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=492, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=494, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=496, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=498, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=500, starts_line=None, is_jump_target=False, positions=None),
 ]
 
 # One last piece of inspect fodder to check the default line number handling
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-01-11-53-59.bpo-47186.RBCPk8.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-01-11-53-59.bpo-47186.RBCPk8.rst
new file mode 100644
index 0000000000000..002da2ba3791a
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-01-11-53-59.bpo-47186.RBCPk8.rst	
@@ -0,0 +1 @@
+Replace :opcode:`JUMP_IF_NOT_EXC_MATCH` by :opcode:`CHECK_EXC_MATCH` + jump.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 581de22587219..fe374bf0632cd 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -207,7 +207,6 @@ mark_stacks(PyCodeObject *code_obj, int len)
                 case JUMP_IF_TRUE_OR_POP:
                 case POP_JUMP_IF_FALSE:
                 case POP_JUMP_IF_TRUE:
-                case JUMP_IF_NOT_EXC_MATCH:
                 case JUMP_IF_NOT_EG_MATCH:
                 {
                     int64_t target_stack;
@@ -216,8 +215,7 @@ mark_stacks(PyCodeObject *code_obj, int len)
                     if (stacks[j] == UNINITIALIZED && j < i) {
                         todo = 1;
                     }
-                    if (opcode == JUMP_IF_NOT_EXC_MATCH ||
-                        opcode == JUMP_IF_NOT_EG_MATCH)
+                    if (opcode == JUMP_IF_NOT_EG_MATCH)
                     {
                         next_stack = pop_value(pop_value(next_stack));
                         target_stack = next_stack;
diff --git a/Python/ceval.c b/Python/ceval.c
index 8c1f21b086da9..43080f8db0422 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3853,7 +3853,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
             DISPATCH();
         }
 
-        TARGET(JUMP_IF_NOT_EXC_MATCH) {
+        TARGET(CHECK_EXC_MATCH) {
             PyObject *right = POP();
             PyObject *left = TOP();
             assert(PyExceptionInstance_Check(left));
@@ -3864,9 +3864,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
 
             int res = PyErr_GivenExceptionMatches(left, right);
             Py_DECREF(right);
-            if (res == 0) {
-                JUMPTO(oparg);
-            }
+            PUSH(Py_NewRef(res ? Py_True : Py_False));
             DISPATCH();
         }
 
diff --git a/Python/compile.c b/Python/compile.c
index 7a073777ee1cf..bdf886bf42352 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -977,8 +977,8 @@ stack_effect(int opcode, int oparg, int jump)
         case IS_OP:
         case CONTAINS_OP:
             return -1;
-        case JUMP_IF_NOT_EXC_MATCH:
-            return -1;
+        case CHECK_EXC_MATCH:
+            return 0;
         case JUMP_IF_NOT_EG_MATCH:
             return jump > 0 ? -1 : 0;
         case IMPORT_NAME:
@@ -3352,7 +3352,8 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s)
    []                           JUMP            L0
 
    [exc]                L1:     <evaluate E1>           )
-   [exc, E1]                    JUMP_IF_NOT_EXC_MATCH L2        ) only if E1
+   [exc, E1]                    CHECK_EXC_MATCH         )
+   [exc, bool]                  POP_JUMP_IF_FALSE L2    ) only if E1
    [exc]                        <assign to V1>  (or POP if no V1)
    []                           <code for S1>
                                 JUMP            L0
@@ -3410,7 +3411,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
             return 0;
         if (handler->v.ExceptHandler.type) {
             VISIT(c, expr, handler->v.ExceptHandler.type);
-            ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except);
+            ADDOP(c, CHECK_EXC_MATCH);
+            ADDOP_JUMP(c, POP_JUMP_IF_FALSE, except);
         }
         if (handler->v.ExceptHandler.name) {
             basicblock *cleanup_end, *cleanup_body;
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 3afaf0b029831..2eba5531723fb 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -35,6 +35,7 @@ static void *opcode_targets[256] = {
     &&TARGET_MATCH_KEYS,
     &&TARGET_JUMP_BACKWARD_QUICK,
     &&TARGET_PUSH_EXC_INFO,
+    &&TARGET_CHECK_EXC_MATCH,
     &&TARGET_LOAD_ATTR_ADAPTIVE,
     &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
     &&TARGET_LOAD_ATTR_MODULE,
@@ -47,40 +48,39 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&TARGET_LOAD_GLOBAL_MODULE,
     &&TARGET_LOAD_METHOD_ADAPTIVE,
-    &&TARGET_LOAD_METHOD_CLASS,
     &&TARGET_WITH_EXCEPT_START,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
     &&TARGET_BEFORE_ASYNC_WITH,
     &&TARGET_BEFORE_WITH,
     &&TARGET_END_ASYNC_FOR,
+    &&TARGET_LOAD_METHOD_CLASS,
     &&TARGET_LOAD_METHOD_MODULE,
     &&TARGET_LOAD_METHOD_NO_DICT,
     &&TARGET_LOAD_METHOD_WITH_DICT,
     &&TARGET_LOAD_METHOD_WITH_VALUES,
-    &&TARGET_PRECALL_ADAPTIVE,
     &&TARGET_STORE_SUBSCR,
     &&TARGET_DELETE_SUBSCR,
+    &&TARGET_PRECALL_ADAPTIVE,
     &&TARGET_PRECALL_BOUND_METHOD,
     &&TARGET_PRECALL_BUILTIN_CLASS,
     &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS,
     &&TARGET_PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
     &&TARGET_PRECALL_NO_KW_BUILTIN_FAST,
-    &&TARGET_PRECALL_NO_KW_BUILTIN_O,
     &&TARGET_GET_ITER,
     &&TARGET_GET_YIELD_FROM_ITER,
     &&TARGET_PRINT_EXPR,
     &&TARGET_LOAD_BUILD_CLASS,
+    &&TARGET_PRECALL_NO_KW_BUILTIN_O,
     &&TARGET_PRECALL_NO_KW_ISINSTANCE,
-    &&TARGET_PRECALL_NO_KW_LEN,
     &&TARGET_LOAD_ASSERTION_ERROR,
     &&TARGET_RETURN_GENERATOR,
+    &&TARGET_PRECALL_NO_KW_LEN,
     &&TARGET_PRECALL_NO_KW_LIST_APPEND,
     &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST,
     &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
     &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O,
     &&TARGET_PRECALL_NO_KW_STR_1,
-    &&TARGET_PRECALL_NO_KW_TUPLE_1,
     &&TARGET_LIST_TO_TUPLE,
     &&TARGET_RETURN_VALUE,
     &&TARGET_IMPORT_STAR,
@@ -112,7 +112,7 @@ static void *opcode_targets[256] = {
     &&TARGET_JUMP_FORWARD,
     &&TARGET_JUMP_IF_FALSE_OR_POP,
     &&TARGET_JUMP_IF_TRUE_OR_POP,
-    &&TARGET_PRECALL_NO_KW_TYPE_1,
+    &&TARGET_PRECALL_NO_KW_TUPLE_1,
     &&TARGET_POP_JUMP_IF_FALSE,
     &&TARGET_POP_JUMP_IF_TRUE,
     &&TARGET_LOAD_GLOBAL,
@@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
     &&TARGET_CONTAINS_OP,
     &&TARGET_RERAISE,
     &&TARGET_COPY,
-    &&TARGET_JUMP_IF_NOT_EXC_MATCH,
+    &&TARGET_PRECALL_NO_KW_TYPE_1,
     &&TARGET_BINARY_OP,
     &&TARGET_SEND,
     &&TARGET_LOAD_FAST,



More information about the Python-checkins mailing list