From 2a61cfc71911c7745bf829327f1c853b369e597a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 22 Oct 2024 15:57:51 +0100 Subject: [PATCH 01/34] Replace RETURN_VLAUE/RETURN_CONST with RETURN_VALUE_FUNC/RETURN_VALUE_GEN --- Include/internal/pycore_ceval.h | 2 + Include/internal/pycore_magic_number.h | 3 +- Include/internal/pycore_opcode_metadata.h | 68 +++++----- Include/internal/pycore_opcode_utils.h | 3 +- Include/internal/pycore_uop_ids.h | 3 +- Include/internal/pycore_uop_metadata.h | 10 +- Include/opcode_ids.h | 151 +++++++++++----------- Lib/_opcode_metadata.py | 151 +++++++++++----------- Lib/dis.py | 1 - Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_compile.py | 16 +-- Lib/test/test_compiler_assemble.py | 6 +- Lib/test/test_peepholer.py | 19 ++- Objects/frameobject.c | 5 +- Python/bytecodes.c | 50 ++++--- Python/ceval.c | 14 +- Python/executor_cases.c.h | 33 ++++- Python/flowgraph.c | 17 +-- Python/generated_cases.c.h | 102 +++++++-------- Python/instrumentation.c | 20 +-- Python/opcode_targets.h | 8 +- Python/optimizer.c | 4 +- Python/optimizer_analysis.c | 3 +- Python/optimizer_bytecodes.c | 25 +++- Python/optimizer_cases.c.h | 30 ++++- Python/specialize.c | 2 +- 26 files changed, 430 insertions(+), 318 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index cff2b1f7114793..0f80ba7575ec7b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -267,6 +267,8 @@ PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, Py PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); PyAPI_FUNC(int) _PyEval_UnpackIterableStackRef(PyThreadState *tstate, _PyStackRef v, int argcnt, int argcntafter, _PyStackRef *sp); PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); +PyAPI_FUNC(void) _PyEval_ClearThreadFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); +PyAPI_FUNC(void) _PyEval_ClearGenFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch); PyAPI_FUNC(void) _PyObjectArray_Free(PyObject **array, PyObject **scratch); diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 4aa89f3cac8063..c91a52d59e1aa7 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.14a1 3609 (Break up RETURN_VALUE) 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 3610 /* 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 c18423476d3962..7f37bee1829626 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -24,6 +24,7 @@ extern "C" { ((OP) == JUMP_NO_INTERRUPT) || \ ((OP) == JUMP_IF_FALSE) || \ ((OP) == JUMP_IF_TRUE) || \ + ((OP) == RETURN_VALUE) || \ ((OP) == SETUP_FINALLY) || \ ((OP) == SETUP_CLEANUP) || \ ((OP) == SETUP_WITH) || \ @@ -253,9 +254,9 @@ 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: + case INSTRUMENTED_RETURN_VALUE_FUNC: + return 1; + case INSTRUMENTED_RETURN_VALUE_GEN: return 1; case INSTRUMENTED_YIELD_VALUE: return 1; @@ -393,11 +394,13 @@ 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: + return 0; + case RETURN_VALUE_FUNC: + return 1; + case RETURN_VALUE_GEN: return 1; case SEND: return 2; @@ -712,9 +715,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case INSTRUMENTED_RESUME: return 0; - case INSTRUMENTED_RETURN_CONST: + case INSTRUMENTED_RETURN_VALUE_FUNC: return 1; - case INSTRUMENTED_RETURN_VALUE: + case INSTRUMENTED_RETURN_VALUE_GEN: return 1; case INSTRUMENTED_YIELD_VALUE: return 1; @@ -852,11 +855,13 @@ 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: + return 0; + case RETURN_VALUE_FUNC: + return 1; + case RETURN_VALUE_GEN: return 1; case SEND: return 2; @@ -962,7 +967,7 @@ enum InstructionFormat { }; #define IS_VALID_OPCODE(OP) \ - (((OP) >= 0) && ((OP) < 266) && \ + (((OP) >= 0) && ((OP) < 267) && \ (_PyOpcode_opcode_metadata[(OP)].valid_entry)) #define HAS_ARG_FLAG (1) @@ -1011,9 +1016,9 @@ struct opcode_metadata { int16_t flags; }; -extern const struct opcode_metadata _PyOpcode_opcode_metadata[266]; +extern const struct opcode_metadata _PyOpcode_opcode_metadata[267]; #ifdef NEED_OPCODE_METADATA -const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { +const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, @@ -1123,8 +1128,8 @@ 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_RETURN_VALUE_FUNC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_RETURN_VALUE_GEN] = { 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 }, [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, @@ -1187,9 +1192,9 @@ 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 }, + [RETURN_VALUE_FUNC] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [RETURN_VALUE_GEN] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1234,6 +1239,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [POP_BLOCK] = { true, -1, HAS_PURE_FLAG }, + [RETURN_VALUE] = { true, -1, HAS_ESCAPES_FLAG }, [SETUP_CLEANUP] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, [SETUP_FINALLY] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, [SETUP_WITH] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, @@ -1386,9 +1392,9 @@ _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 } } }, + [RETURN_VALUE_FUNC] = { .nuops = 1, .uops = { { _RETURN_VALUE_FUNC, 0, 0 } } }, + [RETURN_VALUE_GEN] = { .nuops = 1, .uops = { { _RETURN_VALUE_GEN, 0, 0 } } }, [SEND_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, 0, 0 }, { _SEND_GEN_FRAME, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } }, [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } }, @@ -1429,9 +1435,9 @@ _PyOpcode_macro_expansion[256] = { }; #endif // NEED_OPCODE_METADATA -extern const char *_PyOpcode_OpName[266]; +extern const char *_PyOpcode_OpName[267]; #ifdef NEED_OPCODE_METADATA -const char *_PyOpcode_OpName[266] = { +const char *_PyOpcode_OpName[267] = { [BINARY_OP] = "BINARY_OP", [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", @@ -1541,8 +1547,8 @@ 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_RETURN_VALUE_FUNC] = "INSTRUMENTED_RETURN_VALUE_FUNC", + [INSTRUMENTED_RETURN_VALUE_GEN] = "INSTRUMENTED_RETURN_VALUE_GEN", [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", [INTERPRETER_EXIT] = "INTERPRETER_EXIT", [IS_OP] = "IS_OP", @@ -1611,9 +1617,10 @@ 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", + [RETURN_VALUE_FUNC] = "RETURN_VALUE_FUNC", + [RETURN_VALUE_GEN] = "RETURN_VALUE_GEN", [SEND] = "SEND", [SEND_GEN] = "SEND_GEN", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", @@ -1797,8 +1804,8 @@ 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_RETURN_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, + [INSTRUMENTED_RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, [INTERPRETER_EXIT] = INTERPRETER_EXIT, [IS_OP] = IS_OP, @@ -1861,9 +1868,9 @@ 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, + [RETURN_VALUE_FUNC] = RETURN_VALUE_FUNC, + [RETURN_VALUE_GEN] = RETURN_VALUE_GEN, [SEND] = SEND, [SEND_GEN] = SEND, [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, @@ -1954,15 +1961,16 @@ struct pseudo_targets { uint8_t as_sequence; uint8_t targets[4]; }; -extern const struct pseudo_targets _PyOpcode_PseudoTargets[10]; +extern const struct pseudo_targets _PyOpcode_PseudoTargets[11]; #ifdef NEED_OPCODE_METADATA -const struct pseudo_targets _PyOpcode_PseudoTargets[10] = { +const struct pseudo_targets _PyOpcode_PseudoTargets[11] = { [LOAD_CLOSURE-256] = { 0, { LOAD_FAST, 0, 0, 0 } }, [STORE_FAST_MAYBE_NULL-256] = { 0, { STORE_FAST, 0, 0, 0 } }, [JUMP-256] = { 0, { JUMP_FORWARD, JUMP_BACKWARD, 0, 0 } }, [JUMP_NO_INTERRUPT-256] = { 0, { JUMP_FORWARD, JUMP_BACKWARD_NO_INTERRUPT, 0, 0 } }, [JUMP_IF_FALSE-256] = { 1, { COPY, TO_BOOL, POP_JUMP_IF_FALSE, 0 } }, [JUMP_IF_TRUE-256] = { 1, { COPY, TO_BOOL, POP_JUMP_IF_TRUE, 0 } }, + [RETURN_VALUE-256] = { 0, { RETURN_VALUE_FUNC, RETURN_VALUE_GEN, 0, 0 } }, [SETUP_FINALLY-256] = { 0, { NOP, 0, 0, 0 } }, [SETUP_CLEANUP-256] = { 0, { NOP, 0, 0, 0 } }, [SETUP_WITH-256] = { 0, { NOP, 0, 0, 0 } }, @@ -1972,7 +1980,7 @@ const struct pseudo_targets _PyOpcode_PseudoTargets[10] = { #endif // NEED_OPCODE_METADATA static inline bool is_pseudo_target(int pseudo, int target) { - if (pseudo < 256 || pseudo >= 266) { + if (pseudo < 256 || pseudo >= 267) { return false; } for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) { diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index e76f4840a66891..24195825260018 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -47,7 +47,8 @@ extern "C" { #define IS_SCOPE_EXIT_OPCODE(opcode) \ ((opcode) == RETURN_VALUE || \ - (opcode) == RETURN_CONST || \ + (opcode) == RETURN_VALUE_FUNC || \ + (opcode) == RETURN_VALUE_GEN || \ (opcode) == RAISE_VARARGS || \ (opcode) == RERAISE) diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 1951c65a2871cf..4af691a98cbbc8 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -253,7 +253,8 @@ extern "C" { #define _REPLACE_WITH_TRUE 457 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE RETURN_VALUE +#define _RETURN_VALUE_FUNC RETURN_VALUE_FUNC +#define _RETURN_VALUE_GEN RETURN_VALUE_GEN #define _SAVE_RETURN_OFFSET 458 #define _SEND 459 #define _SEND_GEN_FRAME 460 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 2f0a7fb2f6e549..79e8fcc96f433f 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -92,7 +92,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_RETURN_VALUE] = 0, + [_RETURN_VALUE_FUNC] = HAS_ESCAPES_FLAG, + [_RETURN_VALUE_GEN] = HAS_ESCAPES_FLAG, [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -511,7 +512,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE", [_RESUME_CHECK] = "_RESUME_CHECK", [_RETURN_GENERATOR] = "_RETURN_GENERATOR", - [_RETURN_VALUE] = "_RETURN_VALUE", + [_RETURN_VALUE_FUNC] = "_RETURN_VALUE_FUNC", + [_RETURN_VALUE_GEN] = "_RETURN_VALUE_GEN", [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET", [_SEND_GEN_FRAME] = "_SEND_GEN_FRAME", [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS", @@ -710,7 +712,9 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _CALL_INTRINSIC_2: return 2; - case _RETURN_VALUE: + case _RETURN_VALUE_FUNC: + return 1; + case _RETURN_VALUE_GEN: return 1; case _GET_AITER: return 1; diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 327bdb792464a0..f37e8898009153 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -43,74 +43,74 @@ extern "C" { #define PUSH_EXC_INFO 30 #define PUSH_NULL 31 #define RETURN_GENERATOR 32 -#define RETURN_VALUE 33 -#define SETUP_ANNOTATIONS 34 -#define STORE_SLICE 35 -#define STORE_SUBSCR 36 -#define TO_BOOL 37 -#define UNARY_INVERT 38 -#define UNARY_NEGATIVE 39 -#define UNARY_NOT 40 -#define WITH_EXCEPT_START 41 -#define BINARY_OP 42 -#define BUILD_LIST 43 -#define BUILD_MAP 44 -#define BUILD_SET 45 -#define BUILD_SLICE 46 -#define BUILD_STRING 47 -#define BUILD_TUPLE 48 -#define CALL 49 -#define CALL_FUNCTION_EX 50 -#define CALL_INTRINSIC_1 51 -#define CALL_INTRINSIC_2 52 -#define CALL_KW 53 -#define COMPARE_OP 54 -#define CONTAINS_OP 55 -#define CONVERT_VALUE 56 -#define COPY 57 -#define COPY_FREE_VARS 58 -#define DELETE_ATTR 59 -#define DELETE_DEREF 60 -#define DELETE_FAST 61 -#define DELETE_GLOBAL 62 -#define DELETE_NAME 63 -#define DICT_MERGE 64 -#define DICT_UPDATE 65 -#define EXTENDED_ARG 66 -#define FOR_ITER 67 -#define GET_AWAITABLE 68 -#define IMPORT_FROM 69 -#define IMPORT_NAME 70 -#define IS_OP 71 -#define JUMP_BACKWARD 72 -#define JUMP_BACKWARD_NO_INTERRUPT 73 -#define JUMP_FORWARD 74 -#define LIST_APPEND 75 -#define LIST_EXTEND 76 -#define LOAD_ATTR 77 -#define LOAD_COMMON_CONSTANT 78 -#define LOAD_CONST 79 -#define LOAD_DEREF 80 -#define LOAD_FAST 81 -#define LOAD_FAST_AND_CLEAR 82 -#define LOAD_FAST_CHECK 83 -#define LOAD_FAST_LOAD_FAST 84 -#define LOAD_FROM_DICT_OR_DEREF 85 -#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 RETURN_VALUE_FUNC 33 +#define RETURN_VALUE_GEN 34 +#define SETUP_ANNOTATIONS 35 +#define STORE_SLICE 36 +#define STORE_SUBSCR 37 +#define TO_BOOL 38 +#define UNARY_INVERT 39 +#define UNARY_NEGATIVE 40 +#define UNARY_NOT 41 +#define WITH_EXCEPT_START 42 +#define BINARY_OP 43 +#define BUILD_LIST 44 +#define BUILD_MAP 45 +#define BUILD_SET 46 +#define BUILD_SLICE 47 +#define BUILD_STRING 48 +#define BUILD_TUPLE 49 +#define CALL 50 +#define CALL_FUNCTION_EX 51 +#define CALL_INTRINSIC_1 52 +#define CALL_INTRINSIC_2 53 +#define CALL_KW 54 +#define COMPARE_OP 55 +#define CONTAINS_OP 56 +#define CONVERT_VALUE 57 +#define COPY 58 +#define COPY_FREE_VARS 59 +#define DELETE_ATTR 60 +#define DELETE_DEREF 61 +#define DELETE_FAST 62 +#define DELETE_GLOBAL 63 +#define DELETE_NAME 64 +#define DICT_MERGE 65 +#define DICT_UPDATE 66 +#define EXTENDED_ARG 67 +#define FOR_ITER 68 +#define GET_AWAITABLE 69 +#define IMPORT_FROM 70 +#define IMPORT_NAME 71 +#define IS_OP 72 +#define JUMP_BACKWARD 73 +#define JUMP_BACKWARD_NO_INTERRUPT 74 +#define JUMP_FORWARD 75 +#define LIST_APPEND 76 +#define LIST_EXTEND 77 +#define LOAD_ATTR 78 +#define LOAD_COMMON_CONSTANT 79 +#define LOAD_CONST 80 +#define LOAD_DEREF 81 +#define LOAD_FAST 82 +#define LOAD_FAST_AND_CLEAR 83 +#define LOAD_FAST_CHECK 84 +#define LOAD_FAST_LOAD_FAST 85 +#define LOAD_FROM_DICT_OR_DEREF 86 +#define LOAD_FROM_DICT_OR_GLOBALS 87 +#define LOAD_GLOBAL 88 +#define LOAD_NAME 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 @@ -217,8 +217,8 @@ extern "C" { #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 INSTRUMENTED_RETURN_VALUE_FUNC 249 +#define INSTRUMENTED_RETURN_VALUE_GEN 250 #define INSTRUMENTED_YIELD_VALUE 251 #define INSTRUMENTED_CALL 252 #define INSTRUMENTED_JUMP_BACKWARD 253 @@ -230,12 +230,13 @@ extern "C" { #define JUMP_NO_INTERRUPT 259 #define LOAD_CLOSURE 260 #define POP_BLOCK 261 -#define SETUP_CLEANUP 262 -#define SETUP_FINALLY 263 -#define SETUP_WITH 264 -#define STORE_FAST_MAYBE_NULL 265 +#define RETURN_VALUE 262 +#define SETUP_CLEANUP 263 +#define SETUP_FINALLY 264 +#define SETUP_WITH 265 +#define STORE_FAST_MAYBE_NULL 266 -#define HAVE_ARGUMENT 41 +#define HAVE_ARGUMENT 42 #define MIN_SPECIALIZED_OPCODE 150 #define MIN_INSTRUMENTED_OPCODE 236 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 9a793717cf082b..d943bef5cbfb6c 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -232,74 +232,74 @@ 'PUSH_EXC_INFO': 30, 'PUSH_NULL': 31, 'RETURN_GENERATOR': 32, - 'RETURN_VALUE': 33, - 'SETUP_ANNOTATIONS': 34, - 'STORE_SLICE': 35, - 'STORE_SUBSCR': 36, - 'TO_BOOL': 37, - 'UNARY_INVERT': 38, - 'UNARY_NEGATIVE': 39, - 'UNARY_NOT': 40, - 'WITH_EXCEPT_START': 41, - 'BINARY_OP': 42, - 'BUILD_LIST': 43, - 'BUILD_MAP': 44, - 'BUILD_SET': 45, - 'BUILD_SLICE': 46, - 'BUILD_STRING': 47, - 'BUILD_TUPLE': 48, - 'CALL': 49, - 'CALL_FUNCTION_EX': 50, - 'CALL_INTRINSIC_1': 51, - 'CALL_INTRINSIC_2': 52, - 'CALL_KW': 53, - 'COMPARE_OP': 54, - 'CONTAINS_OP': 55, - 'CONVERT_VALUE': 56, - 'COPY': 57, - 'COPY_FREE_VARS': 58, - 'DELETE_ATTR': 59, - 'DELETE_DEREF': 60, - 'DELETE_FAST': 61, - 'DELETE_GLOBAL': 62, - 'DELETE_NAME': 63, - 'DICT_MERGE': 64, - 'DICT_UPDATE': 65, - 'EXTENDED_ARG': 66, - 'FOR_ITER': 67, - 'GET_AWAITABLE': 68, - 'IMPORT_FROM': 69, - 'IMPORT_NAME': 70, - 'IS_OP': 71, - 'JUMP_BACKWARD': 72, - 'JUMP_BACKWARD_NO_INTERRUPT': 73, - 'JUMP_FORWARD': 74, - 'LIST_APPEND': 75, - 'LIST_EXTEND': 76, - 'LOAD_ATTR': 77, - 'LOAD_COMMON_CONSTANT': 78, - 'LOAD_CONST': 79, - 'LOAD_DEREF': 80, - 'LOAD_FAST': 81, - 'LOAD_FAST_AND_CLEAR': 82, - 'LOAD_FAST_CHECK': 83, - 'LOAD_FAST_LOAD_FAST': 84, - 'LOAD_FROM_DICT_OR_DEREF': 85, - '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, + 'RETURN_VALUE_FUNC': 33, + 'RETURN_VALUE_GEN': 34, + 'SETUP_ANNOTATIONS': 35, + 'STORE_SLICE': 36, + 'STORE_SUBSCR': 37, + 'TO_BOOL': 38, + 'UNARY_INVERT': 39, + 'UNARY_NEGATIVE': 40, + 'UNARY_NOT': 41, + 'WITH_EXCEPT_START': 42, + 'BINARY_OP': 43, + 'BUILD_LIST': 44, + 'BUILD_MAP': 45, + 'BUILD_SET': 46, + 'BUILD_SLICE': 47, + 'BUILD_STRING': 48, + 'BUILD_TUPLE': 49, + 'CALL': 50, + 'CALL_FUNCTION_EX': 51, + 'CALL_INTRINSIC_1': 52, + 'CALL_INTRINSIC_2': 53, + 'CALL_KW': 54, + 'COMPARE_OP': 55, + 'CONTAINS_OP': 56, + 'CONVERT_VALUE': 57, + 'COPY': 58, + 'COPY_FREE_VARS': 59, + 'DELETE_ATTR': 60, + 'DELETE_DEREF': 61, + 'DELETE_FAST': 62, + 'DELETE_GLOBAL': 63, + 'DELETE_NAME': 64, + 'DICT_MERGE': 65, + 'DICT_UPDATE': 66, + 'EXTENDED_ARG': 67, + 'FOR_ITER': 68, + 'GET_AWAITABLE': 69, + 'IMPORT_FROM': 70, + 'IMPORT_NAME': 71, + 'IS_OP': 72, + 'JUMP_BACKWARD': 73, + 'JUMP_BACKWARD_NO_INTERRUPT': 74, + 'JUMP_FORWARD': 75, + 'LIST_APPEND': 76, + 'LIST_EXTEND': 77, + 'LOAD_ATTR': 78, + 'LOAD_COMMON_CONSTANT': 79, + 'LOAD_CONST': 80, + 'LOAD_DEREF': 81, + 'LOAD_FAST': 82, + 'LOAD_FAST_AND_CLEAR': 83, + 'LOAD_FAST_CHECK': 84, + 'LOAD_FAST_LOAD_FAST': 85, + 'LOAD_FROM_DICT_OR_DEREF': 86, + 'LOAD_FROM_DICT_OR_GLOBALS': 87, + 'LOAD_GLOBAL': 88, + 'LOAD_NAME': 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, @@ -328,8 +328,8 @@ '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_RETURN_VALUE_FUNC': 249, + 'INSTRUMENTED_RETURN_VALUE_GEN': 250, 'INSTRUMENTED_YIELD_VALUE': 251, 'INSTRUMENTED_CALL': 252, 'INSTRUMENTED_JUMP_BACKWARD': 253, @@ -339,11 +339,12 @@ 'JUMP_NO_INTERRUPT': 259, 'LOAD_CLOSURE': 260, 'POP_BLOCK': 261, - 'SETUP_CLEANUP': 262, - 'SETUP_FINALLY': 263, - 'SETUP_WITH': 264, - 'STORE_FAST_MAYBE_NULL': 265, + 'RETURN_VALUE': 262, + 'SETUP_CLEANUP': 263, + 'SETUP_FINALLY': 264, + 'SETUP_WITH': 265, + 'STORE_FAST_MAYBE_NULL': 266, } -HAVE_ARGUMENT = 41 +HAVE_ARGUMENT = 42 MIN_INSTRUMENTED_OPCODE = 236 diff --git a/Lib/dis.py b/Lib/dis.py index e87e6a78469ab0..165cb5e1603353 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -36,7 +36,6 @@ ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] LOAD_CONST = opmap['LOAD_CONST'] -RETURN_CONST = opmap['RETURN_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 01d2e392302e86..88657346fa4e04 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ def get_load_const(self, tree): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname == 'LOAD_CONST' or instr.opname == 'RETURN_CONST': + if instr.opname == 'LOAD_CONST': consts.append(instr.argval) return consts diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6f838da6018741..09487223da6b8d 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -884,7 +884,7 @@ def unused_code_at_end(): # RETURN_VALUE opcode. This does not always crash an interpreter. # When you build with the clang memory sanitizer it reliably aborts. self.assertEqual( - 'RETURN_CONST', + 'RETURN_VALUE_FUNC', list(dis.get_instructions(unused_code_at_end))[-1].opname) @support.cpython_only @@ -1046,7 +1046,7 @@ def unused_block_while_else(): for func in funcs: opcodes = list(dis.get_instructions(func)) self.assertLessEqual(len(opcodes), 3) - self.assertEqual('RETURN_CONST', opcodes[-1].opname) + self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) self.assertEqual(None, opcodes[-1].argval) def test_false_while_loop(self): @@ -1064,7 +1064,7 @@ def continue_in_while(): for func in funcs: opcodes = list(dis.get_instructions(func)) self.assertEqual(2, len(opcodes)) - self.assertEqual('RETURN_CONST', opcodes[1].opname) + self.assertEqual('RETURN_VALUE_FUNC', opcodes[1].opname) self.assertEqual(None, opcodes[1].argval) def test_consts_in_conditionals(self): @@ -1760,7 +1760,7 @@ def test_multiline_generator_expression(self): line=1, end_line=2, column=1, end_column=8, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=1, end_line=2, column=1, end_column=8, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_FUNC', line=4, end_line=4, column=7, end_column=14, occurrence=1) def test_multiline_async_generator_expression(self): @@ -1777,7 +1777,7 @@ def test_multiline_async_generator_expression(self): self.assertIsInstance(compiled_code, types.CodeType) self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', line=1, end_line=2, column=1, end_column=8, occurrence=2) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_FUNC', line=1, end_line=6, column=0, end_column=32, occurrence=1) def test_multiline_list_comprehension(self): @@ -1815,7 +1815,7 @@ async def f(): 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_FUNC', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_multiline_set_comprehension(self): @@ -1853,7 +1853,7 @@ async def f(): 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_GEN', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_multiline_dict_comprehension(self): @@ -1891,7 +1891,7 @@ async def f(): 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_FUNC', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_matchcase_sequence(self): diff --git a/Lib/test/test_compiler_assemble.py b/Lib/test/test_compiler_assemble.py index 1b98b0d97ed8a5..2a964be4e15f49 100644 --- a/Lib/test/test_compiler_assemble.py +++ b/Lib/test/test_compiler_assemble.py @@ -126,12 +126,14 @@ def test_exception_table(self): insts = [ ('RESUME', 0), ('SETUP_FINALLY', 3), - ('RETURN_CONST', 0), + ('LOAD_CONST', 0), + ('RETURN_VALUE_FUNC', None), ('SETUP_CLEANUP', 8), ('PUSH_EXC_INFO', None), ('POP_TOP', None), ('POP_EXCEPT', None), - ('RETURN_CONST', 0), + ('LOAD_CONST', 0), + ('RETURN_VALUE_FUNC', None), ('COPY', 3), ('POP_EXCEPT', None), ('RERAISE', 1), diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index b143f3d27a1537..57d173c20ef06c 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -114,7 +114,7 @@ def f(): 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 @@ def f(): 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',), ): @@ -989,9 +989,11 @@ def test_conditional_jump_forward_non_const_condition(self): expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), - ('RETURN_CONST', 1, 13), + ('LOAD_CONST', 2, 13), + ('RETURN_VALUE', None, 13), lbl, - ('RETURN_CONST', 2, 14), + ('LOAD_CONST', 2, 13), + ('RETURN_VALUE', None, 13), ] self.cfg_optimization_test(insts, expected_insts, @@ -1013,7 +1015,8 @@ def test_conditional_jump_forward_const_condition(self): expected_insts = [ ('NOP', None, 11), ('NOP', None, 12), - ('RETURN_CONST', 1, 14), + ('LOAD_CONST', 3, 14), + ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1057,9 +1060,11 @@ def test_except_handler_label(self): insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), ('POP_BLOCK', None, -1), - ('RETURN_CONST', 1, 11), + ('LOAD_CONST', 1, 11), + ('RETURN_VALUE', None, None), handler, - ('RETURN_CONST', 2, 12), + ('LOAD_CONST', 2, 12), + ('RETURN_VALUE', None, None), ] expected_insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 5ef48919a081be..214650507c83f2 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1243,12 +1243,11 @@ mark_stacks(PyCodeObject *code_obj, int len) next_stack = pop_value(next_stack); stacks[next_i] = next_stack; break; - case RETURN_VALUE: + case RETURN_VALUE_FUNC: + case RETURN_VALUE_GEN: 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/Python/bytecodes.c b/Python/bytecodes.c index 62e9b5ddd1584c..d3b8bdc79d1796 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -977,13 +977,13 @@ dummy_func( return PyStackRef_AsPyObjectSteal(retval); } - // 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. - inst(RETURN_VALUE, (retval -- res)) { + // 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_FUNC, (retval -- res)) { #if TIER_ONE assert(frame != &entry_frame); + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; DEAD(retval); @@ -993,7 +993,27 @@ dummy_func( // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); + _PyEval_ClearThreadFrame(tstate, dying); + RELOAD_STACK(); + LOAD_IP(frame->return_offset); + res = temp; + LLTRACE_RESUME_FRAME(); + } + + inst(RETURN_VALUE_GEN, (retval -- res)) { + #if TIER_ONE + assert(frame != &entry_frame); + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + #endif + _PyStackRef temp = retval; + DEAD(retval); + SAVE_STACK(); + 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_ClearGenFrame(tstate, dying); RELOAD_STACK(); LOAD_IP(frame->return_offset); res = temp; @@ -1007,18 +1027,13 @@ dummy_func( ERROR_IF(err, error); } - macro(INSTRUMENTED_RETURN_VALUE) = + macro(INSTRUMENTED_RETURN_VALUE_FUNC) = _RETURN_VALUE_EVENT + - RETURN_VALUE; - - macro(RETURN_CONST) = - LOAD_CONST + - RETURN_VALUE; + RETURN_VALUE_FUNC; - macro(INSTRUMENTED_RETURN_CONST) = - LOAD_CONST + + macro(INSTRUMENTED_RETURN_VALUE_GEN) = _RETURN_VALUE_EVENT + - RETURN_VALUE; + RETURN_VALUE_GEN; inst(GET_AITER, (obj -- iter)) { unaryfunc getter = NULL; @@ -2632,6 +2647,11 @@ dummy_func( COPY, TO_BOOL, POP_JUMP_IF_TRUE, ]; + pseudo(RETURN_VALUE, (--)) = { + RETURN_VALUE_FUNC, + RETURN_VALUE_GEN, + }; + tier1 inst(ENTER_EXECUTOR, (--)) { #ifdef _Py_TIER2 PyCodeObject *code = _PyFrame_GetCode(frame); diff --git a/Python/ceval.c b/Python/ceval.c index ca75646b585f07..73d1a3f71994cc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1706,8 +1706,8 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, return -1; } -static void -clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) +void +_PyEval_ClearThreadFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_THREAD); // Make sure that this is, indeed, the top frame. We can't check this in @@ -1722,8 +1722,8 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) _PyThreadState_PopFrame(tstate, frame); } -static void -clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) +void +_PyEval_ClearGenFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_GENERATOR); PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); @@ -1743,10 +1743,10 @@ void _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) { if (frame->owner == FRAME_OWNED_BY_THREAD) { - clear_thread_frame(tstate, frame); + _PyEval_ClearThreadFrame(tstate, frame); } else { - clear_gen_frame(tstate, frame); + _PyEval_ClearGenFrame(tstate, frame); } } @@ -1766,7 +1766,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, _PyStackRef func, _PyFrame_Initialize(frame, func, locals, code, 0, previous); if (initialize_locals(tstate, func_obj, frame->localsplus, args, argcount, kwnames)) { assert(frame->owner == FRAME_OWNED_BY_THREAD); - clear_thread_frame(tstate, frame); + _PyEval_ClearThreadFrame(tstate, frame); return NULL; } return frame; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 5df4986cd838b5..72032951c99cc8 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1251,12 +1251,13 @@ break; } - case _RETURN_VALUE: { + case _RETURN_VALUE_FUNC: { _PyStackRef retval; _PyStackRef res; retval = stack_pointer[-1]; #if TIER_ONE assert(frame != &entry_frame); + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -1267,7 +1268,35 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); + _PyEval_ClearThreadFrame(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()); + break; + } + + case _RETURN_VALUE_GEN: { + _PyStackRef retval; + _PyStackRef res; + retval = stack_pointer[-1]; + #if TIER_ONE + assert(frame != &entry_frame); + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + #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_ClearGenFrame(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 388862912d6826..1dda73daeda940 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 || last->i_opcode == RETURN_VALUE_FUNC || last->i_opcode == RETURN_VALUE_GEN); } static void @@ -1662,12 +1662,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); @@ -2436,7 +2430,7 @@ convert_pseudo_conditional_jumps(cfg_builder *g) } static int -convert_pseudo_ops(cfg_builder *g) +convert_pseudo_ops(cfg_builder *g, int is_generator) { basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { @@ -2453,6 +2447,9 @@ convert_pseudo_ops(cfg_builder *g) assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST)); instr->i_opcode = STORE_FAST; } + else if (instr->i_opcode == RETURN_VALUE) { + instr->i_opcode = is_generator ? RETURN_VALUE_GEN : RETURN_VALUE_FUNC; + } } } return remove_redundant_nops_and_jumps(g); @@ -2594,8 +2591,8 @@ _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)); + // assert(all_exits_have_lineno(g->g_entryblock)); return SUCCESS; } @@ -2915,7 +2912,7 @@ _PyCfg_OptimizedCfgToInstructionSequence(cfg_builder *g, return ERROR; } - RETURN_IF_ERROR(convert_pseudo_ops(g)); + RETURN_IF_ERROR(convert_pseudo_ops(g, IS_GENERATOR(code_flags))); /* Order of basic blocks must have been determined by now */ diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index efbf2fba8c3106..6bdf335f97499c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4881,25 +4881,17 @@ DISPATCH(); } - TARGET(INSTRUMENTED_RETURN_CONST) { + TARGET(INSTRUMENTED_RETURN_VALUE_FUNC) { _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; (void)this_instr; next_instr += 1; - INSTRUCTION_STATS(INSTRUMENTED_RETURN_CONST); - _PyStackRef value; + INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE_FUNC); _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()); + val = stack_pointer[-1]; _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, @@ -4907,11 +4899,12 @@ stack_pointer = _PyFrame_GetStackPointer(frame); if (err) goto error; } - // _RETURN_VALUE + // _RETURN_VALUE_FUNC { retval = val; #if TIER_ONE assert(frame != &entry_frame); + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -4922,7 +4915,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); + _PyEval_ClearThreadFrame(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; @@ -4934,11 +4927,11 @@ DISPATCH(); } - TARGET(INSTRUMENTED_RETURN_VALUE) { + TARGET(INSTRUMENTED_RETURN_VALUE_GEN) { _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; (void)this_instr; next_instr += 1; - INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE); + INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE_GEN); _PyStackRef val; _PyStackRef retval; _PyStackRef res; @@ -4952,11 +4945,12 @@ stack_pointer = _PyFrame_GetStackPointer(frame); if (err) goto error; } - // _RETURN_VALUE + // _RETURN_VALUE_GEN { retval = val; #if TIER_ONE assert(frame != &entry_frame); + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -4967,7 +4961,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); + _PyEval_ClearGenFrame(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; @@ -6951,42 +6945,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; @@ -7020,15 +6978,47 @@ DISPATCH(); } - TARGET(RETURN_VALUE) { + TARGET(RETURN_VALUE_FUNC) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RETURN_VALUE_FUNC); + _PyStackRef retval; + _PyStackRef res; + retval = stack_pointer[-1]; + #if TIER_ONE + assert(frame != &entry_frame); + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); + #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_ClearThreadFrame(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_VALUE_GEN) { frame->instr_ptr = next_instr; next_instr += 1; - INSTRUCTION_STATS(RETURN_VALUE); + INSTRUCTION_STATS(RETURN_VALUE_GEN); _PyStackRef retval; _PyStackRef res; retval = stack_pointer[-1]; #if TIER_ONE assert(frame != &entry_frame); + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -7039,7 +7029,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); + _PyEval_ClearGenFrame(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index e1e494c31a1120..8ad3d680c019eb 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -56,10 +56,10 @@ 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, + [RETURN_VALUE_GEN] = PY_MONITORING_EVENT_PY_RETURN, + [INSTRUMENTED_RETURN_VALUE_GEN] = PY_MONITORING_EVENT_PY_RETURN, + [RETURN_VALUE_FUNC] = PY_MONITORING_EVENT_PY_RETURN, + [INSTRUMENTED_RETURN_VALUE_FUNC] = PY_MONITORING_EVENT_PY_RETURN, [CALL] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL, [CALL_KW] = PY_MONITORING_EVENT_CALL, @@ -93,8 +93,8 @@ 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_RETURN_VALUE_FUNC] = RETURN_VALUE_FUNC, + [INSTRUMENTED_RETURN_VALUE_GEN] = RETURN_VALUE_GEN, [INSTRUMENTED_CALL] = CALL, [INSTRUMENTED_CALL_KW] = CALL_KW, [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, @@ -112,10 +112,10 @@ 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, + [RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, + [INSTRUMENTED_RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, + [RETURN_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, + [INSTRUMENTED_RETURN_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, [CALL] = INSTRUMENTED_CALL, [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, [CALL_KW] = INSTRUMENTED_CALL_KW, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 3fc9d3118d59ad..b71c935d29b114 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -32,7 +32,8 @@ static void *opcode_targets[256] = { &&TARGET_PUSH_EXC_INFO, &&TARGET_PUSH_NULL, &&TARGET_RETURN_GENERATOR, - &&TARGET_RETURN_VALUE, + &&TARGET_RETURN_VALUE_FUNC, + &&TARGET_RETURN_VALUE_GEN, &&TARGET_SETUP_ANNOTATIONS, &&TARGET_STORE_SLICE, &&TARGET_STORE_SUBSCR, @@ -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, @@ -248,8 +248,8 @@ static void *opcode_targets[256] = { &&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE, &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, &&TARGET_INSTRUMENTED_RESUME, - &&TARGET_INSTRUMENTED_RETURN_VALUE, - &&TARGET_INSTRUMENTED_RETURN_CONST, + &&TARGET_INSTRUMENTED_RETURN_VALUE_FUNC, + &&TARGET_INSTRUMENTED_RETURN_VALUE_GEN, &&TARGET_INSTRUMENTED_YIELD_VALUE, &&TARGET_INSTRUMENTED_CALL, &&TARGET_INSTRUMENTED_JUMP_BACKWARD, diff --git a/Python/optimizer.c b/Python/optimizer.c index b876b6c2bd72fd..1d7dd4b5d5c594 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -709,7 +709,7 @@ translate_bytecode_to_trace( int nuops = expansion->nuops; RESERVE(nuops + 1); /* One extra for exit */ int16_t last_op = expansion->uops[nuops-1].uop; - if (last_op == _RETURN_VALUE || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) { + if (last_op == _RETURN_VALUE_FUNC || last_op == _RETURN_VALUE_GEN || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) { // Check for trace stack underflow now: // We can't bail e.g. in the middle of // LOAD_CONST + _RETURN_VALUE. @@ -770,7 +770,7 @@ translate_bytecode_to_trace( Py_FatalError("garbled expansion"); } - if (uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { + if (uop == _RETURN_VALUE_FUNC || uop == _RETURN_VALUE_GEN || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { TRACE_STACK_POP(); /* Set the operand to the function or code object returned to, * to assist optimization passes. (See _PUSH_FRAME below.) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 25166bc2dc5c02..6a92a0be025295 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -407,7 +407,8 @@ eliminate_pop_guard(_PyUOpInstruction *this_instr, bool exit) static PyCodeObject * get_code(_PyUOpInstruction *op) { - assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE || op->opcode == _RETURN_GENERATOR); + assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE_FUNC || + op->opcode == _RETURN_VALUE_GEN || op->opcode == _RETURN_GENERATOR); PyCodeObject *co = NULL; uint64_t operand = op->operand; if (operand == 0) { diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d71b55cbe1c68d..28c7c2eae244e1 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -647,7 +647,30 @@ dummy_func(void) { ctx->done = true; } - op(_RETURN_VALUE, (retval -- res)) { + op(_RETURN_VALUE_FUNC, (retval -- res)) { + SAVE_STACK(); + ctx->frame->stack_pointer = stack_pointer; + frame_pop(ctx); + stack_pointer = ctx->frame->stack_pointer; + + /* Stack space handling */ + assert(corresponding_check_stack == NULL); + assert(co != NULL); + int framesize = co->co_framesize; + assert(framesize > 0); + assert(framesize <= curr_space); + curr_space -= framesize; + + co = get_code(this_instr); + if (co == NULL) { + // might be impossible, but bailing is still safe + ctx->done = true; + } + RELOAD_STACK(); + res = retval; + } + + op(_RETURN_VALUE_GEN, (retval -- res)) { SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; frame_pop(ctx); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 6ec9e69d1dbc44..362fa883b1cb2c 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -621,7 +621,35 @@ break; } - case _RETURN_VALUE: { + case _RETURN_VALUE_FUNC: { + _Py_UopsSymbol *retval; + _Py_UopsSymbol *res; + retval = stack_pointer[-1]; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + ctx->frame->stack_pointer = stack_pointer; + frame_pop(ctx); + stack_pointer = ctx->frame->stack_pointer; + /* Stack space handling */ + assert(corresponding_check_stack == NULL); + assert(co != NULL); + int framesize = co->co_framesize; + assert(framesize > 0); + assert(framesize <= curr_space); + curr_space -= framesize; + co = get_code(this_instr); + if (co == NULL) { + // might be impossible, but bailing is still safe + ctx->done = true; + } + res = retval; + stack_pointer[0] = res; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _RETURN_VALUE_GEN: { _Py_UopsSymbol *retval; _Py_UopsSymbol *res; retval = stack_pointer[-1]; diff --git a/Python/specialize.c b/Python/specialize.c index 4b33a468733d6b..278ee84281338b 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2758,7 +2758,7 @@ const struct _PyCode8 _Py_InitCleanup = { .co_framesize = 2 + FRAME_SPECIALS_SIZE, .co_code_adaptive = { EXIT_INIT_CHECK, 0, - RETURN_VALUE, 0, + RETURN_VALUE_FUNC, 0, RESUME, RESUME_AT_FUNC_START, } }; From 42a526cc5c04bee97aca6f0b009389d4c6abde2b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Oct 2024 09:15:19 +0100 Subject: [PATCH 02/34] Add LOAD_CONST_IMMORTAL --- Include/internal/pycore_magic_number.h | 2 +- Include/internal/pycore_opcode_metadata.h | 9 ++- Include/internal/pycore_uop_ids.h | 1 + Include/internal/pycore_uop_metadata.h | 4 ++ Include/opcode_ids.h | 41 +++++++------- Lib/_opcode_metadata.py | 44 ++++++++------- Lib/dis.py | 1 - Lib/test/test__opcode.py | 2 +- Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_code.py | 2 +- Programs/test_frozenmain.h | 67 ++++++++++++----------- Python/bytecodes.c | 10 ++++ Python/executor_cases.c.h | 12 ++++ Python/generated_cases.c.h | 16 ++++++ Python/opcode_targets.h | 2 +- Python/optimizer_bytecodes.c | 7 +++ Python/optimizer_cases.c.h | 11 ++++ Python/specialize.c | 16 ++++++ 18 files changed, 169 insertions(+), 80 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index c91a52d59e1aa7..aae91bd65823f2 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -274,7 +274,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3610 +#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 7f37bee1829626..7ecb511673fe4e 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -318,6 +318,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: @@ -779,6 +781,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: @@ -1155,6 +1159,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [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 }, @@ -1361,6 +1366,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 } } }, @@ -1579,6 +1585,7 @@ const char *_PyOpcode_OpName[267] = { [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", @@ -1831,6 +1838,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, @@ -1947,7 +1955,6 @@ const uint8_t _PyOpcode_Deopt[256] = { case 146: \ case 147: \ case 148: \ - case 227: \ case 228: \ case 229: \ case 230: \ diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 4af691a98cbbc8..034f23c4c4bbc4 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 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 79e8fcc96f433f..5f1b3e961c34c0 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -36,6 +36,7 @@ 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, [_STORE_FAST_0] = HAS_LOCAL_FLAG, [_STORE_FAST_1] = HAS_LOCAL_FLAG, [_STORE_FAST_2] = HAS_LOCAL_FLAG, @@ -461,6 +462,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", @@ -600,6 +602,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_CONST: return 0; + case _LOAD_CONST_IMMORTAL: + 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 f37e8898009153..48ead22391f964 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -184,26 +184,27 @@ 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 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 236 #define INSTRUMENTED_END_SEND 237 #define INSTRUMENTED_LOAD_SUPER_ATTR 238 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index d943bef5cbfb6c..8f41c20aee31b9 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -6,6 +6,9 @@ "RESUME": [ "RESUME_CHECK", ], + "LOAD_CONST": [ + "LOAD_CONST_IMMORTAL", + ], "TO_BOOL": [ "TO_BOOL_ALWAYS_TRUE", "TO_BOOL_BOOL", @@ -174,26 +177,27 @@ '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 = { diff --git a/Lib/dis.py b/Lib/dis.py index 165cb5e1603353..296ebb8e6e755d 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -35,7 +35,6 @@ FUNCTION_ATTR_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure', 'annotate') ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] -LOAD_CONST = opmap['LOAD_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index d5cf014d40daf8..789285e6369505 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -33,7 +33,7 @@ def test_is_valid(self): 'POP_TOP', 'IMPORT_NAME', 'JUMP', - 'INSTRUMENTED_RETURN_VALUE', + 'INSTRUMENTED_RETURN_VALUE_FUNC', ] opcodes = [dis.opmap[opname] for opname in names] self.check_bool_function_result(_opcode.is_valid, opcodes, True) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 88657346fa4e04..e24a01a3f7de66 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ def get_load_const(self, tree): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname == 'LOAD_CONST': + if instr.opname in ('LOAD_CONST_MORTAL', 'LOAD_CONST_IMMORTAL'): consts.append(instr.argval) return consts diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index ba77e1c5341db8..8287f5b1f53e3a 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -408,7 +408,7 @@ def test_co_positions_artificial_instructions(self): ], [ ("PUSH_EXC_INFO", None), - ("LOAD_CONST", None), # artificial 'None' + ("LOAD_CONST_IMMORTAL", None), # artificial 'None' ("STORE_NAME", "e"), # XX: we know the location for this ("DELETE_NAME", "e"), ("RERAISE", 1), diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 624d9c0b653ad7..f647cba5570a28 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,37 +1,38 @@ // 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,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, - 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,0,243,168,0,0,0,149,0,80,0,80,1, + 71,0,111,0,80,0,80,1,71,1,111,1,89,2,31,0, + 80,2,50,1,0,0,0,0,0,0,29,0,89,2,31,0, + 80,3,89,0,78,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,50,2,0,0,0,0,0,0, + 29,0,89,1,78,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,31,0,50,0,0,0,0,0, + 0,0,80,4,2,0,0,0,111,5,80,5,16,0,68,20, + 0,0,111,6,89,2,31,0,80,6,89,6,12,0,80,7, + 89,5,89,6,2,0,0,0,12,0,48,4,50,1,0,0, + 0,0,0,0,29,0,73,22,0,0,9,0,29,0,80,1, + 33,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, + 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, + 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, + 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, + 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, + 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, + 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, + 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, + 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, + 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, + 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, + 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, + 0,0,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,243,15,6,12,2,114,16,0,0, + 0, }; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index d3b8bdc79d1796..f43014fa57f490 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -255,10 +255,20 @@ 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(8) inst(STORE_FAST, (value --)) { SETLOCAL(oparg, value); DEAD(value); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 72032951c99cc8..50e1c8d5c3daf1 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -210,6 +210,18 @@ 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 _STORE_FAST_0: { _PyStackRef value; oparg = 0; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 6bdf335f97499c..36a8bc04301060 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5895,6 +5895,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; @@ -5903,6 +5904,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; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index b71c935d29b114..43b3366fd620a0 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -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, @@ -234,7 +235,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_END_SEND, &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 28c7c2eae244e1..4acb1e0e9db231 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -427,6 +427,13 @@ 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_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 362fa883b1cb2c..677e3ea8cc6f22 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -68,6 +68,17 @@ 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 _STORE_FAST: { _Py_UopsSymbol *value; value = stack_pointer[-1]; diff --git a/Python/specialize.c b/Python/specialize.c index 278ee84281338b..90d5817cf865e8 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -442,6 +442,7 @@ _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++) { @@ -465,6 +466,21 @@ _PyCode_Quicken(PyCodeObject *code) } i += caches; } + else if (opcode == LOAD_CONST) { + /* We can't do this in the bytecode compiler as + * can intern strings and make them immortal. */ + oparg = (oparg << 8) | instructions[i].op.arg; + 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 = (oparg << 8) | instructions[i].op.arg; + } + else { + oparg = 0; + } } #endif /* ENABLE_SPECIALIZATION */ } From 2a3b1e2c5ca126ea342dcbe81c477f202455972a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Oct 2024 10:59:34 +0100 Subject: [PATCH 03/34] Fix up all the tests apart from test_dis --- Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_code.py | 7 ++--- Lib/test/test_compile.py | 26 +++++++++--------- Lib/test/test_compiler_assemble.py | 4 +-- Lib/test/test_dis.py | 10 +++---- Lib/test/test_embed.py | 3 +++ Lib/test/test_monitoring.py | 5 ++++ Lib/test/test_peepholer.py | 43 +++++++++++++++++------------- 8 files changed, 57 insertions(+), 43 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index e24a01a3f7de66..53ee5914d126e4 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ def get_load_const(self, tree): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname in ('LOAD_CONST_MORTAL', 'LOAD_CONST_IMMORTAL'): + if instr.opname in ('LOAD_CONST', 'LOAD_CONST_IMMORTAL'): consts.append(instr.argval) return consts diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 8287f5b1f53e3a..7a5fe926b01248 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -256,10 +256,11 @@ def func(): 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__ @@ -408,7 +409,7 @@ def test_co_positions_artificial_instructions(self): ], [ ("PUSH_EXC_INFO", None), - ("LOAD_CONST_IMMORTAL", None), # artificial 'None' + ("LOAD_CONST", None), # artificial 'None' ("STORE_NAME", "e"), # XX: we know the location for this ("DELETE_NAME", "e"), ("RERAISE", 1), diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 09487223da6b8d..a45ff0c62d7d9a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1045,7 +1045,7 @@ def unused_block_while_else(): for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertLessEqual(len(opcodes), 3) + self.assertLessEqual(len(opcodes), 4) self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) self.assertEqual(None, opcodes[-1].argval) @@ -1063,8 +1063,8 @@ def continue_in_while(): # Check that we did not raise but we also don't generate bytecode for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertEqual(2, len(opcodes)) - self.assertEqual('RETURN_VALUE_FUNC', opcodes[1].opname) + self.assertEqual(3, len(opcodes)) + self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) self.assertEqual(None, opcodes[1].argval) def test_consts_in_conditionals(self): @@ -1088,7 +1088,7 @@ def or_false(x): opcodes = list(dis.get_instructions(func)) self.assertLessEqual(len(opcodes), 3) self.assertIn('LOAD_', opcodes[-2].opname) - self.assertEqual('RETURN_VALUE', opcodes[-1].opname) + self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) def test_imported_load_method(self): sources = [ @@ -1760,7 +1760,7 @@ def test_multiline_generator_expression(self): line=1, end_line=2, column=1, end_column=8, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=1, end_line=2, column=1, end_column=8, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_FUNC', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', line=4, end_line=4, column=7, end_column=14, occurrence=1) def test_multiline_async_generator_expression(self): @@ -1777,7 +1777,7 @@ def test_multiline_async_generator_expression(self): self.assertIsInstance(compiled_code, types.CodeType) self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', line=1, end_line=2, column=1, end_column=8, occurrence=2) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_FUNC', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', line=1, end_line=6, column=0, end_column=32, occurrence=1) def test_multiline_list_comprehension(self): @@ -1815,7 +1815,7 @@ async def f(): 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_VALUE_FUNC', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_multiline_set_comprehension(self): @@ -1891,7 +1891,7 @@ async def f(): 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_VALUE_FUNC', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_matchcase_sequence(self): @@ -2204,17 +2204,17 @@ def f(): 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 three `LOAD_CONST None` instructions for the no-exception __exit__ call, + # and one for the RETURN_VALUE. # They should all have the locations of the context manager ('xyz'). load_none = [instr for instr in dis.get_instructions(f) if instr.opname == 'LOAD_CONST' and instr.argval is None] return_value = [instr for instr in dis.get_instructions(f) if - instr.opname == 'RETURN_VALUE'] + instr.opname == 'RETURN_VALUE_FUNC'] - 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 2a964be4e15f49..e8f0ace8804a43 100644 --- a/Lib/test/test_compiler_assemble.py +++ b/Lib/test/test_compiler_assemble.py @@ -125,10 +125,10 @@ def test_exception_table(self): # code for "try: pass\n except: pass" insts = [ ('RESUME', 0), - ('SETUP_FINALLY', 3), + ('SETUP_FINALLY', 4), ('LOAD_CONST', 0), ('RETURN_VALUE_FUNC', None), - ('SETUP_CLEANUP', 8), + ('SETUP_CLEANUP', 10), ('PUSH_EXC_INFO', None), ('POP_TOP', None), ('POP_EXCEPT', None), diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 1ee0fbe98914be..0c85a897a519d5 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -222,11 +222,11 @@ def bug42562(): # 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_FUNC'], 0x00, ]) dis_bug_45757 = """\ diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 035d4418b15c51..4ea43edccda63e 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -388,6 +388,9 @@ def is_specialized(f): 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_monitoring.py b/Lib/test/test_monitoring.py index 1b06816214e7d6..b640aa08e4a812 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1205,6 +1205,7 @@ def func1(): ('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 @@ def func2(): ('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 @@ def func3(): ('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 @@ def func1(): ('instruction', 'func1', 10), ('instruction', 'func1', 12), ('instruction', 'func1', 14), + ('instruction', 'func1', 16), ('line', 'get_events', 11)]) sys.monitoring.restart_events() @@ -1298,6 +1302,7 @@ def func1(): ('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 57d173c20ef06c..4601b26eb479cf 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -162,7 +162,7 @@ def test_folding_of_tuples_of_constants(self): # One LOAD_CONST for the tuple, one for the None return value load_consts = [instr for instr in dis.get_instructions(code) if instr.opname == 'LOAD_CONST'] - self.assertEqual(len(load_consts), 1) + self.assertEqual(len(load_consts), 2) self.check_lnotab(code) # Bug 1053819: Tuple of constants misidentified when presented with: @@ -337,7 +337,7 @@ def f(x): return x self.assertNotInBytecode(f, 'LOAD_CONST', None) returns = [instr for instr in dis.get_instructions(f) - if instr.opname == 'RETURN_VALUE'] + if instr.opname == 'RETURN_VALUE_FUNC'] self.assertEqual(len(returns), 1) self.check_lnotab(f) @@ -351,7 +351,7 @@ def f(cond, true_value, false_value): self.assertNotInBytecode(f, 'JUMP_FORWARD') self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) - if instr.opname == 'RETURN_VALUE'] + if instr.opname == 'RETURN_VALUE_FUNC'] self.assertEqual(len(returns), 2) self.check_lnotab(f) @@ -981,19 +981,19 @@ def test_conditional_jump_forward_non_const_condition(self): ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), ('LOAD_CONST', 2, 13), - ('RETURN_VALUE', None, 13), + ('RETURN_VALUE_FUNC', None, 13), lbl, ('LOAD_CONST', 3, 14), - ('RETURN_VALUE', None, 14), + ('RETURN_VALUE_FUNC', None, 14), ] expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), - ('LOAD_CONST', 2, 13), - ('RETURN_VALUE', None, 13), + ('LOAD_CONST', 1, 13), + ('RETURN_VALUE_FUNC', None, 13), lbl, - ('LOAD_CONST', 2, 13), - ('RETURN_VALUE', None, 13), + ('LOAD_CONST', 2, 14), + ('RETURN_VALUE_FUNC', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1010,13 +1010,13 @@ def test_conditional_jump_forward_const_condition(self): ('LOAD_CONST', 2, 13), lbl, ('LOAD_CONST', 3, 14), - ('RETURN_VALUE', None, 14), + ('RETURN_VALUE_FUNC', None, 14), ] expected_insts = [ ('NOP', None, 11), ('NOP', None, 12), - ('LOAD_CONST', 3, 14), - ('RETURN_VALUE', None, 14), + ('LOAD_CONST', 1, 14), + ('RETURN_VALUE_FUNC', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1061,16 +1061,18 @@ def test_except_handler_label(self): ('SETUP_FINALLY', handler := self.Label(), 10), ('POP_BLOCK', None, -1), ('LOAD_CONST', 1, 11), - ('RETURN_VALUE', None, None), + ('RETURN_VALUE_FUNC', None, 11), handler, ('LOAD_CONST', 2, 12), - ('RETURN_VALUE', None, None), + ('RETURN_VALUE_FUNC', None, 12), ] expected_insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), - ('RETURN_CONST', 1, 11), + ('LOAD_CONST', 1, 11), + ('RETURN_VALUE_FUNC', None, 11), handler, - ('RETURN_CONST', 2, 12), + ('LOAD_CONST', 2, 12), + ('RETURN_VALUE_FUNC', None, 12), ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(5))) @@ -1093,7 +1095,8 @@ def test_no_unsafe_static_swap(self): ('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) @@ -1114,7 +1117,8 @@ def test_dead_store_elimination_in_same_lineno(self): ('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) @@ -1136,7 +1140,8 @@ def test_no_dead_store_elimination_in_different_lineno(self): ('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) From 031f320aa0cad0327ae509ea2d68dea5687f3e5f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Oct 2024 11:28:35 +0100 Subject: [PATCH 04/34] Update optimizer --- Python/optimizer_analysis.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 6a92a0be025295..7ff0c8207e1a68 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -296,7 +296,8 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, } break; } - case _RETURN_VALUE: + case _RETURN_VALUE_FUNC: + case _RETURN_VALUE_GEN: { builtins_watched >>= 1; globals_watched >>= 1; From cb5252ba0e388038c507ed7258ec7e8cecb8def8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Oct 2024 15:00:42 +0100 Subject: [PATCH 05/34] Fix up test_dis --- Lib/test/test_dis.py | 426 +++++++++++++++++++++++-------------------- 1 file changed, 230 insertions(+), 196 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 0c85a897a519d5..3a28d97a007441 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -52,7 +52,8 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ @@ -62,7 +63,8 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 - RETURN_CONST 0 + LOAD_CONST 0 + RETURN_VALUE_FUNC """ dis_c_class_method = """\ @@ -73,7 +75,8 @@ def cm(cls, x): COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ @@ -83,7 +86,8 @@ def cm(cls, x): LOAD_CONST 1 (1) COMPARE_OP 72 (==) STORE_FAST 0 (x) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -110,7 +114,8 @@ def _f(a): CALL 1 POP_TOP -%3d RETURN_CONST 1 (1) +%3d LOAD_CONST 1 (1) + RETURN_VALUE_FUNC """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -123,7 +128,8 @@ def _f(a): 14 CALL 1 22 POP_TOP -%3d 24 RETURN_CONST 1 (1) +%3d 24 LOAD_CONST 1 (1) + 26 RETURN_VALUE_FUNC """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -136,7 +142,8 @@ def _f(a): %-14s CALL 1 %-14s POP_TOP -%-14s RETURN_CONST 1 (1) +%-14s LOAD_CONST 1 (1) +%-14s RETURN_VALUE_FUNC """ dis_f_co_code = """\ @@ -145,7 +152,8 @@ def _f(a): LOAD_FAST 0 CALL 1 POP_TOP - RETURN_CONST 1 + LOAD_CONST 1 + RETURN_VALUE_FUNC """ def bug708901(): @@ -170,7 +178,8 @@ def bug708901(): %3d L2: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -217,7 +226,8 @@ def bug42562(): dis_bug42562 = """\ RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ # Extended arg followed by NOP @@ -234,7 +244,7 @@ def bug42562(): NOP EXTENDED_ARG 1 LOAD_CONST 297 - RETURN_VALUE + RETURN_VALUE_FUNC """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -269,7 +279,8 @@ def wrap_func_w_kwargs(): LOAD_CONST 4 (('c',)) CALL_KW 3 POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) @@ -281,7 +292,8 @@ def wrap_func_w_kwargs(): IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP - RETURN_CONST 2 (None) + LOAD_CONST 2 (None) + RETURN_VALUE_FUNC """ dis_intrinsic_1_5 = """\ @@ -289,7 +301,7 @@ def wrap_func_w_kwargs(): 1 LOAD_NAME 0 (a) CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + RETURN_VALUE_FUNC """ dis_intrinsic_1_6 = """\ @@ -299,7 +311,7 @@ def wrap_func_w_kwargs(): LOAD_NAME 0 (a) LIST_EXTEND 1 CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + RETURN_VALUE_FUNC """ _BIG_LINENO_FORMAT = """\ @@ -307,7 +319,8 @@ def wrap_func_w_kwargs(): %3d LOAD_GLOBAL 0 (spam) POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ _BIG_LINENO_FORMAT2 = """\ @@ -315,17 +328,20 @@ def wrap_func_w_kwargs(): %4d LOAD_GLOBAL 0 (spam) POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ dis_module_expected_results = """\ Disassembly of f: 4 RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC Disassembly of g: 5 RESUME 0 - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """ @@ -337,7 +353,7 @@ def wrap_func_w_kwargs(): 1 LOAD_NAME 0 (x) LOAD_CONST 0 (1) BINARY_OP 0 (+) - RETURN_VALUE + RETURN_VALUE_FUNC """ simple_stmt_str = "x = x + 1" @@ -349,7 +365,8 @@ def wrap_func_w_kwargs(): LOAD_CONST 0 (1) BINARY_OP 0 (+) STORE_NAME 0 (x) - RETURN_CONST 1 (None) + LOAD_CONST 1 (None) + RETURN_VALUE_FUNC """ annot_stmt_str = """\ @@ -377,7 +394,8 @@ def wrap_func_w_kwargs(): 2 LOAD_CONST 2 (", line 2>) MAKE_FUNCTION STORE_NAME 3 (__annotate__) - RETURN_CONST 3 (None) + LOAD_CONST 3 (None) + RETURN_VALUE_FUNC """ fn_with_annotate_str = """ @@ -394,7 +412,8 @@ def foo(a: int, b: str) -> str: MAKE_FUNCTION SET_FUNCTION_ATTRIBUTE 16 (annotate) STORE_NAME 0 (foo) - RETURN_CONST 2 (None) + LOAD_CONST 2 (None) + RETURN_VALUE_FUNC """ compound_stmt_str = """\ @@ -429,7 +448,7 @@ def foo(a: int, b: str) -> str: POP_TOP %4d L2: LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE + RETURN_VALUE_FUNC -- L3: PUSH_EXC_INFO @@ -447,7 +466,7 @@ def foo(a: int, b: str) -> str: DELETE_FAST 0 (e) %4d LOAD_FAST 1 (tb) - RETURN_VALUE + RETURN_VALUE_FUNC -- L6: LOAD_CONST 0 (None) STORE_FAST 0 (e) @@ -495,7 +514,7 @@ def _fstring(a, b, c, d): LOAD_CONST 2 ('4') FORMAT_WITH_SPEC BUILD_STRING 7 - RETURN_VALUE + RETURN_VALUE_FUNC """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -526,7 +545,8 @@ def _with(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC %4d L3: PUSH_EXC_INFO WITH_EXCEPT_START @@ -541,7 +561,8 @@ def _with(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC -- L6: COPY 3 POP_EXCEPT @@ -602,12 +623,13 @@ async def _asyncwith(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_GEN %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 @@ -629,7 +651,8 @@ async def _asyncwith(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_GEN -- L24: COPY 3 POP_EXCEPT @@ -682,7 +705,7 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - RETURN_VALUE + RETURN_VALUE_FUNC -- L3: PUSH_EXC_INFO @@ -716,7 +739,8 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - RETURN_CONST 1 (1) + LOAD_CONST 1 (1) + RETURN_VALUE_FUNC -- L1: PUSH_EXC_INFO @@ -767,7 +791,7 @@ def foo(x): STORE_FAST 1 (foo) %4d LOAD_FAST 1 (foo) - RETURN_VALUE + RETURN_VALUE_FUNC """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -792,7 +816,7 @@ def foo(x): GET_ITER CALL 0 CALL 1 - RETURN_VALUE + RETURN_VALUE_FUNC """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -821,7 +845,8 @@ def foo(x): JUMP_BACKWARD 12 (to L2) L3: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_GEN -- L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 @@ -845,7 +870,7 @@ def load_test(x, y=0): %3d LOAD_FAST_LOAD_FAST 35 (a, b) BUILD_TUPLE 2 - RETURN_VALUE + RETURN_VALUE_FUNC """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -860,7 +885,7 @@ def loop_test(): %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) LIST_EXTEND 1 - LOAD_CONST 2 (3) + LOAD_CONST_IMMORTAL 2 (3) BINARY_OP 5 (*) GET_ITER L1: FOR_ITER_LIST 14 (to L2) @@ -874,7 +899,8 @@ def loop_test(): %3d L2: END_FOR POP_TOP - RETURN_CONST 0 (None) + LOAD_CONST_IMMORTAL 0 (None) + RETURN_VALUE_FUNC """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -891,7 +917,8 @@ def extended_arg_quick(): UNPACK_EX 256 POP_TOP STORE_FAST 0 (_) - RETURN_CONST 0 (None) + LOAD_CONST 0 (None) + RETURN_VALUE_FUNC """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -1004,7 +1031,8 @@ def test_dis_with_some_positions(self): '', '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_FUNC', '', ' -- L1: PUSH_EXC_INFO', '', @@ -1034,7 +1062,8 @@ def test_dis_with_linenos_but_no_columns(self): '', '2:5-2:6 LOAD_CONST 1 (1)', '2:?-2:? STORE_FAST 0 (x)', - '2:?-2:? RETURN_CONST 0 (None)', + '2:?-2:? LOAD_CONST 0 (None)', + '2:?-2:? RETURN_VALUE_FUNC', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1046,7 +1075,8 @@ def f(): f.__code__ = f.__code__.replace(co_linetable=b'') expect = '\n'.join([ ' RESUME 0', - ' RETURN_CONST 0 (None)', + ' LOAD_CONST 0 (None)', + ' RETURN_VALUE_FUNC', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1238,7 +1268,7 @@ def test_binary_specialize(self): 1 LOAD_NAME 0 (a) LOAD_NAME 1 (b) %s - RETURN_VALUE + RETURN_VALUE_FUNC """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) @@ -1254,9 +1284,9 @@ def test_binary_specialize(self): 0 RESUME_CHECK 0 1 LOAD_NAME 0 (a) - LOAD_CONST 0 (0) + LOAD_CONST_IMMORTAL 0 (0) %s - RETURN_VALUE + RETURN_VALUE_FUNC """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -1274,9 +1304,9 @@ def test_load_attr_specialize(self): 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 + RETURN_VALUE_FUNC """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1291,9 +1321,9 @@ def test_call_specialize(self): 1 LOAD_NAME 0 (str) PUSH_NULL - LOAD_CONST 0 (1) + LOAD_CONST_IMMORTAL 0 (1) CALL_STR_1 1 - RETURN_VALUE + RETURN_VALUE_FUNC """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1706,201 +1736,204 @@ 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_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), - Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, 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_FAST', opcode=82, 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=82, 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=49, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=107, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, 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_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='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='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='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, 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_DEREF', opcode=81, 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=81, 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=80, 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=80, 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='BUILD_LIST', opcode=44, 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=45, 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=80, 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='CALL', opcode=50, 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), - Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), ] 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='COPY_FREE_VARS', opcode=59, 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=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), - Instruction(opname='LOAD_FAST', opcode=81, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=81, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='BUILD_TUPLE', opcode=48, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, 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=82, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=82, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=82, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='BUILD_TUPLE', opcode=49, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, 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='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=107, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, 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_DEREF', opcode=80, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=49, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, 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_DEREF', opcode=81, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=50, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, 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=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=81, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), - Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None), ] expected_opinfo_inner = [ - Instruction(opname='COPY_FREE_VARS', opcode=58, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='COPY_FREE_VARS', opcode=59, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, 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_DEREF', opcode=80, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=80, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - 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='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, 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_DEREF', opcode=81, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=81, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=85, 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=50, 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=80, 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_FUNC', 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='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='LOAD_GLOBAL', opcode=88, 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=80, 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='CALL', opcode=50, 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')]), + Instruction(opname='FOR_ITER', opcode=68, 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')]), Instruction(opname='STORE_FAST', opcode=107, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, 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=30, start_offset=30, starts_line=True, line_number=4, 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=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - 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='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, 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=82, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=50, 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='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='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='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='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='LOAD_FAST', opcode=82, 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=80, 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='COMPARE_OP', opcode=55, 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=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=73, 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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=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=73, 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='JUMP_FORWARD', opcode=75, 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='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='LOAD_GLOBAL', opcode=88, 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=80, 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='CALL', opcode=50, 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='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='LOAD_FAST_CHECK', opcode=84, 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=38, 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=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=88, 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=82, 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=50, 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='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='LOAD_FAST', opcode=82, 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=80, 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='BINARY_OP', opcode=43, 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='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='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='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='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='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='LOAD_FAST', opcode=82, 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=80, 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='COMPARE_OP', opcode=55, 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=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=73, 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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=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=73, 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=75, 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=88, 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=80, 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='CALL', opcode=50, 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='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='LOAD_CONST', opcode=80, 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=80, 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='BINARY_OP', opcode=43, 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_FAST', opcode=82, 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=58, 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=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='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='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=50, 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='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='LOAD_GLOBAL', opcode=88, 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=80, 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='CALL', opcode=50, 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), - Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=274, start_offset=274, 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=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - 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='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=50, 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='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='LOAD_GLOBAL', opcode=88, 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=80, 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='CALL', opcode=50, 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=80, 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_FUNC', 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=42, 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=38, 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=74, 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=58, 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=88, 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=88, 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=80, arg=9, 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=50, 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=74, 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=58, 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=88, 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=80, arg=10, 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=50, 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=58, 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=80, 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_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=4, start_offset=4, starts_line=False, line_number=simple.__code__.co_firstlineno, label=None), ] @@ -1967,6 +2000,7 @@ def test_co_positions(self): (2, 2, 8, 9), (1, 3, 0, 1), (1, 3, 0, 1), + (1, 3, 0, 1), (1, 3, 0, 1) ] self.assertEqual(positions, expected) From 892edbcf4be510aa2bf6022a1f2bd44087dfb50a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Oct 2024 15:13:48 +0100 Subject: [PATCH 06/34] Fix up a couple of comments --- Python/flowgraph.c | 1 + Python/specialize.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 1dda73daeda940..11cea34a5ef6ad 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -2592,6 +2592,7 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, RETURN_IF_ERROR(push_cold_blocks_to_end(g)); 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/specialize.c b/Python/specialize.c index 90d5817cf865e8..52f3040855939f 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -468,7 +468,7 @@ _PyCode_Quicken(PyCodeObject *code) } else if (opcode == LOAD_CONST) { /* We can't do this in the bytecode compiler as - * can intern strings and make them immortal. */ + * marhsalling can intern strings and make them immortal. */ oparg = (oparg << 8) | instructions[i].op.arg; PyObject *obj = PyTuple_GET_ITEM(code->co_consts, oparg); if (_Py_IsImmortal(obj)) { From 5ce99ca91ddad7fd12a379a1c2ccafd13063068d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 09:34:28 +0100 Subject: [PATCH 07/34] Apply suggestions from code review Co-authored-by: Tomas R. --- Include/internal/pycore_magic_number.h | 2 +- Python/specialize.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index aae91bd65823f2..8a695d98d64b68 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -261,7 +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.14a1 3609 (Break up RETURN_VALUE) + Python 3.14a2 3609 (Break up RETURN_VALUE) Python 3.15 will start with 3650 diff --git a/Python/specialize.c b/Python/specialize.c index 52f3040855939f..3abba25b751486 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -468,7 +468,7 @@ _PyCode_Quicken(PyCodeObject *code) } else if (opcode == LOAD_CONST) { /* We can't do this in the bytecode compiler as - * marhsalling can intern strings and make them immortal. */ + * marshalling can intern strings and make them immortal. */ oparg = (oparg << 8) | instructions[i].op.arg; PyObject *obj = PyTuple_GET_ITEM(code->co_consts, oparg); if (_Py_IsImmortal(obj)) { From 325c5fe5637dd1c091610572871360548d925946 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 09:36:28 +0100 Subject: [PATCH 08/34] Clarify comment --- Lib/test/test_compile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index a45ff0c62d7d9a..0830a9800c2696 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -2204,8 +2204,8 @@ def f(): start_line, end_line, _, _ = instr.positions self.assertEqual(start_line, end_line) - # Expect three `LOAD_CONST None` instructions for the no-exception __exit__ call, - # and one for the 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 From 61491539b472d5080682cd1d21ef09e17aaf7367 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 10:06:54 +0100 Subject: [PATCH 09/34] Remove unused function --- Python/flowgraph.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 11cea34a5ef6ad..646560ae662582 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -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) *****/ From 59a554a253cac7f5eb906b6397a886b98f4a7e24 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 10:11:15 +0100 Subject: [PATCH 10/34] Update test --- Lib/test/test_capi/test_opt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index f1ab72180d714d..22ee904cfc5b79 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1025,7 +1025,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 2) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 2) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # sequential calls: max(12, 13) == 13 @@ -1052,7 +1052,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 2) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 2) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # nested calls: 15 + 12 == 27 @@ -1087,7 +1087,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 4) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 4) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 4) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # max(12, 18 + max(12, 13)) == 31 @@ -1123,7 +1123,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 4) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 4) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 4) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # max(18 + max(12, 13), 12) == 31 @@ -1167,7 +1167,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 15) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 15) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 15) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) @@ -1261,7 +1261,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE"), 0) + self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 1) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) largest_stack = _testinternalcapi.get_co_framesize(dummy15.__code__) From bcb4e6525698c43ec9c99f1ee32f1e66cd1cde90 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 11:00:40 +0100 Subject: [PATCH 11/34] Update dis docs --- Doc/library/dis.rst | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a2e44e09ffc925..0006fb19420a0e 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -76,7 +76,7 @@ the following command can be used to display the disassembly of 3 LOAD_GLOBAL 1 (len + NULL) LOAD_FAST 0 (alist) CALL 1 - RETURN_VALUE + RETURN_VALUE_FUNC (The "2" is a line number). @@ -203,7 +203,7 @@ Example: LOAD_GLOBAL LOAD_FAST CALL - RETURN_VALUE + RETURN_VALUE_FUNC Analysis functions @@ -857,16 +857,20 @@ container object remains on the stack so that it is available for further iterations of the loop. -.. opcode:: RETURN_VALUE +.. opcode:: RETURN_VALUE_FUNC Returns with ``STACK[-1]`` to the caller of the function. + Used in normal functions. + .. versionadded:: 3.14 -.. opcode:: RETURN_CONST (consti) - Returns with ``co_consts[consti]`` to the caller of the function. +.. opcode:: RETURN_VALUE_GEN - .. versionadded:: 3.12 + Returns with ``STACK[-1]`` to the caller of the generator. + Used in generator functions. + + .. versionadded:: 3.14 .. opcode:: YIELD_VALUE @@ -1086,6 +1090,14 @@ iterations of the loop. Pushes ``co_consts[consti]`` onto the stack. +.. 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. From f3383e57af32e9d7789e837581269885ba6b8666 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 11:53:10 +0100 Subject: [PATCH 12/34] Remove link to remove instruction --- Doc/whatsnew/3.12.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 463fc269ee8fcc..1354355894e375 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 =============== From 68e97baeecf1b35633dc9c4b6e1db5fcf84a82a9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 09:48:46 +0100 Subject: [PATCH 13/34] Restore RETURN_VALUE --- Include/internal/pycore_opcode_metadata.h | 57 ++---- Include/internal/pycore_opcode_utils.h | 2 - Include/internal/pycore_uop_ids.h | 3 +- Include/internal/pycore_uop_metadata.h | 10 +- Include/opcode_ids.h | 207 +++++++++++----------- Lib/_opcode_metadata.py | 207 +++++++++++----------- Lib/test/test__opcode.py | 2 +- Lib/test/test_capi/test_opt.py | 12 +- Lib/test/test_compile.py | 20 +-- Lib/test/test_compiler_assemble.py | 4 +- Lib/test/test_dis.py | 102 +++++------ Lib/test/test_peepholer.py | 24 +-- Objects/frameobject.c | 3 +- Programs/test_frozenmain.h | 22 +-- Python/bytecodes.c | 38 +--- Python/executor_cases.c.h | 33 +--- Python/flowgraph.c | 5 +- Python/generated_cases.c.h | 93 +--------- Python/instrumentation.c | 15 +- Python/opcode_targets.h | 8 +- Python/optimizer.c | 4 +- Python/optimizer_analysis.c | 6 +- Python/optimizer_bytecodes.c | 25 +-- Python/optimizer_cases.c.h | 30 +--- Python/specialize.c | 2 +- 25 files changed, 350 insertions(+), 584 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 7ecb511673fe4e..eb325e2ba1498a 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -24,7 +24,6 @@ extern "C" { ((OP) == JUMP_NO_INTERRUPT) || \ ((OP) == JUMP_IF_FALSE) || \ ((OP) == JUMP_IF_TRUE) || \ - ((OP) == RETURN_VALUE) || \ ((OP) == SETUP_FINALLY) || \ ((OP) == SETUP_CLEANUP) || \ ((OP) == SETUP_WITH) || \ @@ -254,9 +253,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case INSTRUMENTED_RESUME: return 0; - case INSTRUMENTED_RETURN_VALUE_FUNC: - return 1; - case INSTRUMENTED_RETURN_VALUE_GEN: + case INSTRUMENTED_RETURN_VALUE: return 1; case INSTRUMENTED_YIELD_VALUE: return 1; @@ -399,10 +396,6 @@ int _PyOpcode_num_popped(int opcode, int oparg) { case RETURN_GENERATOR: return 0; case RETURN_VALUE: - return 0; - case RETURN_VALUE_FUNC: - return 1; - case RETURN_VALUE_GEN: return 1; case SEND: return 2; @@ -717,9 +710,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case INSTRUMENTED_RESUME: return 0; - case INSTRUMENTED_RETURN_VALUE_FUNC: - return 1; - case INSTRUMENTED_RETURN_VALUE_GEN: + case INSTRUMENTED_RETURN_VALUE: return 1; case INSTRUMENTED_YIELD_VALUE: return 1; @@ -862,10 +853,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { case RETURN_GENERATOR: return 1; case RETURN_VALUE: - return 0; - case RETURN_VALUE_FUNC: - return 1; - case RETURN_VALUE_GEN: return 1; case SEND: return 2; @@ -971,7 +958,7 @@ enum InstructionFormat { }; #define IS_VALID_OPCODE(OP) \ - (((OP) >= 0) && ((OP) < 267) && \ + (((OP) >= 0) && ((OP) < 266) && \ (_PyOpcode_opcode_metadata[(OP)].valid_entry)) #define HAS_ARG_FLAG (1) @@ -1020,9 +1007,9 @@ struct opcode_metadata { int16_t flags; }; -extern const struct opcode_metadata _PyOpcode_opcode_metadata[267]; +extern const struct opcode_metadata _PyOpcode_opcode_metadata[266]; #ifdef NEED_OPCODE_METADATA -const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { +const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG }, @@ -1132,8 +1119,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [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_VALUE_FUNC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [INSTRUMENTED_RETURN_VALUE_GEN] = { true, INSTR_FMT_IX, 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 }, [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, @@ -1198,8 +1184,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [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_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [RETURN_VALUE_FUNC] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, - [RETURN_VALUE_GEN] = { true, INSTR_FMT_IX, 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 }, [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1244,7 +1229,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [POP_BLOCK] = { true, -1, HAS_PURE_FLAG }, - [RETURN_VALUE] = { true, -1, HAS_ESCAPES_FLAG }, [SETUP_CLEANUP] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, [SETUP_FINALLY] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, [SETUP_WITH] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG }, @@ -1399,8 +1383,7 @@ _PyOpcode_macro_expansion[256] = { [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } }, [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } }, [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, 0, 0 } } }, - [RETURN_VALUE_FUNC] = { .nuops = 1, .uops = { { _RETURN_VALUE_FUNC, 0, 0 } } }, - [RETURN_VALUE_GEN] = { .nuops = 1, .uops = { { _RETURN_VALUE_GEN, 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 } } }, [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } }, [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } }, @@ -1441,9 +1424,9 @@ _PyOpcode_macro_expansion[256] = { }; #endif // NEED_OPCODE_METADATA -extern const char *_PyOpcode_OpName[267]; +extern const char *_PyOpcode_OpName[266]; #ifdef NEED_OPCODE_METADATA -const char *_PyOpcode_OpName[267] = { +const char *_PyOpcode_OpName[266] = { [BINARY_OP] = "BINARY_OP", [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", @@ -1553,8 +1536,7 @@ const char *_PyOpcode_OpName[267] = { [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_VALUE_FUNC] = "INSTRUMENTED_RETURN_VALUE_FUNC", - [INSTRUMENTED_RETURN_VALUE_GEN] = "INSTRUMENTED_RETURN_VALUE_GEN", + [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE", [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", [INTERPRETER_EXIT] = "INTERPRETER_EXIT", [IS_OP] = "IS_OP", @@ -1626,8 +1608,6 @@ const char *_PyOpcode_OpName[267] = { [RESUME_CHECK] = "RESUME_CHECK", [RETURN_GENERATOR] = "RETURN_GENERATOR", [RETURN_VALUE] = "RETURN_VALUE", - [RETURN_VALUE_FUNC] = "RETURN_VALUE_FUNC", - [RETURN_VALUE_GEN] = "RETURN_VALUE_GEN", [SEND] = "SEND", [SEND_GEN] = "SEND_GEN", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", @@ -1811,8 +1791,7 @@ 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_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, - [INSTRUMENTED_RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, + [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, [INTERPRETER_EXIT] = INTERPRETER_EXIT, [IS_OP] = IS_OP, @@ -1877,8 +1856,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [RESUME] = RESUME, [RESUME_CHECK] = RESUME, [RETURN_GENERATOR] = RETURN_GENERATOR, - [RETURN_VALUE_FUNC] = RETURN_VALUE_FUNC, - [RETURN_VALUE_GEN] = RETURN_VALUE_GEN, + [RETURN_VALUE] = RETURN_VALUE, [SEND] = SEND, [SEND_GEN] = SEND, [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, @@ -1922,6 +1900,7 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_METADATA #define EXTRA_CASES \ + case 115: \ case 116: \ case 117: \ case 118: \ @@ -1963,21 +1942,21 @@ const uint8_t _PyOpcode_Deopt[256] = { case 233: \ case 234: \ case 235: \ + case 236: \ ; struct pseudo_targets { uint8_t as_sequence; uint8_t targets[4]; }; -extern const struct pseudo_targets _PyOpcode_PseudoTargets[11]; +extern const struct pseudo_targets _PyOpcode_PseudoTargets[10]; #ifdef NEED_OPCODE_METADATA -const struct pseudo_targets _PyOpcode_PseudoTargets[11] = { +const struct pseudo_targets _PyOpcode_PseudoTargets[10] = { [LOAD_CLOSURE-256] = { 0, { LOAD_FAST, 0, 0, 0 } }, [STORE_FAST_MAYBE_NULL-256] = { 0, { STORE_FAST, 0, 0, 0 } }, [JUMP-256] = { 0, { JUMP_FORWARD, JUMP_BACKWARD, 0, 0 } }, [JUMP_NO_INTERRUPT-256] = { 0, { JUMP_FORWARD, JUMP_BACKWARD_NO_INTERRUPT, 0, 0 } }, [JUMP_IF_FALSE-256] = { 1, { COPY, TO_BOOL, POP_JUMP_IF_FALSE, 0 } }, [JUMP_IF_TRUE-256] = { 1, { COPY, TO_BOOL, POP_JUMP_IF_TRUE, 0 } }, - [RETURN_VALUE-256] = { 0, { RETURN_VALUE_FUNC, RETURN_VALUE_GEN, 0, 0 } }, [SETUP_FINALLY-256] = { 0, { NOP, 0, 0, 0 } }, [SETUP_CLEANUP-256] = { 0, { NOP, 0, 0, 0 } }, [SETUP_WITH-256] = { 0, { NOP, 0, 0, 0 } }, @@ -1987,7 +1966,7 @@ const struct pseudo_targets _PyOpcode_PseudoTargets[11] = { #endif // NEED_OPCODE_METADATA static inline bool is_pseudo_target(int pseudo, int target) { - if (pseudo < 256 || pseudo >= 267) { + if (pseudo < 256 || pseudo >= 266) { return false; } for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) { diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index 24195825260018..c6ce7e65a65d4b 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -47,8 +47,6 @@ extern "C" { #define IS_SCOPE_EXIT_OPCODE(opcode) \ ((opcode) == RETURN_VALUE || \ - (opcode) == RETURN_VALUE_FUNC || \ - (opcode) == RETURN_VALUE_GEN || \ (opcode) == RAISE_VARARGS || \ (opcode) == RERAISE) diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 034f23c4c4bbc4..5c8fba72fb99f9 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -254,8 +254,7 @@ extern "C" { #define _REPLACE_WITH_TRUE 457 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE_FUNC RETURN_VALUE_FUNC -#define _RETURN_VALUE_GEN RETURN_VALUE_GEN +#define _RETURN_VALUE RETURN_VALUE #define _SAVE_RETURN_OFFSET 458 #define _SEND 459 #define _SEND_GEN_FRAME 460 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 5f1b3e961c34c0..9af1e8e937e2d7 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -93,8 +93,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, - [_RETURN_VALUE_FUNC] = HAS_ESCAPES_FLAG, - [_RETURN_VALUE_GEN] = HAS_ESCAPES_FLAG, + [_RETURN_VALUE] = 0, [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, @@ -514,8 +513,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE", [_RESUME_CHECK] = "_RESUME_CHECK", [_RETURN_GENERATOR] = "_RETURN_GENERATOR", - [_RETURN_VALUE_FUNC] = "_RETURN_VALUE_FUNC", - [_RETURN_VALUE_GEN] = "_RETURN_VALUE_GEN", + [_RETURN_VALUE] = "_RETURN_VALUE", [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET", [_SEND_GEN_FRAME] = "_SEND_GEN_FRAME", [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS", @@ -716,9 +714,7 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _CALL_INTRINSIC_2: return 2; - case _RETURN_VALUE_FUNC: - return 1; - case _RETURN_VALUE_GEN: + case _RETURN_VALUE: return 1; case _GET_AITER: return 1; diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 48ead22391f964..8250f3f496c8f5 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -43,89 +43,88 @@ extern "C" { #define PUSH_EXC_INFO 30 #define PUSH_NULL 31 #define RETURN_GENERATOR 32 -#define RETURN_VALUE_FUNC 33 -#define RETURN_VALUE_GEN 34 -#define SETUP_ANNOTATIONS 35 -#define STORE_SLICE 36 -#define STORE_SUBSCR 37 -#define TO_BOOL 38 -#define UNARY_INVERT 39 -#define UNARY_NEGATIVE 40 -#define UNARY_NOT 41 -#define WITH_EXCEPT_START 42 -#define BINARY_OP 43 -#define BUILD_LIST 44 -#define BUILD_MAP 45 -#define BUILD_SET 46 -#define BUILD_SLICE 47 -#define BUILD_STRING 48 -#define BUILD_TUPLE 49 -#define CALL 50 -#define CALL_FUNCTION_EX 51 -#define CALL_INTRINSIC_1 52 -#define CALL_INTRINSIC_2 53 -#define CALL_KW 54 -#define COMPARE_OP 55 -#define CONTAINS_OP 56 -#define CONVERT_VALUE 57 -#define COPY 58 -#define COPY_FREE_VARS 59 -#define DELETE_ATTR 60 -#define DELETE_DEREF 61 -#define DELETE_FAST 62 -#define DELETE_GLOBAL 63 -#define DELETE_NAME 64 -#define DICT_MERGE 65 -#define DICT_UPDATE 66 -#define EXTENDED_ARG 67 -#define FOR_ITER 68 -#define GET_AWAITABLE 69 -#define IMPORT_FROM 70 -#define IMPORT_NAME 71 -#define IS_OP 72 -#define JUMP_BACKWARD 73 -#define JUMP_BACKWARD_NO_INTERRUPT 74 -#define JUMP_FORWARD 75 -#define LIST_APPEND 76 -#define LIST_EXTEND 77 -#define LOAD_ATTR 78 -#define LOAD_COMMON_CONSTANT 79 -#define LOAD_CONST 80 -#define LOAD_DEREF 81 -#define LOAD_FAST 82 -#define LOAD_FAST_AND_CLEAR 83 -#define LOAD_FAST_CHECK 84 -#define LOAD_FAST_LOAD_FAST 85 -#define LOAD_FROM_DICT_OR_DEREF 86 -#define LOAD_FROM_DICT_OR_GLOBALS 87 -#define LOAD_GLOBAL 88 -#define LOAD_NAME 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 -#define SET_UPDATE 104 -#define STORE_ATTR 105 -#define STORE_DEREF 106 -#define STORE_FAST 107 -#define STORE_FAST_LOAD_FAST 108 -#define STORE_FAST_STORE_FAST 109 -#define STORE_GLOBAL 110 -#define STORE_NAME 111 -#define SWAP 112 -#define UNPACK_EX 113 -#define UNPACK_SEQUENCE 114 -#define YIELD_VALUE 115 +#define RETURN_VALUE 33 +#define SETUP_ANNOTATIONS 34 +#define STORE_SLICE 35 +#define STORE_SUBSCR 36 +#define TO_BOOL 37 +#define UNARY_INVERT 38 +#define UNARY_NEGATIVE 39 +#define UNARY_NOT 40 +#define WITH_EXCEPT_START 41 +#define BINARY_OP 42 +#define BUILD_LIST 43 +#define BUILD_MAP 44 +#define BUILD_SET 45 +#define BUILD_SLICE 46 +#define BUILD_STRING 47 +#define BUILD_TUPLE 48 +#define CALL 49 +#define CALL_FUNCTION_EX 50 +#define CALL_INTRINSIC_1 51 +#define CALL_INTRINSIC_2 52 +#define CALL_KW 53 +#define COMPARE_OP 54 +#define CONTAINS_OP 55 +#define CONVERT_VALUE 56 +#define COPY 57 +#define COPY_FREE_VARS 58 +#define DELETE_ATTR 59 +#define DELETE_DEREF 60 +#define DELETE_FAST 61 +#define DELETE_GLOBAL 62 +#define DELETE_NAME 63 +#define DICT_MERGE 64 +#define DICT_UPDATE 65 +#define EXTENDED_ARG 66 +#define FOR_ITER 67 +#define GET_AWAITABLE 68 +#define IMPORT_FROM 69 +#define IMPORT_NAME 70 +#define IS_OP 71 +#define JUMP_BACKWARD 72 +#define JUMP_BACKWARD_NO_INTERRUPT 73 +#define JUMP_FORWARD 74 +#define LIST_APPEND 75 +#define LIST_EXTEND 76 +#define LOAD_ATTR 77 +#define LOAD_COMMON_CONSTANT 78 +#define LOAD_CONST 79 +#define LOAD_DEREF 80 +#define LOAD_FAST 81 +#define LOAD_FAST_AND_CLEAR 82 +#define LOAD_FAST_CHECK 83 +#define LOAD_FAST_LOAD_FAST 84 +#define LOAD_FROM_DICT_OR_DEREF 85 +#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 SEND 100 +#define SET_ADD 101 +#define SET_FUNCTION_ATTRIBUTE 102 +#define SET_UPDATE 103 +#define STORE_ATTR 104 +#define STORE_DEREF 105 +#define STORE_FAST 106 +#define STORE_FAST_LOAD_FAST 107 +#define STORE_FAST_STORE_FAST 108 +#define STORE_GLOBAL 109 +#define STORE_NAME 110 +#define SWAP 111 +#define UNPACK_EX 112 +#define UNPACK_SEQUENCE 113 +#define YIELD_VALUE 114 #define RESUME 149 #define BINARY_OP_ADD_FLOAT 150 #define BINARY_OP_ADD_INT 151 @@ -205,21 +204,20 @@ extern "C" { #define UNPACK_SEQUENCE_LIST 225 #define UNPACK_SEQUENCE_TUPLE 226 #define UNPACK_SEQUENCE_TWO_TUPLE 227 -#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_FUNC 249 -#define INSTRUMENTED_RETURN_VALUE_GEN 250 +#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 @@ -231,15 +229,14 @@ extern "C" { #define JUMP_NO_INTERRUPT 259 #define LOAD_CLOSURE 260 #define POP_BLOCK 261 -#define RETURN_VALUE 262 -#define SETUP_CLEANUP 263 -#define SETUP_FINALLY 264 -#define SETUP_WITH 265 -#define STORE_FAST_MAYBE_NULL 266 +#define SETUP_CLEANUP 262 +#define SETUP_FINALLY 263 +#define SETUP_WITH 264 +#define STORE_FAST_MAYBE_NULL 265 -#define HAVE_ARGUMENT 42 +#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 8f41c20aee31b9..3754171dcb18fa 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -236,104 +236,102 @@ 'PUSH_EXC_INFO': 30, 'PUSH_NULL': 31, 'RETURN_GENERATOR': 32, - 'RETURN_VALUE_FUNC': 33, - 'RETURN_VALUE_GEN': 34, - 'SETUP_ANNOTATIONS': 35, - 'STORE_SLICE': 36, - 'STORE_SUBSCR': 37, - 'TO_BOOL': 38, - 'UNARY_INVERT': 39, - 'UNARY_NEGATIVE': 40, - 'UNARY_NOT': 41, - 'WITH_EXCEPT_START': 42, - 'BINARY_OP': 43, - 'BUILD_LIST': 44, - 'BUILD_MAP': 45, - 'BUILD_SET': 46, - 'BUILD_SLICE': 47, - 'BUILD_STRING': 48, - 'BUILD_TUPLE': 49, - 'CALL': 50, - 'CALL_FUNCTION_EX': 51, - 'CALL_INTRINSIC_1': 52, - 'CALL_INTRINSIC_2': 53, - 'CALL_KW': 54, - 'COMPARE_OP': 55, - 'CONTAINS_OP': 56, - 'CONVERT_VALUE': 57, - 'COPY': 58, - 'COPY_FREE_VARS': 59, - 'DELETE_ATTR': 60, - 'DELETE_DEREF': 61, - 'DELETE_FAST': 62, - 'DELETE_GLOBAL': 63, - 'DELETE_NAME': 64, - 'DICT_MERGE': 65, - 'DICT_UPDATE': 66, - 'EXTENDED_ARG': 67, - 'FOR_ITER': 68, - 'GET_AWAITABLE': 69, - 'IMPORT_FROM': 70, - 'IMPORT_NAME': 71, - 'IS_OP': 72, - 'JUMP_BACKWARD': 73, - 'JUMP_BACKWARD_NO_INTERRUPT': 74, - 'JUMP_FORWARD': 75, - 'LIST_APPEND': 76, - 'LIST_EXTEND': 77, - 'LOAD_ATTR': 78, - 'LOAD_COMMON_CONSTANT': 79, - 'LOAD_CONST': 80, - 'LOAD_DEREF': 81, - 'LOAD_FAST': 82, - 'LOAD_FAST_AND_CLEAR': 83, - 'LOAD_FAST_CHECK': 84, - 'LOAD_FAST_LOAD_FAST': 85, - 'LOAD_FROM_DICT_OR_DEREF': 86, - 'LOAD_FROM_DICT_OR_GLOBALS': 87, - 'LOAD_GLOBAL': 88, - 'LOAD_NAME': 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, - 'SET_UPDATE': 104, - 'STORE_ATTR': 105, - 'STORE_DEREF': 106, - 'STORE_FAST': 107, - 'STORE_FAST_LOAD_FAST': 108, - 'STORE_FAST_STORE_FAST': 109, - 'STORE_GLOBAL': 110, - 'STORE_NAME': 111, - 'SWAP': 112, - '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_FUNC': 249, - 'INSTRUMENTED_RETURN_VALUE_GEN': 250, + 'RETURN_VALUE': 33, + 'SETUP_ANNOTATIONS': 34, + 'STORE_SLICE': 35, + 'STORE_SUBSCR': 36, + 'TO_BOOL': 37, + 'UNARY_INVERT': 38, + 'UNARY_NEGATIVE': 39, + 'UNARY_NOT': 40, + 'WITH_EXCEPT_START': 41, + 'BINARY_OP': 42, + 'BUILD_LIST': 43, + 'BUILD_MAP': 44, + 'BUILD_SET': 45, + 'BUILD_SLICE': 46, + 'BUILD_STRING': 47, + 'BUILD_TUPLE': 48, + 'CALL': 49, + 'CALL_FUNCTION_EX': 50, + 'CALL_INTRINSIC_1': 51, + 'CALL_INTRINSIC_2': 52, + 'CALL_KW': 53, + 'COMPARE_OP': 54, + 'CONTAINS_OP': 55, + 'CONVERT_VALUE': 56, + 'COPY': 57, + 'COPY_FREE_VARS': 58, + 'DELETE_ATTR': 59, + 'DELETE_DEREF': 60, + 'DELETE_FAST': 61, + 'DELETE_GLOBAL': 62, + 'DELETE_NAME': 63, + 'DICT_MERGE': 64, + 'DICT_UPDATE': 65, + 'EXTENDED_ARG': 66, + 'FOR_ITER': 67, + 'GET_AWAITABLE': 68, + 'IMPORT_FROM': 69, + 'IMPORT_NAME': 70, + 'IS_OP': 71, + 'JUMP_BACKWARD': 72, + 'JUMP_BACKWARD_NO_INTERRUPT': 73, + 'JUMP_FORWARD': 74, + 'LIST_APPEND': 75, + 'LIST_EXTEND': 76, + 'LOAD_ATTR': 77, + 'LOAD_COMMON_CONSTANT': 78, + 'LOAD_CONST': 79, + 'LOAD_DEREF': 80, + 'LOAD_FAST': 81, + 'LOAD_FAST_AND_CLEAR': 82, + 'LOAD_FAST_CHECK': 83, + 'LOAD_FAST_LOAD_FAST': 84, + 'LOAD_FROM_DICT_OR_DEREF': 85, + '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, + 'SEND': 100, + 'SET_ADD': 101, + 'SET_FUNCTION_ATTRIBUTE': 102, + 'SET_UPDATE': 103, + 'STORE_ATTR': 104, + 'STORE_DEREF': 105, + 'STORE_FAST': 106, + 'STORE_FAST_LOAD_FAST': 107, + 'STORE_FAST_STORE_FAST': 108, + 'STORE_GLOBAL': 109, + 'STORE_NAME': 110, + 'SWAP': 111, + 'UNPACK_EX': 112, + 'UNPACK_SEQUENCE': 113, + 'YIELD_VALUE': 114, + '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, @@ -343,12 +341,11 @@ 'JUMP_NO_INTERRUPT': 259, 'LOAD_CLOSURE': 260, 'POP_BLOCK': 261, - 'RETURN_VALUE': 262, - 'SETUP_CLEANUP': 263, - 'SETUP_FINALLY': 264, - 'SETUP_WITH': 265, - 'STORE_FAST_MAYBE_NULL': 266, + 'SETUP_CLEANUP': 262, + 'SETUP_FINALLY': 263, + 'SETUP_WITH': 264, + 'STORE_FAST_MAYBE_NULL': 265, } -HAVE_ARGUMENT = 42 -MIN_INSTRUMENTED_OPCODE = 236 +HAVE_ARGUMENT = 41 +MIN_INSTRUMENTED_OPCODE = 237 diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 789285e6369505..d5cf014d40daf8 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -33,7 +33,7 @@ def test_is_valid(self): 'POP_TOP', 'IMPORT_NAME', 'JUMP', - 'INSTRUMENTED_RETURN_VALUE_FUNC', + 'INSTRUMENTED_RETURN_VALUE', ] opcodes = [dis.opmap[opname] for opname in names] self.check_bool_function_result(_opcode.is_valid, opcodes, True) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 22ee904cfc5b79..f1ab72180d714d 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1025,7 +1025,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 2) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 2) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # sequential calls: max(12, 13) == 13 @@ -1052,7 +1052,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 2) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 2) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # nested calls: 15 + 12 == 27 @@ -1087,7 +1087,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 4) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 4) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 4) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # max(12, 18 + max(12, 13)) == 31 @@ -1123,7 +1123,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 4) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 4) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 4) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) # max(18 + max(12, 13), 12) == 31 @@ -1167,7 +1167,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 15) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 15) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 15) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) @@ -1261,7 +1261,7 @@ def testfunc(n): uops_and_operands = [(opcode, operand) for opcode, _, _, operand in ex] uop_names = [uop[0] for uop in uops_and_operands] self.assertEqual(uop_names.count("_PUSH_FRAME"), 2) - self.assertEqual(uop_names.count("_RETURN_VALUE_FUNC"), 0) + self.assertEqual(uop_names.count("_RETURN_VALUE"), 0) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE"), 1) self.assertEqual(uop_names.count("_CHECK_STACK_SPACE_OPERAND"), 1) largest_stack = _testinternalcapi.get_co_framesize(dummy15.__code__) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 0830a9800c2696..8ceab1ad3a1606 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -884,7 +884,7 @@ def unused_code_at_end(): # RETURN_VALUE opcode. This does not always crash an interpreter. # When you build with the clang memory sanitizer it reliably aborts. self.assertEqual( - 'RETURN_VALUE_FUNC', + 'RETURN_VALUE', list(dis.get_instructions(unused_code_at_end))[-1].opname) @support.cpython_only @@ -1046,7 +1046,7 @@ def unused_block_while_else(): for func in funcs: opcodes = list(dis.get_instructions(func)) self.assertLessEqual(len(opcodes), 4) - self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) self.assertEqual(None, opcodes[-1].argval) def test_false_while_loop(self): @@ -1064,7 +1064,7 @@ def continue_in_while(): for func in funcs: opcodes = list(dis.get_instructions(func)) self.assertEqual(3, len(opcodes)) - self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) self.assertEqual(None, opcodes[1].argval) def test_consts_in_conditionals(self): @@ -1088,7 +1088,7 @@ def or_false(x): opcodes = list(dis.get_instructions(func)) self.assertLessEqual(len(opcodes), 3) self.assertIn('LOAD_', opcodes[-2].opname) - self.assertEqual('RETURN_VALUE_FUNC', opcodes[-1].opname) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) def test_imported_load_method(self): sources = [ @@ -1760,7 +1760,7 @@ def test_multiline_generator_expression(self): line=1, end_line=2, column=1, end_column=8, occurrence=1) self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', line=1, end_line=2, column=1, end_column=8, occurrence=1) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', + 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 +1777,7 @@ def test_multiline_async_generator_expression(self): self.assertIsInstance(compiled_code, types.CodeType) self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', line=1, end_line=2, column=1, end_column=8, occurrence=2) - self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE_GEN', + 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 +1815,7 @@ async def f(): 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_VALUE_GEN', + 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 +1853,7 @@ async def f(): 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_VALUE_GEN', + 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 +1891,7 @@ async def f(): 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_VALUE_GEN', + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', line=2, end_line=7, column=4, end_column=36, occurrence=1) def test_matchcase_sequence(self): @@ -2211,7 +2211,7 @@ def f(): load_none = [instr for instr in dis.get_instructions(f) if instr.opname == 'LOAD_CONST' and instr.argval is None] return_value = [instr for instr in dis.get_instructions(f) if - instr.opname == 'RETURN_VALUE_FUNC'] + instr.opname == 'RETURN_VALUE'] self.assertEqual(len(load_none), 4) self.assertEqual(len(return_value), 2) diff --git a/Lib/test/test_compiler_assemble.py b/Lib/test/test_compiler_assemble.py index e8f0ace8804a43..625d3c704c3529 100644 --- a/Lib/test/test_compiler_assemble.py +++ b/Lib/test/test_compiler_assemble.py @@ -127,13 +127,13 @@ def test_exception_table(self): ('RESUME', 0), ('SETUP_FINALLY', 4), ('LOAD_CONST', 0), - ('RETURN_VALUE_FUNC', None), + ('RETURN_VALUE', None), ('SETUP_CLEANUP', 10), ('PUSH_EXC_INFO', None), ('POP_TOP', None), ('POP_EXCEPT', None), ('LOAD_CONST', 0), - ('RETURN_VALUE_FUNC', None), + ('RETURN_VALUE', None), ('COPY', 3), ('POP_EXCEPT', None), ('RERAISE', 1), diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 3a28d97a007441..1e8f882f9cf428 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -53,7 +53,7 @@ def cm(cls, x): LOAD_FAST 0 (self) STORE_ATTR 0 (x) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ @@ -64,7 +64,7 @@ def cm(cls, x): LOAD_FAST 0 STORE_ATTR 0 LOAD_CONST 0 - RETURN_VALUE_FUNC + RETURN_VALUE """ dis_c_class_method = """\ @@ -76,7 +76,7 @@ def cm(cls, x): LOAD_FAST 0 (cls) STORE_ATTR 0 (x) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ @@ -87,7 +87,7 @@ def cm(cls, x): COMPARE_OP 72 (==) STORE_FAST 0 (x) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -115,7 +115,7 @@ def _f(a): POP_TOP %3d LOAD_CONST 1 (1) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -129,7 +129,7 @@ def _f(a): 22 POP_TOP %3d 24 LOAD_CONST 1 (1) - 26 RETURN_VALUE_FUNC + 26 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -143,7 +143,7 @@ def _f(a): %-14s POP_TOP %-14s LOAD_CONST 1 (1) -%-14s RETURN_VALUE_FUNC +%-14s RETURN_VALUE """ dis_f_co_code = """\ @@ -153,7 +153,7 @@ def _f(a): CALL 1 POP_TOP LOAD_CONST 1 - RETURN_VALUE_FUNC + RETURN_VALUE """ def bug708901(): @@ -179,7 +179,7 @@ def bug708901(): %3d L2: END_FOR POP_TOP LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -227,7 +227,7 @@ def bug42562(): dis_bug42562 = """\ RESUME 0 LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ # Extended arg followed by NOP @@ -236,7 +236,7 @@ def bug42562(): opcode.opmap['NOP'], 0xFF, opcode.opmap['EXTENDED_ARG'], 0x01, opcode.opmap['LOAD_CONST'], 0x29, - opcode.opmap['RETURN_VALUE_FUNC'], 0x00, + opcode.opmap['RETURN_VALUE'], 0x00, ]) dis_bug_45757 = """\ @@ -244,7 +244,7 @@ def bug42562(): NOP EXTENDED_ARG 1 LOAD_CONST 297 - RETURN_VALUE_FUNC + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -280,7 +280,7 @@ def wrap_func_w_kwargs(): CALL_KW 3 POP_TOP LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) @@ -293,7 +293,7 @@ def wrap_func_w_kwargs(): CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP LOAD_CONST 2 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ dis_intrinsic_1_5 = """\ @@ -301,7 +301,7 @@ def wrap_func_w_kwargs(): 1 LOAD_NAME 0 (a) CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE_FUNC + RETURN_VALUE """ dis_intrinsic_1_6 = """\ @@ -311,7 +311,7 @@ def wrap_func_w_kwargs(): LOAD_NAME 0 (a) LIST_EXTEND 1 CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE_FUNC + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ @@ -320,7 +320,7 @@ def wrap_func_w_kwargs(): %3d LOAD_GLOBAL 0 (spam) POP_TOP LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ _BIG_LINENO_FORMAT2 = """\ @@ -329,19 +329,19 @@ def wrap_func_w_kwargs(): %4d LOAD_GLOBAL 0 (spam) POP_TOP LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ dis_module_expected_results = """\ Disassembly of f: 4 RESUME 0 LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE Disassembly of g: 5 RESUME 0 LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ @@ -353,7 +353,7 @@ def wrap_func_w_kwargs(): 1 LOAD_NAME 0 (x) LOAD_CONST 0 (1) BINARY_OP 0 (+) - RETURN_VALUE_FUNC + RETURN_VALUE """ simple_stmt_str = "x = x + 1" @@ -366,7 +366,7 @@ def wrap_func_w_kwargs(): BINARY_OP 0 (+) STORE_NAME 0 (x) LOAD_CONST 1 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ annot_stmt_str = """\ @@ -395,7 +395,7 @@ def wrap_func_w_kwargs(): MAKE_FUNCTION STORE_NAME 3 (__annotate__) LOAD_CONST 3 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ fn_with_annotate_str = """ @@ -413,7 +413,7 @@ def foo(a: int, b: str) -> str: SET_FUNCTION_ATTRIBUTE 16 (annotate) STORE_NAME 0 (foo) LOAD_CONST 2 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ compound_stmt_str = """\ @@ -448,7 +448,7 @@ def foo(a: int, b: str) -> str: POP_TOP %4d L2: LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE_FUNC + RETURN_VALUE -- L3: PUSH_EXC_INFO @@ -466,7 +466,7 @@ def foo(a: int, b: str) -> str: DELETE_FAST 0 (e) %4d LOAD_FAST 1 (tb) - RETURN_VALUE_FUNC + RETURN_VALUE -- L6: LOAD_CONST 0 (None) STORE_FAST 0 (e) @@ -514,7 +514,7 @@ def _fstring(a, b, c, d): LOAD_CONST 2 ('4') FORMAT_WITH_SPEC BUILD_STRING 7 - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -546,7 +546,7 @@ def _with(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE %4d L3: PUSH_EXC_INFO WITH_EXCEPT_START @@ -562,7 +562,7 @@ def _with(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE -- L6: COPY 3 POP_EXCEPT @@ -624,7 +624,7 @@ async def _asyncwith(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) - RETURN_VALUE_GEN + RETURN_VALUE %4d L12: CLEANUP_THROW L13: JUMP_BACKWARD_NO_INTERRUPT 26 (to L5) @@ -652,7 +652,7 @@ async def _asyncwith(c): %4d LOAD_CONST 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) - RETURN_VALUE_GEN + RETURN_VALUE -- L24: COPY 3 POP_EXCEPT @@ -705,7 +705,7 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - RETURN_VALUE_FUNC + RETURN_VALUE -- L3: PUSH_EXC_INFO @@ -740,7 +740,7 @@ def _tryfinallyconst(b): CALL 0 POP_TOP LOAD_CONST 1 (1) - RETURN_VALUE_FUNC + RETURN_VALUE -- L1: PUSH_EXC_INFO @@ -791,7 +791,7 @@ def foo(x): STORE_FAST 1 (foo) %4d LOAD_FAST 1 (foo) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -816,7 +816,7 @@ def foo(x): GET_ITER CALL 0 CALL 1 - RETURN_VALUE_FUNC + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, @@ -846,7 +846,7 @@ def foo(x): L3: END_FOR POP_TOP LOAD_CONST 0 (None) - RETURN_VALUE_GEN + RETURN_VALUE -- L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) RERAISE 1 @@ -870,7 +870,7 @@ def load_test(x, y=0): %3d LOAD_FAST_LOAD_FAST 35 (a, b) BUILD_TUPLE 2 - RETURN_VALUE_FUNC + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -900,7 +900,7 @@ def loop_test(): %3d L2: END_FOR POP_TOP LOAD_CONST_IMMORTAL 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -918,7 +918,7 @@ def extended_arg_quick(): POP_TOP STORE_FAST 0 (_) LOAD_CONST 0 (None) - RETURN_VALUE_FUNC + RETURN_VALUE """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -1032,7 +1032,7 @@ def test_dis_with_some_positions(self): '2:3-3:15 NOP', '', '3:11-3:15 LOAD_CONST 0 (None)', - '3:11-3:15 RETURN_VALUE_FUNC', + '3:11-3:15 RETURN_VALUE', '', ' -- L1: PUSH_EXC_INFO', '', @@ -1063,7 +1063,7 @@ def test_dis_with_linenos_but_no_columns(self): '2:5-2:6 LOAD_CONST 1 (1)', '2:?-2:? STORE_FAST 0 (x)', '2:?-2:? LOAD_CONST 0 (None)', - '2:?-2:? RETURN_VALUE_FUNC', + '2:?-2:? RETURN_VALUE', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1076,7 +1076,7 @@ def f(): expect = '\n'.join([ ' RESUME 0', ' LOAD_CONST 0 (None)', - ' RETURN_VALUE_FUNC', + ' RETURN_VALUE', '', ]) self.do_disassembly_test(f, expect, show_positions=True) @@ -1268,7 +1268,7 @@ def test_binary_specialize(self): 1 LOAD_NAME 0 (a) LOAD_NAME 1 (b) %s - RETURN_VALUE_FUNC + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) @@ -1286,7 +1286,7 @@ def test_binary_specialize(self): 1 LOAD_NAME 0 (a) LOAD_CONST_IMMORTAL 0 (0) %s - RETURN_VALUE_FUNC + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -1306,7 +1306,7 @@ def test_load_attr_specialize(self): 1 LOAD_CONST_IMMORTAL 0 ('a') LOAD_ATTR_SLOT 0 (__class__) - RETURN_VALUE_FUNC + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1323,7 +1323,7 @@ def test_call_specialize(self): PUSH_NULL LOAD_CONST_IMMORTAL 0 (1) CALL_STR_1 1 - RETURN_VALUE_FUNC + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1759,7 +1759,7 @@ def _prepare_test_cases(): Instruction(opname='CALL', opcode=50, 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=82, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, label=None, positions=None, cache_info=None), - Instruction(opname='RETURN_VALUE_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), ] expected_opinfo_f = [ @@ -1786,7 +1786,7 @@ def _prepare_test_cases(): Instruction(opname='CALL', opcode=50, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, 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=5, label=None, positions=None, cache_info=None), Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), - Instruction(opname='RETURN_VALUE_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None), + Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None), ] expected_opinfo_inner = [ @@ -1801,7 +1801,7 @@ def _prepare_test_cases(): Instruction(opname='CALL', opcode=50, 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='LOAD_CONST', opcode=80, 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_FUNC', 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), + 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 = [ @@ -1887,7 +1887,7 @@ def _prepare_test_cases(): Instruction(opname='CALL', opcode=50, 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='LOAD_CONST', opcode=80, 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_FUNC', 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='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=42, 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=38, 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')]), @@ -1933,7 +1933,7 @@ 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='LOAD_CONST', opcode=80, 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_FUNC', opcode=33, arg=None, argval=None, argrepr='', offset=4, start_offset=4, 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), ] diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 4601b26eb479cf..9f3dddad2ca1b9 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -337,7 +337,7 @@ def f(x): return x self.assertNotInBytecode(f, 'LOAD_CONST', None) returns = [instr for instr in dis.get_instructions(f) - if instr.opname == 'RETURN_VALUE_FUNC'] + if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 1) self.check_lnotab(f) @@ -351,7 +351,7 @@ def f(cond, true_value, false_value): self.assertNotInBytecode(f, 'JUMP_FORWARD') self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) - if instr.opname == 'RETURN_VALUE_FUNC'] + if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 2) self.check_lnotab(f) @@ -981,19 +981,19 @@ def test_conditional_jump_forward_non_const_condition(self): ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), ('LOAD_CONST', 2, 13), - ('RETURN_VALUE_FUNC', None, 13), + ('RETURN_VALUE', None, 13), lbl, ('LOAD_CONST', 3, 14), - ('RETURN_VALUE_FUNC', None, 14), + ('RETURN_VALUE', None, 14), ] expected_insts = [ ('LOAD_NAME', 1, 11), ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), ('LOAD_CONST', 1, 13), - ('RETURN_VALUE_FUNC', None, 13), + ('RETURN_VALUE', None, 13), lbl, ('LOAD_CONST', 2, 14), - ('RETURN_VALUE_FUNC', None, 14), + ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1010,13 +1010,13 @@ def test_conditional_jump_forward_const_condition(self): ('LOAD_CONST', 2, 13), lbl, ('LOAD_CONST', 3, 14), - ('RETURN_VALUE_FUNC', None, 14), + ('RETURN_VALUE', None, 14), ] expected_insts = [ ('NOP', None, 11), ('NOP', None, 12), ('LOAD_CONST', 1, 14), - ('RETURN_VALUE_FUNC', None, 14), + ('RETURN_VALUE', None, 14), ] self.cfg_optimization_test(insts, expected_insts, @@ -1061,18 +1061,18 @@ def test_except_handler_label(self): ('SETUP_FINALLY', handler := self.Label(), 10), ('POP_BLOCK', None, -1), ('LOAD_CONST', 1, 11), - ('RETURN_VALUE_FUNC', None, 11), + ('RETURN_VALUE', None, 11), handler, ('LOAD_CONST', 2, 12), - ('RETURN_VALUE_FUNC', None, 12), + ('RETURN_VALUE', None, 12), ] expected_insts = [ ('SETUP_FINALLY', handler := self.Label(), 10), ('LOAD_CONST', 1, 11), - ('RETURN_VALUE_FUNC', None, 11), + ('RETURN_VALUE', None, 11), handler, ('LOAD_CONST', 2, 12), - ('RETURN_VALUE_FUNC', None, 12), + ('RETURN_VALUE', None, 12), ] self.cfg_optimization_test(insts, expected_insts, consts=list(range(5))) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 214650507c83f2..c6152260f97244 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1243,8 +1243,7 @@ mark_stacks(PyCodeObject *code_obj, int len) next_stack = pop_value(next_stack); stacks[next_i] = next_stack; break; - case RETURN_VALUE_FUNC: - case RETURN_VALUE_GEN: + case RETURN_VALUE: assert(pop_value(next_stack) == EMPTY_STACK); assert(top_of_stack(next_stack) == Object); break; diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index f647cba5570a28..8fbddfecd369f5 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,17 +1,17 @@ // 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,168,0,0,0,149,0,80,0,80,1, - 71,0,111,0,80,0,80,1,71,1,111,1,89,2,31,0, - 80,2,50,1,0,0,0,0,0,0,29,0,89,2,31,0, - 80,3,89,0,78,6,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,50,2,0,0,0,0,0,0, - 29,0,89,1,78,8,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,31,0,50,0,0,0,0,0, - 0,0,80,4,2,0,0,0,111,5,80,5,16,0,68,20, - 0,0,111,6,89,2,31,0,80,6,89,6,12,0,80,7, - 89,5,89,6,2,0,0,0,12,0,48,4,50,1,0,0, - 0,0,0,0,29,0,73,22,0,0,9,0,29,0,80,1, + 0,0,0,0,0,243,168,0,0,0,149,0,79,0,79,1, + 70,0,110,0,79,0,79,1,70,1,110,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,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,110,5,79,5,16,0,67,20, + 0,0,110,6,88,2,31,0,79,6,88,6,12,0,79,7, + 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,79,1, 33,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index f43014fa57f490..4466b3eb3b8765 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -990,10 +990,9 @@ dummy_func( // 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_FUNC, (retval -- res)) { + inst(RETURN_VALUE, (retval -- res)) { #if TIER_ONE assert(frame != &entry_frame); - assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; DEAD(retval); @@ -1003,27 +1002,7 @@ dummy_func( // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_ClearThreadFrame(tstate, dying); - RELOAD_STACK(); - LOAD_IP(frame->return_offset); - res = temp; - LLTRACE_RESUME_FRAME(); - } - - inst(RETURN_VALUE_GEN, (retval -- res)) { - #if TIER_ONE - assert(frame != &entry_frame); - assert(frame->owner == FRAME_OWNED_BY_GENERATOR); - #endif - _PyStackRef temp = retval; - DEAD(retval); - SAVE_STACK(); - 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_ClearGenFrame(tstate, dying); + _PyEval_FrameClearAndPop(tstate, dying); RELOAD_STACK(); LOAD_IP(frame->return_offset); res = temp; @@ -1037,13 +1016,9 @@ dummy_func( ERROR_IF(err, error); } - macro(INSTRUMENTED_RETURN_VALUE_FUNC) = - _RETURN_VALUE_EVENT + - RETURN_VALUE_FUNC; - - macro(INSTRUMENTED_RETURN_VALUE_GEN) = + macro(INSTRUMENTED_RETURN_VALUE) = _RETURN_VALUE_EVENT + - RETURN_VALUE_GEN; + RETURN_VALUE; inst(GET_AITER, (obj -- iter)) { unaryfunc getter = NULL; @@ -2657,11 +2632,6 @@ dummy_func( COPY, TO_BOOL, POP_JUMP_IF_TRUE, ]; - pseudo(RETURN_VALUE, (--)) = { - RETURN_VALUE_FUNC, - RETURN_VALUE_GEN, - }; - tier1 inst(ENTER_EXECUTOR, (--)) { #ifdef _Py_TIER2 PyCodeObject *code = _PyFrame_GetCode(frame); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 50e1c8d5c3daf1..d641f9b0500159 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1263,13 +1263,12 @@ break; } - case _RETURN_VALUE_FUNC: { + case _RETURN_VALUE: { _PyStackRef retval; _PyStackRef res; retval = stack_pointer[-1]; #if TIER_ONE assert(frame != &entry_frame); - assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -1280,35 +1279,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_ClearThreadFrame(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()); - break; - } - - case _RETURN_VALUE_GEN: { - _PyStackRef retval; - _PyStackRef res; - retval = stack_pointer[-1]; - #if TIER_ONE - assert(frame != &entry_frame); - assert(frame->owner == FRAME_OWNED_BY_GENERATOR); - #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_ClearGenFrame(tstate, dying); + _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 646560ae662582..13446d61126398 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_VALUE_FUNC || last->i_opcode == RETURN_VALUE_GEN); + return last && last->i_opcode == RETURN_VALUE); } static void @@ -2431,9 +2431,6 @@ convert_pseudo_ops(cfg_builder *g, int is_generator) assert(is_pseudo_target(STORE_FAST_MAYBE_NULL, STORE_FAST)); instr->i_opcode = STORE_FAST; } - else if (instr->i_opcode == RETURN_VALUE) { - instr->i_opcode = is_generator ? RETURN_VALUE_GEN : RETURN_VALUE_FUNC; - } } } return remove_redundant_nops_and_jumps(g); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 36a8bc04301060..7eb80db421b2f2 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4881,11 +4881,11 @@ DISPATCH(); } - TARGET(INSTRUMENTED_RETURN_VALUE_FUNC) { + TARGET(INSTRUMENTED_RETURN_VALUE) { _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; (void)this_instr; next_instr += 1; - INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE_FUNC); + INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE); _PyStackRef val; _PyStackRef retval; _PyStackRef res; @@ -4899,12 +4899,11 @@ stack_pointer = _PyFrame_GetStackPointer(frame); if (err) goto error; } - // _RETURN_VALUE_FUNC + // _RETURN_VALUE { retval = val; #if TIER_ONE assert(frame != &entry_frame); - assert(frame->owner != FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -4915,53 +4914,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_ClearThreadFrame(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_GEN) { - _Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr; - (void)this_instr; - next_instr += 1; - INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE_GEN); - _PyStackRef val; - _PyStackRef retval; - _PyStackRef res; - // _RETURN_VALUE_EVENT - { - val = stack_pointer[-1]; - _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_GEN - { - retval = val; - #if TIER_ONE - assert(frame != &entry_frame); - assert(frame->owner == FRAME_OWNED_BY_GENERATOR); - #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_ClearGenFrame(tstate, dying); + _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; @@ -6994,47 +6947,15 @@ DISPATCH(); } - TARGET(RETURN_VALUE_FUNC) { - frame->instr_ptr = next_instr; - next_instr += 1; - INSTRUCTION_STATS(RETURN_VALUE_FUNC); - _PyStackRef retval; - _PyStackRef res; - retval = stack_pointer[-1]; - #if TIER_ONE - assert(frame != &entry_frame); - assert(frame->owner != FRAME_OWNED_BY_GENERATOR); - #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_ClearThreadFrame(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_VALUE_GEN) { + TARGET(RETURN_VALUE) { frame->instr_ptr = next_instr; next_instr += 1; - INSTRUCTION_STATS(RETURN_VALUE_GEN); + INSTRUCTION_STATS(RETURN_VALUE); _PyStackRef retval; _PyStackRef res; retval = stack_pointer[-1]; #if TIER_ONE assert(frame != &entry_frame); - assert(frame->owner == FRAME_OWNED_BY_GENERATOR); #endif _PyStackRef temp = retval; stack_pointer += -1; @@ -7045,7 +6966,7 @@ // GH-99729: We need to unlink the frame *before* clearing it: _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; - _PyEval_ClearGenFrame(tstate, dying); + _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); res = temp; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 8ad3d680c019eb..d4568764117563 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -56,10 +56,8 @@ 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_VALUE_GEN] = PY_MONITORING_EVENT_PY_RETURN, - [INSTRUMENTED_RETURN_VALUE_GEN] = PY_MONITORING_EVENT_PY_RETURN, - [RETURN_VALUE_FUNC] = PY_MONITORING_EVENT_PY_RETURN, - [INSTRUMENTED_RETURN_VALUE_FUNC] = 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, [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL, [CALL_KW] = PY_MONITORING_EVENT_CALL, @@ -93,8 +91,7 @@ static const int8_t EVENT_FOR_OPCODE[256] = { static const uint8_t DE_INSTRUMENT[256] = { [INSTRUMENTED_RESUME] = RESUME, - [INSTRUMENTED_RETURN_VALUE_FUNC] = RETURN_VALUE_FUNC, - [INSTRUMENTED_RETURN_VALUE_GEN] = RETURN_VALUE_GEN, + [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE, [INSTRUMENTED_CALL] = CALL, [INSTRUMENTED_CALL_KW] = CALL_KW, [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, @@ -112,10 +109,8 @@ static const uint8_t DE_INSTRUMENT[256] = { }; static const uint8_t INSTRUMENTED_OPCODES[256] = { - [RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, - [INSTRUMENTED_RETURN_VALUE_GEN] = INSTRUMENTED_RETURN_VALUE_GEN, - [RETURN_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, - [INSTRUMENTED_RETURN_VALUE_FUNC] = INSTRUMENTED_RETURN_VALUE_FUNC, + [RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, + [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [CALL] = INSTRUMENTED_CALL, [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, [CALL_KW] = INSTRUMENTED_CALL_KW, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 43b3366fd620a0..5dc921ce32f41a 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -32,8 +32,7 @@ static void *opcode_targets[256] = { &&TARGET_PUSH_EXC_INFO, &&TARGET_PUSH_NULL, &&TARGET_RETURN_GENERATOR, - &&TARGET_RETURN_VALUE_FUNC, - &&TARGET_RETURN_VALUE_GEN, + &&TARGET_RETURN_VALUE, &&TARGET_SETUP_ANNOTATIONS, &&TARGET_STORE_SLICE, &&TARGET_STORE_SUBSCR, @@ -148,6 +147,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_RESUME, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, @@ -235,6 +235,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_END_SEND, &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, @@ -248,8 +249,7 @@ static void *opcode_targets[256] = { &&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE, &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, &&TARGET_INSTRUMENTED_RESUME, - &&TARGET_INSTRUMENTED_RETURN_VALUE_FUNC, - &&TARGET_INSTRUMENTED_RETURN_VALUE_GEN, + &&TARGET_INSTRUMENTED_RETURN_VALUE, &&TARGET_INSTRUMENTED_YIELD_VALUE, &&TARGET_INSTRUMENTED_CALL, &&TARGET_INSTRUMENTED_JUMP_BACKWARD, diff --git a/Python/optimizer.c b/Python/optimizer.c index 1d7dd4b5d5c594..b876b6c2bd72fd 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -709,7 +709,7 @@ translate_bytecode_to_trace( int nuops = expansion->nuops; RESERVE(nuops + 1); /* One extra for exit */ int16_t last_op = expansion->uops[nuops-1].uop; - if (last_op == _RETURN_VALUE_FUNC || last_op == _RETURN_VALUE_GEN || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) { + if (last_op == _RETURN_VALUE || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) { // Check for trace stack underflow now: // We can't bail e.g. in the middle of // LOAD_CONST + _RETURN_VALUE. @@ -770,7 +770,7 @@ translate_bytecode_to_trace( Py_FatalError("garbled expansion"); } - if (uop == _RETURN_VALUE_FUNC || uop == _RETURN_VALUE_GEN || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { + if (uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { TRACE_STACK_POP(); /* Set the operand to the function or code object returned to, * to assist optimization passes. (See _PUSH_FRAME below.) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 7ff0c8207e1a68..25166bc2dc5c02 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -296,8 +296,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, } break; } - case _RETURN_VALUE_FUNC: - case _RETURN_VALUE_GEN: + case _RETURN_VALUE: { builtins_watched >>= 1; globals_watched >>= 1; @@ -408,8 +407,7 @@ eliminate_pop_guard(_PyUOpInstruction *this_instr, bool exit) static PyCodeObject * get_code(_PyUOpInstruction *op) { - assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE_FUNC || - op->opcode == _RETURN_VALUE_GEN || op->opcode == _RETURN_GENERATOR); + assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE || op->opcode == _RETURN_GENERATOR); PyCodeObject *co = NULL; uint64_t operand = op->operand; if (operand == 0) { diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 4acb1e0e9db231..d7a6036614cbec 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -654,30 +654,7 @@ dummy_func(void) { ctx->done = true; } - op(_RETURN_VALUE_FUNC, (retval -- res)) { - SAVE_STACK(); - ctx->frame->stack_pointer = stack_pointer; - frame_pop(ctx); - stack_pointer = ctx->frame->stack_pointer; - - /* Stack space handling */ - assert(corresponding_check_stack == NULL); - assert(co != NULL); - int framesize = co->co_framesize; - assert(framesize > 0); - assert(framesize <= curr_space); - curr_space -= framesize; - - co = get_code(this_instr); - if (co == NULL) { - // might be impossible, but bailing is still safe - ctx->done = true; - } - RELOAD_STACK(); - res = retval; - } - - op(_RETURN_VALUE_GEN, (retval -- res)) { + op(_RETURN_VALUE, (retval -- res)) { SAVE_STACK(); ctx->frame->stack_pointer = stack_pointer; frame_pop(ctx); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 677e3ea8cc6f22..0b57716566722f 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -632,35 +632,7 @@ break; } - case _RETURN_VALUE_FUNC: { - _Py_UopsSymbol *retval; - _Py_UopsSymbol *res; - retval = stack_pointer[-1]; - stack_pointer += -1; - assert(WITHIN_STACK_BOUNDS()); - ctx->frame->stack_pointer = stack_pointer; - frame_pop(ctx); - stack_pointer = ctx->frame->stack_pointer; - /* Stack space handling */ - assert(corresponding_check_stack == NULL); - assert(co != NULL); - int framesize = co->co_framesize; - assert(framesize > 0); - assert(framesize <= curr_space); - curr_space -= framesize; - co = get_code(this_instr); - if (co == NULL) { - // might be impossible, but bailing is still safe - ctx->done = true; - } - res = retval; - stack_pointer[0] = res; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - break; - } - - case _RETURN_VALUE_GEN: { + case _RETURN_VALUE: { _Py_UopsSymbol *retval; _Py_UopsSymbol *res; retval = stack_pointer[-1]; diff --git a/Python/specialize.c b/Python/specialize.c index 3abba25b751486..ee8acd17127814 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2774,7 +2774,7 @@ const struct _PyCode8 _Py_InitCleanup = { .co_framesize = 2 + FRAME_SPECIALS_SIZE, .co_code_adaptive = { EXIT_INIT_CHECK, 0, - RETURN_VALUE_FUNC, 0, + RETURN_VALUE, 0, RESUME, RESUME_AT_FUNC_START, } }; From 0b8a5ad736b9aa515280921815257bb877f7a2d8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 16:25:52 +0100 Subject: [PATCH 14/34] Add LOAD_INT instruction --- Include/internal/pycore_magic_number.h | 2 +- Include/internal/pycore_opcode_metadata.h | 9 ++- Include/internal/pycore_uop_ids.h | 81 ++++++++++++----------- Include/internal/pycore_uop_metadata.h | 21 ++++++ Include/opcode_ids.h | 55 +++++++-------- Lib/_opcode_metadata.py | 55 +++++++-------- Lib/dis.py | 2 + Lib/test/test_ast/test_ast.py | 1 - Lib/test/test_compile.py | 4 +- Lib/test/test_compiler_codegen.py | 22 +++--- Lib/test/test_import/__init__.py | 4 +- Programs/test_frozenmain.h | 63 +++++++++--------- Python/bytecodes.c | 8 +++ Python/codegen.c | 8 +++ Python/compile.c | 2 + Python/executor_cases.c.h | 74 +++++++++++++++++++++ Python/flowgraph.c | 13 ++-- Python/generated_cases.c.h | 16 +++++ Python/opcode_targets.h | 2 +- Python/optimizer_cases.c.h | 9 +++ 20 files changed, 304 insertions(+), 147 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 8a695d98d64b68..579e8b5f4250dc 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -261,7 +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 (Break up RETURN_VALUE) + Python 3.14a2 3609 (Add LOAD_INT and LOAD_CONST_IMMORTAL instructions) Python 3.15 will start with 3650 diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index eb325e2ba1498a..c1073009369dd5 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -337,6 +337,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_GLOBAL_MODULE: return 0; + case LOAD_INT: + return 0; case LOAD_LOCALS: return 0; case LOAD_NAME: @@ -794,6 +796,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1 + (oparg & 1); case LOAD_GLOBAL_MODULE: return 1 + (oparg & 1); + case LOAD_INT: + return 1; case LOAD_LOCALS: return 1; case LOAD_NAME: @@ -1156,6 +1160,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, + [LOAD_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_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_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1360,6 +1365,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } }, [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION_PUSH_KEYS, 1, 2 }, { _LOAD_GLOBAL_BUILTINS_FROM_KEYS, 1, 3 } } }, [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } }, + [LOAD_INT] = { .nuops = 1, .uops = { { _LOAD_INT, 0, 0 } } }, [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } }, [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, 0, 0 } } }, [LOAD_SPECIAL] = { .nuops = 1, .uops = { { _LOAD_SPECIAL, 0, 0 } } }, @@ -1578,6 +1584,7 @@ const char *_PyOpcode_OpName[266] = { [LOAD_GLOBAL] = "LOAD_GLOBAL", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [LOAD_INT] = "LOAD_INT", [LOAD_LOCALS] = "LOAD_LOCALS", [LOAD_NAME] = "LOAD_NAME", [LOAD_SPECIAL] = "LOAD_SPECIAL", @@ -1828,6 +1835,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_GLOBAL] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_INT] = LOAD_INT, [LOAD_LOCALS] = LOAD_LOCALS, [LOAD_NAME] = LOAD_NAME, [LOAD_SPECIAL] = LOAD_SPECIAL, @@ -1900,7 +1908,6 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_METADATA #define EXTRA_CASES \ - case 115: \ case 116: \ case 117: \ case 118: \ diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 5c8fba72fb99f9..6fe620345fab0f 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -220,74 +220,79 @@ extern "C" { #define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 440 #define _LOAD_GLOBAL_MODULE 441 #define _LOAD_GLOBAL_MODULE_FROM_KEYS 442 +#define _LOAD_INT 443 +#define _LOAD_INT_0 444 +#define _LOAD_INT_1 445 +#define _LOAD_INT_2 446 +#define _LOAD_INT_3 447 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME #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 @@ -297,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 9af1e8e937e2d7..7d624407fdca2b 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -37,6 +37,11 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_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_INT_0] = HAS_CONST_FLAG, + [_LOAD_INT_1] = HAS_CONST_FLAG, + [_LOAD_INT_2] = HAS_CONST_FLAG, + [_LOAD_INT_3] = HAS_CONST_FLAG, + [_LOAD_INT] = HAS_ARG_FLAG | HAS_CONST_FLAG, [_STORE_FAST_0] = HAS_LOCAL_FLAG, [_STORE_FAST_1] = HAS_LOCAL_FLAG, [_STORE_FAST_2] = HAS_LOCAL_FLAG, @@ -290,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_INT] = 4, [_STORE_FAST] = 8, [_INIT_CALL_PY_EXACT_ARGS] = 5, }; @@ -485,6 +491,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = "_LOAD_GLOBAL_BUILTINS_FROM_KEYS", [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE", [_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS", + [_LOAD_INT] = "_LOAD_INT", + [_LOAD_INT_0] = "_LOAD_INT_0", + [_LOAD_INT_1] = "_LOAD_INT_1", + [_LOAD_INT_2] = "_LOAD_INT_2", + [_LOAD_INT_3] = "_LOAD_INT_3", [_LOAD_LOCALS] = "_LOAD_LOCALS", [_LOAD_NAME] = "_LOAD_NAME", [_LOAD_SPECIAL] = "_LOAD_SPECIAL", @@ -602,6 +613,16 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_CONST_IMMORTAL: return 0; + case _LOAD_INT_0: + return 0; + case _LOAD_INT_1: + return 0; + case _LOAD_INT_2: + return 0; + case _LOAD_INT_3: + return 0; + case _LOAD_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 8250f3f496c8f5..eb499e9576dbe3 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -98,33 +98,34 @@ extern "C" { #define LOAD_FROM_DICT_OR_DEREF 85 #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 SEND 100 -#define SET_ADD 101 -#define SET_FUNCTION_ATTRIBUTE 102 -#define SET_UPDATE 103 -#define STORE_ATTR 104 -#define STORE_DEREF 105 -#define STORE_FAST 106 -#define STORE_FAST_LOAD_FAST 107 -#define STORE_FAST_STORE_FAST 108 -#define STORE_GLOBAL 109 -#define STORE_NAME 110 -#define SWAP 111 -#define UNPACK_EX 112 -#define UNPACK_SEQUENCE 113 -#define YIELD_VALUE 114 +#define LOAD_INT 88 +#define LOAD_NAME 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 +#define SET_UPDATE 104 +#define STORE_ATTR 105 +#define STORE_DEREF 106 +#define STORE_FAST 107 +#define STORE_FAST_LOAD_FAST 108 +#define STORE_FAST_STORE_FAST 109 +#define STORE_GLOBAL 110 +#define STORE_NAME 111 +#define SWAP 112 +#define UNPACK_EX 113 +#define UNPACK_SEQUENCE 114 +#define YIELD_VALUE 115 #define RESUME 149 #define BINARY_OP_ADD_FLOAT 150 #define BINARY_OP_ADD_INT 151 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 3754171dcb18fa..1561461de2653e 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -291,33 +291,34 @@ 'LOAD_FROM_DICT_OR_DEREF': 85, '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, - 'SEND': 100, - 'SET_ADD': 101, - 'SET_FUNCTION_ATTRIBUTE': 102, - 'SET_UPDATE': 103, - 'STORE_ATTR': 104, - 'STORE_DEREF': 105, - 'STORE_FAST': 106, - 'STORE_FAST_LOAD_FAST': 107, - 'STORE_FAST_STORE_FAST': 108, - 'STORE_GLOBAL': 109, - 'STORE_NAME': 110, - 'SWAP': 111, - 'UNPACK_EX': 112, - 'UNPACK_SEQUENCE': 113, - 'YIELD_VALUE': 114, + 'LOAD_INT': 88, + 'LOAD_NAME': 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, + 'SET_UPDATE': 104, + 'STORE_ATTR': 105, + 'STORE_DEREF': 106, + 'STORE_FAST': 107, + 'STORE_FAST_LOAD_FAST': 108, + 'STORE_FAST_STORE_FAST': 109, + 'STORE_GLOBAL': 110, + 'STORE_NAME': 111, + 'SWAP': 112, + 'UNPACK_EX': 113, + 'UNPACK_SEQUENCE': 114, + 'YIELD_VALUE': 115, 'INSTRUMENTED_END_FOR': 237, 'INSTRUMENTED_END_SEND': 238, 'INSTRUMENTED_LOAD_SUPER_ATTR': 239, diff --git a/Lib/dis.py b/Lib/dis.py index 296ebb8e6e755d..6188687786e8e6 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -674,6 +674,8 @@ def _get_const_value(op, arg, co_consts): """ assert op in hasconst + if op == LOAD_INT: + return arg argval = UNKNOWN if co_consts is not None: argval = co_consts[arg] diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 53ee5914d126e4..f26bcc058d1287 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2311,7 +2311,6 @@ def get_load_const(self, tree): def test_load_const(self): consts = [None, True, False, - 124, 2.0, 3j, "unicode", diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 8ceab1ad3a1606..360cdd2bb26e48 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -867,7 +867,7 @@ def test_strip_unused_None(self): 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 @@ -1738,7 +1738,7 @@ def test_multiline_assert(self): 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', diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index 8a15c400a449e1..15f759d50ca78f 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -29,13 +29,13 @@ def test_if_expression(self): ('LOAD_CONST', 0, 1), ('TO_BOOL', 0, 1), ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), - ('LOAD_CONST', 1, 1), + ('LOAD_INT', 42, 1), ('JUMP_NO_INTERRUPT', exit_lbl := self.Label()), false_lbl, - ('LOAD_CONST', 2, 1), + ('LOAD_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 @@ def f(x): # Function body ('RESUME', 0), ('LOAD_FAST', 0), - ('LOAD_CONST', 1), + ('LOAD_INT', 42), ('BINARY_OP', 0), ('RETURN_VALUE', None), ('LOAD_CONST', 0), @@ -125,23 +125,23 @@ def g(): [ ('RESUME', 0), ('NOP', None), - ('LOAD_CONST', 1), + ('LOAD_INT', 12), ('RETURN_VALUE', None), - ('LOAD_CONST', 0), + ('LOAD_CONST', 1), ('RETURN_VALUE', None), ], [ ('RESUME', 0), - ('LOAD_CONST', 1), + ('LOAD_INT', 1), ('STORE_FAST', 0), - ('LOAD_CONST', 2), + ('LOAD_INT', 2), ('STORE_FAST', 1), - ('LOAD_CONST', 3), + ('LOAD_INT', 3), ('STORE_FAST', 2), - ('LOAD_CONST', 4), + ('LOAD_INT', 4), ('STORE_FAST', 3), ('NOP', None), - ('LOAD_CONST', 5), + ('LOAD_INT', 42), ('RETURN_VALUE', None), ('LOAD_CONST', 0), ('RETURN_VALUE', None), diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 5d0d02480b3929..158d530a5a216b 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1125,7 +1125,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 @@ -1194,7 +1194,7 @@ def test_foreign_code(self): 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/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 8fbddfecd369f5..5f6c1e50140fee 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,38 +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,168,0,0,0,149,0,79,0,79,1, - 70,0,110,0,79,0,79,1,70,1,110,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,88,0,79,0, + 70,0,111,0,88,0,79,0,70,1,111,1,89,2,31,0, + 79,1,49,1,0,0,0,0,0,0,29,0,89,2,31,0, + 79,2,89,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, + 29,0,89,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,110,5,79,5,16,0,67,20, - 0,0,110,6,88,2,31,0,79,6,88,6,12,0,79,7, - 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,79,1, - 33,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, - 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, - 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, - 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, - 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, - 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, - 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, - 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, - 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, - 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, - 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, - 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, - 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, - 0,0,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,243,15,6,12,2,114,16,0,0, - 0, + 0,0,79,3,2,0,0,0,111,5,79,4,16,0,67,20, + 0,0,111,6,89,2,31,0,79,5,89,6,12,0,79,6, + 89,5,89,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,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 4466b3eb3b8765..0724fa1f7a79e5 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -269,6 +269,14 @@ dummy_func( value = PyStackRef_FromPyObjectImmortal(obj); } + replicate(4) inst(LOAD_INT, (-- value)) { + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; + value = PyStackRef_FromPyObjectImmortal(obj); + } + replicate(8) inst(STORE_FAST, (value --)) { SETLOCAL(oparg, value); DEAD(value); diff --git a/Python/codegen.c b/Python/codegen.c index 689d2b5124e9d3..7e74711e057b7e 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) { + ADDOP_I(c, loc, LOAD_INT, val); + return SUCCESS; + } + } Py_ssize_t arg = _PyCompile_AddConst(c, o); if (arg < 0) { return ERROR; diff --git a/Python/compile.c b/Python/compile.c index d463fcde204a05..2f8a6038043ae0 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -447,6 +447,8 @@ _PyCompile_DictAddObj(PyObject *dict, PyObject *o) Py_ssize_t _PyCompile_AddConst(compiler *c, PyObject *o) { + + PyObject *key = merge_consts_recursive(c->c_const_cache, o); if (key == NULL) { return ERROR; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index d641f9b0500159..6b67b28dbff0fa 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -222,6 +222,80 @@ break; } + case _LOAD_INT_0: { + _PyStackRef value; + oparg = 0; + assert(oparg == CURRENT_OPARG()); + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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_INT_1: { + _PyStackRef value; + oparg = 1; + assert(oparg == CURRENT_OPARG()); + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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_INT_2: { + _PyStackRef value; + oparg = 2; + assert(oparg == CURRENT_OPARG()); + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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_INT_3: { + _PyStackRef value; + oparg = 3; + assert(oparg == CURRENT_OPARG()); + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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_INT: { + _PyStackRef value; + oparg = CURRENT_OPARG(); + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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 13446d61126398..0edbef86afd476 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1115,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_INT) { is_redundant_pair = true; } else if (prev_opcode == COPY && prev_oparg == 1) { @@ -1272,6 +1272,9 @@ get_const_value(int opcode, int oparg, PyObject *co_consts) if (opcode == LOAD_CONST) { constant = PyList_GET_ITEM(co_consts, oparg); } + if (opcode == LOAD_INT) { + return PyLong_FromLong(oparg); + } if (constant == NULL) { PyErr_SetString(PyExc_SystemError, @@ -1567,7 +1570,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_INT) { continue; } int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; @@ -2098,7 +2101,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) && opcode != LOAD_INT) { int index = b->b_instr[i].i_oparg; index_map[index] = index; } @@ -2151,7 +2155,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) && opcode != LOAD_INT) { int index = b->b_instr[i].i_oparg; assert(reverse_index_map[index] >= 0); assert(reverse_index_map[index] < n_used_consts); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7eb80db421b2f2..82b1f60fa0ded0 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6189,6 +6189,22 @@ DISPATCH(); } + TARGET(LOAD_INT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_INT); + _PyStackRef value; + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + assert(oparg < 256); + 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_LOCALS) { frame->instr_ptr = next_instr; next_instr += 1; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 5dc921ce32f41a..ca1889ce7591db 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -87,6 +87,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FROM_DICT_OR_DEREF, &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, &&TARGET_LOAD_GLOBAL, + &&TARGET_LOAD_INT, &&TARGET_LOAD_NAME, &&TARGET_LOAD_SPECIAL, &&TARGET_LOAD_SUPER_ATTR, @@ -147,7 +148,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_RESUME, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 0b57716566722f..6200d6df31d7b3 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -79,6 +79,15 @@ break; } + case _LOAD_INT: { + _Py_UopsSymbol *value; + value = sym_new_not_null(ctx); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _STORE_FAST: { _Py_UopsSymbol *value; value = stack_pointer[-1]; From 1bfdd706fdc64662a00d7f2f26c891b516a5611f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 24 Oct 2024 17:47:05 +0100 Subject: [PATCH 15/34] Fix up dis and some tests --- Lib/dis.py | 1 + Lib/test/test_compile.py | 6 ++---- Lib/test/test_peepholer.py | 12 +++++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Lib/dis.py b/Lib/dis.py index 6188687786e8e6..4592c276cc6830 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -36,6 +36,7 @@ ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] +LOAD_INT = opmap['LOAD_INT'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] FOR_ITER = opmap['FOR_ITER'] diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 360cdd2bb26e48..958170f675e1d9 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -775,7 +775,6 @@ def check_same_constant(const): 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 @@ def test_remove_unused_consts_extended_args(self): 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 @@ -982,7 +981,6 @@ def check_different_constants(const1, const2): 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') diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 9f3dddad2ca1b9..dc586e4ddd14fd 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -248,14 +248,17 @@ def test_folding_of_binops_on_constants(self): ): with self.subTest(line=line): code = compile(line, '', 'single') - self.assertInBytecode(code, 'LOAD_CONST', elem) + if isinstance(elem, int): + self.assertInBytecode(code, 'LOAD_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_INT', 2) self.assertInBytecode(code, 'LOAD_CONST', 'b') self.check_lnotab(code) @@ -307,7 +310,10 @@ def test_folding_of_unaryops_on_constants(self): ): with self.subTest(line=line): code = compile(line, '', 'single') - self.assertInBytecode(code, 'LOAD_CONST', elem) + if isinstance(elem, int): + self.assertInBytecode(code, 'LOAD_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) From f934559c500bc674989caae31ac35c7652bc4e67 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 10:54:29 +0100 Subject: [PATCH 16/34] Fix up test dis --- Lib/test/test_dis.py | 319 +++++++++++++++++++++---------------------- 1 file changed, 157 insertions(+), 162 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 1e8f882f9cf428..6e9094d1848ace 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -48,7 +48,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) + LOAD_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) @@ -59,7 +59,7 @@ def cm(cls, x): dis_c_instance_method_bytes = """\ RESUME 0 LOAD_FAST 1 - LOAD_CONST 1 + LOAD_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 @@ -71,7 +71,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) + LOAD_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) @@ -83,7 +83,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) + LOAD_INT 1 (1) COMPARE_OP 72 (==) STORE_FAST 0 (x) LOAD_CONST 0 (None) @@ -114,7 +114,7 @@ def _f(a): CALL 1 POP_TOP -%3d LOAD_CONST 1 (1) +%3d LOAD_INT 1 (1) RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -128,7 +128,7 @@ def _f(a): 14 CALL 1 22 POP_TOP -%3d 24 LOAD_CONST 1 (1) +%3d 24 LOAD_INT 1 (1) 26 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -142,7 +142,7 @@ def _f(a): %-14s CALL 1 %-14s POP_TOP -%-14s LOAD_CONST 1 (1) +%-14s LOAD_INT 1 (1) %-14s RETURN_VALUE """ @@ -152,7 +152,7 @@ def _f(a): LOAD_FAST 0 CALL 1 POP_TOP - LOAD_CONST 1 + LOAD_INT 1 (1) RETURN_VALUE """ @@ -165,9 +165,9 @@ def bug708901(): %3d RESUME 0 %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) + LOAD_INT 1 (1) -%3d LOAD_CONST 2 (10) +%3d LOAD_INT 10 (10) %3d CALL 2 GET_ITER @@ -203,7 +203,7 @@ def bug1333982(x=[]): GET_ITER CALL 0 -%3d LOAD_CONST 2 (1) +%3d LOAD_INT 1 (1) %3d BINARY_OP 0 (+) CALL 0 @@ -273,10 +273,10 @@ def wrap_func_w_kwargs(): %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_INT 1 (1) + LOAD_INT 2 (2) + LOAD_INT 5 (5) + LOAD_CONST 1 (('c',)) CALL_KW 3 POP_TOP LOAD_CONST 0 (None) @@ -287,12 +287,12 @@ def wrap_func_w_kwargs(): dis_intrinsic_1_2 = """\ 0 RESUME 0 - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) + 1 LOAD_INT 0 (0) + LOAD_CONST 0 (('*',)) IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) POP_TOP - LOAD_CONST 2 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ @@ -351,7 +351,7 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) + LOAD_INT 1 (1) BINARY_OP 0 (+) RETURN_VALUE """ @@ -362,10 +362,10 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) + LOAD_INT 1 (1) BINARY_OP 0 (+) STORE_NAME 0 (x) - LOAD_CONST 1 (None) + LOAD_CONST 0 (None) RETURN_VALUE """ @@ -380,21 +380,21 @@ def wrap_func_w_kwargs(): dis_annot_stmt_str = """\ 0 RESUME 0 - 2 LOAD_CONST 0 (1) + 2 LOAD_INT 1 (1) STORE_NAME 0 (x) - 4 LOAD_CONST 0 (1) + 4 LOAD_INT 1 (1) LOAD_NAME 1 (lst) LOAD_NAME 2 (fun) PUSH_NULL - LOAD_CONST 1 (0) + LOAD_INT 0 (0) CALL 1 STORE_SUBSCR - 2 LOAD_CONST 2 (", line 2>) + 2 LOAD_CONST 0 (", line 2>) MAKE_FUNCTION STORE_NAME 3 (__annotate__) - LOAD_CONST 3 (None) + LOAD_CONST 1 (None) RETURN_VALUE """ @@ -425,13 +425,13 @@ def foo(a: int, b: str) -> str: dis_compound_stmt_str = """\ 0 RESUME 0 - 1 LOAD_CONST 0 (0) + 1 LOAD_INT 0 (0) STORE_NAME 0 (x) 2 L1: NOP 3 LOAD_NAME 0 (x) - LOAD_CONST 1 (1) + LOAD_INT 1 (1) BINARY_OP 13 (+=) STORE_NAME 0 (x) JUMP_BACKWARD 8 (to L1) @@ -442,8 +442,8 @@ def foo(a: int, b: str) -> str: %4d NOP -%4d L1: LOAD_CONST 1 (1) - LOAD_CONST 2 (0) +%4d L1: LOAD_INT 1 (1) + LOAD_INT 0 (0) --> BINARY_OP 11 (/) POP_TOP @@ -534,7 +534,7 @@ def _with(c): CALL 0 L1: POP_TOP -%4d LOAD_CONST 1 (1) +%4d LOAD_INT 1 (1) STORE_FAST 1 (x) %4d L2: LOAD_CONST 0 (None) @@ -543,7 +543,7 @@ def _with(c): CALL 3 POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -559,7 +559,7 @@ def _with(c): POP_TOP POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -605,7 +605,7 @@ async def _asyncwith(c): L5: END_SEND L6: POP_TOP -%4d LOAD_CONST 1 (1) +%4d LOAD_INT 1 (1) STORE_FAST 1 (x) %4d L7: LOAD_CONST 0 (None) @@ -621,7 +621,7 @@ async def _asyncwith(c): L11: END_SEND POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -649,7 +649,7 @@ async def _asyncwith(c): POP_TOP POP_TOP -%4d LOAD_CONST 2 (2) +%4d LOAD_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -739,7 +739,7 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - LOAD_CONST 1 (1) + LOAD_INT 1 (1) RETURN_VALUE -- L1: PUSH_EXC_INFO @@ -885,7 +885,7 @@ def loop_test(): %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) LIST_EXTEND 1 - LOAD_CONST_IMMORTAL 2 (3) + LOAD_INT 3 (3) BINARY_OP 5 (*) GET_ITER L1: FOR_ITER_LIST 14 (to L2) @@ -1060,7 +1060,7 @@ def test_dis_with_linenos_but_no_columns(self): expect = '\n'.join([ '1:0-1:0 RESUME 0', '', - '2:5-2:6 LOAD_CONST 1 (1)', + '2:5-2:6 LOAD_INT 1 (1)', '2:?-2:? STORE_FAST 0 (x)', '2:?-2:? LOAD_CONST 0 (None)', '2:?-2:? RETURN_VALUE', @@ -1284,7 +1284,7 @@ def test_binary_specialize(self): 0 RESUME_CHECK 0 1 LOAD_NAME 0 (a) - LOAD_CONST_IMMORTAL 0 (0) + LOAD_INT 0 (0) %s RETURN_VALUE """ @@ -1321,7 +1321,7 @@ def test_call_specialize(self): 1 LOAD_NAME 0 (str) PUSH_NULL - LOAD_CONST_IMMORTAL 0 (1) + LOAD_INT 1 (1) CALL_STR_1 1 RETURN_VALUE """ @@ -1545,8 +1545,6 @@ def f(c=c): Number of locals: 0 Stack size: \\d+ Flags: 0x0 -Constants: - 0: 1 Names: 0: x""" @@ -1560,8 +1558,7 @@ def f(c=c): Stack size: \\d+ Flags: 0x0 Constants: - 0: 1 - 1: None + 0: None Names: 0: x""" @@ -1575,8 +1572,7 @@ def f(c=c): Stack size: \\d+ Flags: 0x0 Constants: - 0: 0 - 1: 1 + 0: None Names: 0: x""" @@ -1597,7 +1593,6 @@ async def async_def(): Flags: OPTIMIZED, NEWLOCALS, COROUTINE Constants: 0: None - 1: 1 Names: 0: b 1: c @@ -1739,158 +1734,158 @@ def _prepare_test_cases(): 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=80, 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_FAST', opcode=82, 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=82, 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=49, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, 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), + Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=107, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=False, line_number=2, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, 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_DEREF', opcode=81, 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=81, 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=80, 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=80, 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='BUILD_LIST', opcode=44, 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=45, 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=80, 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='CALL', opcode=50, 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='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=24, start_offset=24, starts_line=True, line_number=7, 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_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_INT', opcode=88, arg=1, argval=1, argrepr='1', 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=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=82, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=True, line_number=8, 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), Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None, cache_info=None), ] expected_opinfo_f = [ - Instruction(opname='COPY_FREE_VARS', opcode=59, 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='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=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=80, 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=82, arg=3, argval='a', argrepr='a', offset=10, start_offset=10, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=82, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=82, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=82, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='BUILD_TUPLE', opcode=49, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=80, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, 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), + Instruction(opname='LOAD_FAST', opcode=81, arg=4, argval='b', argrepr='b', offset=12, start_offset=12, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=81, arg=0, argval='c', argrepr='c', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=81, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='BUILD_TUPLE', opcode=48, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_CONST', opcode=79, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='MAKE_FUNCTION', opcode=23, 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='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=103, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), Instruction(opname='STORE_FAST', opcode=107, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, 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_DEREF', opcode=81, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=50, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2, b'\x00\x00\x00\x00')]), + Instruction(opname='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=5, 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_DEREF', opcode=80, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=False, line_number=5, label=None, positions=None, cache_info=None), + Instruction(opname='CALL', opcode=49, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, 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=5, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST', opcode=82, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_FAST', opcode=81, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=True, line_number=6, label=None, positions=None, cache_info=None), Instruction(opname='RETURN_VALUE', opcode=33, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None, cache_info=None), ] expected_opinfo_inner = [ - Instruction(opname='COPY_FREE_VARS', opcode=59, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), + Instruction(opname='COPY_FREE_VARS', opcode=58, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None, cache_info=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=88, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, 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_DEREF', opcode=81, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_DEREF', opcode=81, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_FAST_LOAD_FAST', opcode=85, 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=50, 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='LOAD_GLOBAL', opcode=87, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, 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_DEREF', opcode=80, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=3, argval='b', argrepr='b', offset=16, start_offset=16, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=4, argval='c', argrepr='c', offset=18, start_offset=18, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + Instruction(opname='LOAD_DEREF', opcode=80, arg=5, argval='d', argrepr='d', offset=20, start_offset=20, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + 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='LOAD_CONST', opcode=80, 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=88, 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=80, 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='CALL', opcode=50, 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='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_INT', opcode=88, arg=10, argval=10, argrepr='10', 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=68, 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')]), + 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')]), Instruction(opname='STORE_FAST', opcode=107, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_GLOBAL', opcode=88, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, 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=82, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=50, 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='LOAD_GLOBAL', opcode=87, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, 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=40, start_offset=40, starts_line=False, line_number=4, label=None, positions=None, cache_info=None), + 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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='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_INT', opcode=88, arg=4, argval=4, argrepr='4', 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=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=73, 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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='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_INT', opcode=88, arg=6, argval=6, argrepr='6', 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=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=73, 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='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=75, 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='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=88, 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=80, 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='CALL', opcode=50, 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='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=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=84, 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=38, 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='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=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=88, 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=82, 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=50, 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='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=82, 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=80, 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='BINARY_OP', opcode=43, 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='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_INT', opcode=88, arg=1, argval=1, argrepr='1', 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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='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_INT', opcode=88, arg=6, argval=6, argrepr='6', 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=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=73, 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=82, 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=80, 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='COMPARE_OP', opcode=55, 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='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_INT', opcode=88, arg=4, argval=4, argrepr='4', 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=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=73, 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=75, 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=88, 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=80, 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='CALL', opcode=50, 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='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=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=80, 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=80, 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='BINARY_OP', opcode=43, 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='LOAD_INT', opcode=88, arg=1, 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_INT', opcode=88, arg=0, argval=0, argrepr='0', 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=82, 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=58, 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_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=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=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=50, 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='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=88, 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=80, 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='CALL', opcode=50, 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='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=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=80, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=True, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='LOAD_CONST', opcode=80, arg=0, argval=None, argrepr='None', offset=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), - Instruction(opname='CALL', opcode=50, 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='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), + Instruction(opname='LOAD_CONST', opcode=79, arg=0, argval=None, argrepr='None', offset=274, start_offset=274, 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=276, start_offset=276, starts_line=False, line_number=25, label=None, positions=None, cache_info=None), + 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=88, 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=80, 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='CALL', opcode=50, 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='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=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='LOAD_CONST', opcode=80, 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='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=42, 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=38, 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='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), @@ -1898,32 +1893,32 @@ def _prepare_test_cases(): 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='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=74, 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=58, 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='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=88, 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='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=88, 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=80, arg=9, 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=50, 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='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=74, 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='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=58, 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='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=88, 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=80, arg=10, 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=50, 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='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=58, 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='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), ] @@ -1932,7 +1927,7 @@ def _prepare_test_cases(): 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='LOAD_CONST', opcode=80, 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), ] @@ -2330,20 +2325,20 @@ def test_bytecode_co_positions(self): 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_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_INT") + self.assertInBytecode(code, "LOAD_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_INT", 1) class TestFinderMethods(unittest.TestCase): def test__find_imports(self): From f135b690a0bee56d77e386ff827c2a6c110a9484 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:14:18 +0100 Subject: [PATCH 17/34] Address review comments --- Python/bytecodes.c | 2 +- Python/codegen.c | 2 +- Python/compile.c | 2 -- Python/executor_cases.c.h | 10 +++++----- Python/flowgraph.c | 2 +- Python/generated_cases.c.h | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 0724fa1f7a79e5..fba5af6296f979 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -272,7 +272,7 @@ dummy_func( replicate(4) inst(LOAD_INT, (-- value)) { /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); } diff --git a/Python/codegen.c b/Python/codegen.c index 7e74711e057b7e..41f8ad996ae548 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -283,7 +283,7 @@ 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) { + if (!overflow && val >= 0 && val < 256 && val < _PY_NSMALLPOSINTS) { ADDOP_I(c, loc, LOAD_INT, val); return SUCCESS; } diff --git a/Python/compile.c b/Python/compile.c index 2f8a6038043ae0..d463fcde204a05 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -447,8 +447,6 @@ _PyCompile_DictAddObj(PyObject *dict, PyObject *o) Py_ssize_t _PyCompile_AddConst(compiler *c, PyObject *o) { - - PyObject *key = merge_consts_recursive(c->c_const_cache, o); if (key == NULL) { return ERROR; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 6b67b28dbff0fa..7cfa55d01536f0 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -228,7 +228,7 @@ assert(oparg == CURRENT_OPARG()); /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; @@ -243,7 +243,7 @@ assert(oparg == CURRENT_OPARG()); /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; @@ -258,7 +258,7 @@ assert(oparg == CURRENT_OPARG()); /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; @@ -273,7 +273,7 @@ assert(oparg == CURRENT_OPARG()); /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; @@ -287,7 +287,7 @@ oparg = CURRENT_OPARG(); /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 0edbef86afd476..e3f7dae7ae2e47 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); + return last && last->i_opcode == RETURN_VALUE; } static void diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 82b1f60fa0ded0..51bd524dee3991 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6196,7 +6196,7 @@ _PyStackRef value; /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; - assert(oparg < 256); + assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); stack_pointer[0] = value; From 8f2a781a19982107ff75bc4db4657e1b2a7e43f7 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:15:26 +0100 Subject: [PATCH 18/34] Fix __annotate__ docstring --- Python/codegen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Python/codegen.c b/Python/codegen.c index 41f8ad996ae548..b27a6c3fd01e95 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -664,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 + // apperaing 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); From 97c6cdce07b29d6b3801626fa27ffcbdb254c348 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:38:28 +0100 Subject: [PATCH 19/34] Teach optimizer about LOAD_INT --- Python/optimizer_bytecodes.c | 6 +++++- Python/optimizer_cases.c.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d7a6036614cbec..50b61f8b62931c 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -427,13 +427,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_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 6200d6df31d7b3..364fa9911b29b4 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -81,7 +81,8 @@ case _LOAD_INT: { _Py_UopsSymbol *value; - value = sym_new_not_null(ctx); + PyObject *val = PyLong_FromLong(this_instr->oparg); + value = sym_new_const(ctx, val); stack_pointer[0] = value; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); From eefcbdf975047929813af3cfa49bc6b5219e96e1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:46:32 +0100 Subject: [PATCH 20/34] Remove remnants of earlier PR --- Doc/library/dis.rst | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 0006fb19420a0e..6a288a647cdc6a 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -76,7 +76,7 @@ the following command can be used to display the disassembly of 3 LOAD_GLOBAL 1 (len + NULL) LOAD_FAST 0 (alist) CALL 1 - RETURN_VALUE_FUNC + RETURN_VALUE (The "2" is a line number). @@ -203,7 +203,7 @@ Example: LOAD_GLOBAL LOAD_FAST CALL - RETURN_VALUE_FUNC + RETURN_VALUE Analysis functions @@ -857,7 +857,7 @@ container object remains on the stack so that it is available for further iterations of the loop. -.. opcode:: RETURN_VALUE_FUNC +.. opcode:: RETURN_VALUE Returns with ``STACK[-1]`` to the caller of the function. Used in normal functions. @@ -865,14 +865,6 @@ iterations of the loop. .. versionadded:: 3.14 -.. opcode:: RETURN_VALUE_GEN - - Returns with ``STACK[-1]`` to the caller of the generator. - Used in generator functions. - - .. versionadded:: 3.14 - - .. opcode:: YIELD_VALUE Yields ``STACK.pop()`` from a :term:`generator`. From 58dab8e91a4eda5b80ec584812965ff6dd1d62fd Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:47:40 +0100 Subject: [PATCH 21/34] Remove last remnant of earlier PR --- Doc/library/dis.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 6a288a647cdc6a..f3bcdd65dd7628 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -860,7 +860,6 @@ iterations of the loop. .. opcode:: RETURN_VALUE Returns with ``STACK[-1]`` to the caller of the function. - Used in normal functions. .. versionadded:: 3.14 From 81e4dd6e03155a0d0e7c08cfdebd5bb482fa45f0 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:48:47 +0100 Subject: [PATCH 22/34] Remove the definitely last remnant of earlier PR --- Doc/library/dis.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index f3bcdd65dd7628..eba21aa7b30228 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -861,8 +861,6 @@ iterations of the loop. Returns with ``STACK[-1]`` to the caller of the function. - .. versionadded:: 3.14 - .. opcode:: YIELD_VALUE From 050fc1ea03ce0b4c7c0b068ff6c0e2b75a4f1536 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 15:56:34 +0100 Subject: [PATCH 23/34] Document LOAD_INT and add news --- Doc/library/dis.rst | 8 ++++++++ .../2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst | 4 ++++ 2 files changed, 12 insertions(+) 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 eba21aa7b30228..aa4ed7bbc8f8f9 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1079,6 +1079,14 @@ iterations of the loop. Pushes ``co_consts[consti]`` onto the stack. +.. opcode:: LOAD_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. 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 00000000000000..6a3e0089521279 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst @@ -0,0 +1,4 @@ +Adds :opcode:`LOAD_INT` and :opcode:`LOAD_CONST_IMMORTAL` instructions. +``LOAD_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. From 46055c1fa1a516cc28b293d7d8cdb3f15025294c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 16:03:50 +0100 Subject: [PATCH 24/34] Revert unnecessary name changes --- Include/internal/pycore_ceval.h | 2 -- Python/ceval.c | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 0f80ba7575ec7b..cff2b1f7114793 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -267,8 +267,6 @@ PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, Py PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); PyAPI_FUNC(int) _PyEval_UnpackIterableStackRef(PyThreadState *tstate, _PyStackRef v, int argcnt, int argcntafter, _PyStackRef *sp); PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); -PyAPI_FUNC(void) _PyEval_ClearThreadFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); -PyAPI_FUNC(void) _PyEval_ClearGenFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch); PyAPI_FUNC(void) _PyObjectArray_Free(PyObject **array, PyObject **scratch); diff --git a/Python/ceval.c b/Python/ceval.c index 73d1a3f71994cc..c592d92418053c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1707,7 +1707,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, } void -_PyEval_ClearThreadFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) +clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_THREAD); // Make sure that this is, indeed, the top frame. We can't check this in @@ -1723,7 +1723,7 @@ _PyEval_ClearThreadFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) } void -_PyEval_ClearGenFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) +clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_GENERATOR); PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); @@ -1743,10 +1743,10 @@ void _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) { if (frame->owner == FRAME_OWNED_BY_THREAD) { - _PyEval_ClearThreadFrame(tstate, frame); + clear_thread_frame(tstate, frame); } else { - _PyEval_ClearGenFrame(tstate, frame); + clear_gen_frame(tstate, frame); } } @@ -1766,7 +1766,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, _PyStackRef func, _PyFrame_Initialize(frame, func, locals, code, 0, previous); if (initialize_locals(tstate, func_obj, frame->localsplus, args, argcount, kwnames)) { assert(frame->owner == FRAME_OWNED_BY_THREAD); - _PyEval_ClearThreadFrame(tstate, frame); + clear_thread_frame(tstate, frame); return NULL; } return frame; From 79305d27a8364197c2bc4e305517d03da866463a Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 16:14:27 +0100 Subject: [PATCH 25/34] Make functions static again to avoid warning --- Python/ceval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index c592d92418053c..ca75646b585f07 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1706,7 +1706,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, return -1; } -void +static void clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_THREAD); @@ -1722,7 +1722,7 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) _PyThreadState_PopFrame(tstate, frame); } -void +static void clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_GENERATOR); From 7e4b2a8e5b859091ceb8e6984b292fb80d1e271d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Oct 2024 16:23:29 +0100 Subject: [PATCH 26/34] implement review suggestion --- Lib/test/test_ast/test_ast.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index f26bcc058d1287..13a5a7571197c7 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ def get_load_const(self, tree): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname in ('LOAD_CONST', 'LOAD_CONST_IMMORTAL'): + if instr.opname in ('LOAD_CONST', 'LOAD_CONST_IMMORTAL', 'LOAD_INT'): consts.append(instr.argval) return consts @@ -2311,6 +2311,7 @@ def get_load_const(self, tree): def test_load_const(self): consts = [None, True, False, + 124, 2.0, 3j, "unicode", From 57e891eee4f5ed88c9d4faaeb10c536989dc2d24 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 10:06:24 +0000 Subject: [PATCH 27/34] Address review comments --- Include/internal/pycore_magic_number.h | 2 +- Lib/test/test_ast/test_ast.py | 2 +- .../2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst | 1 + Python/codegen.c | 2 +- Python/flowgraph.c | 2 +- Python/specialize.c | 8 +++----- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 579e8b5f4250dc..17d6889a37d395 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -261,7 +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_INT and LOAD_CONST_IMMORTAL instructions) + Python 3.14a2 3609 (Add LOAD_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) Python 3.15 will start with 3650 diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 13a5a7571197c7..1eb2f83efb7ac7 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2303,7 +2303,7 @@ def get_load_const(self, tree): co = compile(tree, '', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname in ('LOAD_CONST', 'LOAD_CONST_IMMORTAL', 'LOAD_INT'): + if instr.opcode in dis.hasconst: consts.append(instr.argval) return consts 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 index 6a3e0089521279..98260a45905699 100644 --- 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 @@ -2,3 +2,4 @@ Adds :opcode:`LOAD_INT` and :opcode:`LOAD_CONST_IMMORTAL` instructions. ``LOAD_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 ``RETRUN_CONST`` instruction. diff --git a/Python/codegen.c b/Python/codegen.c index b27a6c3fd01e95..c416490e453db1 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -665,7 +665,7 @@ codegen_setup_annotations_scope(compiler *c, location loc, key, loc.lineno, NULL, &umd)); // Insert None into consts to prevent an annotation - // apperaing to be a docstring + // appearing to be a docstring _PyCompile_AddConst(c, Py_None); // if .format != 1: raise NotImplementedError _Py_DECLARE_STR(format, ".format"); diff --git a/Python/flowgraph.c b/Python/flowgraph.c index e3f7dae7ae2e47..3a78593d08abdf 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -2419,7 +2419,7 @@ convert_pseudo_conditional_jumps(cfg_builder *g) } static int -convert_pseudo_ops(cfg_builder *g, int is_generator) +convert_pseudo_ops(cfg_builder *g) { basicblock *entryblock = g->g_entryblock; for (basicblock *b = entryblock; b != NULL; b = b->b_next) { diff --git a/Python/specialize.c b/Python/specialize.c index ee8acd17127814..ae47809305a300 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -448,6 +448,7 @@ _PyCode_Quicken(PyCodeObject *code) 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) { @@ -469,16 +470,13 @@ _PyCode_Quicken(PyCodeObject *code) else if (opcode == LOAD_CONST) { /* We can't do this in the bytecode compiler as * marshalling can intern strings and make them immortal. */ - oparg = (oparg << 8) | instructions[i].op.arg; + 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 = (oparg << 8) | instructions[i].op.arg; - } - else { + if (opcode != EXTENDED_ARG) { oparg = 0; } } From 207e35ec068e88bc5eab8305181e1688a2135478 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 10:26:25 +0000 Subject: [PATCH 28/34] Fix typo --- .../2024-10-25-15-56-14.gh-issue-125837.KlCdgD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 98260a45905699..21c7277101e739 100644 --- 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 @@ -2,4 +2,4 @@ Adds :opcode:`LOAD_INT` and :opcode:`LOAD_CONST_IMMORTAL` instructions. ``LOAD_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 ``RETRUN_CONST`` instruction. +Removes ``RETURN_CONST`` instruction. From 7c88f6934c168d1fcdab365c74ff2c19209e8ab9 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 10:47:05 +0000 Subject: [PATCH 29/34] Remove extra argument --- Python/flowgraph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 3a78593d08abdf..78de6295c9f95a 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -2899,7 +2899,7 @@ _PyCfg_OptimizedCfgToInstructionSequence(cfg_builder *g, return ERROR; } - RETURN_IF_ERROR(convert_pseudo_ops(g, IS_GENERATOR(code_flags))); + RETURN_IF_ERROR(convert_pseudo_ops(g)); /* Order of basic blocks must have been determined by now */ From 9d4e5750acc617dbfe545710737b68c4972a6181 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 14:49:31 +0000 Subject: [PATCH 30/34] Rename LOAD_INT to LOAD_SMALL_INT --- Doc/library/dis.rst | 2 +- Include/internal/pycore_magic_number.h | 2 +- Include/internal/pycore_opcode_metadata.h | 16 ++-- Include/internal/pycore_uop_ids.h | 10 +- Include/internal/pycore_uop_metadata.h | 32 +++---- Include/opcode_ids.h | 4 +- Lib/_opcode_metadata.py | 4 +- Lib/dis.py | 4 +- Lib/test/test_compiler_codegen.py | 18 ++-- Lib/test/test_dis.py | 96 +++++++++---------- Lib/test/test_peepholer.py | 6 +- ...-10-25-15-56-14.gh-issue-125837.KlCdgD.rst | 4 +- Python/bytecodes.c | 2 +- Python/codegen.c | 2 +- Python/executor_cases.c.h | 10 +- Python/flowgraph.c | 10 +- Python/generated_cases.c.h | 32 +++---- Python/opcode_targets.h | 2 +- Python/optimizer_bytecodes.c | 2 +- Python/optimizer_cases.c.h | 2 +- 20 files changed, 130 insertions(+), 130 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index aa4ed7bbc8f8f9..6c12d1b5e0dcea 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1079,7 +1079,7 @@ iterations of the loop. Pushes ``co_consts[consti]`` onto the stack. -.. opcode:: LOAD_INT (i) +.. opcode:: LOAD_SMALL_INT (i) Pushes the integer ``i`` onto the stack. ``i`` must be in ``range(256)`` diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 17d6889a37d395..14e29576875c6e 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -261,7 +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_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) + Python 3.14a2 3609 (Add LOAD_SMALL_INT and LOAD_CONST_IMMORTAL instructions, remove RETURN_CONST) Python 3.15 will start with 3650 diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index c1073009369dd5..cbea294684cdf4 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -337,12 +337,12 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_GLOBAL_MODULE: return 0; - case LOAD_INT: - return 0; case LOAD_LOCALS: return 0; case LOAD_NAME: return 0; + case LOAD_SMALL_INT: + return 0; case LOAD_SPECIAL: return 1; case LOAD_SUPER_ATTR: @@ -796,12 +796,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1 + (oparg & 1); case LOAD_GLOBAL_MODULE: return 1 + (oparg & 1); - case LOAD_INT: - return 1; case LOAD_LOCALS: return 1; case LOAD_NAME: return 1; + case LOAD_SMALL_INT: + return 1; case LOAD_SPECIAL: return 2; case LOAD_SUPER_ATTR: @@ -1160,9 +1160,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = { [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, - [LOAD_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_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 | HAS_CONST_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 }, @@ -1365,9 +1365,9 @@ _PyOpcode_macro_expansion[256] = { [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } }, [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION_PUSH_KEYS, 1, 2 }, { _LOAD_GLOBAL_BUILTINS_FROM_KEYS, 1, 3 } } }, [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION_PUSH_KEYS, 1, 1 }, { _LOAD_GLOBAL_MODULE_FROM_KEYS, 1, 3 } } }, - [LOAD_INT] = { .nuops = 1, .uops = { { _LOAD_INT, 0, 0 } } }, [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 } } }, @@ -1584,9 +1584,9 @@ const char *_PyOpcode_OpName[266] = { [LOAD_GLOBAL] = "LOAD_GLOBAL", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [LOAD_INT] = "LOAD_INT", [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", @@ -1835,9 +1835,9 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_GLOBAL] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_INT] = LOAD_INT, [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, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 6fe620345fab0f..de628d240d1c07 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -220,13 +220,13 @@ extern "C" { #define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 440 #define _LOAD_GLOBAL_MODULE 441 #define _LOAD_GLOBAL_MODULE_FROM_KEYS 442 -#define _LOAD_INT 443 -#define _LOAD_INT_0 444 -#define _LOAD_INT_1 445 -#define _LOAD_INT_2 446 -#define _LOAD_INT_3 447 #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 diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 7d624407fdca2b..861e612925dee8 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -37,11 +37,11 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_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_INT_0] = HAS_CONST_FLAG, - [_LOAD_INT_1] = HAS_CONST_FLAG, - [_LOAD_INT_2] = HAS_CONST_FLAG, - [_LOAD_INT_3] = HAS_CONST_FLAG, - [_LOAD_INT] = HAS_ARG_FLAG | HAS_CONST_FLAG, + [_LOAD_SMALL_INT_0] = HAS_CONST_FLAG, + [_LOAD_SMALL_INT_1] = HAS_CONST_FLAG, + [_LOAD_SMALL_INT_2] = HAS_CONST_FLAG, + [_LOAD_SMALL_INT_3] = HAS_CONST_FLAG, + [_LOAD_SMALL_INT] = HAS_ARG_FLAG | HAS_CONST_FLAG, [_STORE_FAST_0] = HAS_LOCAL_FLAG, [_STORE_FAST_1] = HAS_LOCAL_FLAG, [_STORE_FAST_2] = HAS_LOCAL_FLAG, @@ -295,7 +295,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = { [_LOAD_FAST] = 8, - [_LOAD_INT] = 4, + [_LOAD_SMALL_INT] = 4, [_STORE_FAST] = 8, [_INIT_CALL_PY_EXACT_ARGS] = 5, }; @@ -491,13 +491,13 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_GLOBAL_BUILTINS_FROM_KEYS] = "_LOAD_GLOBAL_BUILTINS_FROM_KEYS", [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE", [_LOAD_GLOBAL_MODULE_FROM_KEYS] = "_LOAD_GLOBAL_MODULE_FROM_KEYS", - [_LOAD_INT] = "_LOAD_INT", - [_LOAD_INT_0] = "_LOAD_INT_0", - [_LOAD_INT_1] = "_LOAD_INT_1", - [_LOAD_INT_2] = "_LOAD_INT_2", - [_LOAD_INT_3] = "_LOAD_INT_3", [_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", @@ -613,15 +613,15 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_CONST_IMMORTAL: return 0; - case _LOAD_INT_0: + case _LOAD_SMALL_INT_0: return 0; - case _LOAD_INT_1: + case _LOAD_SMALL_INT_1: return 0; - case _LOAD_INT_2: + case _LOAD_SMALL_INT_2: return 0; - case _LOAD_INT_3: + case _LOAD_SMALL_INT_3: return 0; - case _LOAD_INT: + case _LOAD_SMALL_INT: return 0; case _STORE_FAST_0: return 1; diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index eb499e9576dbe3..ce3d23eaa6d56d 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -98,8 +98,8 @@ extern "C" { #define LOAD_FROM_DICT_OR_DEREF 85 #define LOAD_FROM_DICT_OR_GLOBALS 86 #define LOAD_GLOBAL 87 -#define LOAD_INT 88 -#define LOAD_NAME 89 +#define LOAD_NAME 88 +#define LOAD_SMALL_INT 89 #define LOAD_SPECIAL 90 #define LOAD_SUPER_ATTR 91 #define MAKE_CELL 92 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 1561461de2653e..cda3c340c322f3 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -291,8 +291,8 @@ 'LOAD_FROM_DICT_OR_DEREF': 85, 'LOAD_FROM_DICT_OR_GLOBALS': 86, 'LOAD_GLOBAL': 87, - 'LOAD_INT': 88, - 'LOAD_NAME': 89, + 'LOAD_NAME': 88, + 'LOAD_SMALL_INT': 89, 'LOAD_SPECIAL': 90, 'LOAD_SUPER_ATTR': 91, 'MAKE_CELL': 92, diff --git a/Lib/dis.py b/Lib/dis.py index 4592c276cc6830..80e2b1a990f0aa 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -36,7 +36,7 @@ ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] -LOAD_INT = opmap['LOAD_INT'] +LOAD_SMALL_INT = opmap['LOAD_SMALL_INT'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] FOR_ITER = opmap['FOR_ITER'] @@ -675,7 +675,7 @@ def _get_const_value(op, arg, co_consts): """ assert op in hasconst - if op == LOAD_INT: + if op == LOAD_SMALL_INT: return arg argval = UNKNOWN if co_consts is not None: diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index 15f759d50ca78f..2dd7cf65ee3c2a 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -29,10 +29,10 @@ def test_if_expression(self): ('LOAD_CONST', 0, 1), ('TO_BOOL', 0, 1), ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), - ('LOAD_INT', 42, 1), + ('LOAD_SMALL_INT', 42, 1), ('JUMP_NO_INTERRUPT', exit_lbl := self.Label()), false_lbl, - ('LOAD_INT', 24, 1), + ('LOAD_SMALL_INT', 24, 1), exit_lbl, ('POP_TOP', None), ('LOAD_CONST', 1), @@ -82,7 +82,7 @@ def f(x): # Function body ('RESUME', 0), ('LOAD_FAST', 0), - ('LOAD_INT', 42), + ('LOAD_SMALL_INT', 42), ('BINARY_OP', 0), ('RETURN_VALUE', None), ('LOAD_CONST', 0), @@ -125,23 +125,23 @@ def g(): [ ('RESUME', 0), ('NOP', None), - ('LOAD_INT', 12), + ('LOAD_SMALL_INT', 12), ('RETURN_VALUE', None), ('LOAD_CONST', 1), ('RETURN_VALUE', None), ], [ ('RESUME', 0), - ('LOAD_INT', 1), + ('LOAD_SMALL_INT', 1), ('STORE_FAST', 0), - ('LOAD_INT', 2), + ('LOAD_SMALL_INT', 2), ('STORE_FAST', 1), - ('LOAD_INT', 3), + ('LOAD_SMALL_INT', 3), ('STORE_FAST', 2), - ('LOAD_INT', 4), + ('LOAD_SMALL_INT', 4), ('STORE_FAST', 3), ('NOP', None), - ('LOAD_INT', 42), + ('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 6e9094d1848ace..f4a77e19c8adda 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -48,7 +48,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) @@ -59,7 +59,7 @@ def cm(cls, x): dis_c_instance_method_bytes = """\ RESUME 0 LOAD_FAST 1 - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 @@ -71,7 +71,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) @@ -83,7 +83,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 0 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) COMPARE_OP 72 (==) STORE_FAST 0 (x) LOAD_CONST 0 (None) @@ -114,7 +114,7 @@ def _f(a): CALL 1 POP_TOP -%3d LOAD_INT 1 (1) +%3d LOAD_SMALL_INT 1 (1) RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -128,7 +128,7 @@ def _f(a): 14 CALL 1 22 POP_TOP -%3d 24 LOAD_INT 1 (1) +%3d 24 LOAD_SMALL_INT 1 (1) 26 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -142,7 +142,7 @@ def _f(a): %-14s CALL 1 %-14s POP_TOP -%-14s LOAD_INT 1 (1) +%-14s LOAD_SMALL_INT 1 (1) %-14s RETURN_VALUE """ @@ -152,7 +152,7 @@ def _f(a): LOAD_FAST 0 CALL 1 POP_TOP - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) RETURN_VALUE """ @@ -165,9 +165,9 @@ def bug708901(): %3d RESUME 0 %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) -%3d LOAD_INT 10 (10) +%3d LOAD_SMALL_INT 10 (10) %3d CALL 2 GET_ITER @@ -203,7 +203,7 @@ def bug1333982(x=[]): GET_ITER CALL 0 -%3d LOAD_INT 1 (1) +%3d LOAD_SMALL_INT 1 (1) %3d BINARY_OP 0 (+) CALL 0 @@ -273,9 +273,9 @@ def wrap_func_w_kwargs(): %3d RESUME 0 %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_INT 1 (1) - LOAD_INT 2 (2) - LOAD_INT 5 (5) + LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 2 (2) + LOAD_SMALL_INT 5 (5) LOAD_CONST 1 (('c',)) CALL_KW 3 POP_TOP @@ -287,7 +287,7 @@ def wrap_func_w_kwargs(): dis_intrinsic_1_2 = """\ 0 RESUME 0 - 1 LOAD_INT 0 (0) + 1 LOAD_SMALL_INT 0 (0) LOAD_CONST 0 (('*',)) IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) @@ -351,7 +351,7 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) BINARY_OP 0 (+) RETURN_VALUE """ @@ -362,7 +362,7 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) BINARY_OP 0 (+) STORE_NAME 0 (x) LOAD_CONST 0 (None) @@ -380,14 +380,14 @@ def wrap_func_w_kwargs(): dis_annot_stmt_str = """\ 0 RESUME 0 - 2 LOAD_INT 1 (1) + 2 LOAD_SMALL_INT 1 (1) STORE_NAME 0 (x) - 4 LOAD_INT 1 (1) + 4 LOAD_SMALL_INT 1 (1) LOAD_NAME 1 (lst) LOAD_NAME 2 (fun) PUSH_NULL - LOAD_INT 0 (0) + LOAD_SMALL_INT 0 (0) CALL 1 STORE_SUBSCR @@ -425,13 +425,13 @@ def foo(a: int, b: str) -> str: dis_compound_stmt_str = """\ 0 RESUME 0 - 1 LOAD_INT 0 (0) + 1 LOAD_SMALL_INT 0 (0) STORE_NAME 0 (x) 2 L1: NOP 3 LOAD_NAME 0 (x) - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) BINARY_OP 13 (+=) STORE_NAME 0 (x) JUMP_BACKWARD 8 (to L1) @@ -442,8 +442,8 @@ def foo(a: int, b: str) -> str: %4d NOP -%4d L1: LOAD_INT 1 (1) - LOAD_INT 0 (0) +%4d L1: LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 0 (0) --> BINARY_OP 11 (/) POP_TOP @@ -534,7 +534,7 @@ def _with(c): CALL 0 L1: POP_TOP -%4d LOAD_INT 1 (1) +%4d LOAD_SMALL_INT 1 (1) STORE_FAST 1 (x) %4d L2: LOAD_CONST 0 (None) @@ -543,7 +543,7 @@ def _with(c): CALL 3 POP_TOP -%4d LOAD_INT 2 (2) +%4d LOAD_SMALL_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -559,7 +559,7 @@ def _with(c): POP_TOP POP_TOP -%4d LOAD_INT 2 (2) +%4d LOAD_SMALL_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -605,7 +605,7 @@ async def _asyncwith(c): L5: END_SEND L6: POP_TOP -%4d LOAD_INT 1 (1) +%4d LOAD_SMALL_INT 1 (1) STORE_FAST 1 (x) %4d L7: LOAD_CONST 0 (None) @@ -621,7 +621,7 @@ async def _asyncwith(c): L11: END_SEND POP_TOP -%4d LOAD_INT 2 (2) +%4d LOAD_SMALL_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -649,7 +649,7 @@ async def _asyncwith(c): POP_TOP POP_TOP -%4d LOAD_INT 2 (2) +%4d LOAD_SMALL_INT 2 (2) STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -739,7 +739,7 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) RETURN_VALUE -- L1: PUSH_EXC_INFO @@ -885,7 +885,7 @@ def loop_test(): %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) LIST_EXTEND 1 - LOAD_INT 3 (3) + LOAD_SMALL_INT 3 (3) BINARY_OP 5 (*) GET_ITER L1: FOR_ITER_LIST 14 (to L2) @@ -1060,7 +1060,7 @@ def test_dis_with_linenos_but_no_columns(self): expect = '\n'.join([ '1:0-1:0 RESUME 0', '', - '2:5-2:6 LOAD_INT 1 (1)', + '2:5-2:6 LOAD_SMALL_INT 1 (1)', '2:?-2:? STORE_FAST 0 (x)', '2:?-2:? LOAD_CONST 0 (None)', '2:?-2:? RETURN_VALUE', @@ -1284,7 +1284,7 @@ def test_binary_specialize(self): 0 RESUME_CHECK 0 1 LOAD_NAME 0 (a) - LOAD_INT 0 (0) + LOAD_SMALL_INT 0 (0) %s RETURN_VALUE """ @@ -1321,7 +1321,7 @@ def test_call_specialize(self): 1 LOAD_NAME 0 (str) PUSH_NULL - LOAD_INT 1 (1) + LOAD_SMALL_INT 1 (1) CALL_STR_1 1 RETURN_VALUE """ @@ -1747,7 +1747,7 @@ def _prepare_test_cases(): 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_INT', opcode=88, arg=1, 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=88, arg=1, argval=1, argrepr='1', 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=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), @@ -1802,7 +1802,7 @@ def _prepare_test_cases(): 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_INT', opcode=88, arg=10, 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=88, arg=10, argval=10, argrepr='10', 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')]), @@ -1812,12 +1812,12 @@ def _prepare_test_cases(): 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_INT', opcode=88, arg=4, 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=88, arg=4, argval=4, argrepr='4', 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=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_INT', opcode=88, arg=6, 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=88, arg=6, argval=6, argrepr='6', 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=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')]), @@ -1837,16 +1837,16 @@ def _prepare_test_cases(): 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_INT', opcode=88, arg=1, 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=88, arg=1, argval=1, argrepr='1', 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_INT', opcode=88, arg=6, 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=88, arg=6, argval=6, argrepr='6', 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=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_INT', opcode=88, arg=4, 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=88, arg=4, argval=4, argrepr='4', 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=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')]), @@ -1856,8 +1856,8 @@ def _prepare_test_cases(): 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_INT', opcode=88, arg=1, 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_INT', opcode=88, arg=0, 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=88, arg=1, 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_SMALL_INT', opcode=88, arg=0, argval=0, argrepr='0', 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), @@ -2325,20 +2325,20 @@ def test_bytecode_co_positions(self): class TestBytecodeTestCase(BytecodeTestCase): def test_assert_not_in_with_op_not_in_bytecode(self): code = compile("a = 1", "", "exec") - self.assertInBytecode(code, "LOAD_INT", 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_INT") - self.assertInBytecode(code, "LOAD_INT", 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_INT", 1) + self.assertNotInBytecode(code, "LOAD_SMALL_INT", 1) class TestFinderMethods(unittest.TestCase): def test__find_imports(self): diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index dc586e4ddd14fd..c7da151dce3b37 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -249,7 +249,7 @@ def test_folding_of_binops_on_constants(self): with self.subTest(line=line): code = compile(line, '', 'single') if isinstance(elem, int): - self.assertInBytecode(code, 'LOAD_INT', elem) + self.assertInBytecode(code, 'LOAD_SMALL_INT', elem) else: self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): @@ -258,7 +258,7 @@ def test_folding_of_binops_on_constants(self): # Verify that unfoldables are skipped code = compile('a=2+"b"', '', 'single') - self.assertInBytecode(code, 'LOAD_INT', 2) + self.assertInBytecode(code, 'LOAD_SMALL_INT', 2) self.assertInBytecode(code, 'LOAD_CONST', 'b') self.check_lnotab(code) @@ -311,7 +311,7 @@ def test_folding_of_unaryops_on_constants(self): with self.subTest(line=line): code = compile(line, '', 'single') if isinstance(elem, int): - self.assertInBytecode(code, 'LOAD_INT', elem) + self.assertInBytecode(code, 'LOAD_SMALL_INT', elem) else: self.assertInBytecode(code, 'LOAD_CONST', elem) for instr in dis.get_instructions(code): 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 index 21c7277101e739..9538f34f969377 100644 --- 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 @@ -1,5 +1,5 @@ -Adds :opcode:`LOAD_INT` and :opcode:`LOAD_CONST_IMMORTAL` instructions. -``LOAD_INT`` pushes a small integer equal to the ``oparg`` to the stack. +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/Python/bytecodes.c b/Python/bytecodes.c index fba5af6296f979..2bcbe6a195ddae 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -269,7 +269,7 @@ dummy_func( value = PyStackRef_FromPyObjectImmortal(obj); } - replicate(4) inst(LOAD_INT, (-- value)) { + replicate(4) inst(LOAD_SMALL_INT, (-- value)) { /* Tell code generator that this is a const load */ (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); diff --git a/Python/codegen.c b/Python/codegen.c index c416490e453db1..adf945ff514fb6 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -284,7 +284,7 @@ codegen_addop_load_const(compiler *c, location loc, PyObject *o) int overflow; long val = PyLong_AsLongAndOverflow(o, &overflow); if (!overflow && val >= 0 && val < 256 && val < _PY_NSMALLPOSINTS) { - ADDOP_I(c, loc, LOAD_INT, val); + ADDOP_I(c, loc, LOAD_SMALL_INT, val); return SUCCESS; } } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 7cfa55d01536f0..3f27b39276e89b 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -222,7 +222,7 @@ break; } - case _LOAD_INT_0: { + case _LOAD_SMALL_INT_0: { _PyStackRef value; oparg = 0; assert(oparg == CURRENT_OPARG()); @@ -237,7 +237,7 @@ break; } - case _LOAD_INT_1: { + case _LOAD_SMALL_INT_1: { _PyStackRef value; oparg = 1; assert(oparg == CURRENT_OPARG()); @@ -252,7 +252,7 @@ break; } - case _LOAD_INT_2: { + case _LOAD_SMALL_INT_2: { _PyStackRef value; oparg = 2; assert(oparg == CURRENT_OPARG()); @@ -267,7 +267,7 @@ break; } - case _LOAD_INT_3: { + case _LOAD_SMALL_INT_3: { _PyStackRef value; oparg = 3; assert(oparg == CURRENT_OPARG()); @@ -282,7 +282,7 @@ break; } - case _LOAD_INT: { + case _LOAD_SMALL_INT: { _PyStackRef value; oparg = CURRENT_OPARG(); /* Tell code generator that this is a const load */ diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 78de6295c9f95a..6bf3109123a8f1 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1115,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 || prev_opcode == LOAD_INT) { + if (prev_opcode == LOAD_CONST || prev_opcode == LOAD_SMALL_INT) { is_redundant_pair = true; } else if (prev_opcode == COPY && prev_oparg == 1) { @@ -1272,7 +1272,7 @@ get_const_value(int opcode, int oparg, PyObject *co_consts) if (opcode == LOAD_CONST) { constant = PyList_GET_ITEM(co_consts, oparg); } - if (opcode == LOAD_INT) { + if (opcode == LOAD_SMALL_INT) { return PyLong_FromLong(oparg); } @@ -1570,7 +1570,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * oparg = inst->i_oparg; } assert(!IS_ASSEMBLER_OPCODE(opcode)); - if (opcode != LOAD_CONST && opcode != LOAD_INT) { + if (opcode != LOAD_CONST && opcode != LOAD_SMALL_INT) { continue; } int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; @@ -2102,7 +2102,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { int opcode = b->b_instr[i].i_opcode; - if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_INT) { + if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_SMALL_INT) { int index = b->b_instr[i].i_oparg; index_map[index] = index; } @@ -2156,7 +2156,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { int opcode = b->b_instr[i].i_opcode; - if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_INT) { + if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_SMALL_INT) { int index = b->b_instr[i].i_oparg; assert(reverse_index_map[index] >= 0); assert(reverse_index_map[index] < n_used_consts); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 51bd524dee3991..7ba6f4a0918483 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6189,22 +6189,6 @@ DISPATCH(); } - TARGET(LOAD_INT) { - frame->instr_ptr = next_instr; - next_instr += 1; - INSTRUCTION_STATS(LOAD_INT); - _PyStackRef value; - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; - 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_LOCALS) { frame->instr_ptr = next_instr; next_instr += 1; @@ -6242,6 +6226,22 @@ DISPATCH(); } + TARGET(LOAD_SMALL_INT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_SMALL_INT); + _PyStackRef value; + /* Tell code generator that this is a const load */ + (void)FRAME_CO_CONSTS; + 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; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index ca1889ce7591db..c93941dcac4abf 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -87,8 +87,8 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FROM_DICT_OR_DEREF, &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, &&TARGET_LOAD_GLOBAL, - &&TARGET_LOAD_INT, &&TARGET_LOAD_NAME, + &&TARGET_LOAD_SMALL_INT, &&TARGET_LOAD_SPECIAL, &&TARGET_LOAD_SUPER_ATTR, &&TARGET_MAKE_CELL, diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 50b61f8b62931c..2b75a62c6844e3 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -433,7 +433,7 @@ dummy_func(void) { value = sym_new_const(ctx, val); } - op(_LOAD_INT, (-- value)) { + op(_LOAD_SMALL_INT, (-- value)) { PyObject *val = PyLong_FromLong(this_instr->oparg); value = sym_new_const(ctx, val); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 364fa9911b29b4..4eb27f5c3f4fee 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -79,7 +79,7 @@ break; } - case _LOAD_INT: { + case _LOAD_SMALL_INT: { _Py_UopsSymbol *value; PyObject *val = PyLong_FromLong(this_instr->oparg); value = sym_new_const(ctx, val); From ae1145331a96925a7e9afee26d18eb33bc071827 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 14:51:49 +0000 Subject: [PATCH 31/34] Regenerate test file --- Programs/test_frozenmain.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 5f6c1e50140fee..c936622c020e3c 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,16 +1,16 @@ // 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,168,0,0,0,149,0,88,0,79,0, - 70,0,111,0,88,0,79,0,70,1,111,1,89,2,31,0, - 79,1,49,1,0,0,0,0,0,0,29,0,89,2,31,0, - 79,2,89,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,89,1,77,8,0,0,0,0,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,3,2,0,0,0,111,5,79,4,16,0,67,20, - 0,0,111,6,89,2,31,0,79,5,89,6,12,0,79,6, - 89,5,89,6,2,0,0,0,12,0,47,4,49,1,0,0, + 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,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, From 3a504371f1358ff0690ffd5a2ed4d5111c9aa4e4 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 14:53:40 +0000 Subject: [PATCH 32/34] Fix test_dis --- Lib/test/test_dis.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index f4a77e19c8adda..df090f95646276 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1747,7 +1747,7 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=88, arg=1, 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='1', 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=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), @@ -1802,7 +1802,7 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=88, arg=10, 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='10', 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')]), @@ -1812,12 +1812,12 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=88, arg=4, 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='4', 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=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_SMALL_INT', opcode=88, arg=6, 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='6', 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=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')]), @@ -1837,16 +1837,16 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=88, arg=1, 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='1', 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_SMALL_INT', opcode=88, arg=6, 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='6', 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=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_SMALL_INT', opcode=88, arg=4, 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='4', 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=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')]), @@ -1856,8 +1856,8 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=88, arg=1, 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_SMALL_INT', opcode=88, arg=0, 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='1', 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='0', 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), From 47927cfd3003daca35ba8807209d9c2c7bfeb505 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Oct 2024 17:44:53 +0000 Subject: [PATCH 33/34] Don't mark LOAD_SMALL_INT as having a constant, as it doesn't load from code.co_consts --- Include/internal/pycore_opcode_metadata.h | 2 +- Include/internal/pycore_uop_metadata.h | 10 +-- Lib/dis.py | 5 +- Lib/test/test_ast/test_ast.py | 1 - Lib/test/test_dis.py | 88 +++++++++++------------ Python/bytecodes.c | 2 - Python/executor_cases.c.h | 10 --- Python/flowgraph.c | 14 ++-- Python/generated_cases.c.h | 2 - 9 files changed, 63 insertions(+), 71 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index cbea294684cdf4..fbb57dd5170433 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1162,7 +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 | HAS_CONST_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 }, diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 861e612925dee8..4cfdecec78b0db 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -37,11 +37,11 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_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] = HAS_CONST_FLAG, - [_LOAD_SMALL_INT_1] = HAS_CONST_FLAG, - [_LOAD_SMALL_INT_2] = HAS_CONST_FLAG, - [_LOAD_SMALL_INT_3] = HAS_CONST_FLAG, - [_LOAD_SMALL_INT] = 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, diff --git a/Lib/dis.py b/Lib/dis.py index 80e2b1a990f0aa..1000684a445ad2 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -673,7 +673,7 @@ 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 @@ -993,7 +993,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 1eb2f83efb7ac7..bac771b8e0b52e 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2311,7 +2311,6 @@ def get_load_const(self, tree): def test_load_const(self): consts = [None, True, False, - 124, 2.0, 3j, "unicode", diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index df090f95646276..4ae2a90fca1c21 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -48,7 +48,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) @@ -59,7 +59,7 @@ def cm(cls, x): dis_c_instance_method_bytes = """\ RESUME 0 LOAD_FAST 1 - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 STORE_ATTR 0 @@ -71,7 +71,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 1 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) @@ -83,7 +83,7 @@ def cm(cls, x): %3d RESUME 0 %3d LOAD_FAST 0 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 COMPARE_OP 72 (==) STORE_FAST 0 (x) LOAD_CONST 0 (None) @@ -114,7 +114,7 @@ def _f(a): CALL 1 POP_TOP -%3d LOAD_SMALL_INT 1 (1) +%3d LOAD_SMALL_INT 1 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -128,7 +128,7 @@ def _f(a): 14 CALL 1 22 POP_TOP -%3d 24 LOAD_SMALL_INT 1 (1) +%3d 24 LOAD_SMALL_INT 1 26 RETURN_VALUE """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, @@ -142,7 +142,7 @@ def _f(a): %-14s CALL 1 %-14s POP_TOP -%-14s LOAD_SMALL_INT 1 (1) +%-14s LOAD_SMALL_INT 1 %-14s RETURN_VALUE """ @@ -152,7 +152,7 @@ def _f(a): LOAD_FAST 0 CALL 1 POP_TOP - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 RETURN_VALUE """ @@ -165,9 +165,9 @@ def bug708901(): %3d RESUME 0 %3d LOAD_GLOBAL 1 (range + NULL) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 -%3d LOAD_SMALL_INT 10 (10) +%3d LOAD_SMALL_INT 10 %3d CALL 2 GET_ITER @@ -203,7 +203,7 @@ def bug1333982(x=[]): GET_ITER CALL 0 -%3d LOAD_SMALL_INT 1 (1) +%3d LOAD_SMALL_INT 1 %3d BINARY_OP 0 (+) CALL 0 @@ -273,9 +273,9 @@ def wrap_func_w_kwargs(): %3d RESUME 0 %3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_SMALL_INT 1 (1) - LOAD_SMALL_INT 2 (2) - LOAD_SMALL_INT 5 (5) + LOAD_SMALL_INT 1 + LOAD_SMALL_INT 2 + LOAD_SMALL_INT 5 LOAD_CONST 1 (('c',)) CALL_KW 3 POP_TOP @@ -287,7 +287,7 @@ def wrap_func_w_kwargs(): dis_intrinsic_1_2 = """\ 0 RESUME 0 - 1 LOAD_SMALL_INT 0 (0) + 1 LOAD_SMALL_INT 0 LOAD_CONST 0 (('*',)) IMPORT_NAME 0 (math) CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) @@ -351,7 +351,7 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 BINARY_OP 0 (+) RETURN_VALUE """ @@ -362,7 +362,7 @@ def wrap_func_w_kwargs(): 0 RESUME 0 1 LOAD_NAME 0 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 BINARY_OP 0 (+) STORE_NAME 0 (x) LOAD_CONST 0 (None) @@ -380,14 +380,14 @@ def wrap_func_w_kwargs(): dis_annot_stmt_str = """\ 0 RESUME 0 - 2 LOAD_SMALL_INT 1 (1) + 2 LOAD_SMALL_INT 1 STORE_NAME 0 (x) - 4 LOAD_SMALL_INT 1 (1) + 4 LOAD_SMALL_INT 1 LOAD_NAME 1 (lst) LOAD_NAME 2 (fun) PUSH_NULL - LOAD_SMALL_INT 0 (0) + LOAD_SMALL_INT 0 CALL 1 STORE_SUBSCR @@ -425,13 +425,13 @@ def foo(a: int, b: str) -> str: dis_compound_stmt_str = """\ 0 RESUME 0 - 1 LOAD_SMALL_INT 0 (0) + 1 LOAD_SMALL_INT 0 STORE_NAME 0 (x) 2 L1: NOP 3 LOAD_NAME 0 (x) - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 BINARY_OP 13 (+=) STORE_NAME 0 (x) JUMP_BACKWARD 8 (to L1) @@ -442,8 +442,8 @@ def foo(a: int, b: str) -> str: %4d NOP -%4d L1: LOAD_SMALL_INT 1 (1) - LOAD_SMALL_INT 0 (0) +%4d L1: LOAD_SMALL_INT 1 + LOAD_SMALL_INT 0 --> BINARY_OP 11 (/) POP_TOP @@ -534,7 +534,7 @@ def _with(c): CALL 0 L1: POP_TOP -%4d LOAD_SMALL_INT 1 (1) +%4d LOAD_SMALL_INT 1 STORE_FAST 1 (x) %4d L2: LOAD_CONST 0 (None) @@ -543,7 +543,7 @@ def _with(c): CALL 3 POP_TOP -%4d LOAD_SMALL_INT 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -559,7 +559,7 @@ def _with(c): POP_TOP POP_TOP -%4d LOAD_SMALL_INT 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -605,7 +605,7 @@ async def _asyncwith(c): L5: END_SEND L6: POP_TOP -%4d LOAD_SMALL_INT 1 (1) +%4d LOAD_SMALL_INT 1 STORE_FAST 1 (x) %4d L7: LOAD_CONST 0 (None) @@ -621,7 +621,7 @@ async def _asyncwith(c): L11: END_SEND POP_TOP -%4d LOAD_SMALL_INT 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -649,7 +649,7 @@ async def _asyncwith(c): POP_TOP POP_TOP -%4d LOAD_SMALL_INT 2 (2) +%4d LOAD_SMALL_INT 2 STORE_FAST 2 (y) LOAD_CONST 0 (None) RETURN_VALUE @@ -739,7 +739,7 @@ def _tryfinallyconst(b): PUSH_NULL CALL 0 POP_TOP - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 RETURN_VALUE -- L1: PUSH_EXC_INFO @@ -885,7 +885,7 @@ def loop_test(): %3d BUILD_LIST 0 LOAD_CONST 1 ((1, 2, 3)) LIST_EXTEND 1 - LOAD_SMALL_INT 3 (3) + LOAD_SMALL_INT 3 BINARY_OP 5 (*) GET_ITER L1: FOR_ITER_LIST 14 (to L2) @@ -1060,7 +1060,7 @@ def test_dis_with_linenos_but_no_columns(self): expect = '\n'.join([ '1:0-1:0 RESUME 0', '', - '2:5-2:6 LOAD_SMALL_INT 1 (1)', + '2:5-2:6 LOAD_SMALL_INT 1', '2:?-2:? STORE_FAST 0 (x)', '2:?-2:? LOAD_CONST 0 (None)', '2:?-2:? RETURN_VALUE', @@ -1284,7 +1284,7 @@ def test_binary_specialize(self): 0 RESUME_CHECK 0 1 LOAD_NAME 0 (a) - LOAD_SMALL_INT 0 (0) + LOAD_SMALL_INT 0 %s RETURN_VALUE """ @@ -1321,7 +1321,7 @@ def test_call_specialize(self): 1 LOAD_NAME 0 (str) PUSH_NULL - LOAD_SMALL_INT 1 (1) + LOAD_SMALL_INT 1 CALL_STR_1 1 RETURN_VALUE """ @@ -1747,7 +1747,7 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=89, arg=1, 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=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), @@ -1802,7 +1802,7 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=89, arg=10, 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')]), @@ -1812,12 +1812,12 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=89, arg=4, 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=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_SMALL_INT', opcode=89, arg=6, 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=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')]), @@ -1837,16 +1837,16 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=89, arg=1, 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_SMALL_INT', opcode=89, arg=6, 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=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_SMALL_INT', opcode=89, arg=4, 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=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')]), @@ -1856,8 +1856,8 @@ def _prepare_test_cases(): 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_SMALL_INT', opcode=89, arg=1, 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_SMALL_INT', opcode=89, arg=0, 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), diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 2bcbe6a195ddae..677747f5af9670 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -270,8 +270,6 @@ dummy_func( } replicate(4) inst(LOAD_SMALL_INT, (-- value)) { - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 3f27b39276e89b..3149398f0d2b68 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -226,8 +226,6 @@ _PyStackRef value; oparg = 0; assert(oparg == CURRENT_OPARG()); - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); @@ -241,8 +239,6 @@ _PyStackRef value; oparg = 1; assert(oparg == CURRENT_OPARG()); - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); @@ -256,8 +252,6 @@ _PyStackRef value; oparg = 2; assert(oparg == CURRENT_OPARG()); - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); @@ -271,8 +265,6 @@ _PyStackRef value; oparg = 3; assert(oparg == CURRENT_OPARG()); - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); @@ -285,8 +277,6 @@ case _LOAD_SMALL_INT: { _PyStackRef value; oparg = CURRENT_OPARG(); - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 6bf3109123a8f1..5418131950076d 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1264,11 +1264,17 @@ 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); } @@ -1332,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; } } @@ -2102,7 +2108,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { int opcode = b->b_instr[i].i_opcode; - if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_SMALL_INT) { + if (OPCODE_HAS_CONST(opcode)) { int index = b->b_instr[i].i_oparg; index_map[index] = index; } @@ -2156,7 +2162,7 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts) for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { int opcode = b->b_instr[i].i_opcode; - if (OPCODE_HAS_CONST(opcode) && opcode != LOAD_SMALL_INT) { + 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); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 7ba6f4a0918483..4c7fe5fe13402a 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6231,8 +6231,6 @@ next_instr += 1; INSTRUCTION_STATS(LOAD_SMALL_INT); _PyStackRef value; - /* Tell code generator that this is a const load */ - (void)FRAME_CO_CONSTS; assert(oparg < _PY_NSMALLPOSINTS); PyObject *obj = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + oparg]; value = PyStackRef_FromPyObjectImmortal(obj); From 3caac1a7b05e1b33e680dbee427e8a6420972208 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 29 Oct 2024 09:37:39 +0000 Subject: [PATCH 34/34] Add back int to test --- Lib/test/test_ast/test_ast.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index bac771b8e0b52e..786f98ba34af7f 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -2311,6 +2311,7 @@ def get_load_const(self, tree): def test_load_const(self): consts = [None, True, False, + 1000, 2.0, 3j, "unicode",