From faa3272fb8d63d481a136cc0467a0cba6ed7b264 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 29 Oct 2024 11:15:42 +0000 Subject: [PATCH] GH-125837: Split `LOAD_CONST` into three. (GH-125972) * Add LOAD_CONST_IMMORTAL opcode * Add LOAD_SMALL_INT opcode * Remove RETURN_CONST opcode --- Doc/library/dis.rst | 23 +- Doc/whatsnew/3.12.rst | 2 +- Include/internal/pycore_magic_number.h | 3 +- Include/internal/pycore_opcode_metadata.h | 33 +- Include/internal/pycore_opcode_utils.h | 1 - Include/internal/pycore_uop_ids.h | 82 ++--- Include/internal/pycore_uop_metadata.h | 25 ++ Include/opcode_ids.h | 96 +++--- Lib/_opcode_metadata.py | 99 +++--- Lib/dis.py | 10 +- Lib/test/test_ast/test_ast.py | 4 +- Lib/test/test_code.py | 5 +- Lib/test/test_compile.py | 38 +-- Lib/test/test_compiler_assemble.py | 10 +- Lib/test/test_compiler_codegen.py | 22 +- Lib/test/test_dis.py | 323 ++++++++++-------- Lib/test/test_embed.py | 3 + Lib/test/test_import/__init__.py | 4 +- Lib/test/test_monitoring.py | 5 + Lib/test/test_peepholer.py | 48 ++- ...-10-25-15-56-14.gh-issue-125837.KlCdgD.rst | 5 + Objects/frameobject.c | 2 - Programs/test_frozenmain.h | 58 ++-- Python/bytecodes.c | 32 +- Python/codegen.c | 11 + Python/executor_cases.c.h | 76 +++++ Python/flowgraph.c | 50 ++- Python/generated_cases.c.h | 119 ++----- Python/instrumentation.c | 5 - Python/opcode_targets.h | 4 +- Python/optimizer_bytecodes.c | 11 + Python/optimizer_cases.c.h | 21 ++ Python/specialize.c | 14 + 33 files changed, 706 insertions(+), 538 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a2e44e09ffc..6c12d1b5e0d 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -862,13 +862,6 @@ 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`. @@ -1086,6 +1079,22 @@ iterations of the loop. Pushes ``co_consts[consti]`` onto the stack. +.. opcode:: LOAD_SMALL_INT (i) + + Pushes the integer ``i`` onto the stack. + ``i`` must be in ``range(256)`` + + .. versionadded:: 3.14 + + +.. opcode:: LOAD_CONST_IMMORTAL (consti) + + Pushes ``co_consts[consti]`` onto the stack. + Can be used when the constant value is known to be immortal. + + .. versionadded:: 3.14 + + .. opcode:: LOAD_NAME (namei) Pushes the value associated with ``co_names[namei]`` onto the stack. diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 463fc269ee8..1354355894e 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1123,7 +1123,7 @@ CPython bytecode changes * Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and Vladimir Matveev in :gh:`103497`.) -* Add the :opcode:`RETURN_CONST` instruction. (Contributed by Wenyang Wang in :gh:`101632`.) +* Add the ``RETURN_CONST`` instruction. (Contributed by Wenyang Wang in :gh:`101632`.) Demos and Tools =============== diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 4aa89f3cac8..14e29576875 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -261,6 +261,7 @@ Known values: Python 3.14a1 3606 (Specialize CALL_KW) Python 3.14a1 3607 (Add pseudo instructions JUMP_IF_TRUE/FALSE) Python 3.14a1 3608 (Add support for slices) + Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) Python 3.15 will start with 3650 @@ -273,7 +274,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3608 +#define PYC_MAGIC_NUMBER 3609 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes (little-endian) and then appending b'\r\n'. */ #define PYC_MAGIC_NUMBER_TOKEN \ diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 93c9e718bb0..58e583eabbc 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -253,8 +253,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case INSTRUMENTED_RESUME: return 0; - case INSTRUMENTED_RETURN_CONST: - return 0; case INSTRUMENTED_RETURN_VALUE: return 1; case INSTRUMENTED_YIELD_VALUE: @@ -317,6 +315,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_CONST: return 0; + case LOAD_CONST_IMMORTAL: + return 0; case LOAD_DEREF: return 0; case LOAD_FAST: @@ -341,6 +341,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_NAME: return 0; + case LOAD_SMALL_INT: + return 0; case LOAD_SPECIAL: return 1; case LOAD_SUPER_ATTR: @@ -393,8 +395,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case RESUME_CHECK: return 0; - case RETURN_CONST: - return 0; case RETURN_GENERATOR: return 0; case RETURN_VALUE: @@ -712,8 +712,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case INSTRUMENTED_RESUME: return 0; - case INSTRUMENTED_RETURN_CONST: - return 1; case INSTRUMENTED_RETURN_VALUE: return 1; case INSTRUMENTED_YIELD_VALUE: @@ -776,6 +774,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1; case LOAD_CONST: return 1; + case LOAD_CONST_IMMORTAL: + return 1; case LOAD_DEREF: return 1; case LOAD_FAST: @@ -800,6 +800,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1; case LOAD_NAME: return 1; + case LOAD_SMALL_INT: + return 1; case LOAD_SPECIAL: return 2; case LOAD_SUPER_ATTR: @@ -852,8 +854,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case RESUME_CHECK: return 0; - case RETURN_CONST: - return 1; case RETURN_GENERATOR: return 1; case RETURN_VALUE: @@ -1123,7 +1123,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, - [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, 0 }, @@ -1150,6 +1149,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG }, + [LOAD_CONST_IMMORTAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, @@ -1162,6 +1162,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1187,7 +1188,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [RESERVED] = { true, INSTR_FMT_IX, 0 }, [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, - [RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [RETURN_VALUE] = { true, INSTR_FMT_IX, 0 }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1355,6 +1355,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, 0, 0 } } }, [LOAD_COMMON_CONSTANT] = { .nuops = 1, .uops = { { _LOAD_COMMON_CONSTANT, 0, 0 } } }, [LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, 0, 0 } } }, + [LOAD_CONST_IMMORTAL] = { .nuops = 1, .uops = { { _LOAD_CONST_IMMORTAL, 0, 0 } } }, [LOAD_DEREF] = { .nuops = 1, .uops = { { _LOAD_DEREF, 0, 0 } } }, [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } }, [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } }, @@ -1366,6 +1367,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } }, [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } }, [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } }, + [LOAD_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, 0, 0 } } }, [LOAD_SPECIAL] = { .nuops = 1, .uops = { { _LOAD_SPECIAL, 0, 0 } } }, [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } }, [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } }, @@ -1386,7 +1388,6 @@ _PyOpcode_macro_expansion[256] = { [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, 0, 0 } } }, [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } }, [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } }, - [RETURN_CONST] = { .nuops = 2, .uops = { { _LOAD_CONST, 0, 0 }, { _RETURN_VALUE, 0, 0 } } }, [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, 0, 0 } } }, [RETURN_VALUE] = { .nuops = 1, .uops = { { _RETURN_VALUE, 0, 0 } } }, [SEND_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, 0, 0 }, { _SEND_GEN_FRAME, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, @@ -1541,7 +1542,6 @@ const char *_PyOpcode_OpName[266] = { [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE", [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE", [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME", - [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST", [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE", [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", [INTERPRETER_EXIT] = "INTERPRETER_EXIT", @@ -1573,6 +1573,7 @@ const char *_PyOpcode_OpName[266] = { [LOAD_CLOSURE] = "LOAD_CLOSURE", [LOAD_COMMON_CONSTANT] = "LOAD_COMMON_CONSTANT", [LOAD_CONST] = "LOAD_CONST", + [LOAD_CONST_IMMORTAL] = "LOAD_CONST_IMMORTAL", [LOAD_DEREF] = "LOAD_DEREF", [LOAD_FAST] = "LOAD_FAST", [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", @@ -1585,6 +1586,7 @@ const char *_PyOpcode_OpName[266] = { [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [LOAD_LOCALS] = "LOAD_LOCALS", [LOAD_NAME] = "LOAD_NAME", + [LOAD_SMALL_INT] = "LOAD_SMALL_INT", [LOAD_SPECIAL] = "LOAD_SPECIAL", [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR", [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR", @@ -1611,7 +1613,6 @@ const char *_PyOpcode_OpName[266] = { [RESERVED] = "RESERVED", [RESUME] = "RESUME", [RESUME_CHECK] = "RESUME_CHECK", - [RETURN_CONST] = "RETURN_CONST", [RETURN_GENERATOR] = "RETURN_GENERATOR", [RETURN_VALUE] = "RETURN_VALUE", [SEND] = "SEND", @@ -1797,7 +1798,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME, - [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, [INTERPRETER_EXIT] = INTERPRETER_EXIT, @@ -1824,6 +1824,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, [LOAD_COMMON_CONSTANT] = LOAD_COMMON_CONSTANT, [LOAD_CONST] = LOAD_CONST, + [LOAD_CONST_IMMORTAL] = LOAD_CONST, [LOAD_DEREF] = LOAD_DEREF, [LOAD_FAST] = LOAD_FAST, [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, @@ -1836,6 +1837,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, [LOAD_LOCALS] = LOAD_LOCALS, [LOAD_NAME] = LOAD_NAME, + [LOAD_SMALL_INT] = LOAD_SMALL_INT, [LOAD_SPECIAL] = LOAD_SPECIAL, [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR, @@ -1861,7 +1863,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [RESERVED] = RESERVED, [RESUME] = RESUME, [RESUME_CHECK] = RESUME, - [RETURN_CONST] = RETURN_CONST, [RETURN_GENERATOR] = RETURN_GENERATOR, [RETURN_VALUE] = RETURN_VALUE, [SEND] = SEND, @@ -1940,7 +1941,6 @@ const uint8_t _PyOpcode_Deopt[256] = { case 146: \ case 147: \ case 148: \ - case 227: \ case 228: \ case 229: \ case 230: \ @@ -1949,6 +1949,7 @@ const uint8_t _PyOpcode_Deopt[256] = { case 233: \ case 234: \ case 235: \ + case 236: \ ; struct pseudo_targets { uint8_t as_sequence; diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index e76f4840a66..c6ce7e65a65 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -47,7 +47,6 @@ extern "C" { #define IS_SCOPE_EXIT_OPCODE(opcode) \ ((opcode) == RETURN_VALUE || \ - (opcode) == RETURN_CONST || \ (opcode) == RAISE_VARARGS || \ (opcode) == RERAISE) diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 1951c65a287..de628d240d1 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -195,6 +195,7 @@ extern "C" { #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST +#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL #define _LOAD_CONST_INLINE 425 #define _LOAD_CONST_INLINE_BORROW 426 #define _LOAD_CONST_INLINE_BORROW_WITH_NULL 427 @@ -221,72 +222,77 @@ extern "C" { #define _LOAD_GLOBAL_MODULE_FROM_KEYS 442 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME +#define _LOAD_SMALL_INT 443 +#define _LOAD_SMALL_INT_0 444 +#define _LOAD_SMALL_INT_1 445 +#define _LOAD_SMALL_INT_2 446 +#define _LOAD_SMALL_INT_3 447 #define _LOAD_SPECIAL LOAD_SPECIAL #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 443 +#define _MAKE_CALLARGS_A_TUPLE 448 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 444 +#define _MAKE_WARM 449 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 445 -#define _MAYBE_EXPAND_METHOD_KW 446 -#define _MONITOR_CALL 447 -#define _MONITOR_JUMP_BACKWARD 448 -#define _MONITOR_RESUME 449 +#define _MAYBE_EXPAND_METHOD 450 +#define _MAYBE_EXPAND_METHOD_KW 451 +#define _MONITOR_CALL 452 +#define _MONITOR_JUMP_BACKWARD 453 +#define _MONITOR_RESUME 454 #define _NOP NOP #define _POP_EXCEPT POP_EXCEPT -#define _POP_JUMP_IF_FALSE 450 -#define _POP_JUMP_IF_TRUE 451 +#define _POP_JUMP_IF_FALSE 455 +#define _POP_JUMP_IF_TRUE 456 #define _POP_TOP POP_TOP -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 452 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 457 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 453 +#define _PUSH_FRAME 458 #define _PUSH_NULL PUSH_NULL -#define _PY_FRAME_GENERAL 454 -#define _PY_FRAME_KW 455 -#define _QUICKEN_RESUME 456 -#define _REPLACE_WITH_TRUE 457 +#define _PY_FRAME_GENERAL 459 +#define _PY_FRAME_KW 460 +#define _QUICKEN_RESUME 461 +#define _REPLACE_WITH_TRUE 462 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 458 -#define _SEND 459 -#define _SEND_GEN_FRAME 460 +#define _SAVE_RETURN_OFFSET 463 +#define _SEND 464 +#define _SEND_GEN_FRAME 465 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _START_EXECUTOR 461 -#define _STORE_ATTR 462 -#define _STORE_ATTR_INSTANCE_VALUE 463 -#define _STORE_ATTR_SLOT 464 -#define _STORE_ATTR_WITH_HINT 465 +#define _START_EXECUTOR 466 +#define _STORE_ATTR 467 +#define _STORE_ATTR_INSTANCE_VALUE 468 +#define _STORE_ATTR_SLOT 469 +#define _STORE_ATTR_WITH_HINT 470 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 466 -#define _STORE_FAST_0 467 -#define _STORE_FAST_1 468 -#define _STORE_FAST_2 469 -#define _STORE_FAST_3 470 -#define _STORE_FAST_4 471 -#define _STORE_FAST_5 472 -#define _STORE_FAST_6 473 -#define _STORE_FAST_7 474 +#define _STORE_FAST 471 +#define _STORE_FAST_0 472 +#define _STORE_FAST_1 473 +#define _STORE_FAST_2 474 +#define _STORE_FAST_3 475 +#define _STORE_FAST_4 476 +#define _STORE_FAST_5 477 +#define _STORE_FAST_6 478 +#define _STORE_FAST_7 479 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 475 -#define _STORE_SUBSCR 476 +#define _STORE_SLICE 480 +#define _STORE_SUBSCR 481 #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT #define _SWAP SWAP -#define _TIER2_RESUME_CHECK 477 -#define _TO_BOOL 478 +#define _TIER2_RESUME_CHECK 482 +#define _TO_BOOL 483 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT #define _TO_BOOL_LIST TO_BOOL_LIST @@ -296,13 +302,13 @@ extern "C" { #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 479 +#define _UNPACK_SEQUENCE 484 #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 479 +#define MAX_UOP_ID 484 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 2f0a7fb2f6e..4cfdecec78b 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -36,6 +36,12 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG, + [_LOAD_CONST_IMMORTAL] = HAS_ARG_FLAG | HAS_CONST_FLAG, + [_LOAD_SMALL_INT_0] = 0, + [_LOAD_SMALL_INT_1] = 0, + [_LOAD_SMALL_INT_2] = 0, + [_LOAD_SMALL_INT_3] = 0, + [_LOAD_SMALL_INT] = HAS_ARG_FLAG, [_STORE_FAST_0] = HAS_LOCAL_FLAG, [_STORE_FAST_1] = HAS_LOCAL_FLAG, [_STORE_FAST_2] = HAS_LOCAL_FLAG, @@ -289,6 +295,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = { [_LOAD_FAST] = 8, + [_LOAD_SMALL_INT] = 4, [_STORE_FAST] = 8, [_INIT_CALL_PY_EXACT_ARGS] = 5, }; @@ -460,6 +467,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS", [_LOAD_COMMON_CONSTANT] = "_LOAD_COMMON_CONSTANT", [_LOAD_CONST] = "_LOAD_CONST", + [_LOAD_CONST_IMMORTAL] = "_LOAD_CONST_IMMORTAL", [_LOAD_CONST_INLINE] = "_LOAD_CONST_INLINE", [_LOAD_CONST_INLINE_BORROW] = "_LOAD_CONST_INLINE_BORROW", [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = "_LOAD_CONST_INLINE_BORROW_WITH_NULL", @@ -485,6 +493,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS", [_LOAD_LOCALS] = "_LOAD_LOCALS", [_LOAD_NAME] = "_LOAD_NAME", + [_LOAD_SMALL_INT] = "_LOAD_SMALL_INT", + [_LOAD_SMALL_INT_0] = "_LOAD_SMALL_INT_0", + [_LOAD_SMALL_INT_1] = "_LOAD_SMALL_INT_1", + [_LOAD_SMALL_INT_2] = "_LOAD_SMALL_INT_2", + [_LOAD_SMALL_INT_3] = "_LOAD_SMALL_INT_3", [_LOAD_SPECIAL] = "_LOAD_SPECIAL", [_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR", [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD", @@ -598,6 +611,18 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_CONST: return 0; + case _LOAD_CONST_IMMORTAL: + return 0; + case _LOAD_SMALL_INT_0: + return 0; + case _LOAD_SMALL_INT_1: + return 0; + case _LOAD_SMALL_INT_2: + return 0; + case _LOAD_SMALL_INT_3: + return 0; + case _LOAD_SMALL_INT: + return 0; case _STORE_FAST_0: return 1; case _STORE_FAST_1: diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 327bdb79246..ce3d23eaa6d 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -99,18 +99,18 @@ extern "C" { #define LOAD_FROM_DICT_OR_GLOBALS 86 #define LOAD_GLOBAL 87 #define LOAD_NAME 88 -#define LOAD_SPECIAL 89 -#define LOAD_SUPER_ATTR 90 -#define MAKE_CELL 91 -#define MAP_ADD 92 -#define MATCH_CLASS 93 -#define POP_JUMP_IF_FALSE 94 -#define POP_JUMP_IF_NONE 95 -#define POP_JUMP_IF_NOT_NONE 96 -#define POP_JUMP_IF_TRUE 97 -#define RAISE_VARARGS 98 -#define RERAISE 99 -#define RETURN_CONST 100 +#define LOAD_SMALL_INT 89 +#define LOAD_SPECIAL 90 +#define LOAD_SUPER_ATTR 91 +#define MAKE_CELL 92 +#define MAP_ADD 93 +#define MATCH_CLASS 94 +#define POP_JUMP_IF_FALSE 95 +#define POP_JUMP_IF_NONE 96 +#define POP_JUMP_IF_NOT_NONE 97 +#define POP_JUMP_IF_TRUE 98 +#define RAISE_VARARGS 99 +#define RERAISE 100 #define SEND 101 #define SET_ADD 102 #define SET_FUNCTION_ATTRIBUTE 103 @@ -184,41 +184,41 @@ extern "C" { #define LOAD_ATTR_PROPERTY 204 #define LOAD_ATTR_SLOT 205 #define LOAD_ATTR_WITH_HINT 206 -#define LOAD_GLOBAL_BUILTIN 207 -#define LOAD_GLOBAL_MODULE 208 -#define LOAD_SUPER_ATTR_ATTR 209 -#define LOAD_SUPER_ATTR_METHOD 210 -#define RESUME_CHECK 211 -#define SEND_GEN 212 -#define STORE_ATTR_INSTANCE_VALUE 213 -#define STORE_ATTR_SLOT 214 -#define STORE_ATTR_WITH_HINT 215 -#define STORE_SUBSCR_DICT 216 -#define STORE_SUBSCR_LIST_INT 217 -#define TO_BOOL_ALWAYS_TRUE 218 -#define TO_BOOL_BOOL 219 -#define TO_BOOL_INT 220 -#define TO_BOOL_LIST 221 -#define TO_BOOL_NONE 222 -#define TO_BOOL_STR 223 -#define UNPACK_SEQUENCE_LIST 224 -#define UNPACK_SEQUENCE_TUPLE 225 -#define UNPACK_SEQUENCE_TWO_TUPLE 226 -#define INSTRUMENTED_END_FOR 236 -#define INSTRUMENTED_END_SEND 237 -#define INSTRUMENTED_LOAD_SUPER_ATTR 238 -#define INSTRUMENTED_FOR_ITER 239 -#define INSTRUMENTED_CALL_KW 240 -#define INSTRUMENTED_CALL_FUNCTION_EX 241 -#define INSTRUMENTED_INSTRUCTION 242 -#define INSTRUMENTED_JUMP_FORWARD 243 -#define INSTRUMENTED_POP_JUMP_IF_TRUE 244 -#define INSTRUMENTED_POP_JUMP_IF_FALSE 245 -#define INSTRUMENTED_POP_JUMP_IF_NONE 246 -#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 247 -#define INSTRUMENTED_RESUME 248 -#define INSTRUMENTED_RETURN_VALUE 249 -#define INSTRUMENTED_RETURN_CONST 250 +#define LOAD_CONST_IMMORTAL 207 +#define LOAD_GLOBAL_BUILTIN 208 +#define LOAD_GLOBAL_MODULE 209 +#define LOAD_SUPER_ATTR_ATTR 210 +#define LOAD_SUPER_ATTR_METHOD 211 +#define RESUME_CHECK 212 +#define SEND_GEN 213 +#define STORE_ATTR_INSTANCE_VALUE 214 +#define STORE_ATTR_SLOT 215 +#define STORE_ATTR_WITH_HINT 216 +#define STORE_SUBSCR_DICT 217 +#define STORE_SUBSCR_LIST_INT 218 +#define TO_BOOL_ALWAYS_TRUE 219 +#define TO_BOOL_BOOL 220 +#define TO_BOOL_INT 221 +#define TO_BOOL_LIST 222 +#define TO_BOOL_NONE 223 +#define TO_BOOL_STR 224 +#define UNPACK_SEQUENCE_LIST 225 +#define UNPACK_SEQUENCE_TUPLE 226 +#define UNPACK_SEQUENCE_TWO_TUPLE 227 +#define INSTRUMENTED_END_FOR 237 +#define INSTRUMENTED_END_SEND 238 +#define INSTRUMENTED_LOAD_SUPER_ATTR 239 +#define INSTRUMENTED_FOR_ITER 240 +#define INSTRUMENTED_CALL_KW 241 +#define INSTRUMENTED_CALL_FUNCTION_EX 242 +#define INSTRUMENTED_INSTRUCTION 243 +#define INSTRUMENTED_JUMP_FORWARD 244 +#define INSTRUMENTED_POP_JUMP_IF_TRUE 245 +#define INSTRUMENTED_POP_JUMP_IF_FALSE 246 +#define INSTRUMENTED_POP_JUMP_IF_NONE 247 +#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 248 +#define INSTRUMENTED_RESUME 249 +#define INSTRUMENTED_RETURN_VALUE 250 #define INSTRUMENTED_YIELD_VALUE 251 #define INSTRUMENTED_CALL 252 #define INSTRUMENTED_JUMP_BACKWARD 253 @@ -237,7 +237,7 @@ extern "C" { #define HAVE_ARGUMENT 41 #define MIN_SPECIALIZED_OPCODE 150 -#define MIN_INSTRUMENTED_OPCODE 236 +#define MIN_INSTRUMENTED_OPCODE 237 #ifdef __cplusplus } diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 9a793717cf0..cda3c340c32 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -6,6 +6,9 @@ _specializations = { "RESUME": [ "RESUME_CHECK", ], + "LOAD_CONST": [ + "LOAD_CONST_IMMORTAL", + ], "TO_BOOL": [ "TO_BOOL_ALWAYS_TRUE", "TO_BOOL_BOOL", @@ -174,26 +177,27 @@ _specialized_opmap = { 'LOAD_ATTR_PROPERTY': 204, 'LOAD_ATTR_SLOT': 205, 'LOAD_ATTR_WITH_HINT': 206, - 'LOAD_GLOBAL_BUILTIN': 207, - 'LOAD_GLOBAL_MODULE': 208, - 'LOAD_SUPER_ATTR_ATTR': 209, - 'LOAD_SUPER_ATTR_METHOD': 210, - 'RESUME_CHECK': 211, - 'SEND_GEN': 212, - 'STORE_ATTR_INSTANCE_VALUE': 213, - 'STORE_ATTR_SLOT': 214, - 'STORE_ATTR_WITH_HINT': 215, - 'STORE_SUBSCR_DICT': 216, - 'STORE_SUBSCR_LIST_INT': 217, - 'TO_BOOL_ALWAYS_TRUE': 218, - 'TO_BOOL_BOOL': 219, - 'TO_BOOL_INT': 220, - 'TO_BOOL_LIST': 221, - 'TO_BOOL_NONE': 222, - 'TO_BOOL_STR': 223, - 'UNPACK_SEQUENCE_LIST': 224, - 'UNPACK_SEQUENCE_TUPLE': 225, - 'UNPACK_SEQUENCE_TWO_TUPLE': 226, + 'LOAD_CONST_IMMORTAL': 207, + 'LOAD_GLOBAL_BUILTIN': 208, + 'LOAD_GLOBAL_MODULE': 209, + 'LOAD_SUPER_ATTR_ATTR': 210, + 'LOAD_SUPER_ATTR_METHOD': 211, + 'RESUME_CHECK': 212, + 'SEND_GEN': 213, + 'STORE_ATTR_INSTANCE_VALUE': 214, + 'STORE_ATTR_SLOT': 215, + 'STORE_ATTR_WITH_HINT': 216, + 'STORE_SUBSCR_DICT': 217, + 'STORE_SUBSCR_LIST_INT': 218, + 'TO_BOOL_ALWAYS_TRUE': 219, + 'TO_BOOL_BOOL': 220, + 'TO_BOOL_INT': 221, + 'TO_BOOL_LIST': 222, + 'TO_BOOL_NONE': 223, + 'TO_BOOL_STR': 224, + 'UNPACK_SEQUENCE_LIST': 225, + 'UNPACK_SEQUENCE_TUPLE': 226, + 'UNPACK_SEQUENCE_TWO_TUPLE': 227, } opmap = { @@ -288,18 +292,18 @@ opmap = { 'LOAD_FROM_DICT_OR_GLOBALS': 86, 'LOAD_GLOBAL': 87, 'LOAD_NAME': 88, - 'LOAD_SPECIAL': 89, - 'LOAD_SUPER_ATTR': 90, - 'MAKE_CELL': 91, - 'MAP_ADD': 92, - 'MATCH_CLASS': 93, - 'POP_JUMP_IF_FALSE': 94, - 'POP_JUMP_IF_NONE': 95, - 'POP_JUMP_IF_NOT_NONE': 96, - 'POP_JUMP_IF_TRUE': 97, - 'RAISE_VARARGS': 98, - 'RERAISE': 99, - 'RETURN_CONST': 100, + 'LOAD_SMALL_INT': 89, + 'LOAD_SPECIAL': 90, + 'LOAD_SUPER_ATTR': 91, + 'MAKE_CELL': 92, + 'MAP_ADD': 93, + 'MATCH_CLASS': 94, + 'POP_JUMP_IF_FALSE': 95, + 'POP_JUMP_IF_NONE': 96, + 'POP_JUMP_IF_NOT_NONE': 97, + 'POP_JUMP_IF_TRUE': 98, + 'RAISE_VARARGS': 99, + 'RERAISE': 100, 'SEND': 101, 'SET_ADD': 102, 'SET_FUNCTION_ATTRIBUTE': 103, @@ -315,21 +319,20 @@ opmap = { 'UNPACK_EX': 113, 'UNPACK_SEQUENCE': 114, 'YIELD_VALUE': 115, - 'INSTRUMENTED_END_FOR': 236, - 'INSTRUMENTED_END_SEND': 237, - 'INSTRUMENTED_LOAD_SUPER_ATTR': 238, - 'INSTRUMENTED_FOR_ITER': 239, - 'INSTRUMENTED_CALL_KW': 240, - 'INSTRUMENTED_CALL_FUNCTION_EX': 241, - 'INSTRUMENTED_INSTRUCTION': 242, - 'INSTRUMENTED_JUMP_FORWARD': 243, - 'INSTRUMENTED_POP_JUMP_IF_TRUE': 244, - 'INSTRUMENTED_POP_JUMP_IF_FALSE': 245, - 'INSTRUMENTED_POP_JUMP_IF_NONE': 246, - 'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 247, - 'INSTRUMENTED_RESUME': 248, - 'INSTRUMENTED_RETURN_VALUE': 249, - 'INSTRUMENTED_RETURN_CONST': 250, + 'INSTRUMENTED_END_FOR': 237, + 'INSTRUMENTED_END_SEND': 238, + 'INSTRUMENTED_LOAD_SUPER_ATTR': 239, + 'INSTRUMENTED_FOR_ITER': 240, + 'INSTRUMENTED_CALL_KW': 241, + 'INSTRUMENTED_CALL_FUNCTION_EX': 242, + 'INSTRUMENTED_INSTRUCTION': 243, + 'INSTRUMENTED_JUMP_FORWARD': 244, + 'INSTRUMENTED_POP_JUMP_IF_TRUE': 245, + 'INSTRUMENTED_POP_JUMP_IF_FALSE': 246, + 'INSTRUMENTED_POP_JUMP_IF_NONE': 247, + 'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 248, + 'INSTRUMENTED_RESUME': 249, + 'INSTRUMENTED_RETURN_VALUE': 250, 'INSTRUMENTED_YIELD_VALUE': 251, 'INSTRUMENTED_CALL': 252, 'INSTRUMENTED_JUMP_BACKWARD': 253, @@ -346,4 +349,4 @@ opmap = { } HAVE_ARGUMENT = 41 -MIN_INSTRUMENTED_OPCODE = 236 +MIN_INSTRUMENTED_OPCODE = 237 diff --git a/Lib/dis.py b/Lib/dis.py index db69848e9ab..c28fa6b3dc4 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -35,9 +35,8 @@ SET_FUNCTION_ATTRIBUTE = opmap['SET_FUNCTION_ATTRIBUTE'] FUNCTION_ATTR_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure', 'annotate') ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] -LOAD_CONST = opmap['LOAD_CONST'] -RETURN_CONST = opmap['RETURN_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] +LOAD_SMALL_INT = opmap['LOAD_SMALL_INT'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] FOR_ITER = opmap['FOR_ITER'] @@ -674,8 +673,10 @@ def _get_const_value(op, arg, co_consts): Otherwise (if it is a LOAD_CONST and co_consts is not provided) returns the dis.UNKNOWN sentinel. """ - assert op in hasconst + assert op in hasconst or op == LOAD_SMALL_INT + if op == LOAD_SMALL_INT: + return arg argval = UNKNOWN if co_consts is not None: argval = co_consts[arg] @@ -994,7 +995,8 @@ def _find_imports(co): if op == IMPORT_NAME and i >= 2: from_op = opargs[i-1] level_op = opargs[i-2] - if (from_op[0] in hasconst and level_op[0] in hasconst): + if (from_op[0] in hasconst and + (level_op[0] in hasconst or level_op[0] == LOAD_SMALL_INT)): level = _get_const_value(level_op[0], level_op[1], consts) fromlist = _get_const_value(from_op[0], from_op[1], consts) yield (names[oparg], level, fromlist) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index dd1c6447fca..739a020f708 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ class ConstantTests(unittest.TestCase): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname == 'LOAD_CONST' or instr.opname == 'RETURN_CONST': + if instr.opcode in dis.hasconst: consts.append(instr.argval) return consts @@ -2311,7 +2311,7 @@ class ConstantTests(unittest.TestCase): def test_load_const(self): consts = [None, True, False, - 124, + 1000, 2.0, 3j, "unicode", diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 93f3a5833cb..dcdd15a43e6 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -254,10 +254,11 @@ class CodeTest(unittest.TestCase): return x code = func.__code__ - # different co_name, co_varnames, co_consts + # Different co_name, co_varnames, co_consts. + # Must have the same number of constants and + # variables or we get crashes. def func2(): y = 2 - z = 3 return y code2 = func2.__code__ diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6f838da6018..958170f675e 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -775,7 +775,6 @@ class TestSpecifics(unittest.TestCase): self.assertEqual(repr(f1()), repr(const)) check_same_constant(None) - check_same_constant(0) check_same_constant(0.0) check_same_constant(b'abc') check_same_constant('abc') @@ -853,9 +852,9 @@ class TestSpecifics(unittest.TestCase): eval(compile(code, "file.py", "exec"), g) exec(code, g) f = g['f'] - expected = tuple([None, '', 1] + [f't{i}' for i in range(N)]) + expected = tuple([None, ''] + [f't{i}' for i in range(N)]) self.assertEqual(f.__code__.co_consts, expected) - expected = "".join(expected[3:]) + expected = "".join(expected[2:]) self.assertEqual(expected, f()) # Stripping unused constants is not a strict requirement for the @@ -867,7 +866,7 @@ class TestSpecifics(unittest.TestCase): def f1(): "docstring" return 42 - self.assertEqual(f1.__code__.co_consts, (f1.__doc__, 42)) + self.assertEqual(f1.__code__.co_consts, (f1.__doc__,)) # This is a regression test for a CPython specific peephole optimizer # implementation bug present in a few releases. It's assertion verifies @@ -884,7 +883,7 @@ class TestSpecifics(unittest.TestCase): # RETURN_VALUE opcode. This does not always crash an interpreter. # When you build with the clang memory sanitizer it reliably aborts. self.assertEqual( - 'RETURN_CONST', + 'RETURN_VALUE', list(dis.get_instructions(unused_code_at_end))[-1].opname) @support.cpython_only @@ -982,7 +981,6 @@ class TestSpecifics(unittest.TestCase): self.assertEqual(repr(f1()), repr(const1)) self.assertEqual(repr(f2()), repr(const2)) - check_different_constants(0, 0.0) check_different_constants(+0.0, -0.0) check_different_constants((0,), (0.0,)) check_different_constants('a', b'a') @@ -1045,8 +1043,8 @@ class TestSpecifics(unittest.TestCase): for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertLessEqual(len(opcodes), 3) - self.assertEqual('RETURN_CONST', opcodes[-1].opname) + self.assertLessEqual(len(opcodes), 4) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) self.assertEqual(None, opcodes[-1].argval) def test_false_while_loop(self): @@ -1063,8 +1061,8 @@ class TestSpecifics(unittest.TestCase): # 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(2, len(opcodes)) - self.assertEqual('RETURN_CONST', opcodes[1].opname) + self.assertEqual(3, len(opcodes)) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) self.assertEqual(None, opcodes[1].argval) def test_consts_in_conditionals(self): @@ -1738,7 +1736,7 @@ class TestSourcePositions(unittest.TestCase): line=1, end_line=3, column=0, end_column=36, occurrence=1) # The "error msg": self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST', - line=3, end_line=3, column=25, end_column=36, occurrence=4) + line=3, end_line=3, column=25, end_column=36, occurrence=2) self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', line=1, end_line=3, column=0, end_column=36, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS', @@ -1760,7 +1758,7 @@ class TestSourcePositions(unittest.TestCase): 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_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=4, end_line=4, column=7, end_column=14, occurrence=1) def test_multiline_async_generator_expression(self): @@ -1777,7 +1775,7 @@ class TestSourcePositions(unittest.TestCase): 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_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=1, end_line=6, column=0, end_column=32, occurrence=1) def test_multiline_list_comprehension(self): @@ -1815,7 +1813,7 @@ class TestSourcePositions(unittest.TestCase): line=2, end_line=3, column=5, end_column=12, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=2, end_line=3, column=5, end_column=12, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_multiline_set_comprehension(self): @@ -1853,7 +1851,7 @@ class TestSourcePositions(unittest.TestCase): line=2, end_line=3, column=5, end_column=12, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=2, end_line=3, column=5, end_column=12, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_multiline_dict_comprehension(self): @@ -1891,7 +1889,7 @@ class TestSourcePositions(unittest.TestCase): line=2, end_line=3, column=5, end_column=11, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=2, end_line=3, column=5, end_column=11, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_matchcase_sequence(self): @@ -2204,8 +2202,8 @@ class TestSourcePositions(unittest.TestCase): start_line, end_line, _, _ = instr.positions self.assertEqual(start_line, end_line) - # Expect three load None instructions for the no-exception __exit__ call, - # and one RETURN_VALUE. + # Expect four `LOAD_CONST None` instructions: + # three for the no-exception __exit__ call, and one for the return. # They should all have the locations of the context manager ('xyz'). load_none = [instr for instr in dis.get_instructions(f) if @@ -2213,8 +2211,8 @@ class TestSourcePositions(unittest.TestCase): return_value = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] - self.assertEqual(len(load_none), 3) - self.assertEqual(len(return_value), 1) + self.assertEqual(len(load_none), 4) + self.assertEqual(len(return_value), 2) for instr in load_none + return_value: start_line, end_line, start_col, end_col = instr.positions self.assertEqual(start_line, f.__code__.co_firstlineno + 1) diff --git a/Lib/test/test_compiler_assemble.py b/Lib/test/test_compiler_assemble.py index 1b98b0d97ed..625d3c704c3 100644 --- a/Lib/test/test_compiler_assemble.py +++ b/Lib/test/test_compiler_assemble.py @@ -125,13 +125,15 @@ class IsolatedAssembleTests(AssemblerTestCase): # code for "try: pass\n except: pass" insts = [ ('RESUME', 0), - ('SETUP_FINALLY', 3), - ('RETURN_CONST', 0), - ('SETUP_CLEANUP', 8), + ('SETUP_FINALLY', 4), + ('LOAD_CONST', 0), + ('RETURN_VALUE', None), + ('SETUP_CLEANUP', 10), ('PUSH_EXC_INFO', None), ('POP_TOP', None), ('POP_EXCEPT', None), - ('RETURN_CONST', 0), + ('LOAD_CONST', 0), + ('RETURN_VALUE', None), ('COPY', 3), ('POP_EXCEPT', None), ('RERAISE', 1), diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index 8a15c400a44..2dd7cf65ee3 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -29,13 +29,13 @@ class IsolatedCodeGenTests(CodegenTestCase): ('LOAD_CONST', 0, 1), ('TO_BOOL', 0, 1), ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), - ('LOAD_CONST', 1, 1), + ('LOAD_SMALL_INT', 42, 1), ('JUMP_NO_INTERRUPT', exit_lbl := self.Label()), false_lbl, - ('LOAD_CONST', 2, 1), + ('LOAD_SMALL_INT', 24, 1), exit_lbl, ('POP_TOP', None), - ('LOAD_CONST', 3), + ('LOAD_CONST', 1), ('RETURN_VALUE', None), ] self.codegen_test(snippet, expected) @@ -82,7 +82,7 @@ class IsolatedCodeGenTests(CodegenTestCase): # Function body ('RESUME', 0), ('LOAD_FAST', 0), - ('LOAD_CONST', 1), + ('LOAD_SMALL_INT', 42), ('BINARY_OP', 0), ('RETURN_VALUE', None), ('LOAD_CONST', 0), @@ -125,23 +125,23 @@ class IsolatedCodeGenTests(CodegenTestCase): [ ('RESUME', 0), ('NOP', None), - ('LOAD_CONST', 1), + ('LOAD_SMALL_INT', 12), ('RETURN_VALUE', None), - ('LOAD_CONST', 0), + ('LOAD_CONST', 1), ('RETURN_VALUE', None), ], [ ('RESUME', 0), - ('LOAD_CONST', 1), + ('LOAD_SMALL_INT', 1), ('STORE_FAST', 0), - ('LOAD_CONST', 2), + ('LOAD_SMALL_INT', 2), ('STORE_FAST', 1), - ('LOAD_CONST', 3), + ('LOAD_SMALL_INT', 3), ('STORE_FAST', 2), - ('LOAD_CONST', 4), + ('LOAD_SMALL_INT', 4), ('STORE_FAST', 3), ('NOP', None), - ('LOAD_CONST', 5), + ('LOAD_SMALL_INT', 42), ('RETURN_VALUE', None), ('LOAD_CONST', 0), ('RETURN_VALUE', None), diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 1f9c04cdbc9..bd1d1735181 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -48,42 +48,46 @@ dis_c_instance_method = """\ %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ RESUME 0 LOAD_FAST 1 - LOAD_CONST 1 + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 - RETURN_CONST 0 + LOAD_CONST 0 + RETURN_VALUE """ dis_c_class_method = """\ %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ %3d RESUME 0 %3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) STORE_FAST 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -110,7 +114,8 @@ dis_f = """\ CALL 1 POP_TOP -%3d RETURN_CONST 1 (1) +%3d LOAD_SMALL_INT 1 + RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -123,7 +128,8 @@ dis_f_with_offsets = """\ 14 CALL 1 22 POP_TOP -%3d 24 RETURN_CONST 1 (1) +%3d 24 LOAD_SMALL_INT 1 + 26 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -136,7 +142,8 @@ dis_f_with_positions_format = f"""\ %-14s CALL 1 %-14s POP_TOP -%-14s RETURN_CONST 1 (1) +%-14s LOAD_SMALL_INT 1 +%-14s RETURN_VALUE """ dis_f_co_code = """\ @@ -145,7 +152,8 @@ dis_f_co_code = """\ LOAD_FAST 0 CALL 1 POP_TOP - RETURN_CONST 1 + LOAD_SMALL_INT 1 + RETURN_VALUE """ def bug708901(): @@ -157,9 +165,9 @@ dis_bug708901 = """\ %3d RESUME 0 %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) + LOAD_SMALL_INT 1 -%3d LOAD_CONST 2 (10) +%3d LOAD_SMALL_INT 10 %3d CALL 2 GET_ITER @@ -170,7 +178,8 @@ dis_bug708901 = """\ %3d L2: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -194,7 +203,7 @@ dis_bug1333982 = """\ GET_ITER CALL 0 -%3d LOAD_CONST 2 (1) +%3d LOAD_SMALL_INT 1 %3d BINARY_OP 0 (+) CALL 0 @@ -217,16 +226,17 @@ bug42562.__code__ = bug42562.__code__.replace(co_linetable=b'\xf8') dis_bug42562 = """\ RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ # Extended arg followed by NOP code_bug_45757 = bytes([ - opcode.opmap['EXTENDED_ARG'], 0x01, # EXTENDED_ARG 0x01 - opcode.opmap['NOP'], 0xFF, # NOP 0xFF - opcode.opmap['EXTENDED_ARG'], 0x01, # EXTENDED_ARG 0x01 - opcode.opmap['LOAD_CONST'], 0x29, # LOAD_CONST 0x29 - opcode.opmap['RETURN_VALUE'], 0x00, # RETURN_VALUE 0x00 + opcode.opmap['EXTENDED_ARG'], 0x01, + opcode.opmap['NOP'], 0xFF, + opcode.opmap['EXTENDED_ARG'], 0x01, + opcode.opmap['LOAD_CONST'], 0x29, + opcode.opmap['RETURN_VALUE'], 0x00, ]) dis_bug_45757 = """\ @@ -263,25 +273,27 @@ dis_kw_names = """\ %3d RESUME 0 %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) + LOAD_SMALL_INT 1 + LOAD_SMALL_INT 2 + LOAD_SMALL_INT 5 + LOAD_CONST 1 (('c',)) CALL_KW 3 POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ 0 RESUME 0 - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) + 1 LOAD_SMALL_INT 0 + LOAD_CONST 0 (('*',)) IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP - RETURN_CONST 2 (None) + LOAD_CONST 1 (None) + RETURN_VALUE """ dis_intrinsic_1_5 = """\ @@ -307,7 +319,8 @@ _BIG_LINENO_FORMAT = """\ %3d LOAD_GLOBAL 0 (spam) POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ _BIG_LINENO_FORMAT2 = """\ @@ -315,17 +328,20 @@ _BIG_LINENO_FORMAT2 = """\ %4d LOAD_GLOBAL 0 (spam) POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ dis_module_expected_results = """\ Disassembly of f: 4 RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE Disassembly of g: 5 RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ @@ -335,7 +351,7 @@ dis_expr_str = """\ 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) + LOAD_SMALL_INT 1 BINARY_OP 0 (+) RETURN_VALUE """ @@ -346,10 +362,11 @@ dis_simple_stmt_str = """\ 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) + LOAD_SMALL_INT 1 BINARY_OP 0 (+) STORE_NAME 0 (x) - RETURN_CONST 1 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """ annot_stmt_str = """\ @@ -363,21 +380,22 @@ lst[fun(0)]: int = 1 dis_annot_stmt_str = """\ 0 RESUME 0 - 2 LOAD_CONST 0 (1) + 2 LOAD_SMALL_INT 1 STORE_NAME 0 (x) - 4 LOAD_CONST 0 (1) + 4 LOAD_SMALL_INT 1 LOAD_NAME 1 (lst) LOAD_NAME 2 (fun) PUSH_NULL - LOAD_CONST 1 (0) + LOAD_SMALL_INT 0 CALL 1 STORE_SUBSCR - 2 LOAD_CONST 2 (", line 2>) + 2 LOAD_CONST 0 (", line 2>) MAKE_FUNCTION STORE_NAME 3 (__annotate__) - RETURN_CONST 3 (None) + LOAD_CONST 1 (None) + RETURN_VALUE """ fn_with_annotate_str = """ @@ -394,7 +412,8 @@ dis_fn_with_annotate_str = """\ MAKE_FUNCTION SET_FUNCTION_ATTRIBUTE 16 (annotate) STORE_NAME 0 (foo) - RETURN_CONST 2 (None) + LOAD_CONST 2 (None) + RETURN_VALUE """ compound_stmt_str = """\ @@ -406,13 +425,13 @@ while 1: dis_compound_stmt_str = """\ 0 RESUME 0 - 1 LOAD_CONST 0 (0) + 1 LOAD_SMALL_INT 0 STORE_NAME 0 (x) 2 L1: NOP 3 LOAD_NAME 0 (x) - LOAD_CONST 1 (1) + LOAD_SMALL_INT 1 BINARY_OP 13 (+=) STORE_NAME 0 (x) JUMP_BACKWARD 8 (to L1) @@ -423,8 +442,8 @@ dis_traceback = """\ %4d NOP -%4d L1: LOAD_CONST 1 (1) - LOAD_CONST 2 (0) +%4d L1: LOAD_SMALL_INT 1 + LOAD_SMALL_INT 0 --> BINARY_OP 11 (/) POP_TOP @@ -515,7 +534,7 @@ dis_with = """\ CALL 0 L1: POP_TOP -%4d LOAD_CONST 1 (1) +%4d LOAD_SMALL_INT 1 STORE_FAST 1 (x) %4d L2: LOAD_CONST 0 (None) @@ -524,9 +543,10 @@ dis_with = """\ CALL 3 POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE %4d L3: PUSH_EXC_INFO WITH_EXCEPT_START @@ -539,9 +559,10 @@ dis_with = """\ POP_TOP POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE -- L6: COPY 3 POP_EXCEPT @@ -584,7 +605,7 @@ dis_asyncwith = """\ L5: END_SEND L6: POP_TOP -%4d LOAD_CONST 1 (1) +%4d LOAD_SMALL_INT 1 STORE_FAST 1 (x) %4d L7: LOAD_CONST 0 (None) @@ -600,14 +621,15 @@ dis_asyncwith = """\ L11: END_SEND POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE %4d L12: CLEANUP_THROW - L13: JUMP_BACKWARD_NO_INTERRUPT 25 (to L5) + L13: JUMP_BACKWARD_NO_INTERRUPT 26 (to L5) L14: CLEANUP_THROW - L15: JUMP_BACKWARD_NO_INTERRUPT 9 (to L11) + L15: JUMP_BACKWARD_NO_INTERRUPT 10 (to L11) L16: PUSH_EXC_INFO WITH_EXCEPT_START GET_AWAITABLE 2 @@ -627,9 +649,10 @@ dis_asyncwith = """\ POP_TOP POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE -- L24: COPY 3 POP_EXCEPT @@ -716,7 +739,8 @@ dis_tryfinallyconst = """\ PUSH_NULL CALL 0 POP_TOP - RETURN_CONST 1 (1) + LOAD_SMALL_INT 1 + RETURN_VALUE -- L1: PUSH_EXC_INFO @@ -822,7 +846,8 @@ Disassembly of at 0x..., file "%s", line %d>: JUMP_BACKWARD 12 (to L2) L3: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE -- L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 @@ -861,7 +886,7 @@ dis_loop_test_quickened_code = """\ %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) LIST_EXTEND 1 - LOAD_CONST 2 (3) + LOAD_SMALL_INT 3 BINARY_OP 5 (*) GET_ITER L1: FOR_ITER_LIST 14 (to L2) @@ -875,7 +900,8 @@ dis_loop_test_quickened_code = """\ %3d L2: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST_IMMORTAL 0 (None) + RETURN_VALUE """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -892,7 +918,8 @@ dis_extended_arg_quick_code = """\ UNPACK_EX 256 POP_TOP STORE_FAST 0 (_) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -1005,7 +1032,8 @@ class DisTests(DisTestBase): '', '2:3-3:15 NOP', '', - '3:11-3:15 RETURN_CONST 0 (None)', + '3:11-3:15 LOAD_CONST 0 (None)', + '3:11-3:15 RETURN_VALUE', '', ' -- L1: PUSH_EXC_INFO', '', @@ -1033,9 +1061,10 @@ class DisTests(DisTestBase): expect = '\n'.join([ '1:0-1:0 RESUME 0', '', - '2:5-2:6 LOAD_CONST 1 (1)', + '2:5-2:6 LOAD_SMALL_INT 1', '2:?-2:? STORE_FAST 0 (x)', - '2:?-2:? RETURN_CONST 0 (None)', + '2:?-2:? LOAD_CONST 0 (None)', + '2:?-2:? RETURN_VALUE', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1047,7 +1076,8 @@ class DisTests(DisTestBase): f.__code__ = f.__code__.replace(co_linetable=b'') expect = '\n'.join([ ' RESUME 0', - ' RETURN_CONST 0 (None)', + ' LOAD_CONST 0 (None)', + ' RETURN_VALUE', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1255,7 +1285,7 @@ class DisTests(DisTestBase): 0 RESUME_CHECK 0 1 LOAD_NAME 0 (a) - LOAD_CONST 0 (0) + LOAD_SMALL_INT 0 %s RETURN_VALUE """ @@ -1275,7 +1305,7 @@ class DisTests(DisTestBase): load_attr_quicken = """\ 0 RESUME_CHECK 0 - 1 LOAD_CONST 0 ('a') + 1 LOAD_CONST_IMMORTAL 0 ('a') LOAD_ATTR_SLOT 0 (__class__) RETURN_VALUE """ @@ -1292,7 +1322,7 @@ class DisTests(DisTestBase): 1 LOAD_NAME 0 (str) PUSH_NULL - LOAD_CONST 0 (1) + LOAD_SMALL_INT 1 CALL_STR_1 1 RETURN_VALUE """ @@ -1516,8 +1546,6 @@ Kw-only arguments: 0 Number of locals: 0 Stack size: \\d+ Flags: 0x0 -Constants: - 0: 1 Names: 0: x""" @@ -1531,8 +1559,7 @@ Number of locals: 0 Stack size: \\d+ Flags: 0x0 Constants: - 0: 1 - 1: None + 0: None Names: 0: x""" @@ -1546,8 +1573,7 @@ Number of locals: 0 Stack size: \\d+ Flags: 0x0 Constants: - 0: 0 - 1: 1 + 0: None Names: 0: x""" @@ -1568,7 +1594,6 @@ Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS, COROUTINE Constants: 0: None - 1: 1 Names: 0: b 1: c @@ -1707,10 +1732,10 @@ def _prepare_test_cases(): Instruction = dis.Instruction expected_opinfo_outer = [ - Instruction(opname='MAKE_CELL', opcode=91, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='MAKE_CELL', opcode=91, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='MAKE_CELL', opcode=92, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='MAKE_CELL', opcode=92, arg=1, argval='b', argrepr='b', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=4, argval=(3, 4), argrepr='(3, 4)', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='a', argrepr='a', offset=8, start_offset=8, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_TUPLE', opcode=48, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), @@ -1723,10 +1748,10 @@ expected_opinfo_outer = [ Instruction(opname='LOAD_DEREF', opcode=80, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_DEREF', opcode=80, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=79, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=1, argval=1, argrepr='', offset=40, start_offset=40, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_LIST', opcode=43, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='BUILD_MAP', opcode=44, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None), @@ -1735,8 +1760,8 @@ expected_opinfo_outer = [ expected_opinfo_f = [ Instruction(opname='COPY_FREE_VARS', opcode=58, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='MAKE_CELL', opcode=91, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='MAKE_CELL', opcode=91, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='MAKE_CELL', opcode=92, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='MAKE_CELL', opcode=92, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=79, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, start_offset=8, starts_line=True, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), @@ -1771,13 +1796,14 @@ expected_opinfo_inner = [ Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=84, arg=1, argval=('e', 'f'), argrepr='e, f', offset=22, start_offset=22, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='RETURN_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=34, start_offset=34, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=36, start_offset=36, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), ] expected_opinfo_jumpy = [ Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=1, argval='range', argrepr='range + NULL', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=10, argval=10, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='GET_ITER', opcode=16, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='FOR_ITER', opcode=67, arg=30, argval=88, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), @@ -1787,64 +1813,64 @@ expected_opinfo_jumpy = [ Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=4, argval=4, argrepr='', offset=54, start_offset=54, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=54, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=94, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=72, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, label=2, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=6, argval=6, argrepr='', offset=70, start_offset=70, starts_line=False, line_number=7, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=54, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=97, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=98, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=72, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None, cache_info=None), Instruction(opname='JUMP_FORWARD', opcode=74, arg=13, argval=114, argrepr='to L5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), Instruction(opname='END_FOR', opcode=9, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=90, start_offset=90, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=92, start_offset=92, starts_line=True, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=102, start_offset=102, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=102, start_offset=102, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=104, start_offset=104, starts_line=False, line_number=10, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=112, start_offset=112, starts_line=False, line_number=10, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST_CHECK', opcode=83, arg=0, argval='i', argrepr='i', offset=114, start_offset=114, starts_line=True, line_number=11, label=5, positions=None, cache_info=None), Instruction(opname='TO_BOOL', opcode=37, arg=None, argval=None, argrepr='', offset=116, start_offset=116, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=94, arg=33, argval=194, argrepr='to L8', offset=124, start_offset=124, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=33, argval=194, argrepr='to L8', offset=124, start_offset=124, starts_line=False, line_number=11, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=128, start_offset=128, starts_line=True, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=140, start_offset=140, starts_line=False, line_number=12, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=148, start_offset=148, starts_line=False, line_number=12, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=150, start_offset=150, starts_line=True, line_number=13, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=5, argval=1, argrepr='1', offset=152, start_offset=152, starts_line=False, line_number=13, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=1, argval=1, argrepr='', offset=152, start_offset=152, starts_line=False, line_number=13, label=None, positions=None, cache_info=None), Instruction(opname='BINARY_OP', opcode=42, arg=23, argval=23, argrepr='-=', offset=154, start_offset=154, starts_line=False, line_number=13, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='STORE_FAST', opcode=107, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=False, line_number=13, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=160, start_offset=160, starts_line=True, line_number=14, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval=6, argrepr='6', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=6, argval=6, argrepr='', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=54, arg=148, argval='>', argrepr='bool(>)', offset=164, start_offset=164, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=94, arg=2, argval=176, argrepr='to L6', offset=168, start_offset=168, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=2, argval=176, argrepr='to L6', offset=168, start_offset=168, starts_line=False, line_number=14, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=72, arg=31, argval=114, argrepr='to L5', offset=172, start_offset=172, starts_line=True, line_number=15, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=176, start_offset=176, starts_line=True, line_number=16, label=6, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=2, argval=4, argrepr='4', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=4, argval=4, argrepr='', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None, cache_info=None), Instruction(opname='COMPARE_OP', opcode=54, arg=18, argval='<', argrepr='bool(<)', offset=180, start_offset=180, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=97, arg=2, argval=192, argrepr='to L7', offset=184, start_offset=184, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=98, arg=2, argval=192, argrepr='to L7', offset=184, start_offset=184, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_BACKWARD', opcode=72, arg=39, argval=114, argrepr='to L5', offset=188, start_offset=188, starts_line=False, line_number=16, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='JUMP_FORWARD', opcode=74, arg=11, argval=216, argrepr='to L9', offset=192, start_offset=192, starts_line=True, line_number=17, label=7, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=194, start_offset=194, starts_line=True, line_number=19, label=8, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, start_offset=204, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=2, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, start_offset=204, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=206, start_offset=206, starts_line=False, line_number=19, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=214, start_offset=214, starts_line=False, line_number=19, label=None, positions=None, cache_info=None), Instruction(opname='NOP', opcode=27, arg=None, argval=None, argrepr='', offset=216, start_offset=216, starts_line=True, line_number=20, label=9, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=5, argval=1, argrepr='1', offset=218, start_offset=218, starts_line=True, line_number=21, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=7, argval=0, argrepr='0', offset=220, start_offset=220, starts_line=False, line_number=21, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=True, line_number=21, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SMALL_INT', opcode=89, arg=0, argval=0, argrepr='', offset=220, start_offset=220, starts_line=False, line_number=21, label=None, positions=None, cache_info=None), Instruction(opname='BINARY_OP', opcode=42, arg=11, argval=11, argrepr='/', offset=222, start_offset=222, starts_line=False, line_number=21, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=21, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='i', argrepr='i', offset=228, start_offset=228, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='COPY', opcode=57, arg=1, argval=1, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_SPECIAL', opcode=89, arg=1, argval=1, argrepr='__exit__', offset=232, start_offset=232, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SPECIAL', opcode=90, arg=1, argval=1, argrepr='__exit__', offset=232, start_offset=232, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='SWAP', opcode=112, arg=2, argval=2, argrepr='', offset=234, start_offset=234, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='SWAP', opcode=112, arg=3, argval=3, argrepr='', offset=236, start_offset=236, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_SPECIAL', opcode=89, arg=0, argval=0, argrepr='__enter__', offset=238, start_offset=238, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_SPECIAL', opcode=90, arg=0, argval=0, argrepr='__enter__', offset=238, start_offset=238, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=0, argval=0, argrepr='', offset=240, start_offset=240, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='STORE_FAST', opcode=107, arg=1, argval='dodgy', argrepr='dodgy', offset=248, start_offset=248, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=250, start_offset=250, starts_line=True, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=260, start_offset=260, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=3, argval='Never reach this', argrepr="'Never reach this'", offset=260, start_offset=260, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=26, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=26, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), @@ -1853,55 +1879,57 @@ expected_opinfo_jumpy = [ Instruction(opname='CALL', opcode=49, arg=3, argval=3, argrepr='', offset=278, start_offset=278, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=286, start_offset=286, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=288, start_offset=288, starts_line=True, line_number=28, label=10, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=298, start_offset=298, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=298, start_offset=298, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), - Instruction(opname='RETURN_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=310, start_offset=310, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), - Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='WITH_EXCEPT_START', opcode=41, arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='TO_BOOL', opcode=37, arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=97, arg=1, argval=330, argrepr='to L11', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='RERAISE', opcode=99, arg=2, argval=2, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=11, positions=None, cache_info=None), - Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=310, start_offset=310, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='WITH_EXCEPT_START', opcode=41, arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='TO_BOOL', opcode=37, arg=None, argval=None, argrepr='', offset=318, start_offset=318, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('version', 2, b'\x00\x00\x00\x00')]), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=98, arg=1, argval=332, argrepr='to L11', offset=326, start_offset=326, starts_line=False, line_number=25, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='RERAISE', opcode=100, arg=2, argval=2, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=11, positions=None, cache_info=None), + Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=336, start_offset=336, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=338, start_offset=338, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=27, argval=288, argrepr='to L10', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=342, start_offset=342, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='RERAISE', opcode=99, arg=1, argval=1, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=350, start_offset=350, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=94, arg=14, argval=394, argrepr='to L12', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), - Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=366, start_offset=366, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=368, start_offset=368, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=378, start_offset=378, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), - Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), - Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=53, argval=288, argrepr='to L10', offset=392, start_offset=392, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), - Instruction(opname='RERAISE', opcode=99, arg=0, argval=0, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=22, label=12, positions=None, cache_info=None), - Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=396, start_offset=396, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='RERAISE', opcode=99, arg=1, argval=1, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=404, start_offset=404, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), - Instruction(opname='LOAD_CONST', opcode=79, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=414, start_offset=414, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=416, start_offset=416, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), - Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), - Instruction(opname='RERAISE', opcode=99, arg=0, argval=0, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), - Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=428, start_offset=428, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), - Instruction(opname='RERAISE', opcode=99, arg=1, argval=1, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=28, argval=288, argrepr='to L10', offset=342, start_offset=342, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=344, start_offset=344, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=348, start_offset=348, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=350, start_offset=350, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_GLOBAL', opcode=87, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=352, start_offset=352, starts_line=True, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + Instruction(opname='CHECK_EXC_MATCH', opcode=5, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=95, arg=14, argval=396, argrepr='to L12', offset=364, start_offset=364, starts_line=False, line_number=22, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00')]), + Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=22, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=370, start_offset=370, starts_line=True, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + Instruction(opname='LOAD_CONST', opcode=79, arg=4, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=380, start_offset=380, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=23, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=390, start_offset=390, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), + Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=392, start_offset=392, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), + Instruction(opname='JUMP_BACKWARD_NO_INTERRUPT', opcode=73, arg=54, argval=288, argrepr='to L10', offset=394, start_offset=394, starts_line=False, line_number=23, label=None, positions=None, cache_info=None), + Instruction(opname='RERAISE', opcode=100, arg=0, argval=0, argrepr='', offset=396, start_offset=396, starts_line=True, line_number=22, label=12, positions=None, cache_info=None), + Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=398, start_offset=398, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=402, start_offset=402, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='PUSH_EXC_INFO', opcode=30, arg=None, argval=None, argrepr='', offset=404, start_offset=404, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=406, start_offset=406, starts_line=True, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1, b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]), + Instruction(opname='LOAD_CONST', opcode=79, arg=5, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=416, start_offset=416, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=49, arg=1, argval=1, argrepr='', offset=418, start_offset=418, starts_line=False, line_number=28, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='RERAISE', opcode=100, arg=0, argval=0, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, label=None, positions=None, cache_info=None), + Instruction(opname='COPY', opcode=57, arg=3, argval=3, argrepr='', offset=430, start_offset=430, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='POP_EXCEPT', opcode=28, arg=None, argval=None, argrepr='', offset=432, start_offset=432, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='RERAISE', opcode=100, arg=1, argval=1, argrepr='', offset=434, start_offset=434, starts_line=False, line_number=None, label=None, positions=None, cache_info=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, positions=None), - Instruction(opname='RETURN_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=2, start_offset=2, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), + Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), ] @@ -1968,6 +1996,7 @@ class InstructionTests(InstructionTestCase): (2, 2, 8, 9), (1, 3, 0, 1), (1, 3, 0, 1), + (1, 3, 0, 1), (1, 3, 0, 1) ] self.assertEqual(positions, expected) @@ -2297,20 +2326,20 @@ class BytecodeTests(InstructionTestCase, DisTestBase): class TestBytecodeTestCase(BytecodeTestCase): def test_assert_not_in_with_op_not_in_bytecode(self): code = compile("a = 1", "", "exec") - self.assertInBytecode(code, "LOAD_CONST", 1) + self.assertInBytecode(code, "LOAD_SMALL_INT", 1) self.assertNotInBytecode(code, "LOAD_NAME") self.assertNotInBytecode(code, "LOAD_NAME", "a") def test_assert_not_in_with_arg_not_in_bytecode(self): code = compile("a = 1", "", "exec") - self.assertInBytecode(code, "LOAD_CONST") - self.assertInBytecode(code, "LOAD_CONST", 1) + self.assertInBytecode(code, "LOAD_SMALL_INT") + self.assertInBytecode(code, "LOAD_SMALL_INT", 1) self.assertNotInBytecode(code, "LOAD_CONST", 2) def test_assert_not_in_with_arg_in_bytecode(self): code = compile("a = 1", "", "exec") with self.assertRaises(AssertionError): - self.assertNotInBytecode(code, "LOAD_CONST", 1) + self.assertNotInBytecode(code, "LOAD_SMALL_INT", 1) class TestFinderMethods(unittest.TestCase): def test__find_imports(self): diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 035d4418b15..4ea43edccda 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -388,6 +388,9 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): opname in opcode._specialized_opmap # Exclude superinstructions: and "__" not in opname + # LOAD_CONST_IMMORTAL is "specialized", but is + # inserted during quickening. + and opname != "LOAD_CONST_IMMORTAL" ): return True return False diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index e6fd33e208c..0e39998ebb3 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1234,7 +1234,7 @@ class PycRewritingTests(unittest.TestCase): import sys code_filename = sys._getframe().f_code.co_filename module_filename = __file__ -constant = 1 +constant = 1000 def func(): pass func_filename = func.__code__.co_filename @@ -1303,7 +1303,7 @@ func_filename = func.__code__.co_filename code = marshal.load(f) constants = list(code.co_consts) foreign_code = importlib.import_module.__code__ - pos = constants.index(1) + pos = constants.index(1000) constants[pos] = foreign_code code = code.replace(co_consts=tuple(constants)) with open(self.compiled_name, "wb") as f: diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index 1b06816214e..b640aa08e4a 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1205,6 +1205,7 @@ class TestLineAndInstructionEvents(CheckEvents): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), + ('instruction', 'func1', 16), ('line', 'get_events', 11)]) def test_c_call(self): @@ -1229,6 +1230,7 @@ class TestLineAndInstructionEvents(CheckEvents): ('instruction', 'func2', 40), ('instruction', 'func2', 42), ('instruction', 'func2', 44), + ('instruction', 'func2', 46), ('line', 'get_events', 11)]) def test_try_except(self): @@ -1262,6 +1264,7 @@ class TestLineAndInstructionEvents(CheckEvents): ('instruction', 'func3', 30), ('instruction', 'func3', 32), ('instruction', 'func3', 34), + ('instruction', 'func3', 36), ('line', 'get_events', 11)]) def test_with_restart(self): @@ -1282,6 +1285,7 @@ class TestLineAndInstructionEvents(CheckEvents): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), + ('instruction', 'func1', 16), ('line', 'get_events', 11)]) sys.monitoring.restart_events() @@ -1298,6 +1302,7 @@ class TestLineAndInstructionEvents(CheckEvents): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), + ('instruction', 'func1', 16), ('line', 'get_events', 11)]) def test_turn_off_only_instruction(self): diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index b143f3d27a1..c7da151dce3 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -114,7 +114,7 @@ class TestTranforms(BytecodeTestCase): return None self.assertNotInBytecode(f, 'LOAD_GLOBAL') - self.assertInBytecode(f, 'RETURN_CONST', None) + self.assertInBytecode(f, 'LOAD_CONST', None) self.check_lnotab(f) def test_while_one(self): @@ -131,7 +131,7 @@ class TestTranforms(BytecodeTestCase): def test_pack_unpack(self): for line, elem in ( - ('a, = a,', 'RETURN_CONST',), + ('a, = a,', 'LOAD_CONST',), ('a, b = a, b', 'SWAP',), ('a, b, c = a, b, c', 'SWAP',), ): @@ -162,7 +162,7 @@ class TestTranforms(BytecodeTestCase): # 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), 1) + self.assertEqual(len(load_consts), 2) self.check_lnotab(code) # Bug 1053819: Tuple of constants misidentified when presented with: @@ -248,14 +248,17 @@ class TestTranforms(BytecodeTestCase): ): with self.subTest(line=line): code = compile(line, '', 'single') - self.assertInBytecode(code, 'LOAD_CONST', elem) + if isinstance(elem, int): + self.assertInBytecode(code, 'LOAD_SMALL_INT', elem) + else: + self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): self.assertFalse(instr.opname.startswith('BINARY_')) self.check_lnotab(code) # Verify that unfoldables are skipped code = compile('a=2+"b"', '', 'single') - self.assertInBytecode(code, 'LOAD_CONST', 2) + self.assertInBytecode(code, 'LOAD_SMALL_INT', 2) self.assertInBytecode(code, 'LOAD_CONST', 'b') self.check_lnotab(code) @@ -307,7 +310,10 @@ class TestTranforms(BytecodeTestCase): ): with self.subTest(line=line): code = compile(line, '', 'single') - self.assertInBytecode(code, 'LOAD_CONST', elem) + if isinstance(elem, int): + self.assertInBytecode(code, 'LOAD_SMALL_INT', elem) + else: + self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): self.assertFalse(instr.opname.startswith('UNARY_')) self.check_lnotab(code) @@ -989,9 +995,11 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), - ('RETURN_CONST', 1, 13), + ('LOAD_CONST', 1, 13), + ('RETURN_VALUE', None, 13), lbl, - ('RETURN_CONST', 2, 14), + ('LOAD_CONST', 2, 14), + ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1013,7 +1021,8 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): expected_insts = [ ('NOP', None, 11), ('NOP', None, 12), - ('RETURN_CONST', 1, 14), + ('LOAD_CONST', 1, 14), + ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1057,15 +1066,19 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), ('POP_BLOCK', None, -1), - ('RETURN_CONST', 1, 11), + ('LOAD_CONST', 1, 11), + ('RETURN_VALUE', None, 11), handler, - ('RETURN_CONST', 2, 12), + ('LOAD_CONST', 2, 12), + ('RETURN_VALUE', None, 12), ] expected_insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), - ('RETURN_CONST', 1, 11), + ('LOAD_CONST', 1, 11), + ('RETURN_VALUE', None, 11), handler, - ('RETURN_CONST', 2, 12), + ('LOAD_CONST', 2, 12), + ('RETURN_VALUE', None, 12), ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(5))) @@ -1088,7 +1101,8 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): ('NOP', None, 3), ('STORE_FAST', 1, 4), ('POP_TOP', None, 4), - ('RETURN_CONST', 0) + ('LOAD_CONST', 0, 5), + ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -1109,7 +1123,8 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): ('NOP', None, 3), ('POP_TOP', None, 4), ('STORE_FAST', 1, 4), - ('RETURN_CONST', 0, 5) + ('LOAD_CONST', 0, 5), + ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) @@ -1131,7 +1146,8 @@ class DirectCfgOptimizerTests(CfgOptimizationTestCase): ('STORE_FAST', 1, 4), ('STORE_FAST', 1, 5), ('STORE_FAST', 1, 6), - ('RETURN_CONST', 0, 5) + ('LOAD_CONST', 0, 5), + ('RETURN_VALUE', None, 5) ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(3)), nlocals=1) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst new file mode 100644 index 00000000000..9538f34f969 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst @@ -0,0 +1,5 @@ +Adds :opcode:`LOAD_SMALL_INT` and :opcode:`LOAD_CONST_IMMORTAL` instructions. +``LOAD_SMALL_INT`` pushes a small integer equal to the ``oparg`` to the stack. +``LOAD_CONST_IMMORTAL`` does the same as ``LOAD_CONST`` but is more +efficient for immortal objects. +Removes ``RETURN_CONST`` instruction. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index af2a2ef18e6..55394afa523 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1248,8 +1248,6 @@ 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 624d9c0b653..c936622c020 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,37 +1,37 @@ // 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,166,0,0,0,149,0,79,0,79,1, - 70,0,111,0,79,0,79,1,70,1,111,1,88,2,31,0, - 79,2,49,1,0,0,0,0,0,0,29,0,88,2,31,0, - 79,3,88,0,77,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,243,168,0,0,0,149,0,89,0,79,0, + 70,0,111,0,89,0,79,0,70,1,111,1,88,2,31,0, + 79,1,49,1,0,0,0,0,0,0,29,0,88,2,31,0, + 79,2,88,0,77,6,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,49,2,0,0,0,0,0,0, 29,0,88,1,77,8,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,31,0,49,0,0,0,0,0, - 0,0,79,4,2,0,0,0,111,5,79,5,16,0,67,20, - 0,0,111,6,88,2,31,0,79,6,88,6,12,0,79,7, + 0,0,79,3,2,0,0,0,111,5,79,4,16,0,67,20, + 0,0,111,6,88,2,31,0,79,5,88,6,12,0,79,6, 88,5,88,6,2,0,0,0,12,0,47,4,49,1,0,0, - 0,0,0,0,29,0,72,22,0,0,9,0,29,0,100,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, - 218,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105, - 110,46,112,121,218,8,60,109,111,100,117,108,101,62,114,18, - 0,0,0,1,0,0,0,115,94,0,0,0,240,3,1,1, - 1,243,8,0,1,11,219,0,24,225,0,5,208,6,26,212, - 0,27,217,0,5,128,106,144,35,151,40,145,40,212,0,27, - 216,9,26,215,9,38,210,9,38,211,9,40,168,24,209,9, - 50,128,6,243,2,6,12,2,128,67,241,14,0,5,10,136, - 71,144,67,144,53,152,2,152,54,160,35,153,59,152,45,208, - 10,40,214,4,41,242,15,6,12,2,114,16,0,0,0, + 0,0,0,0,29,0,72,22,0,0,9,0,29,0,79,0, + 33,0,41,7,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,2,0,0, + 0,218,3,107,101,121,169,0,243,0,0,0,0,218,18,116, + 101,115,116,95,102,114,111,122,101,110,109,97,105,110,46,112, + 121,218,8,60,109,111,100,117,108,101,62,114,17,0,0,0, + 1,0,0,0,115,94,0,0,0,240,3,1,1,1,243,8, + 0,1,11,219,0,24,225,0,5,208,6,26,212,0,27,217, + 0,5,128,106,144,35,151,40,145,40,212,0,27,216,9,26, + 215,9,38,210,9,38,211,9,40,168,24,209,9,50,128,6, + 243,2,6,12,2,128,67,241,14,0,5,10,136,71,144,67, + 144,53,152,2,152,54,160,35,153,59,152,45,208,10,40,214, + 4,41,243,15,6,12,2,114,15,0,0,0, }; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 057ee0a92d9..b7469c2dd8d 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -255,10 +255,26 @@ dummy_func( value2 = PyStackRef_DUP(GETLOCAL(oparg2)); } + family(LOAD_CONST, 0) = { + LOAD_CONST_IMMORTAL, + }; + pure inst(LOAD_CONST, (-- value)) { value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg)); } + inst(LOAD_CONST_IMMORTAL, (-- value)) { + PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg); + assert(_Py_IsImmortal(obj)); + value = PyStackRef_FromPyObjectImmortal(obj); + } + + replicate(4) inst(LOAD_SMALL_INT, (-- value)) { + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + } + replicate(8) inst(STORE_FAST, (value --)) { SETLOCAL(oparg, value); DEAD(value); @@ -979,10 +995,9 @@ dummy_func( return result; } - // The stack effect here is ambiguous. - // We definitely pop the return value off the stack on entry. - // We also push it onto the stack on exit, but that's a - // different frame, and it's accounted for by _PUSH_FRAME. + // The stack effect here is a bit misleading. + // retval is popped from the stack, but res + // is pushed to a different frame, the callers' frame. inst(RETURN_VALUE, (retval -- res)) { #if TIER_ONE assert(frame != &entry_frame); @@ -1013,15 +1028,6 @@ dummy_func( _RETURN_VALUE_EVENT + RETURN_VALUE; - macro(RETURN_CONST) = - LOAD_CONST + - RETURN_VALUE; - - macro(INSTRUMENTED_RETURN_CONST) = - LOAD_CONST + - _RETURN_VALUE_EVENT + - RETURN_VALUE; - inst(GET_AITER, (obj -- iter)) { unaryfunc getter = NULL; PyObject *obj_o = PyStackRef_AsPyObjectBorrow(obj); diff --git a/Python/codegen.c b/Python/codegen.c index bfacc6f0c55..976c94234d6 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -280,6 +280,14 @@ codegen_addop_noarg(instr_sequence *seq, int opcode, location loc) static int codegen_addop_load_const(compiler *c, location loc, PyObject *o) { + if (PyLong_CheckExact(o)) { + int overflow; + long val = PyLong_AsLongAndOverflow(o, &overflow); + if (!overflow && val >= 0 && val < 256 && val < _PY_NSMALLPOSINTS) { + ADDOP_I(c, loc, LOAD_SMALL_INT, val); + return SUCCESS; + } + } Py_ssize_t arg = _PyCompile_AddConst(c, o); if (arg < 0) { return ERROR; @@ -656,6 +664,9 @@ codegen_setup_annotations_scope(compiler *c, location loc, codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS, key, loc.lineno, NULL, &umd)); + // Insert None into consts to prevent an annotation + // appearing to be a docstring + _PyCompile_AddConst(c, Py_None); // if .format != 1: raise NotImplementedError _Py_DECLARE_STR(format, ".format"); ADDOP_I(c, loc, LOAD_FAST, 0); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 3a7015ccb78..27b7e324ebe 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -210,6 +210,82 @@ break; } + case _LOAD_CONST_IMMORTAL: { + _PyStackRef value; + oparg = CURRENT_OPARG(); + PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg); + assert(_Py_IsImmortal(obj)); + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT_0: { + _PyStackRef value; + oparg = 0; + assert(oparg == CURRENT_OPARG()); + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT_1: { + _PyStackRef value; + oparg = 1; + assert(oparg == CURRENT_OPARG()); + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT_2: { + _PyStackRef value; + oparg = 2; + assert(oparg == CURRENT_OPARG()); + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT_3: { + _PyStackRef value; + oparg = 3; + assert(oparg == CURRENT_OPARG()); + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT: { + _PyStackRef value; + oparg = CURRENT_OPARG(); + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _STORE_FAST_0: { _PyStackRef value; oparg = 0; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 388862912d6..54181319500 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -283,7 +283,7 @@ dump_instr(cfg_instr *i) static inline int basicblock_returns(const basicblock *b) { cfg_instr *last = basicblock_last_instr(b); - return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST); + return last && last->i_opcode == RETURN_VALUE; } static void @@ -515,22 +515,6 @@ no_redundant_jumps(cfg_builder *g) { } return true; } - -static bool -all_exits_have_lineno(basicblock *entryblock) { - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - cfg_instr *instr = &b->b_instr[i]; - if (instr->i_opcode == RETURN_VALUE) { - if (instr->i_loc.lineno < 0) { - assert(0); - return false; - } - } - } - } - return true; -} #endif /***** CFG preprocessing (jump targets and exceptions) *****/ @@ -1131,7 +1115,7 @@ remove_redundant_nops_and_pairs(basicblock *entryblock) int opcode = instr->i_opcode; bool is_redundant_pair = false; if (opcode == POP_TOP) { - if (prev_opcode == LOAD_CONST) { + if (prev_opcode == LOAD_CONST || prev_opcode == LOAD_SMALL_INT) { is_redundant_pair = true; } else if (prev_opcode == COPY && prev_oparg == 1) { @@ -1280,14 +1264,23 @@ jump_thread(basicblock *bb, cfg_instr *inst, cfg_instr *target, int opcode) return false; } +static int +loads_const(int opcode) +{ + return OPCODE_HAS_CONST(opcode) || opcode == LOAD_SMALL_INT; +} + static PyObject* get_const_value(int opcode, int oparg, PyObject *co_consts) { PyObject *constant = NULL; - assert(OPCODE_HAS_CONST(opcode)); + assert(loads_const(opcode)); if (opcode == LOAD_CONST) { constant = PyList_GET_ITEM(co_consts, oparg); } + if (opcode == LOAD_SMALL_INT) { + return PyLong_FromLong(oparg); + } if (constant == NULL) { PyErr_SetString(PyExc_SystemError, @@ -1345,7 +1338,7 @@ fold_tuple_on_constants(PyObject *const_cache, assert(inst[n].i_oparg == n); for (int i = 0; i < n; i++) { - if (!OPCODE_HAS_CONST(inst[i].i_opcode)) { + if (!loads_const(inst[i].i_opcode)) { return SUCCESS; } } @@ -1583,7 +1576,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * oparg = inst->i_oparg; } assert(!IS_ASSEMBLER_OPCODE(opcode)); - if (opcode != LOAD_CONST) { + if (opcode != LOAD_CONST && opcode != LOAD_SMALL_INT) { continue; } int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; @@ -1662,12 +1655,6 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * : POP_JUMP_IF_NONE; break; } - case RETURN_VALUE: - { - INSTR_SET_OP0(inst, NOP); - INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg); - break; - } case TO_BOOL: { PyObject *cnt = get_const_value(opcode, oparg, consts); @@ -2120,7 +2107,8 @@ 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 (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) { + int opcode = b->b_instr[i].i_opcode; + if (OPCODE_HAS_CONST(opcode)) { int index = b->b_instr[i].i_oparg; index_map[index] = index; } @@ -2173,7 +2161,8 @@ 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 (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) { + int opcode = b->b_instr[i].i_opcode; + if (OPCODE_HAS_CONST(opcode)) { int index = b->b_instr[i].i_oparg; assert(reverse_index_map[index] >= 0); assert(reverse_index_map[index] < n_used_consts); @@ -2594,8 +2583,9 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, RETURN_IF_ERROR(insert_superinstructions(g)); RETURN_IF_ERROR(push_cold_blocks_to_end(g)); - assert(all_exits_have_lineno(g->g_entryblock)); RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); + // temporarily remove assert. See https://github.com/python/cpython/issues/125845 + // assert(all_exits_have_lineno(g->g_entryblock)); return SUCCESS; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 35af1dc412b..a615f65c413 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4879,59 +4879,6 @@ DISPATCH(); } - TARGET(INSTRUMENTED_RETURN_CONST) { - _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; - (void)this_instr; - next_instr += 1; - INSTRUCTION_STATS(INSTRUMENTED_RETURN_CONST); - _PyStackRef value; - _PyStackRef val; - _PyStackRef retval; - _PyStackRef res; - // _LOAD_CONST - { - value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg)); - } - // _RETURN_VALUE_EVENT - { - val = value; - stack_pointer[0] = val; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - int err = _Py_call_instrumentation_arg( - tstate, PY_MONITORING_EVENT_PY_RETURN, - frame, this_instr, PyStackRef_AsPyObjectBorrow(val)); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (err) goto error; - } - // _RETURN_VALUE - { - retval = val; - #if TIER_ONE - assert(frame != &entry_frame); - #endif - _PyStackRef temp = retval; - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(EMPTY()); - _Py_LeaveRecursiveCallPy(tstate); - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); - } - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - DISPATCH(); - } - TARGET(INSTRUMENTED_RETURN_VALUE) { _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; (void)this_instr; @@ -5901,6 +5848,7 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(LOAD_CONST); + PREDICTED(LOAD_CONST); _PyStackRef value; value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg)); stack_pointer[0] = value; @@ -5909,6 +5857,21 @@ DISPATCH(); } + TARGET(LOAD_CONST_IMMORTAL) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_CONST_IMMORTAL); + static_assert(0 == 0, "incorrect cache size"); + _PyStackRef value; + PyObject *obj = GETITEM(FRAME_CO_CONSTS, oparg); + assert(_Py_IsImmortal(obj)); + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + DISPATCH(); + } + TARGET(LOAD_DEREF) { frame->instr_ptr = next_instr; next_instr += 1; @@ -6263,6 +6226,20 @@ DISPATCH(); } + TARGET(LOAD_SMALL_INT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_SMALL_INT); + _PyStackRef value; + assert(oparg < _PY_NSMALLPOSINTS); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + DISPATCH(); + } + TARGET(LOAD_SPECIAL) { frame->instr_ptr = next_instr; next_instr += 1; @@ -6951,42 +6928,6 @@ DISPATCH(); } - TARGET(RETURN_CONST) { - frame->instr_ptr = next_instr; - next_instr += 1; - INSTRUCTION_STATS(RETURN_CONST); - _PyStackRef value; - _PyStackRef retval; - _PyStackRef res; - // _LOAD_CONST - { - value = PyStackRef_FromPyObjectNew(GETITEM(FRAME_CO_CONSTS, oparg)); - } - // _RETURN_VALUE - { - retval = value; - #if TIER_ONE - assert(frame != &entry_frame); - #endif - _PyStackRef temp = retval; - _PyFrame_SetStackPointer(frame, stack_pointer); - assert(EMPTY()); - _Py_LeaveRecursiveCallPy(tstate); - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - stack_pointer = _PyFrame_GetStackPointer(frame); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); - } - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - DISPATCH(); - } - TARGET(RETURN_GENERATOR) { frame->instr_ptr = next_instr; next_instr += 1; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index e1e494c31a1..d4568764117 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -56,8 +56,6 @@ PyObject _PyInstrumentation_DISABLE = _PyObject_HEAD_INIT(&PyBaseObject_Type); PyObject _PyInstrumentation_MISSING = _PyObject_HEAD_INIT(&PyBaseObject_Type); static const int8_t EVENT_FOR_OPCODE[256] = { - [RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN, - [INSTRUMENTED_RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN, [RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, [INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, [CALL] = PY_MONITORING_EVENT_CALL, @@ -94,7 +92,6 @@ static const int8_t EVENT_FOR_OPCODE[256] = { static const uint8_t DE_INSTRUMENT[256] = { [INSTRUMENTED_RESUME] = RESUME, [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE, - [INSTRUMENTED_RETURN_CONST] = RETURN_CONST, [INSTRUMENTED_CALL] = CALL, [INSTRUMENTED_CALL_KW] = CALL_KW, [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, @@ -112,8 +109,6 @@ static const uint8_t DE_INSTRUMENT[256] = { }; static const uint8_t INSTRUMENTED_OPCODES[256] = { - [RETURN_CONST] = INSTRUMENTED_RETURN_CONST, - [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, [RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [CALL] = INSTRUMENTED_CALL, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 3fc9d3118d5..c93941dcac4 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -88,6 +88,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, &&TARGET_LOAD_GLOBAL, &&TARGET_LOAD_NAME, + &&TARGET_LOAD_SMALL_INT, &&TARGET_LOAD_SPECIAL, &&TARGET_LOAD_SUPER_ATTR, &&TARGET_MAKE_CELL, @@ -99,7 +100,6 @@ static void *opcode_targets[256] = { &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_RAISE_VARARGS, &&TARGET_RERAISE, - &&TARGET_RETURN_CONST, &&TARGET_SEND, &&TARGET_SET_ADD, &&TARGET_SET_FUNCTION_ATTRIBUTE, @@ -206,6 +206,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, + &&TARGET_LOAD_CONST_IMMORTAL, &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_SUPER_ATTR_ATTR, @@ -249,7 +250,6 @@ static void *opcode_targets[256] = { &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, &&TARGET_INSTRUMENTED_RESUME, &&TARGET_INSTRUMENTED_RETURN_VALUE, - &&TARGET_INSTRUMENTED_RETURN_CONST, &&TARGET_INSTRUMENTED_YIELD_VALUE, &&TARGET_INSTRUMENTED_CALL, &&TARGET_INSTRUMENTED_JUMP_BACKWARD, diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index f40ad1e5744..71904c1bc73 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -445,6 +445,17 @@ dummy_func(void) { value = sym_new_const(ctx, val); } + op(_LOAD_CONST_IMMORTAL, (-- value)) { + PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg); + REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val); + value = sym_new_const(ctx, val); + } + + op(_LOAD_SMALL_INT, (-- value)) { + PyObject *val = PyLong_FromLong(this_instr->oparg); + value = sym_new_const(ctx, val); + } + op(_LOAD_CONST_INLINE, (ptr/4 -- value)) { value = sym_new_const(ctx, ptr); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 243b3efa41b..0a7e44ef78d 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -68,6 +68,27 @@ break; } + case _LOAD_CONST_IMMORTAL: { + _Py_UopsSymbol *value; + PyObject *val = PyTuple_GET_ITEM(co->co_consts, this_instr->oparg); + REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val); + value = sym_new_const(ctx, val); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_SMALL_INT: { + _Py_UopsSymbol *value; + PyObject *val = PyLong_FromLong(this_instr->oparg); + value = sym_new_const(ctx, val); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _STORE_FAST: { _Py_UopsSymbol *value; value = stack_pointer[-1]; diff --git a/Python/specialize.c b/Python/specialize.c index 4b33a468733..ae47809305a 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -442,11 +442,13 @@ _PyCode_Quicken(PyCodeObject *code) { #if ENABLE_SPECIALIZATION int opcode = 0; + int oparg = 0; _Py_CODEUNIT *instructions = _PyCode_CODE(code); /* The last code unit cannot have a cache, so we don't need to check it */ for (int i = 0; i < Py_SIZE(code)-1; i++) { opcode = instructions[i].op.code; int caches = _PyOpcode_Caches[opcode]; + oparg = (oparg << 8) | instructions[i].op.arg; if (caches) { // The initial value depends on the opcode switch (opcode) { @@ -465,6 +467,18 @@ _PyCode_Quicken(PyCodeObject *code) } i += caches; } + else if (opcode == LOAD_CONST) { + /* We can't do this in the bytecode compiler as + * marshalling can intern strings and make them immortal. */ + + PyObject *obj = PyTuple_GET_ITEM(code->co_consts, oparg); + if (_Py_IsImmortal(obj)) { + instructions[i].op.code = LOAD_CONST_IMMORTAL; + } + } + if (opcode != EXTENDED_ARG) { + oparg = 0; + } } #endif /* ENABLE_SPECIALIZATION */ }