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

This commit is contained in:
penguin_wwy 2023-02-08 06:32:21 +08:00 committed by GitHub
parent 0d3d5007b1
commit 753fc8a5d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 186 additions and 154 deletions

View file

@ -694,6 +694,13 @@ iterations of the loop.
Returns with ``STACK[-1]`` to the caller of the function. 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 .. opcode:: YIELD_VALUE
Yields ``STACK.pop()`` from a :term:`generator`. Yields ``STACK.pop()`` from a :term:`generator`.

View file

@ -192,6 +192,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[RAISE_VARARGS] = RAISE_VARARGS, [RAISE_VARARGS] = RAISE_VARARGS,
[RERAISE] = RERAISE, [RERAISE] = RERAISE,
[RESUME] = RESUME, [RESUME] = RESUME,
[RETURN_CONST] = RETURN_CONST,
[RETURN_GENERATOR] = RETURN_GENERATOR, [RETURN_GENERATOR] = RETURN_GENERATOR,
[RETURN_VALUE] = RETURN_VALUE, [RETURN_VALUE] = RETURN_VALUE,
[SEND] = SEND, [SEND] = SEND,
@ -349,7 +350,7 @@ static const char *const _PyOpcode_OpName[263] = {
[CONTAINS_OP] = "CONTAINS_OP", [CONTAINS_OP] = "CONTAINS_OP",
[RERAISE] = "RERAISE", [RERAISE] = "RERAISE",
[COPY] = "COPY", [COPY] = "COPY",
[STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [RETURN_CONST] = "RETURN_CONST",
[BINARY_OP] = "BINARY_OP", [BINARY_OP] = "BINARY_OP",
[SEND] = "SEND", [SEND] = "SEND",
[LOAD_FAST] = "LOAD_FAST", [LOAD_FAST] = "LOAD_FAST",
@ -371,7 +372,7 @@ static const char *const _PyOpcode_OpName[263] = {
[JUMP_BACKWARD] = "JUMP_BACKWARD", [JUMP_BACKWARD] = "JUMP_BACKWARD",
[COMPARE_AND_BRANCH] = "COMPARE_AND_BRANCH", [COMPARE_AND_BRANCH] = "COMPARE_AND_BRANCH",
[CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [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", [EXTENDED_ARG] = "EXTENDED_ARG",
[LIST_APPEND] = "LIST_APPEND", [LIST_APPEND] = "LIST_APPEND",
[SET_ADD] = "SET_ADD", [SET_ADD] = "SET_ADD",
@ -381,15 +382,15 @@ static const char *const _PyOpcode_OpName[263] = {
[YIELD_VALUE] = "YIELD_VALUE", [YIELD_VALUE] = "YIELD_VALUE",
[RESUME] = "RESUME", [RESUME] = "RESUME",
[MATCH_CLASS] = "MATCH_CLASS", [MATCH_CLASS] = "MATCH_CLASS",
[STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
[STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
[FORMAT_VALUE] = "FORMAT_VALUE", [FORMAT_VALUE] = "FORMAT_VALUE",
[BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
[BUILD_STRING] = "BUILD_STRING", [BUILD_STRING] = "BUILD_STRING",
[STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
[UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
[UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
[UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
[161] = "<161>",
[LIST_EXTEND] = "LIST_EXTEND", [LIST_EXTEND] = "LIST_EXTEND",
[SET_UPDATE] = "SET_UPDATE", [SET_UPDATE] = "SET_UPDATE",
[DICT_MERGE] = "DICT_MERGE", [DICT_MERGE] = "DICT_MERGE",
@ -495,7 +496,6 @@ static const char *const _PyOpcode_OpName[263] = {
#endif #endif
#define EXTRA_CASES \ #define EXTRA_CASES \
case 161: \
case 166: \ case 166: \
case 167: \ case 167: \
case 168: \ case 168: \

16
Include/opcode.h generated
View file

@ -76,6 +76,7 @@ extern "C" {
#define CONTAINS_OP 118 #define CONTAINS_OP 118
#define RERAISE 119 #define RERAISE 119
#define COPY 120 #define COPY 120
#define RETURN_CONST 121
#define BINARY_OP 122 #define BINARY_OP 122
#define SEND 123 #define SEND 123
#define LOAD_FAST 124 #define LOAD_FAST 124
@ -179,13 +180,13 @@ extern "C" {
#define STORE_ATTR_INSTANCE_VALUE 86 #define STORE_ATTR_INSTANCE_VALUE 86
#define STORE_ATTR_SLOT 87 #define STORE_ATTR_SLOT 87
#define STORE_ATTR_WITH_HINT 113 #define STORE_ATTR_WITH_HINT 113
#define STORE_FAST__LOAD_FAST 121 #define STORE_FAST__LOAD_FAST 143
#define STORE_FAST__STORE_FAST 143 #define STORE_FAST__STORE_FAST 153
#define STORE_SUBSCR_DICT 153 #define STORE_SUBSCR_DICT 154
#define STORE_SUBSCR_LIST_INT 154 #define STORE_SUBSCR_LIST_INT 158
#define UNPACK_SEQUENCE_LIST 158 #define UNPACK_SEQUENCE_LIST 159
#define UNPACK_SEQUENCE_TUPLE 159 #define UNPACK_SEQUENCE_TUPLE 160
#define UNPACK_SEQUENCE_TWO_TUPLE 160 #define UNPACK_SEQUENCE_TWO_TUPLE 161
#define DO_TRACING 255 #define DO_TRACING 255
#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ #define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\
@ -196,6 +197,7 @@ extern "C" {
#define HAS_CONST(op) (false\ #define HAS_CONST(op) (false\
|| ((op) == LOAD_CONST) \ || ((op) == LOAD_CONST) \
|| ((op) == RETURN_CONST) \
|| ((op) == KW_NAMES) \ || ((op) == KW_NAMES) \
) )

View file

@ -34,6 +34,7 @@
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
LOAD_CONST = opmap['LOAD_CONST'] LOAD_CONST = opmap['LOAD_CONST']
RETURN_CONST = opmap['RETURN_CONST']
LOAD_GLOBAL = opmap['LOAD_GLOBAL'] LOAD_GLOBAL = opmap['LOAD_GLOBAL']
BINARY_OP = opmap['BINARY_OP'] BINARY_OP = opmap['BINARY_OP']
JUMP_BACKWARD = opmap['JUMP_BACKWARD'] JUMP_BACKWARD = opmap['JUMP_BACKWARD']
@ -363,7 +364,7 @@ def _get_const_value(op, arg, co_consts):
assert op in hasconst assert op in hasconst
argval = UNKNOWN argval = UNKNOWN
if op == LOAD_CONST: if op == LOAD_CONST or op == RETURN_CONST:
if co_consts is not None: if co_consts is not None:
argval = co_consts[arg] argval = co_consts[arg]
return argval return argval

View file

@ -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 3515 (Embed jump mask in COMPARE_OP oparg)
# Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction) # Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction)
# Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth) # 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 # 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 # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated. # 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 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

View file

@ -164,6 +164,8 @@ def pseudo_op(name, op, real_ops):
def_op('CONTAINS_OP', 118) def_op('CONTAINS_OP', 118)
def_op('RERAISE', 119) def_op('RERAISE', 119)
def_op('COPY', 120) def_op('COPY', 120)
def_op('RETURN_CONST', 121)
hasconst.append(121)
def_op('BINARY_OP', 122) def_op('BINARY_OP', 122)
jrel_op('SEND', 123) # Number of bytes to skip jrel_op('SEND', 123) # Number of bytes to skip
def_op('LOAD_FAST', 124) # Local variable number, no null check def_op('LOAD_FAST', 124) # Local variable number, no null check

View file

@ -1900,7 +1900,7 @@ def get_load_const(self, tree):
co = compile(tree, '<string>', 'exec') co = compile(tree, '<string>', 'exec')
consts = [] consts = []
for instr in dis.get_instructions(co): 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) consts.append(instr.argval)
return consts return consts

View file

@ -723,6 +723,7 @@ def f():
pass pass
PY_CODE_LOCATION_INFO_NO_COLUMNS = 13 PY_CODE_LOCATION_INFO_NO_COLUMNS = 13
f.__code__ = f.__code__.replace( f.__code__ = f.__code__.replace(
co_stacksize=1,
co_firstlineno=42, co_firstlineno=42,
co_code=bytes( co_code=bytes(
[ [

View file

@ -741,7 +741,7 @@ def unused_code_at_end():
# RETURN_VALUE opcode. This does not always crash an interpreter. # RETURN_VALUE opcode. This does not always crash an interpreter.
# When you build with the clang memory sanitizer it reliably aborts. # When you build with the clang memory sanitizer it reliably aborts.
self.assertEqual( self.assertEqual(
'RETURN_VALUE', 'RETURN_CONST',
list(dis.get_instructions(unused_code_at_end))[-1].opname) list(dis.get_instructions(unused_code_at_end))[-1].opname)
def test_dont_merge_constants(self): def test_dont_merge_constants(self):
@ -822,10 +822,9 @@ def unused_block_while_else():
for func in funcs: for func in funcs:
opcodes = list(dis.get_instructions(func)) opcodes = list(dis.get_instructions(func))
self.assertLessEqual(len(opcodes), 4) self.assertLessEqual(len(opcodes), 3)
self.assertEqual('LOAD_CONST', opcodes[-2].opname) self.assertEqual('RETURN_CONST', opcodes[-1].opname)
self.assertEqual(None, opcodes[-2].argval) self.assertEqual(None, opcodes[-1].argval)
self.assertEqual('RETURN_VALUE', opcodes[-1].opname)
def test_false_while_loop(self): def test_false_while_loop(self):
def break_in_while(): 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 # Check that we did not raise but we also don't generate bytecode
for func in funcs: for func in funcs:
opcodes = list(dis.get_instructions(func)) opcodes = list(dis.get_instructions(func))
self.assertEqual(3, len(opcodes)) self.assertEqual(2, len(opcodes))
self.assertEqual('LOAD_CONST', opcodes[1].opname) self.assertEqual('RETURN_CONST', opcodes[1].opname)
self.assertEqual(None, opcodes[1].argval) self.assertEqual(None, opcodes[1].argval)
self.assertEqual('RETURN_VALUE', opcodes[2].opname)
def test_consts_in_conditionals(self): def test_consts_in_conditionals(self):
def and_true(x): 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) line=1, end_line=2, column=1, end_column=8, occurrence=1)
self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD',
line=1, end_line=2, column=1, end_column=8, occurrence=1) 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) line=1, end_line=6, column=0, end_column=32, occurrence=1)
def test_multiline_async_generator_expression(self): 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.assertIsInstance(compiled_code, types.CodeType)
self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE',
line=1, end_line=2, column=1, end_column=8, occurrence=2) 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) line=1, end_line=6, column=0, end_column=32, occurrence=1)
def test_multiline_list_comprehension(self): def test_multiline_list_comprehension(self):

View file

@ -49,8 +49,7 @@ def cm(cls, x):
COMPARE_OP 32 (==) COMPARE_OP 32 (==)
LOAD_FAST 0 (self) LOAD_FAST 0 (self)
STORE_ATTR 0 (x) STORE_ATTR 0 (x)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,)
dis_c_instance_method_bytes = """\ dis_c_instance_method_bytes = """\
@ -60,8 +59,7 @@ def cm(cls, x):
COMPARE_OP 32 (==) COMPARE_OP 32 (==)
LOAD_FAST 0 LOAD_FAST 0
STORE_ATTR 0 STORE_ATTR 0
LOAD_CONST 0 RETURN_CONST 0
RETURN_VALUE
""" """
dis_c_class_method = """\ dis_c_class_method = """\
@ -72,8 +70,7 @@ def cm(cls, x):
COMPARE_OP 32 (==) COMPARE_OP 32 (==)
LOAD_FAST 0 (cls) LOAD_FAST 0 (cls)
STORE_ATTR 0 (x) STORE_ATTR 0 (x)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,)
dis_c_static_method = """\ dis_c_static_method = """\
@ -83,8 +80,7 @@ def cm(cls, x):
LOAD_CONST 1 (1) LOAD_CONST 1 (1)
COMPARE_OP 32 (==) COMPARE_OP 32 (==)
STORE_FAST 0 (x) STORE_FAST 0 (x)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,)
# Class disassembling info has an extra newline at end. # Class disassembling info has an extra newline at end.
@ -111,8 +107,7 @@ def _f(a):
CALL 1 CALL 1
POP_TOP POP_TOP
%3d LOAD_CONST 1 (1) %3d RETURN_CONST 1 (1)
RETURN_VALUE
""" % (_f.__code__.co_firstlineno, """ % (_f.__code__.co_firstlineno,
_f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 1,
_f.__code__.co_firstlineno + 2) _f.__code__.co_firstlineno + 2)
@ -124,8 +119,7 @@ def _f(a):
LOAD_FAST 0 LOAD_FAST 0
CALL 1 CALL 1
POP_TOP POP_TOP
LOAD_CONST 1 RETURN_CONST 1
RETURN_VALUE
""" """
@ -150,8 +144,7 @@ def bug708901():
%3d JUMP_BACKWARD 4 (to 30) %3d JUMP_BACKWARD 4 (to 30)
%3d >> END_FOR %3d >> END_FOR
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" % (bug708901.__code__.co_firstlineno, """ % (bug708901.__code__.co_firstlineno,
bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 1,
bug708901.__code__.co_firstlineno + 2, bug708901.__code__.co_firstlineno + 2,
@ -198,8 +191,7 @@ def bug42562():
dis_bug42562 = """\ dis_bug42562 = """\
RESUME 0 RESUME 0
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" """
# Extended arg followed by NOP # Extended arg followed by NOP
@ -240,8 +232,7 @@ def bug42562():
%3d LOAD_GLOBAL 0 (spam) %3d LOAD_GLOBAL 0 (spam)
POP_TOP POP_TOP
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" """
_BIG_LINENO_FORMAT2 = """\ _BIG_LINENO_FORMAT2 = """\
@ -249,20 +240,17 @@ def bug42562():
%4d LOAD_GLOBAL 0 (spam) %4d LOAD_GLOBAL 0 (spam)
POP_TOP POP_TOP
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" """
dis_module_expected_results = """\ dis_module_expected_results = """\
Disassembly of f: Disassembly of f:
4 RESUME 0 4 RESUME 0
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
Disassembly of g: Disassembly of g:
5 RESUME 0 5 RESUME 0
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" """
@ -286,8 +274,7 @@ def bug42562():
LOAD_CONST 0 (1) LOAD_CONST 0 (1)
BINARY_OP 0 (+) BINARY_OP 0 (+)
STORE_NAME 0 (x) STORE_NAME 0 (x)
LOAD_CONST 1 (None) RETURN_CONST 1 (None)
RETURN_VALUE
""" """
annot_stmt_str = """\ annot_stmt_str = """\
@ -326,8 +313,7 @@ def bug42562():
STORE_SUBSCR STORE_SUBSCR
LOAD_NAME 1 (int) LOAD_NAME 1 (int)
POP_TOP POP_TOP
LOAD_CONST 4 (None) RETURN_CONST 4 (None)
RETURN_VALUE
""" """
compound_stmt_str = """\ compound_stmt_str = """\
@ -447,12 +433,11 @@ def _with(c):
%3d LOAD_CONST 2 (2) %3d LOAD_CONST 2 (2)
STORE_FAST 2 (y) STORE_FAST 2 (y)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
%3d >> PUSH_EXC_INFO %3d >> PUSH_EXC_INFO
WITH_EXCEPT_START WITH_EXCEPT_START
POP_JUMP_IF_TRUE 1 (to 46) POP_JUMP_IF_TRUE 1 (to 44)
RERAISE 2 RERAISE 2
>> POP_TOP >> POP_TOP
POP_EXCEPT POP_EXCEPT
@ -461,8 +446,7 @@ def _with(c):
%3d LOAD_CONST 2 (2) %3d LOAD_CONST 2 (2)
STORE_FAST 2 (y) STORE_FAST 2 (y)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
>> COPY 3 >> COPY 3
POP_EXCEPT POP_EXCEPT
RERAISE 1 RERAISE 1
@ -514,23 +498,22 @@ async def _asyncwith(c):
%3d LOAD_CONST 2 (2) %3d LOAD_CONST 2 (2)
STORE_FAST 2 (y) STORE_FAST 2 (y)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
%3d >> CLEANUP_THROW %3d >> CLEANUP_THROW
JUMP_BACKWARD 24 (to 22) JUMP_BACKWARD 23 (to 22)
>> CLEANUP_THROW >> CLEANUP_THROW
JUMP_BACKWARD 9 (to 56) JUMP_BACKWARD 8 (to 56)
>> PUSH_EXC_INFO >> PUSH_EXC_INFO
WITH_EXCEPT_START WITH_EXCEPT_START
GET_AWAITABLE 2 GET_AWAITABLE 2
LOAD_CONST 0 (None) LOAD_CONST 0 (None)
>> SEND 4 (to 92) >> SEND 4 (to 90)
YIELD_VALUE 3 YIELD_VALUE 3
RESUME 3 RESUME 3
JUMP_BACKWARD_NO_INTERRUPT 4 (to 82) JUMP_BACKWARD_NO_INTERRUPT 4 (to 80)
>> CLEANUP_THROW >> CLEANUP_THROW
>> POP_JUMP_IF_TRUE 1 (to 96) >> POP_JUMP_IF_TRUE 1 (to 94)
RERAISE 2 RERAISE 2
>> POP_TOP >> POP_TOP
POP_EXCEPT POP_EXCEPT
@ -539,8 +522,7 @@ async def _asyncwith(c):
%3d LOAD_CONST 2 (2) %3d LOAD_CONST 2 (2)
STORE_FAST 2 (y) STORE_FAST 2 (y)
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
>> COPY 3 >> COPY 3
POP_EXCEPT POP_EXCEPT
RERAISE 1 RERAISE 1
@ -610,8 +592,7 @@ def _tryfinallyconst(b):
LOAD_FAST 0 (b) LOAD_FAST 0 (b)
CALL 0 CALL 0
POP_TOP POP_TOP
LOAD_CONST 1 (1) RETURN_CONST 1 (1)
RETURN_VALUE
PUSH_EXC_INFO PUSH_EXC_INFO
PUSH_NULL PUSH_NULL
LOAD_FAST 0 (b) LOAD_FAST 0 (b)
@ -754,8 +735,7 @@ def loop_test():
JUMP_BACKWARD 17 (to 16) JUMP_BACKWARD 17 (to 16)
%3d >> END_FOR %3d >> END_FOR
LOAD_CONST 0 (None) RETURN_CONST 0 (None)
RETURN_VALUE
""" % (loop_test.__code__.co_firstlineno, """ % (loop_test.__code__.co_firstlineno,
loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 1,
loop_test.__code__.co_firstlineno + 2, loop_test.__code__.co_firstlineno + 2,
@ -772,8 +752,7 @@ def extended_arg_quick():
6 UNPACK_EX 256 6 UNPACK_EX 256
8 STORE_FAST 0 (_) 8 STORE_FAST 0 (_)
10 STORE_FAST 0 (_) 10 STORE_FAST 0 (_)
12 LOAD_CONST 0 (None) 12 RETURN_CONST 0 (None)
14 RETURN_VALUE
"""% (extended_arg_quick.__code__.co_firstlineno, """% (extended_arg_quick.__code__.co_firstlineno,
extended_arg_quick.__code__.co_firstlineno + 1,) 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='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='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='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_CONST', opcode=121, 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),
] ]
expected_opinfo_jumpy = [ 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='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='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='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_CONST', opcode=121, 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=302, starts_line=25, 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=304, starts_line=None, 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=310, argrepr='to 310', 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=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=310, starts_line=None, is_jump_target=True, 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=312, starts_line=None, is_jump_target=False, 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='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=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=23, argval=274, argrepr='to 274', 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=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=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=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=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=328, starts_line=22, 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=340, starts_line=None, 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=376, argrepr='to 376', 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=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=346, starts_line=23, 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=358, starts_line=None, 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=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=370, 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=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=51, argval=274, argrepr='to 274', 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=376, starts_line=22, is_jump_target=True, 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=378, starts_line=None, is_jump_target=False, 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=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=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=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=386, starts_line=28, 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=398, 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=400, 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='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=410, 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=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=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=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=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),
] ]
# One last piece of inspect fodder to check the default line number handling # One last piece of inspect fodder to check the default line number handling
def simple(): pass def simple(): pass
expected_opinfo_simple = [ 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='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_CONST', opcode=121, 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)
] ]
@ -1736,7 +1712,6 @@ def test_co_positions(self):
(2, 2, 8, 9), (2, 2, 8, 9),
(1, 3, 0, 1), (1, 3, 0, 1),
(1, 3, 0, 1), (1, 3, 0, 1),
(1, 3, 0, 1),
(1, 3, 0, 1) (1, 3, 0, 1)
] ]
self.assertEqual(positions, expected) self.assertEqual(positions, expected)

View file

@ -117,7 +117,7 @@ def f():
return None return None
self.assertNotInBytecode(f, 'LOAD_GLOBAL') self.assertNotInBytecode(f, 'LOAD_GLOBAL')
self.assertInBytecode(f, 'LOAD_CONST', None) self.assertInBytecode(f, 'RETURN_CONST', None)
self.check_lnotab(f) self.check_lnotab(f)
def test_while_one(self): def test_while_one(self):
@ -134,7 +134,7 @@ def f():
def test_pack_unpack(self): def test_pack_unpack(self):
for line, elem in ( for line, elem in (
('a, = a,', 'LOAD_CONST',), ('a, = a,', 'RETURN_CONST',),
('a, b = a, b', 'SWAP',), ('a, b = a, b', 'SWAP',),
('a, b, c = a, b, c', '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 # One LOAD_CONST for the tuple, one for the None return value
load_consts = [instr for instr in dis.get_instructions(code) load_consts = [instr for instr in dis.get_instructions(code)
if instr.opname == 'LOAD_CONST'] if instr.opname == 'LOAD_CONST']
self.assertEqual(len(load_consts), 2) self.assertEqual(len(load_consts), 1)
self.check_lnotab(code) self.check_lnotab(code)
# Bug 1053819: Tuple of constants misidentified when presented with: # Bug 1053819: Tuple of constants misidentified when presented with:

View file

@ -0,0 +1 @@
Adds a new :opcode:`RETURN_CONST` instruction.

View file

@ -397,6 +397,8 @@ mark_stacks(PyCodeObject *code_obj, int len)
assert(pop_value(next_stack) == EMPTY_STACK); assert(pop_value(next_stack) == EMPTY_STACK);
assert(top_of_stack(next_stack) == Object); assert(top_of_stack(next_stack) == Object);
break; break;
case RETURN_CONST:
break;
case RAISE_VARARGS: case RAISE_VARARGS:
break; break;
case RERAISE: case RERAISE:

View file

@ -1,7 +1,7 @@
// Auto-generated by Programs/freeze_test_frozenmain.py // Auto-generated by Programs/freeze_test_frozenmain.py
unsigned char M_test_frozenmain[] = { unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, 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, 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, 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, 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, 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, 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, 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, 0,0,0,0,0,0,0,0,1,0,140,25,4,0,121,1,
83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, 41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110,
101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, 32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121,
115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, 115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5,
41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, 218,12,112,114,111,103,114,97,109,95,110,97,109,101,218,10,
218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, 101,120,101,99,117,116,97,98,108,101,218,15,117,115,101,95,
101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, 101,110,118,105,114,111,110,109,101,110,116,218,17,99,111,110,
111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, 102,105,103,117,114,101,95,99,95,115,116,100,105,111,218,14,
218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, 98,117,102,102,101,114,101,100,95,115,116,100,105,111,122,7,
122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, 99,111,110,102,105,103,32,122,2,58,32,41,7,218,3,115,
3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, 121,115,218,17,95,116,101,115,116,105,110,116,101,114,110,97,
110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, 108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114,
97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, 103,118,218,11,103,101,116,95,99,111,110,102,105,103,115,114,
115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, 3,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0,
0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, 250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105,
97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, 110,46,112,121,250,8,60,109,111,100,117,108,101,62,114,18,
114,18,0,0,0,1,0,0,0,115,100,0,0,0,240,3, 0,0,0,1,0,0,0,115,100,0,0,0,240,3,1,1,
1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6, 1,243,8,0,1,11,219,0,24,225,0,5,208,6,26,213,
26,213,0,27,217,0,5,128,106,144,35,151,40,145,40,213, 0,27,217,0,5,128,106,144,35,151,40,145,40,213,0,27,
0,27,216,9,38,208,9,26,215,9,38,209,9,38,212,9, 216,9,38,208,9,26,215,9,38,209,9,38,212,9,40,168,
40,168,24,212,9,50,128,6,240,2,6,12,2,242,0,7, 24,212,9,50,128,6,240,2,6,12,2,242,0,7,1,42,
1,42,128,67,241,14,0,5,10,208,10,40,144,67,209,10, 128,67,241,14,0,5,10,208,10,40,144,67,209,10,40,152,
40,152,54,160,35,156,59,209,10,40,214,4,41,242,15,7, 54,160,35,156,59,209,10,40,214,4,41,241,15,7,1,42,
1,42,114,16,0,0,0, 114,16,0,0,0,
}; };

View file

@ -555,6 +555,23 @@ dummy_func(
goto resume_frame; 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)) { inst(GET_AITER, (obj -- iter)) {
unaryfunc getter = NULL; unaryfunc getter = NULL;
PyTypeObject *type = Py_TYPE(obj); PyTypeObject *type = Py_TYPE(obj);

View file

@ -124,6 +124,7 @@
#define IS_SCOPE_EXIT_OPCODE(opcode) \ #define IS_SCOPE_EXIT_OPCODE(opcode) \
((opcode) == RETURN_VALUE || \ ((opcode) == RETURN_VALUE || \
(opcode) == RETURN_CONST || \
(opcode) == RAISE_VARARGS || \ (opcode) == RAISE_VARARGS || \
(opcode) == RERAISE) (opcode) == RERAISE)
@ -354,7 +355,7 @@ basicblock_last_instr(const basicblock *b) {
static inline int static inline int
basicblock_returns(const basicblock *b) { basicblock_returns(const basicblock *b) {
struct instr *last = basicblock_last_instr(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 static inline int
@ -1119,6 +1120,8 @@ stack_effect(int opcode, int oparg, int jump)
case RETURN_VALUE: case RETURN_VALUE:
return -1; return -1;
case RETURN_CONST:
return 0;
case SETUP_ANNOTATIONS: case SETUP_ANNOTATIONS:
return 0; return 0;
case YIELD_VALUE: case YIELD_VALUE:
@ -9261,6 +9264,10 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
} }
Py_DECREF(cnt); Py_DECREF(cnt);
break; break;
case RETURN_VALUE:
INSTR_SET_OP1(inst, RETURN_CONST, oparg);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
break;
} }
break; break;
} }
@ -9723,9 +9730,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
/* mark used consts */ /* mark used consts */
for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) { for (int i = 0; i < b->b_iused; i++) {
if (b->b_instr[i].i_opcode == LOAD_CONST || if (HAS_CONST(b->b_instr[i].i_opcode)) {
b->b_instr[i].i_opcode == KW_NAMES) {
int index = b->b_instr[i].i_oparg; int index = b->b_instr[i].i_oparg;
index_map[index] = index; 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 (basicblock *b = entryblock; b != NULL; b = b->b_next) {
for (int i = 0; i < b->b_iused; i++) { for (int i = 0; i < b->b_iused; i++) {
if (b->b_instr[i].i_opcode == LOAD_CONST || if (HAS_CONST(b->b_instr[i].i_opcode)) {
b->b_instr[i].i_opcode == KW_NAMES) {
int index = b->b_instr[i].i_oparg; int index = b->b_instr[i].i_oparg;
assert(reverse_index_map[index] >= 0); assert(reverse_index_map[index] >= 0);
assert(reverse_index_map[index] < n_used_consts); assert(reverse_index_map[index] < n_used_consts);

View file

@ -742,6 +742,23 @@
goto resume_frame; 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) { TARGET(GET_AITER) {
PyObject *obj = PEEK(1); PyObject *obj = PEEK(1);
PyObject *iter; PyObject *iter;

View file

@ -92,6 +92,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1; return 1;
case RETURN_VALUE: case RETURN_VALUE:
return 1; return 1;
case RETURN_CONST:
return 0;
case GET_AITER: case GET_AITER:
return 1; return 1;
case GET_ANEXT: case GET_ANEXT:
@ -438,6 +440,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 0; return 0;
case RETURN_VALUE: case RETURN_VALUE:
return 0; return 0;
case RETURN_CONST:
return 0;
case GET_AITER: case GET_AITER:
return 1; return 1;
case GET_ANEXT: case GET_ANEXT:
@ -745,6 +749,7 @@ struct opcode_metadata {
[RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },
[INTERPRETER_EXIT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, [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_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_AITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX },
[GET_ANEXT] = { 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 }, [GET_AWAITABLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },

View file

@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
&&TARGET_CONTAINS_OP, &&TARGET_CONTAINS_OP,
&&TARGET_RERAISE, &&TARGET_RERAISE,
&&TARGET_COPY, &&TARGET_COPY,
&&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_RETURN_CONST,
&&TARGET_BINARY_OP, &&TARGET_BINARY_OP,
&&TARGET_SEND, &&TARGET_SEND,
&&TARGET_LOAD_FAST, &&TARGET_LOAD_FAST,
@ -142,7 +142,7 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_BACKWARD, &&TARGET_JUMP_BACKWARD,
&&TARGET_COMPARE_AND_BRANCH, &&TARGET_COMPARE_AND_BRANCH,
&&TARGET_CALL_FUNCTION_EX, &&TARGET_CALL_FUNCTION_EX,
&&TARGET_STORE_FAST__STORE_FAST, &&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_EXTENDED_ARG, &&TARGET_EXTENDED_ARG,
&&TARGET_LIST_APPEND, &&TARGET_LIST_APPEND,
&&TARGET_SET_ADD, &&TARGET_SET_ADD,
@ -152,15 +152,15 @@ static void *opcode_targets[256] = {
&&TARGET_YIELD_VALUE, &&TARGET_YIELD_VALUE,
&&TARGET_RESUME, &&TARGET_RESUME,
&&TARGET_MATCH_CLASS, &&TARGET_MATCH_CLASS,
&&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_DICT,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_FORMAT_VALUE, &&TARGET_FORMAT_VALUE,
&&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_CONST_KEY_MAP,
&&TARGET_BUILD_STRING, &&TARGET_BUILD_STRING,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_LIST,
&&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TUPLE,
&&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
&&_unknown_opcode,
&&TARGET_LIST_EXTEND, &&TARGET_LIST_EXTEND,
&&TARGET_SET_UPDATE, &&TARGET_SET_UPDATE,
&&TARGET_DICT_MERGE, &&TARGET_DICT_MERGE,