[Python-checkins] gh-101632: Add the new RETURN_CONST opcode (#101633)

iritkatriel webhook-mailer at python.org
Tue Feb 7 17:32:28 EST 2023


https://github.com/python/cpython/commit/753fc8a5d64369cd228c3e43fef1811ac3cfde83
commit: 753fc8a5d64369cd228c3e43fef1811ac3cfde83
branch: main
author: penguin_wwy <940375606 at qq.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-02-07T22:32:21Z
summary:

gh-101632: Add the new RETURN_CONST opcode (#101633)

files:
A Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst
M Doc/library/dis.rst
M Include/internal/pycore_opcode.h
M Include/opcode.h
M Lib/dis.py
M Lib/importlib/_bootstrap_external.py
M Lib/opcode.py
M Lib/test/test_ast.py
M Lib/test/test_code.py
M Lib/test/test_compile.py
M Lib/test/test_dis.py
M Lib/test/test_peepholer.py
M Objects/frameobject.c
M Programs/test_frozenmain.h
M Python/bytecodes.c
M Python/compile.c
M Python/generated_cases.c.h
M Python/opcode_metadata.h
M Python/opcode_targets.h

diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 1fe2d5d6227d..b1e61d7e77b2 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -694,6 +694,13 @@ iterations of the loop.
    Returns with ``STACK[-1]`` to the caller of the function.
 
 
+.. opcode:: RETURN_CONST (consti)
+
+   Returns with ``co_consts[consti]`` to the caller of the function.
+
+   .. versionadded:: 3.12
+
+
 .. opcode:: YIELD_VALUE
 
    Yields ``STACK.pop()`` from a :term:`generator`.
diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h
index 05c0485b0641..47c847213351 100644
--- a/Include/internal/pycore_opcode.h
+++ b/Include/internal/pycore_opcode.h
@@ -192,6 +192,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [RAISE_VARARGS] = RAISE_VARARGS,
     [RERAISE] = RERAISE,
     [RESUME] = RESUME,
+    [RETURN_CONST] = RETURN_CONST,
     [RETURN_GENERATOR] = RETURN_GENERATOR,
     [RETURN_VALUE] = RETURN_VALUE,
     [SEND] = SEND,
@@ -349,7 +350,7 @@ static const char *const _PyOpcode_OpName[263] = {
     [CONTAINS_OP] = "CONTAINS_OP",
     [RERAISE] = "RERAISE",
     [COPY] = "COPY",
-    [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
+    [RETURN_CONST] = "RETURN_CONST",
     [BINARY_OP] = "BINARY_OP",
     [SEND] = "SEND",
     [LOAD_FAST] = "LOAD_FAST",
@@ -371,7 +372,7 @@ static const char *const _PyOpcode_OpName[263] = {
     [JUMP_BACKWARD] = "JUMP_BACKWARD",
     [COMPARE_AND_BRANCH] = "COMPARE_AND_BRANCH",
     [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
-    [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
+    [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
     [EXTENDED_ARG] = "EXTENDED_ARG",
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
@@ -381,15 +382,15 @@ static const char *const _PyOpcode_OpName[263] = {
     [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
     [MATCH_CLASS] = "MATCH_CLASS",
+    [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
     [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
-    [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
     [FORMAT_VALUE] = "FORMAT_VALUE",
     [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
     [BUILD_STRING] = "BUILD_STRING",
+    [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
     [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
     [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
     [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
-    [161] = "<161>",
     [LIST_EXTEND] = "LIST_EXTEND",
     [SET_UPDATE] = "SET_UPDATE",
     [DICT_MERGE] = "DICT_MERGE",
@@ -495,7 +496,6 @@ static const char *const _PyOpcode_OpName[263] = {
 #endif
 
 #define EXTRA_CASES \
-    case 161: \
     case 166: \
     case 167: \
     case 168: \
diff --git a/Include/opcode.h b/Include/opcode.h
index 827f9931beb3..77ad7c22440d 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -76,6 +76,7 @@ extern "C" {
 #define CONTAINS_OP                            118
 #define RERAISE                                119
 #define COPY                                   120
+#define RETURN_CONST                           121
 #define BINARY_OP                              122
 #define SEND                                   123
 #define LOAD_FAST                              124
@@ -179,13 +180,13 @@ extern "C" {
 #define STORE_ATTR_INSTANCE_VALUE               86
 #define STORE_ATTR_SLOT                         87
 #define STORE_ATTR_WITH_HINT                   113
-#define STORE_FAST__LOAD_FAST                  121
-#define STORE_FAST__STORE_FAST                 143
-#define STORE_SUBSCR_DICT                      153
-#define STORE_SUBSCR_LIST_INT                  154
-#define UNPACK_SEQUENCE_LIST                   158
-#define UNPACK_SEQUENCE_TUPLE                  159
-#define UNPACK_SEQUENCE_TWO_TUPLE              160
+#define STORE_FAST__LOAD_FAST                  143
+#define STORE_FAST__STORE_FAST                 153
+#define STORE_SUBSCR_DICT                      154
+#define STORE_SUBSCR_LIST_INT                  158
+#define UNPACK_SEQUENCE_LIST                   159
+#define UNPACK_SEQUENCE_TUPLE                  160
+#define UNPACK_SEQUENCE_TWO_TUPLE              161
 #define DO_TRACING                             255
 
 #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\
@@ -196,6 +197,7 @@ extern "C" {
 
 #define HAS_CONST(op) (false\
     || ((op) == LOAD_CONST) \
+    || ((op) == RETURN_CONST) \
     || ((op) == KW_NAMES) \
     )
 
diff --git a/Lib/dis.py b/Lib/dis.py
index 72ab9536a2bf..a6921008d9d0 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -34,6 +34,7 @@
 MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
 
 LOAD_CONST = opmap['LOAD_CONST']
+RETURN_CONST = opmap['RETURN_CONST']
 LOAD_GLOBAL = opmap['LOAD_GLOBAL']
 BINARY_OP = opmap['BINARY_OP']
 JUMP_BACKWARD = opmap['JUMP_BACKWARD']
@@ -363,7 +364,7 @@ def _get_const_value(op, arg, co_consts):
     assert op in hasconst
 
     argval = UNKNOWN
-    if op == LOAD_CONST:
+    if op == LOAD_CONST or op == RETURN_CONST:
         if co_consts is not None:
             argval = co_consts[arg]
     return argval
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index e760fbb15759..933c8c7d7e05 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -431,6 +431,7 @@ def _write_atomic(path, data, mode=0o666):
 #     Python 3.12a5 3515 (Embed jump mask in COMPARE_OP oparg)
 #     Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction)
 #     Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth)
+#     Python 3.12a5 3518 (Add RETURN_CONST instruction)
 
 #     Python 3.13 will start with 3550
 
@@ -443,7 +444,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 = (3517).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3518).to_bytes(2, 'little') + b'\r\n'
 
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
diff --git a/Lib/opcode.py b/Lib/opcode.py
index c317e23beae6..5f163d2ccb80 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -164,6 +164,8 @@ def pseudo_op(name, op, real_ops):
 def_op('CONTAINS_OP', 118)
 def_op('RERAISE', 119)
 def_op('COPY', 120)
+def_op('RETURN_CONST', 121)
+hasconst.append(121)
 def_op('BINARY_OP', 122)
 jrel_op('SEND', 123) # Number of bytes to skip
 def_op('LOAD_FAST', 124)        # Local variable number, no null check
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 98d9b603bbc1..7c9a57c685df 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -1900,7 +1900,7 @@ def get_load_const(self, tree):
         co = compile(tree, '<string>', 'exec')
         consts = []
         for instr in dis.get_instructions(co):
-            if instr.opname == 'LOAD_CONST':
+            if instr.opname == 'LOAD_CONST' or instr.opname == 'RETURN_CONST':
                 consts.append(instr.argval)
         return consts
 
diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py
index 67ed1694205c..9c2ac83e1b69 100644
--- a/Lib/test/test_code.py
+++ b/Lib/test/test_code.py
@@ -723,6 +723,7 @@ def f():
             pass
         PY_CODE_LOCATION_INFO_NO_COLUMNS = 13
         f.__code__ = f.__code__.replace(
+            co_stacksize=1,
             co_firstlineno=42,
             co_code=bytes(
                 [
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 05a5ed1fa9a6..90b067bcf309 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -741,7 +741,7 @@ def unused_code_at_end():
         # RETURN_VALUE opcode.  This does not always crash an interpreter.
         # When you build with the clang memory sanitizer it reliably aborts.
         self.assertEqual(
-            'RETURN_VALUE',
+            'RETURN_CONST',
             list(dis.get_instructions(unused_code_at_end))[-1].opname)
 
     def test_dont_merge_constants(self):
@@ -822,10 +822,9 @@ def unused_block_while_else():
 
         for func in funcs:
             opcodes = list(dis.get_instructions(func))
-            self.assertLessEqual(len(opcodes), 4)
-            self.assertEqual('LOAD_CONST', opcodes[-2].opname)
-            self.assertEqual(None, opcodes[-2].argval)
-            self.assertEqual('RETURN_VALUE', opcodes[-1].opname)
+            self.assertLessEqual(len(opcodes), 3)
+            self.assertEqual('RETURN_CONST', opcodes[-1].opname)
+            self.assertEqual(None, opcodes[-1].argval)
 
     def test_false_while_loop(self):
         def break_in_while():
@@ -841,10 +840,9 @@ def continue_in_while():
         # Check that we did not raise but we also don't generate bytecode
         for func in funcs:
             opcodes = list(dis.get_instructions(func))
-            self.assertEqual(3, len(opcodes))
-            self.assertEqual('LOAD_CONST', opcodes[1].opname)
+            self.assertEqual(2, len(opcodes))
+            self.assertEqual('RETURN_CONST', opcodes[1].opname)
             self.assertEqual(None, opcodes[1].argval)
-            self.assertEqual('RETURN_VALUE', opcodes[2].opname)
 
     def test_consts_in_conditionals(self):
         def and_true(x):
@@ -1311,7 +1309,7 @@ def test_multiline_generator_expression(self):
             line=1, end_line=2, column=1, end_column=8, occurrence=1)
         self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
             line=1, end_line=2, column=1, end_column=8, occurrence=1)
-        self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
+        self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
             line=1, end_line=6, column=0, end_column=32, occurrence=1)
 
     def test_multiline_async_generator_expression(self):
@@ -1328,7 +1326,7 @@ def test_multiline_async_generator_expression(self):
         self.assertIsInstance(compiled_code, types.CodeType)
         self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE',
             line=1, end_line=2, column=1, end_column=8, occurrence=2)
-        self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE',
+        self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST',
             line=1, end_line=6, column=0, end_column=32, occurrence=1)
 
     def test_multiline_list_comprehension(self):
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index bdf48c153092..1050b15e16ea 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -49,8 +49,7 @@ def cm(cls, x):
            COMPARE_OP              32 (==)
            LOAD_FAST                0 (self)
            STORE_ATTR               0 (x)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,)
 
 dis_c_instance_method_bytes = """\
@@ -60,8 +59,7 @@ def cm(cls, x):
        COMPARE_OP              32 (==)
        LOAD_FAST                0
        STORE_ATTR               0
-       LOAD_CONST               0
-       RETURN_VALUE
+       RETURN_CONST             0
 """
 
 dis_c_class_method = """\
@@ -72,8 +70,7 @@ def cm(cls, x):
            COMPARE_OP              32 (==)
            LOAD_FAST                0 (cls)
            STORE_ATTR               0 (x)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,)
 
 dis_c_static_method = """\
@@ -83,8 +80,7 @@ def cm(cls, x):
            LOAD_CONST               1 (1)
            COMPARE_OP              32 (==)
            STORE_FAST               0 (x)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,)
 
 # Class disassembling info has an extra newline at end.
@@ -111,8 +107,7 @@ def _f(a):
            CALL                     1
            POP_TOP
 
-%3d        LOAD_CONST               1 (1)
-           RETURN_VALUE
+%3d        RETURN_CONST             1 (1)
 """ % (_f.__code__.co_firstlineno,
        _f.__code__.co_firstlineno + 1,
        _f.__code__.co_firstlineno + 2)
@@ -124,8 +119,7 @@ def _f(a):
        LOAD_FAST                0
        CALL                     1
        POP_TOP
-       LOAD_CONST               1
-       RETURN_VALUE
+       RETURN_CONST             1
 """
 
 
@@ -150,8 +144,7 @@ def bug708901():
 %3d        JUMP_BACKWARD            4 (to 30)
 
 %3d     >> END_FOR
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """ % (bug708901.__code__.co_firstlineno,
        bug708901.__code__.co_firstlineno + 1,
        bug708901.__code__.co_firstlineno + 2,
@@ -198,8 +191,7 @@ def bug42562():
 
 dis_bug42562 = """\
        RESUME                   0
-       LOAD_CONST               0 (None)
-       RETURN_VALUE
+       RETURN_CONST             0 (None)
 """
 
 # Extended arg followed by NOP
@@ -240,8 +232,7 @@ def bug42562():
 
 %3d        LOAD_GLOBAL              0 (spam)
            POP_TOP
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """
 
 _BIG_LINENO_FORMAT2 = """\
@@ -249,20 +240,17 @@ def bug42562():
 
 %4d        LOAD_GLOBAL              0 (spam)
             POP_TOP
-            LOAD_CONST               0 (None)
-            RETURN_VALUE
+            RETURN_CONST             0 (None)
 """
 
 dis_module_expected_results = """\
 Disassembly of f:
   4        RESUME                   0
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 
 Disassembly of g:
   5        RESUME                   0
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 
 """
 
@@ -286,8 +274,7 @@ def bug42562():
            LOAD_CONST               0 (1)
            BINARY_OP                0 (+)
            STORE_NAME               0 (x)
-           LOAD_CONST               1 (None)
-           RETURN_VALUE
+           RETURN_CONST             1 (None)
 """
 
 annot_stmt_str = """\
@@ -326,8 +313,7 @@ def bug42562():
            STORE_SUBSCR
            LOAD_NAME                1 (int)
            POP_TOP
-           LOAD_CONST               4 (None)
-           RETURN_VALUE
+           RETURN_CONST             4 (None)
 """
 
 compound_stmt_str = """\
@@ -447,12 +433,11 @@ def _with(c):
 
 %3d        LOAD_CONST               2 (2)
            STORE_FAST               2 (y)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 
 %3d     >> PUSH_EXC_INFO
            WITH_EXCEPT_START
-           POP_JUMP_IF_TRUE         1 (to 46)
+           POP_JUMP_IF_TRUE         1 (to 44)
            RERAISE                  2
         >> POP_TOP
            POP_EXCEPT
@@ -461,8 +446,7 @@ def _with(c):
 
 %3d        LOAD_CONST               2 (2)
            STORE_FAST               2 (y)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
         >> COPY                     3
            POP_EXCEPT
            RERAISE                  1
@@ -514,23 +498,22 @@ async def _asyncwith(c):
 
 %3d        LOAD_CONST               2 (2)
            STORE_FAST               2 (y)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 
 %3d     >> CLEANUP_THROW
-           JUMP_BACKWARD           24 (to 22)
+           JUMP_BACKWARD           23 (to 22)
         >> CLEANUP_THROW
-           JUMP_BACKWARD            9 (to 56)
+           JUMP_BACKWARD            8 (to 56)
         >> PUSH_EXC_INFO
            WITH_EXCEPT_START
            GET_AWAITABLE            2
            LOAD_CONST               0 (None)
-        >> SEND                     4 (to 92)
+        >> SEND                     4 (to 90)
            YIELD_VALUE              3
            RESUME                   3
-           JUMP_BACKWARD_NO_INTERRUPT     4 (to 82)
+           JUMP_BACKWARD_NO_INTERRUPT     4 (to 80)
         >> CLEANUP_THROW
-        >> POP_JUMP_IF_TRUE         1 (to 96)
+        >> POP_JUMP_IF_TRUE         1 (to 94)
            RERAISE                  2
         >> POP_TOP
            POP_EXCEPT
@@ -539,8 +522,7 @@ async def _asyncwith(c):
 
 %3d        LOAD_CONST               2 (2)
            STORE_FAST               2 (y)
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
         >> COPY                     3
            POP_EXCEPT
            RERAISE                  1
@@ -610,8 +592,7 @@ def _tryfinallyconst(b):
            LOAD_FAST                0 (b)
            CALL                     0
            POP_TOP
-           LOAD_CONST               1 (1)
-           RETURN_VALUE
+           RETURN_CONST             1 (1)
            PUSH_EXC_INFO
            PUSH_NULL
            LOAD_FAST                0 (b)
@@ -754,8 +735,7 @@ def loop_test():
            JUMP_BACKWARD           17 (to 16)
 
 %3d     >> END_FOR
-           LOAD_CONST               0 (None)
-           RETURN_VALUE
+           RETURN_CONST             0 (None)
 """ % (loop_test.__code__.co_firstlineno,
        loop_test.__code__.co_firstlineno + 1,
        loop_test.__code__.co_firstlineno + 2,
@@ -772,8 +752,7 @@ def extended_arg_quick():
               6 UNPACK_EX              256
               8 STORE_FAST               0 (_)
              10 STORE_FAST               0 (_)
-             12 LOAD_CONST               0 (None)
-             14 RETURN_VALUE
+             12 RETURN_CONST             0 (None)
 """% (extended_arg_quick.__code__.co_firstlineno,
       extended_arg_quick.__code__.co_firstlineno + 1,)
 
@@ -1549,8 +1528,7 @@ def _prepare_test_cases():
   Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=26, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=40, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=40, starts_line=None, is_jump_target=False, positions=None)
 ]
 
 expected_opinfo_jumpy = [
@@ -1630,52 +1608,50 @@ def _prepare_test_cases():
   Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=286, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=298, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=300, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=304, starts_line=25, is_jump_target=False, positions=None),
-  Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=312, argrepr='to 312', offset=308, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=310, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=True, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=300, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=302, starts_line=25, is_jump_target=False, positions=None),
+  Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=310, argrepr='to 310', offset=306, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=310, starts_line=None, is_jump_target=True, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=274, argrepr='to 274', offset=320, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=330, starts_line=22, is_jump_target=False, positions=None),
-  Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=16, argval=378, argrepr='to 378', 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='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=374, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_BACKWARD', opcode=140, arg=52, argval=274, argrepr='to 274', offset=376, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=378, starts_line=22, is_jump_target=True, positions=None),
-  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=388, 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=400, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=412, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=414, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=416, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='JUMP_BACKWARD', opcode=140, arg=23, argval=274, argrepr='to 274', offset=318, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=328, starts_line=22, is_jump_target=False, positions=None),
+  Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=340, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=16, argval=376, argrepr='to 376', offset=342, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=346, 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=358, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=360, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=370, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='JUMP_BACKWARD', opcode=140, arg=51, argval=274, argrepr='to 274', offset=374, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=376, starts_line=22, is_jump_target=True, positions=None),
+  Instruction(opname='COPY', opcode=120, arg=3, argval=3, 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='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=386, 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=398, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=400, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=410, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=412, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=414, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=416, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None)
 ]
 
 # One last piece of inspect fodder to check the default line number handling
 def simple(): pass
 expected_opinfo_simple = [
   Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False, positions=None),
-  Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False),
-  Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=4, starts_line=None, is_jump_target=False)
+  Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False),
 ]
 
 
@@ -1736,7 +1712,6 @@ def test_co_positions(self):
             (2, 2, 8, 9),
             (1, 3, 0, 1),
             (1, 3, 0, 1),
-            (1, 3, 0, 1),
             (1, 3, 0, 1)
         ]
         self.assertEqual(positions, expected)
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 239c9d03fd9d..707ff821b31a 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -117,7 +117,7 @@ def f():
             return None
 
         self.assertNotInBytecode(f, 'LOAD_GLOBAL')
-        self.assertInBytecode(f, 'LOAD_CONST', None)
+        self.assertInBytecode(f, 'RETURN_CONST', None)
         self.check_lnotab(f)
 
     def test_while_one(self):
@@ -134,7 +134,7 @@ def f():
 
     def test_pack_unpack(self):
         for line, elem in (
-            ('a, = a,', 'LOAD_CONST',),
+            ('a, = a,', 'RETURN_CONST',),
             ('a, b = a, b', 'SWAP',),
             ('a, b, c = a, b, c', 'SWAP',),
             ):
@@ -165,7 +165,7 @@ def test_folding_of_tuples_of_constants(self):
         # One LOAD_CONST for the tuple, one for the None return value
         load_consts = [instr for instr in dis.get_instructions(code)
                               if instr.opname == 'LOAD_CONST']
-        self.assertEqual(len(load_consts), 2)
+        self.assertEqual(len(load_consts), 1)
         self.check_lnotab(code)
 
         # Bug 1053819:  Tuple of constants misidentified when presented with:
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst
new file mode 100644
index 000000000000..136909ca6999
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-02-07-14-56-43.gh-issue-101632.Fd1yxk.rst	
@@ -0,0 +1 @@
+Adds a new :opcode:`RETURN_CONST` instruction.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 6bc04bc8e848..0e52a3e2399c 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -397,6 +397,8 @@ mark_stacks(PyCodeObject *code_obj, int len)
                     assert(pop_value(next_stack) == EMPTY_STACK);
                     assert(top_of_stack(next_stack) == Object);
                     break;
+                case RETURN_CONST:
+                    break;
                 case RAISE_VARARGS:
                     break;
                 case RERAISE:
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 95f78b19e65e..8e5055bd7bce 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -1,7 +1,7 @@
 // Auto-generated by Programs/freeze_test_frozenmain.py
 unsigned char M_test_frozenmain[] = {
     227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
-    0,0,0,0,0,243,184,0,0,0,151,0,100,0,100,1,
+    0,0,0,0,0,243,182,0,0,0,151,0,100,0,100,1,
     108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2,
     100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0,
     101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0,
@@ -12,28 +12,28 @@ unsigned char M_test_frozenmain[] = {
     0,0,0,0,90,5,100,5,68,0,93,23,0,0,90,6,
     2,0,101,2,100,6,101,6,155,0,100,7,101,5,101,6,
     25,0,0,0,0,0,0,0,0,0,155,0,157,4,171,1,
-    0,0,0,0,0,0,0,0,1,0,140,25,4,0,100,1,
-    83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122,
-    101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8,
-    115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103,
-    41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101,
-    218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115,
-    101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99,
-    111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111,
-    218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111,
-    122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218,
-    3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114,
-    110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4,
-    97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103,
-    115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0,
-    0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109,
-    97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62,
-    114,18,0,0,0,1,0,0,0,115,100,0,0,0,240,3,
-    1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6,
-    26,213,0,27,217,0,5,128,106,144,35,151,40,145,40,213,
-    0,27,216,9,38,208,9,26,215,9,38,209,9,38,212,9,
-    40,168,24,212,9,50,128,6,240,2,6,12,2,242,0,7,
-    1,42,128,67,241,14,0,5,10,208,10,40,144,67,209,10,
-    40,152,54,160,35,156,59,209,10,40,214,4,41,242,15,7,
-    1,42,114,16,0,0,0,
+    0,0,0,0,0,0,0,0,1,0,140,25,4,0,121,1,
+    41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110,
+    32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121,
+    115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5,
+    218,12,112,114,111,103,114,97,109,95,110,97,109,101,218,10,
+    101,120,101,99,117,116,97,98,108,101,218,15,117,115,101,95,
+    101,110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,
+    102,105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,
+    98,117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,
+    99,111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,
+    121,115,218,17,95,116,101,115,116,105,110,116,101,114,110,97,
+    108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,
+    103,118,218,11,103,101,116,95,99,111,110,102,105,103,115,114,
+    3,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,
+    250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,
+    110,46,112,121,250,8,60,109,111,100,117,108,101,62,114,18,
+    0,0,0,1,0,0,0,115,100,0,0,0,240,3,1,1,
+    1,243,8,0,1,11,219,0,24,225,0,5,208,6,26,213,
+    0,27,217,0,5,128,106,144,35,151,40,145,40,213,0,27,
+    216,9,38,208,9,26,215,9,38,209,9,38,212,9,40,168,
+    24,212,9,50,128,6,240,2,6,12,2,242,0,7,1,42,
+    128,67,241,14,0,5,10,208,10,40,144,67,209,10,40,152,
+    54,160,35,156,59,209,10,40,214,4,41,241,15,7,1,42,
+    114,16,0,0,0,
 };
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index b43625fd283c..0d7d922816ce 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -555,6 +555,23 @@ dummy_func(
             goto resume_frame;
         }
 
+        inst(RETURN_CONST, (--)) {
+            PyObject *retval = GETITEM(consts, oparg);
+            Py_INCREF(retval);
+            assert(EMPTY());
+            _PyFrame_SetStackPointer(frame, stack_pointer);
+            TRACE_FUNCTION_EXIT();
+            DTRACE_FUNCTION_EXIT();
+            _Py_LeaveRecursiveCallPy(tstate);
+            assert(frame != &entry_frame);
+            // GH-99729: We need to unlink the frame *before* clearing it:
+            _PyInterpreterFrame *dying = frame;
+            frame = cframe.current_frame = dying->previous;
+            _PyEvalFrameClearAndPop(tstate, dying);
+            _PyFrame_StackPush(frame, retval);
+            goto resume_frame;
+        }
+
         inst(GET_AITER, (obj -- iter)) {
             unaryfunc getter = NULL;
             PyTypeObject *type = Py_TYPE(obj);
diff --git a/Python/compile.c b/Python/compile.c
index d9ec68958972..df2dffb95bbd 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -124,6 +124,7 @@
 
 #define IS_SCOPE_EXIT_OPCODE(opcode) \
         ((opcode) == RETURN_VALUE || \
+         (opcode) == RETURN_CONST || \
          (opcode) == RAISE_VARARGS || \
          (opcode) == RERAISE)
 
@@ -354,7 +355,7 @@ basicblock_last_instr(const basicblock *b) {
 static inline int
 basicblock_returns(const basicblock *b) {
     struct instr *last = basicblock_last_instr(b);
-    return last && last->i_opcode == RETURN_VALUE;
+    return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
 }
 
 static inline int
@@ -1119,6 +1120,8 @@ stack_effect(int opcode, int oparg, int jump)
 
         case RETURN_VALUE:
             return -1;
+        case RETURN_CONST:
+            return 0;
         case SETUP_ANNOTATIONS:
             return 0;
         case YIELD_VALUE:
@@ -9261,6 +9264,10 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
                         }
                         Py_DECREF(cnt);
                         break;
+                    case RETURN_VALUE:
+                        INSTR_SET_OP1(inst, RETURN_CONST, oparg);
+                        INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
+                        break;
                 }
                 break;
             }
@@ -9723,9 +9730,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
     /* mark used consts */
     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
         for (int i = 0; i < b->b_iused; i++) {
-            if (b->b_instr[i].i_opcode == LOAD_CONST ||
-                b->b_instr[i].i_opcode == KW_NAMES) {
-
+            if (HAS_CONST(b->b_instr[i].i_opcode)) {
                 int index = b->b_instr[i].i_oparg;
                 index_map[index] = index;
             }
@@ -9780,9 +9785,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
 
     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
         for (int i = 0; i < b->b_iused; i++) {
-            if (b->b_instr[i].i_opcode == LOAD_CONST ||
-                b->b_instr[i].i_opcode == KW_NAMES) {
-
+            if (HAS_CONST(b->b_instr[i].i_opcode)) {
                 int index = b->b_instr[i].i_oparg;
                 assert(reverse_index_map[index] >= 0);
                 assert(reverse_index_map[index] < n_used_consts);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index ab19f4317106..de98b1a4f2ed 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -742,6 +742,23 @@
             goto resume_frame;
         }
 
+        TARGET(RETURN_CONST) {
+            PyObject *retval = GETITEM(consts, oparg);
+            Py_INCREF(retval);
+            assert(EMPTY());
+            _PyFrame_SetStackPointer(frame, stack_pointer);
+            TRACE_FUNCTION_EXIT();
+            DTRACE_FUNCTION_EXIT();
+            _Py_LeaveRecursiveCallPy(tstate);
+            assert(frame != &entry_frame);
+            // GH-99729: We need to unlink the frame *before* clearing it:
+            _PyInterpreterFrame *dying = frame;
+            frame = cframe.current_frame = dying->previous;
+            _PyEvalFrameClearAndPop(tstate, dying);
+            _PyFrame_StackPush(frame, retval);
+            goto resume_frame;
+        }
+
         TARGET(GET_AITER) {
             PyObject *obj = PEEK(1);
             PyObject *iter;
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index d2585351f69f..bae5492c0496 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -92,6 +92,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
             return 1;
         case RETURN_VALUE:
             return 1;
+        case RETURN_CONST:
+            return 0;
         case GET_AITER:
             return 1;
         case GET_ANEXT:
@@ -438,6 +440,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
             return 0;
         case RETURN_VALUE:
             return 0;
+        case RETURN_CONST:
+            return 0;
         case GET_AITER:
             return 1;
         case GET_ANEXT:
@@ -745,6 +749,7 @@ struct opcode_metadata {
     [RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
     [INTERPRETER_EXIT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
     [RETURN_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
+    [RETURN_CONST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
     [GET_AITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
     [GET_ANEXT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
     [GET_AWAITABLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index f1c3f3e0c4ee..eceb246fac49 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
     &&TARGET_CONTAINS_OP,
     &&TARGET_RERAISE,
     &&TARGET_COPY,
-    &&TARGET_STORE_FAST__LOAD_FAST,
+    &&TARGET_RETURN_CONST,
     &&TARGET_BINARY_OP,
     &&TARGET_SEND,
     &&TARGET_LOAD_FAST,
@@ -142,7 +142,7 @@ static void *opcode_targets[256] = {
     &&TARGET_JUMP_BACKWARD,
     &&TARGET_COMPARE_AND_BRANCH,
     &&TARGET_CALL_FUNCTION_EX,
-    &&TARGET_STORE_FAST__STORE_FAST,
+    &&TARGET_STORE_FAST__LOAD_FAST,
     &&TARGET_EXTENDED_ARG,
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
@@ -152,15 +152,15 @@ static void *opcode_targets[256] = {
     &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
     &&TARGET_MATCH_CLASS,
+    &&TARGET_STORE_FAST__STORE_FAST,
     &&TARGET_STORE_SUBSCR_DICT,
-    &&TARGET_STORE_SUBSCR_LIST_INT,
     &&TARGET_FORMAT_VALUE,
     &&TARGET_BUILD_CONST_KEY_MAP,
     &&TARGET_BUILD_STRING,
+    &&TARGET_STORE_SUBSCR_LIST_INT,
     &&TARGET_UNPACK_SEQUENCE_LIST,
     &&TARGET_UNPACK_SEQUENCE_TUPLE,
     &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
-    &&_unknown_opcode,
     &&TARGET_LIST_EXTEND,
     &&TARGET_SET_UPDATE,
     &&TARGET_DICT_MERGE,



More information about the Python-checkins mailing list