mirror of
https://github.com/python/cpython
synced 2024-09-04 15:56:13 +00:00
gh-93554: Conditional jump opcodes only jump forward (GH-96318)
This commit is contained in:
parent
a91f25577c
commit
4c72517cad
|
@ -999,60 +999,48 @@ iterations of the loop.
|
|||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_FORWARD_IF_TRUE (delta)
|
||||
.. opcode:: POP_JUMP_IF_TRUE (delta)
|
||||
|
||||
If TOS is true, increments the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
.. versionchanged:: 3.11
|
||||
The oparg is now a relative delta rather than an absolute target.
|
||||
This opcode is a pseudo-instruction, replaced in final bytecode by
|
||||
the directed versions (forward/backward).
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
This is no longer a pseudo-instruction.
|
||||
|
||||
.. opcode:: POP_JUMP_BACKWARD_IF_TRUE (delta)
|
||||
|
||||
If TOS is true, decrements the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_FORWARD_IF_FALSE (delta)
|
||||
.. opcode:: POP_JUMP_IF_FALSE (delta)
|
||||
|
||||
If TOS is false, increments the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
.. versionchanged:: 3.11
|
||||
The oparg is now a relative delta rather than an absolute target.
|
||||
This opcode is a pseudo-instruction, replaced in final bytecode by
|
||||
the directed versions (forward/backward).
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
This is no longer a pseudo-instruction.
|
||||
|
||||
.. opcode:: POP_JUMP_BACKWARD_IF_FALSE (delta)
|
||||
|
||||
If TOS is false, decrements the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_FORWARD_IF_NOT_NONE (delta)
|
||||
.. opcode:: POP_JUMP_IF_NOT_NONE (delta)
|
||||
|
||||
If TOS is not ``None``, increments the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_BACKWARD_IF_NOT_NONE (delta)
|
||||
|
||||
If TOS is not ``None``, decrements the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
.. versionchanged:: 3.12
|
||||
This is no longer a pseudo-instruction.
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_FORWARD_IF_NONE (delta)
|
||||
.. opcode:: POP_JUMP_IF_NONE (delta)
|
||||
|
||||
If TOS is ``None``, increments the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. opcode:: POP_JUMP_BACKWARD_IF_NONE (delta)
|
||||
|
||||
If TOS is ``None``, decrements the bytecode counter by *delta*. TOS is popped.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
.. versionchanged:: 3.12
|
||||
This is no longer a pseudo-instruction.
|
||||
|
||||
|
||||
.. opcode:: JUMP_IF_TRUE_OR_POP (delta)
|
||||
|
@ -1433,10 +1421,6 @@ but are replaced by real opcodes or removed before bytecode is generated.
|
|||
|
||||
.. opcode:: JUMP
|
||||
.. opcode:: JUMP_NO_INTERRUPT
|
||||
.. opcode:: POP_JUMP_IF_FALSE
|
||||
.. opcode:: POP_JUMP_IF_TRUE
|
||||
.. opcode:: POP_JUMP_IF_NONE
|
||||
.. opcode:: POP_JUMP_IF_NOT_NONE
|
||||
|
||||
Undirected relative jump instructions which are replaced by their
|
||||
directed (forward/backward) counterparts by the assembler.
|
||||
|
|
46
Include/internal/pycore_opcode.h
generated
46
Include/internal/pycore_opcode.h
generated
|
@ -23,10 +23,10 @@ static const uint32_t _PyOpcode_RelativeJump[9] = {
|
|||
536870912U,
|
||||
135118848U,
|
||||
4163U,
|
||||
122880U,
|
||||
0U,
|
||||
0U,
|
||||
1008U,
|
||||
0U,
|
||||
48U,
|
||||
};
|
||||
static const uint32_t _PyOpcode_Jump[9] = {
|
||||
0U,
|
||||
|
@ -34,10 +34,10 @@ static const uint32_t _PyOpcode_Jump[9] = {
|
|||
536870912U,
|
||||
135118848U,
|
||||
4163U,
|
||||
122880U,
|
||||
0U,
|
||||
0U,
|
||||
1008U,
|
||||
0U,
|
||||
48U,
|
||||
};
|
||||
|
||||
const uint8_t _PyOpcode_Caches[256] = {
|
||||
|
@ -187,14 +187,10 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
|||
[MATCH_SEQUENCE] = MATCH_SEQUENCE,
|
||||
[NOP] = NOP,
|
||||
[POP_EXCEPT] = POP_EXCEPT,
|
||||
[POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE,
|
||||
[POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE,
|
||||
[POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE,
|
||||
[POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE,
|
||||
[POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE,
|
||||
[POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE,
|
||||
[POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE,
|
||||
[POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE,
|
||||
[POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
|
||||
[POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
|
||||
[POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
|
||||
[POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
|
||||
[POP_TOP] = POP_TOP,
|
||||
[PREP_RERAISE_STAR] = PREP_RERAISE_STAR,
|
||||
[PRINT_EXPR] = PRINT_EXPR,
|
||||
|
@ -243,7 +239,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
|||
#endif // NEED_OPCODE_TABLES
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
static const char *const _PyOpcode_OpName[267] = {
|
||||
static const char *const _PyOpcode_OpName[263] = {
|
||||
[CACHE] = "CACHE",
|
||||
[POP_TOP] = "POP_TOP",
|
||||
[PUSH_NULL] = "PUSH_NULL",
|
||||
|
@ -358,8 +354,8 @@ static const char *const _PyOpcode_OpName[267] = {
|
|||
[JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP",
|
||||
[JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP",
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
|
||||
[POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE",
|
||||
[POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE",
|
||||
[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
|
||||
[POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
|
||||
[LOAD_GLOBAL] = "LOAD_GLOBAL",
|
||||
[IS_OP] = "IS_OP",
|
||||
[CONTAINS_OP] = "CONTAINS_OP",
|
||||
|
@ -372,8 +368,8 @@ static const char *const _PyOpcode_OpName[267] = {
|
|||
[STORE_FAST] = "STORE_FAST",
|
||||
[DELETE_FAST] = "DELETE_FAST",
|
||||
[LOAD_FAST_CHECK] = "LOAD_FAST_CHECK",
|
||||
[POP_JUMP_FORWARD_IF_NOT_NONE] = "POP_JUMP_FORWARD_IF_NOT_NONE",
|
||||
[POP_JUMP_FORWARD_IF_NONE] = "POP_JUMP_FORWARD_IF_NONE",
|
||||
[POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE",
|
||||
[POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
|
||||
[RAISE_VARARGS] = "RAISE_VARARGS",
|
||||
[GET_AWAITABLE] = "GET_AWAITABLE",
|
||||
[MAKE_FUNCTION] = "MAKE_FUNCTION",
|
||||
|
@ -417,10 +413,6 @@ static const char *const _PyOpcode_OpName[267] = {
|
|||
[STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
|
||||
[CALL] = "CALL",
|
||||
[KW_NAMES] = "KW_NAMES",
|
||||
[POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE",
|
||||
[POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE",
|
||||
[POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE",
|
||||
[POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE",
|
||||
[STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
|
||||
[STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE",
|
||||
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
|
||||
|
@ -429,6 +421,10 @@ static const char *const _PyOpcode_OpName[267] = {
|
|||
[UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
|
||||
[UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
|
||||
[UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
|
||||
[181] = "<181>",
|
||||
[182] = "<182>",
|
||||
[183] = "<183>",
|
||||
[184] = "<184>",
|
||||
[185] = "<185>",
|
||||
[186] = "<186>",
|
||||
[187] = "<187>",
|
||||
|
@ -506,15 +502,15 @@ static const char *const _PyOpcode_OpName[267] = {
|
|||
[POP_BLOCK] = "POP_BLOCK",
|
||||
[JUMP] = "JUMP",
|
||||
[JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT",
|
||||
[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
|
||||
[POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
|
||||
[POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
|
||||
[POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE",
|
||||
[LOAD_METHOD] = "LOAD_METHOD",
|
||||
};
|
||||
#endif
|
||||
|
||||
#define EXTRA_CASES \
|
||||
case 181: \
|
||||
case 182: \
|
||||
case 183: \
|
||||
case 184: \
|
||||
case 185: \
|
||||
case 186: \
|
||||
case 187: \
|
||||
|
|
40
Include/opcode.h
generated
40
Include/opcode.h
generated
|
@ -72,8 +72,8 @@ extern "C" {
|
|||
#define JUMP_FORWARD 110
|
||||
#define JUMP_IF_FALSE_OR_POP 111
|
||||
#define JUMP_IF_TRUE_OR_POP 112
|
||||
#define POP_JUMP_FORWARD_IF_FALSE 114
|
||||
#define POP_JUMP_FORWARD_IF_TRUE 115
|
||||
#define POP_JUMP_IF_FALSE 114
|
||||
#define POP_JUMP_IF_TRUE 115
|
||||
#define LOAD_GLOBAL 116
|
||||
#define IS_OP 117
|
||||
#define CONTAINS_OP 118
|
||||
|
@ -85,8 +85,8 @@ extern "C" {
|
|||
#define STORE_FAST 125
|
||||
#define DELETE_FAST 126
|
||||
#define LOAD_FAST_CHECK 127
|
||||
#define POP_JUMP_FORWARD_IF_NOT_NONE 128
|
||||
#define POP_JUMP_FORWARD_IF_NONE 129
|
||||
#define POP_JUMP_IF_NOT_NONE 128
|
||||
#define POP_JUMP_IF_NONE 129
|
||||
#define RAISE_VARARGS 130
|
||||
#define GET_AWAITABLE 131
|
||||
#define MAKE_FUNCTION 132
|
||||
|
@ -117,10 +117,6 @@ extern "C" {
|
|||
#define DICT_UPDATE 165
|
||||
#define CALL 171
|
||||
#define KW_NAMES 172
|
||||
#define POP_JUMP_BACKWARD_IF_NOT_NONE 173
|
||||
#define POP_JUMP_BACKWARD_IF_NONE 174
|
||||
#define POP_JUMP_BACKWARD_IF_FALSE 175
|
||||
#define POP_JUMP_BACKWARD_IF_TRUE 176
|
||||
#define MIN_PSEUDO_OPCODE 256
|
||||
#define SETUP_FINALLY 256
|
||||
#define SETUP_CLEANUP 257
|
||||
|
@ -128,12 +124,8 @@ extern "C" {
|
|||
#define POP_BLOCK 259
|
||||
#define JUMP 260
|
||||
#define JUMP_NO_INTERRUPT 261
|
||||
#define POP_JUMP_IF_FALSE 262
|
||||
#define POP_JUMP_IF_TRUE 263
|
||||
#define POP_JUMP_IF_NONE 264
|
||||
#define POP_JUMP_IF_NOT_NONE 265
|
||||
#define LOAD_METHOD 266
|
||||
#define MAX_PSEUDO_OPCODE 266
|
||||
#define LOAD_METHOD 262
|
||||
#define MAX_PSEUDO_OPCODE 262
|
||||
#define BINARY_OP_ADAPTIVE 3
|
||||
#define BINARY_OP_ADD_FLOAT 4
|
||||
#define BINARY_OP_ADD_INT 5
|
||||
|
@ -199,23 +191,19 @@ extern "C" {
|
|||
#define STORE_ATTR_SLOT 168
|
||||
#define STORE_ATTR_WITH_HINT 169
|
||||
#define STORE_FAST__LOAD_FAST 170
|
||||
#define STORE_FAST__STORE_FAST 177
|
||||
#define STORE_SUBSCR_ADAPTIVE 178
|
||||
#define STORE_SUBSCR_DICT 179
|
||||
#define STORE_SUBSCR_LIST_INT 180
|
||||
#define UNPACK_SEQUENCE_ADAPTIVE 181
|
||||
#define UNPACK_SEQUENCE_LIST 182
|
||||
#define UNPACK_SEQUENCE_TUPLE 183
|
||||
#define UNPACK_SEQUENCE_TWO_TUPLE 184
|
||||
#define STORE_FAST__STORE_FAST 173
|
||||
#define STORE_SUBSCR_ADAPTIVE 174
|
||||
#define STORE_SUBSCR_DICT 175
|
||||
#define STORE_SUBSCR_LIST_INT 176
|
||||
#define UNPACK_SEQUENCE_ADAPTIVE 177
|
||||
#define UNPACK_SEQUENCE_LIST 178
|
||||
#define UNPACK_SEQUENCE_TUPLE 179
|
||||
#define UNPACK_SEQUENCE_TWO_TUPLE 180
|
||||
#define DO_TRACING 255
|
||||
|
||||
#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\
|
||||
|| ((op) == JUMP) \
|
||||
|| ((op) == JUMP_NO_INTERRUPT) \
|
||||
|| ((op) == POP_JUMP_IF_FALSE) \
|
||||
|| ((op) == POP_JUMP_IF_TRUE) \
|
||||
|| ((op) == POP_JUMP_IF_NONE) \
|
||||
|| ((op) == POP_JUMP_IF_NOT_NONE) \
|
||||
|| ((op) == LOAD_METHOD) \
|
||||
)
|
||||
|
||||
|
|
|
@ -412,6 +412,7 @@ def _write_atomic(path, data, mode=0o666):
|
|||
# Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions)
|
||||
# Python 3.12a1 3507 (Set lineno of module's RESUME to 0)
|
||||
# Python 3.12a1 3508 (Add CLEANUP_THROW)
|
||||
# Python 3.12a1 3509 (Conditional jumps only jump forward)
|
||||
|
||||
# Python 3.13 will start with 3550
|
||||
|
||||
|
@ -424,7 +425,7 @@ def _write_atomic(path, data, mode=0o666):
|
|||
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||
# in PC/launcher.c must also be updated.
|
||||
|
||||
MAGIC_NUMBER = (3508).to_bytes(2, 'little') + b'\r\n'
|
||||
MAGIC_NUMBER = (3509).to_bytes(2, 'little') + b'\r\n'
|
||||
|
||||
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||
|
||||
|
|
|
@ -153,8 +153,8 @@ def pseudo_op(name, op, real_ops):
|
|||
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
|
||||
jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
|
||||
jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
|
||||
jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114)
|
||||
jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115)
|
||||
jrel_op('POP_JUMP_IF_FALSE', 114)
|
||||
jrel_op('POP_JUMP_IF_TRUE', 115)
|
||||
name_op('LOAD_GLOBAL', 116) # Index in name list
|
||||
def_op('IS_OP', 117)
|
||||
def_op('CONTAINS_OP', 118)
|
||||
|
@ -170,8 +170,8 @@ def pseudo_op(name, op, real_ops):
|
|||
haslocal.append(126)
|
||||
def_op('LOAD_FAST_CHECK', 127) # Local variable number
|
||||
haslocal.append(127)
|
||||
jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128)
|
||||
jrel_op('POP_JUMP_FORWARD_IF_NONE', 129)
|
||||
jrel_op('POP_JUMP_IF_NOT_NONE', 128)
|
||||
jrel_op('POP_JUMP_IF_NONE', 129)
|
||||
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
|
||||
def_op('GET_AWAITABLE', 131)
|
||||
def_op('MAKE_FUNCTION', 132) # Flags
|
||||
|
@ -216,10 +216,6 @@ def pseudo_op(name, op, real_ops):
|
|||
def_op('KW_NAMES', 172)
|
||||
hasconst.append(172)
|
||||
|
||||
jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173)
|
||||
jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174)
|
||||
jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175)
|
||||
jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176)
|
||||
|
||||
hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
|
||||
|
||||
|
@ -235,11 +231,8 @@ def pseudo_op(name, op, real_ops):
|
|||
|
||||
pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
|
||||
pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
|
||||
pseudo_op('POP_JUMP_IF_FALSE', 262, ['POP_JUMP_FORWARD_IF_FALSE', 'POP_JUMP_BACKWARD_IF_FALSE'])
|
||||
pseudo_op('POP_JUMP_IF_TRUE', 263, ['POP_JUMP_FORWARD_IF_TRUE', 'POP_JUMP_BACKWARD_IF_TRUE'])
|
||||
pseudo_op('POP_JUMP_IF_NONE', 264, ['POP_JUMP_FORWARD_IF_NONE', 'POP_JUMP_BACKWARD_IF_NONE'])
|
||||
pseudo_op('POP_JUMP_IF_NOT_NONE', 265, ['POP_JUMP_FORWARD_IF_NOT_NONE', 'POP_JUMP_BACKWARD_IF_NOT_NONE'])
|
||||
pseudo_op('LOAD_METHOD', 266, ['LOAD_ATTR'])
|
||||
|
||||
pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR'])
|
||||
|
||||
MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ def bug42562():
|
|||
|
||||
%3d LOAD_GLOBAL 0 (Exception)
|
||||
CHECK_EXC_MATCH
|
||||
POP_JUMP_FORWARD_IF_FALSE 22 (to 80)
|
||||
POP_JUMP_IF_FALSE 22 (to 80)
|
||||
STORE_FAST 0 (e)
|
||||
|
||||
%3d LOAD_FAST 0 (e)
|
||||
|
@ -447,7 +447,7 @@ def _with(c):
|
|||
|
||||
%3d >> PUSH_EXC_INFO
|
||||
WITH_EXCEPT_START
|
||||
POP_JUMP_FORWARD_IF_TRUE 1 (to 46)
|
||||
POP_JUMP_IF_TRUE 1 (to 46)
|
||||
RERAISE 2
|
||||
>> POP_TOP
|
||||
POP_EXCEPT
|
||||
|
@ -520,7 +520,7 @@ async def _asyncwith(c):
|
|||
RESUME 3
|
||||
JUMP_BACKWARD_NO_INTERRUPT 4 (to 82)
|
||||
>> CLEANUP_THROW
|
||||
>> POP_JUMP_FORWARD_IF_TRUE 1 (to 96)
|
||||
>> POP_JUMP_IF_TRUE 1 (to 96)
|
||||
RERAISE 2
|
||||
>> POP_TOP
|
||||
POP_EXCEPT
|
||||
|
@ -874,15 +874,7 @@ def test_boundaries(self):
|
|||
self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
|
||||
|
||||
def test_widths(self):
|
||||
long_opcodes = set(['POP_JUMP_FORWARD_IF_FALSE',
|
||||
'POP_JUMP_FORWARD_IF_TRUE',
|
||||
'POP_JUMP_FORWARD_IF_NOT_NONE',
|
||||
'POP_JUMP_FORWARD_IF_NONE',
|
||||
'POP_JUMP_BACKWARD_IF_FALSE',
|
||||
'POP_JUMP_BACKWARD_IF_TRUE',
|
||||
'POP_JUMP_BACKWARD_IF_NOT_NONE',
|
||||
'POP_JUMP_BACKWARD_IF_NONE',
|
||||
'JUMP_BACKWARD_NO_INTERRUPT',
|
||||
long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT',
|
||||
])
|
||||
for opcode, opname in enumerate(dis.opname):
|
||||
if opname in long_opcodes:
|
||||
|
@ -1544,7 +1536,7 @@ def _prepare_test_cases():
|
|||
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=14, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=26, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='FOR_ITER', opcode=93, arg=29, argval=90, argrepr='to 90', offset=28, starts_line=None, is_jump_target=True, positions=None),
|
||||
Instruction(opname='FOR_ITER', opcode=93, arg=30, argval=92, argrepr='to 92', offset=28, starts_line=None, is_jump_target=True, positions=None),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=32, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=34, starts_line=4, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=46, starts_line=None, is_jump_target=False, positions=None),
|
||||
|
@ -1553,103 +1545,105 @@ def _prepare_test_cases():
|
|||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=60, starts_line=5, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=62, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=64, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=74, argrepr='to 74', offset=70, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=74, argrepr='to 74', offset=70, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=23, argval=28, argrepr='to 28', offset=72, starts_line=6, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=74, starts_line=7, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=76, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=78, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_BACKWARD_IF_FALSE', opcode=175, arg=29, argval=28, argrepr='to 28', offset=84, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=86, starts_line=8, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=116, argrepr='to 116', offset=88, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=90, starts_line=10, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=102, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=104, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=0, argval='i', argrepr='i', offset=116, starts_line=11, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=34, argval=188, argrepr='to 188', offset=118, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=120, starts_line=12, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=132, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=134, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=13, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=148, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=150, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=154, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=156, starts_line=14, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=158, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=160, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=170, argrepr='to 170', offset=166, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=27, argval=116, argrepr='to 116', offset=168, starts_line=15, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=170, starts_line=16, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=172, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=174, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=184, argrepr='to 184', offset=180, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=15, argval=214, argrepr='to 214', offset=182, starts_line=17, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=184, starts_line=11, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_JUMP_BACKWARD_IF_TRUE', opcode=176, arg=34, argval=120, argrepr='to 120', offset=186, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=188, starts_line=19, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=200, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=202, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=214, starts_line=20, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=216, starts_line=21, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=218, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=220, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=224, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=226, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=230, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=232, starts_line=26, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=244, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=246, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=258, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=260, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=262, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=264, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=274, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=276, starts_line=28, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=288, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=290, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=300, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=302, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=306, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_TRUE', opcode=115, arg=1, argval=314, argrepr='to 314', offset=310, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=276, argrepr='to 276', offset=322, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, starts_line=22, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=16, argval=380, argrepr='to 380', offset=346, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=350, starts_line=23, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=362, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=364, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=374, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=52, argval=276, argrepr='to 276', offset=378, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=380, starts_line=22, is_jump_target=True, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=390, starts_line=28, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=402, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=404, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=414, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=416, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=422, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=88, argrepr='to 88', offset=84, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=30, argval=28, argrepr='to 28', offset=86, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=88, starts_line=8, is_jump_target=True, positions=None),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=118, argrepr='to 118', offset=90, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=92, starts_line=10, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=104, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=106, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=0, argval='i', argrepr='i', offset=118, starts_line=11, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=35, argval=192, argrepr='to 192', offset=120, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=122, starts_line=12, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=134, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=148, starts_line=13, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=150, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=152, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=156, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=158, starts_line=14, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=160, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=162, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=172, argrepr='to 172', offset=168, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=27, argval=118, argrepr='to 118', offset=170, starts_line=15, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=172, starts_line=16, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=174, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=176, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=186, argrepr='to 186', offset=182, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=218, argrepr='to 218', offset=184, starts_line=17, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=186, starts_line=11, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=192, argrepr='to 192', offset=188, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=35, argval=122, argrepr='to 122', offset=190, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=192, starts_line=19, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=206, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=218, starts_line=20, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=220, starts_line=21, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=222, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=224, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=230, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=234, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=236, starts_line=26, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=248, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=250, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=260, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=262, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=264, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=266, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=268, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=278, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=280, starts_line=28, is_jump_target=True, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=292, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=294, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=306, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=310, starts_line=25, is_jump_target=False, positions=None),
|
||||
Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=318, argrepr='to 318', offset=314, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=True, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=280, argrepr='to 280', offset=326, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=332, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=334, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=336, starts_line=22, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=16, argval=384, argrepr='to 384', offset=350, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=352, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=354, starts_line=23, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=366, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=368, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='JUMP_BACKWARD', opcode=140, arg=52, argval=280, argrepr='to 280', offset=382, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=384, starts_line=22, is_jump_target=True, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=392, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=394, starts_line=28, is_jump_target=False, positions=None),
|
||||
Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=406, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=408, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=422, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=424, starts_line=None, is_jump_target=False, positions=None),
|
||||
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=426, starts_line=None, is_jump_target=False, positions=None),
|
||||
]
|
||||
|
||||
# One last piece of inspect fodder to check the default line number handling
|
||||
|
|
|
@ -77,9 +77,8 @@ def unot(x):
|
|||
if not x == 2:
|
||||
del x
|
||||
self.assertNotInBytecode(unot, 'UNARY_NOT')
|
||||
self.assertNotInBytecode(unot, 'POP_JUMP_FORWARD_IF_FALSE')
|
||||
self.assertNotInBytecode(unot, 'POP_JUMP_BACKWARD_IF_FALSE')
|
||||
self.assertInBytecode(unot, 'POP_JUMP_FORWARD_IF_TRUE')
|
||||
self.assertNotInBytecode(unot, 'POP_JUMP_IF_FALSE')
|
||||
self.assertInBytecode(unot, 'POP_JUMP_IF_TRUE')
|
||||
self.check_lnotab(unot)
|
||||
|
||||
def test_elim_inversion_of_is_or_in(self):
|
||||
|
@ -409,7 +408,7 @@ def f(a, b, c):
|
|||
self.check_lnotab(f)
|
||||
self.assertNotInBytecode(f, 'JUMP_IF_FALSE_OR_POP')
|
||||
self.assertInBytecode(f, 'JUMP_IF_TRUE_OR_POP')
|
||||
self.assertInBytecode(f, 'POP_JUMP_FORWARD_IF_FALSE')
|
||||
self.assertInBytecode(f, 'POP_JUMP_IF_FALSE')
|
||||
# JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump
|
||||
def f(a, b, c):
|
||||
return ((a or b)
|
||||
|
@ -418,7 +417,7 @@ def f(a, b, c):
|
|||
self.check_lnotab(f)
|
||||
self.assertNotInBytecode(f, 'JUMP_IF_TRUE_OR_POP')
|
||||
self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP')
|
||||
self.assertInBytecode(f, 'POP_JUMP_FORWARD_IF_TRUE')
|
||||
self.assertInBytecode(f, 'POP_JUMP_IF_TRUE')
|
||||
|
||||
def test_elim_jump_to_uncond_jump4(self):
|
||||
def f():
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
Change the jump opcodes so that all conditional jumps are forward jumps.
|
||||
Backward jumps are converted by the assembler into a conditional forward
|
||||
jump whose target is the fallthrough block (and with a reversed condition),
|
||||
followed by an unconditional backward jump. For example:
|
||||
|
||||
``POP_JUMP_IF_TRUE BACKWARD_TARGET`` becomes ``POP_JUMP_IF_FALSE NEXT_BLOCK;
|
||||
JUMP BACKWARD_TARGET``.
|
||||
|
||||
All the directed conditional jump opcodes were removed:
|
||||
``POP_JUMP_FORWARD_IF_TRUE``, ``POP_JUMP_BACKWARD_IF_TRUE``,
|
||||
``POP_JUMP_FORWARD_IF_FALSE``, ``POP_JUMP_BACKWARD_IF_FALSE``,
|
||||
``POP_JUMP_FORWARD_IF_NONE``, ``POP_JUMP_BACKWARD_IF_NONE``,
|
||||
``POP_JUMP_FORWARD_IF_NOT_NONE``, ``POP_JUMP_BACKWARD_IF_NOT_NONE``.
|
||||
|
||||
The corresponding opcodes without direction are no longer pseudo-instructions,
|
||||
and they implement the forward conditional jumps.
|
|
@ -311,25 +311,12 @@ mark_stacks(PyCodeObject *code_obj, int len)
|
|||
switch (opcode) {
|
||||
case JUMP_IF_FALSE_OR_POP:
|
||||
case JUMP_IF_TRUE_OR_POP:
|
||||
case POP_JUMP_FORWARD_IF_FALSE:
|
||||
case POP_JUMP_BACKWARD_IF_FALSE:
|
||||
case POP_JUMP_FORWARD_IF_TRUE:
|
||||
case POP_JUMP_BACKWARD_IF_TRUE:
|
||||
case POP_JUMP_IF_FALSE:
|
||||
case POP_JUMP_IF_TRUE:
|
||||
{
|
||||
int64_t target_stack;
|
||||
int j = get_arg(code, i);
|
||||
if (opcode == POP_JUMP_FORWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == JUMP_IF_FALSE_OR_POP ||
|
||||
opcode == JUMP_IF_TRUE_OR_POP)
|
||||
{
|
||||
j += i + 1;
|
||||
}
|
||||
else {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_TRUE);
|
||||
j = i + 1 - j;
|
||||
}
|
||||
j += i + 1;
|
||||
assert(j < len);
|
||||
if (stacks[j] == UNINITIALIZED && j < i) {
|
||||
todo = 1;
|
||||
|
|
147
Python/ceval.c
147
Python/ceval.c
|
@ -3307,7 +3307,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
|
||||
TARGET(COMPARE_OP_FLOAT_JUMP) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
// Combined: COMPARE_OP (float ? float) + POP_JUMP_(direction)_IF_(true/false)
|
||||
// Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false)
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
|
||||
int when_to_jump_mask = cache->mask;
|
||||
PyObject *right = TOP();
|
||||
|
@ -3325,23 +3325,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
STACK_SHRINK(2);
|
||||
_Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
|
||||
_Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_TRUE);
|
||||
int jump = (9 << (sign + 1)) & when_to_jump_mask;
|
||||
assert(opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_TRUE);
|
||||
int jump = (1 << (sign + 1)) & when_to_jump_mask;
|
||||
if (!jump) {
|
||||
next_instr++;
|
||||
}
|
||||
else if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_FALSE);
|
||||
JUMPBY(1 + oparg);
|
||||
}
|
||||
NOTRACE_DISPATCH();
|
||||
|
@ -3349,7 +3338,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
|
||||
TARGET(COMPARE_OP_INT_JUMP) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
// Combined: COMPARE_OP (int ? int) + POP_JUMP_(direction)_IF_(true/false)
|
||||
// Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false)
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
|
||||
int when_to_jump_mask = cache->mask;
|
||||
PyObject *right = TOP();
|
||||
|
@ -3368,23 +3357,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
STACK_SHRINK(2);
|
||||
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
|
||||
_Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_TRUE);
|
||||
int jump = (9 << (sign + 1)) & when_to_jump_mask;
|
||||
assert(opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_TRUE);
|
||||
int jump = (1 << (sign + 1)) & when_to_jump_mask;
|
||||
if (!jump) {
|
||||
next_instr++;
|
||||
}
|
||||
else if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_FALSE);
|
||||
JUMPBY(1 + oparg);
|
||||
}
|
||||
NOTRACE_DISPATCH();
|
||||
|
@ -3392,9 +3370,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
|
||||
TARGET(COMPARE_OP_STR_JUMP) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
// Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_(direction)_IF_(true/false)
|
||||
// Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false)
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
|
||||
int when_to_jump_mask = cache->mask;
|
||||
int invert = cache->mask;
|
||||
PyObject *right = TOP();
|
||||
PyObject *left = SECOND();
|
||||
DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
|
||||
|
@ -3407,28 +3385,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
assert(oparg == Py_EQ || oparg == Py_NE);
|
||||
JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP);
|
||||
NEXTOPARG();
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_TRUE);
|
||||
assert(opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_TRUE);
|
||||
STACK_SHRINK(2);
|
||||
_Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||
_Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
||||
assert(res == 0 || res == 1);
|
||||
int sign = 1 - res;
|
||||
int jump = (9 << (sign + 1)) & when_to_jump_mask;
|
||||
assert(invert == 0 || invert == 1);
|
||||
int jump = res ^ invert;
|
||||
if (!jump) {
|
||||
next_instr++;
|
||||
}
|
||||
else if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
assert(opcode == POP_JUMP_FORWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_FORWARD_IF_FALSE);
|
||||
JUMPBY(1 + oparg);
|
||||
}
|
||||
NOTRACE_DISPATCH();
|
||||
|
@ -3575,34 +3542,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
JUMP_TO_INSTRUCTION(JUMP_BACKWARD_QUICK);
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_BACKWARD_IF_FALSE) {
|
||||
PREDICTED(POP_JUMP_BACKWARD_IF_FALSE);
|
||||
PyObject *cond = POP();
|
||||
if (Py_IsTrue(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
DISPATCH();
|
||||
}
|
||||
if (Py_IsFalse(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
int err = PyObject_IsTrue(cond);
|
||||
Py_DECREF(cond);
|
||||
if (err > 0)
|
||||
;
|
||||
else if (err == 0) {
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_FORWARD_IF_FALSE) {
|
||||
PREDICTED(POP_JUMP_FORWARD_IF_FALSE);
|
||||
TARGET(POP_JUMP_IF_FALSE) {
|
||||
PREDICTED(POP_JUMP_IF_FALSE);
|
||||
PyObject *cond = POP();
|
||||
if (Py_IsTrue(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
|
@ -3625,32 +3566,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_BACKWARD_IF_TRUE) {
|
||||
PyObject *cond = POP();
|
||||
if (Py_IsFalse(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
DISPATCH();
|
||||
}
|
||||
if (Py_IsTrue(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
int err = PyObject_IsTrue(cond);
|
||||
Py_DECREF(cond);
|
||||
if (err > 0) {
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else if (err == 0)
|
||||
;
|
||||
else
|
||||
goto error;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_FORWARD_IF_TRUE) {
|
||||
TARGET(POP_JUMP_IF_TRUE) {
|
||||
PyObject *cond = POP();
|
||||
if (Py_IsFalse(cond)) {
|
||||
_Py_DECREF_NO_DEALLOC(cond);
|
||||
|
@ -3673,19 +3589,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_BACKWARD_IF_NOT_NONE) {
|
||||
PyObject *value = POP();
|
||||
if (!Py_IsNone(value)) {
|
||||
Py_DECREF(value);
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
_Py_DECREF_NO_DEALLOC(value);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_FORWARD_IF_NOT_NONE) {
|
||||
TARGET(POP_JUMP_IF_NOT_NONE) {
|
||||
PyObject *value = POP();
|
||||
if (!Py_IsNone(value)) {
|
||||
JUMPBY(oparg);
|
||||
|
@ -3694,20 +3598,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_BACKWARD_IF_NONE) {
|
||||
PyObject *value = POP();
|
||||
if (Py_IsNone(value)) {
|
||||
_Py_DECREF_NO_DEALLOC(value);
|
||||
JUMPBY(-oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(value);
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(POP_JUMP_FORWARD_IF_NONE) {
|
||||
TARGET(POP_JUMP_IF_NONE) {
|
||||
PyObject *value = POP();
|
||||
if (Py_IsNone(value)) {
|
||||
_Py_DECREF_NO_DEALLOC(value);
|
||||
|
@ -3834,8 +3725,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
PyObject *res = match ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
PUSH(res);
|
||||
PREDICT(POP_JUMP_FORWARD_IF_FALSE);
|
||||
PREDICT(POP_JUMP_BACKWARD_IF_FALSE);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -3845,8 +3735,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
|||
PyObject *res = match ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
PUSH(res);
|
||||
PREDICT(POP_JUMP_FORWARD_IF_FALSE);
|
||||
PREDICT(POP_JUMP_BACKWARD_IF_FALSE);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
154
Python/compile.c
154
Python/compile.c
|
@ -96,23 +96,11 @@
|
|||
#define IS_ASSEMBLER_OPCODE(opcode) \
|
||||
((opcode) == JUMP_FORWARD || \
|
||||
(opcode) == JUMP_BACKWARD || \
|
||||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT || \
|
||||
(opcode) == POP_JUMP_FORWARD_IF_NONE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_NONE || \
|
||||
(opcode) == POP_JUMP_FORWARD_IF_NOT_NONE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \
|
||||
(opcode) == POP_JUMP_FORWARD_IF_TRUE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_TRUE || \
|
||||
(opcode) == POP_JUMP_FORWARD_IF_FALSE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_FALSE)
|
||||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT)
|
||||
|
||||
#define IS_BACKWARDS_JUMP_OPCODE(opcode) \
|
||||
((opcode) == JUMP_BACKWARD || \
|
||||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_NONE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_TRUE || \
|
||||
(opcode) == POP_JUMP_BACKWARD_IF_FALSE)
|
||||
(opcode) == JUMP_BACKWARD_NO_INTERRUPT)
|
||||
|
||||
#define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \
|
||||
((opcode) == JUMP || \
|
||||
|
@ -1146,17 +1134,9 @@ stack_effect(int opcode, int oparg, int jump)
|
|||
case JUMP_IF_FALSE_OR_POP:
|
||||
return jump ? 0 : -1;
|
||||
|
||||
case POP_JUMP_BACKWARD_IF_NONE:
|
||||
case POP_JUMP_FORWARD_IF_NONE:
|
||||
case POP_JUMP_IF_NONE:
|
||||
case POP_JUMP_BACKWARD_IF_NOT_NONE:
|
||||
case POP_JUMP_FORWARD_IF_NOT_NONE:
|
||||
case POP_JUMP_IF_NOT_NONE:
|
||||
case POP_JUMP_FORWARD_IF_FALSE:
|
||||
case POP_JUMP_BACKWARD_IF_FALSE:
|
||||
case POP_JUMP_IF_FALSE:
|
||||
case POP_JUMP_FORWARD_IF_TRUE:
|
||||
case POP_JUMP_BACKWARD_IF_TRUE:
|
||||
case POP_JUMP_IF_TRUE:
|
||||
return -1;
|
||||
|
||||
|
@ -7747,63 +7727,91 @@ assemble_emit(struct assembler *a, struct instr *i)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_jumps(basicblock *entryblock)
|
||||
static int
|
||||
normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
|
||||
struct instr *last = basicblock_last_instr(b);
|
||||
if (last == NULL || !is_jump(last)) {
|
||||
return 0;
|
||||
}
|
||||
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
|
||||
bool is_forward = last->i_target->b_visited == 0;
|
||||
switch(last->i_opcode) {
|
||||
case JUMP:
|
||||
last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
|
||||
return 0;
|
||||
case JUMP_NO_INTERRUPT:
|
||||
last->i_opcode = is_forward ?
|
||||
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
|
||||
return 0;
|
||||
}
|
||||
int reversed_opcode = 0;
|
||||
switch(last->i_opcode) {
|
||||
case POP_JUMP_IF_NOT_NONE:
|
||||
reversed_opcode = POP_JUMP_IF_NONE;
|
||||
break;
|
||||
case POP_JUMP_IF_NONE:
|
||||
reversed_opcode = POP_JUMP_IF_NOT_NONE;
|
||||
break;
|
||||
case POP_JUMP_IF_FALSE:
|
||||
reversed_opcode = POP_JUMP_IF_TRUE;
|
||||
break;
|
||||
case POP_JUMP_IF_TRUE:
|
||||
reversed_opcode = POP_JUMP_IF_FALSE;
|
||||
break;
|
||||
case JUMP_IF_TRUE_OR_POP:
|
||||
case JUMP_IF_FALSE_OR_POP:
|
||||
if (!is_forward) {
|
||||
/* As far as we can tell, the compiler never emits
|
||||
* these jumps with a backwards target. If/when this
|
||||
* exception is raised, we have found a use case for
|
||||
* a backwards version of this jump (or to replace
|
||||
* it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
|
||||
*/
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"unexpected %s jumping backwards",
|
||||
last->i_opcode == JUMP_IF_TRUE_OR_POP ?
|
||||
"JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (is_forward) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* transform 'conditional jump T' to
|
||||
* 'reversed_jump b_next' followed by 'jump_backwards T'
|
||||
*/
|
||||
|
||||
basicblock *target = last->i_target;
|
||||
basicblock *backwards_jump = cfg_builder_new_block(g);
|
||||
if (backwards_jump == NULL) {
|
||||
return -1;
|
||||
}
|
||||
basicblock_addop(backwards_jump, JUMP, target->b_label, NO_LOCATION);
|
||||
backwards_jump->b_instr[0].i_target = target;
|
||||
last->i_opcode = reversed_opcode;
|
||||
last->i_target = b->b_next;
|
||||
|
||||
backwards_jump->b_cold = b->b_cold;
|
||||
backwards_jump->b_next = b->b_next;
|
||||
b->b_next = backwards_jump;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_jumps(cfg_builder *g)
|
||||
{
|
||||
basicblock *entryblock = g->g_entryblock;
|
||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||
b->b_visited = 0;
|
||||
}
|
||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||
b->b_visited = 1;
|
||||
struct instr *last = basicblock_last_instr(b);
|
||||
if (last == NULL) {
|
||||
continue;
|
||||
}
|
||||
assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
|
||||
if (is_jump(last)) {
|
||||
bool is_forward = last->i_target->b_visited == 0;
|
||||
switch(last->i_opcode) {
|
||||
case JUMP:
|
||||
last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
|
||||
break;
|
||||
case JUMP_NO_INTERRUPT:
|
||||
last->i_opcode = is_forward ?
|
||||
JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
|
||||
break;
|
||||
case POP_JUMP_IF_NOT_NONE:
|
||||
last->i_opcode = is_forward ?
|
||||
POP_JUMP_FORWARD_IF_NOT_NONE : POP_JUMP_BACKWARD_IF_NOT_NONE;
|
||||
break;
|
||||
case POP_JUMP_IF_NONE:
|
||||
last->i_opcode = is_forward ?
|
||||
POP_JUMP_FORWARD_IF_NONE : POP_JUMP_BACKWARD_IF_NONE;
|
||||
break;
|
||||
case POP_JUMP_IF_FALSE:
|
||||
last->i_opcode = is_forward ?
|
||||
POP_JUMP_FORWARD_IF_FALSE : POP_JUMP_BACKWARD_IF_FALSE;
|
||||
break;
|
||||
case POP_JUMP_IF_TRUE:
|
||||
last->i_opcode = is_forward ?
|
||||
POP_JUMP_FORWARD_IF_TRUE : POP_JUMP_BACKWARD_IF_TRUE;
|
||||
break;
|
||||
case JUMP_IF_TRUE_OR_POP:
|
||||
case JUMP_IF_FALSE_OR_POP:
|
||||
if (!is_forward) {
|
||||
/* As far as we can tell, the compiler never emits
|
||||
* these jumps with a backwards target. If/when this
|
||||
* exception is raised, we have found a use case for
|
||||
* a backwards version of this jump (or to replace
|
||||
* it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
|
||||
*/
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"unexpected %s jumping backwards",
|
||||
last->i_opcode == JUMP_IF_TRUE_OR_POP ?
|
||||
"JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (normalize_jumps_in_block(g, b) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -8638,7 +8646,9 @@ assemble(struct compiler *c, int addNone)
|
|||
}
|
||||
|
||||
/* Order of basic blocks must have been determined by now */
|
||||
normalize_jumps(g->g_entryblock);
|
||||
if (normalize_jumps(g) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (add_checks_for_loads_of_unknown_variables(g->g_entryblock, c) < 0) {
|
||||
goto error;
|
||||
|
|
16
Python/opcode_targets.h
generated
16
Python/opcode_targets.h
generated
|
@ -113,8 +113,8 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_JUMP_IF_FALSE_OR_POP,
|
||||
&&TARGET_JUMP_IF_TRUE_OR_POP,
|
||||
&&TARGET_LOAD_ATTR_METHOD_NO_DICT,
|
||||
&&TARGET_POP_JUMP_FORWARD_IF_FALSE,
|
||||
&&TARGET_POP_JUMP_FORWARD_IF_TRUE,
|
||||
&&TARGET_POP_JUMP_IF_FALSE,
|
||||
&&TARGET_POP_JUMP_IF_TRUE,
|
||||
&&TARGET_LOAD_GLOBAL,
|
||||
&&TARGET_IS_OP,
|
||||
&&TARGET_CONTAINS_OP,
|
||||
|
@ -127,8 +127,8 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_STORE_FAST,
|
||||
&&TARGET_DELETE_FAST,
|
||||
&&TARGET_LOAD_FAST_CHECK,
|
||||
&&TARGET_POP_JUMP_FORWARD_IF_NOT_NONE,
|
||||
&&TARGET_POP_JUMP_FORWARD_IF_NONE,
|
||||
&&TARGET_POP_JUMP_IF_NOT_NONE,
|
||||
&&TARGET_POP_JUMP_IF_NONE,
|
||||
&&TARGET_RAISE_VARARGS,
|
||||
&&TARGET_GET_AWAITABLE,
|
||||
&&TARGET_MAKE_FUNCTION,
|
||||
|
@ -172,10 +172,6 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_STORE_FAST__LOAD_FAST,
|
||||
&&TARGET_CALL,
|
||||
&&TARGET_KW_NAMES,
|
||||
&&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE,
|
||||
&&TARGET_POP_JUMP_BACKWARD_IF_NONE,
|
||||
&&TARGET_POP_JUMP_BACKWARD_IF_FALSE,
|
||||
&&TARGET_POP_JUMP_BACKWARD_IF_TRUE,
|
||||
&&TARGET_STORE_FAST__STORE_FAST,
|
||||
&&TARGET_STORE_SUBSCR_ADAPTIVE,
|
||||
&&TARGET_STORE_SUBSCR_DICT,
|
||||
|
@ -254,5 +250,9 @@ static void *opcode_targets[256] = {
|
|||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_DO_TRACING
|
||||
};
|
||||
|
|
|
@ -1999,10 +1999,8 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
|
||||
_PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1);
|
||||
int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]);
|
||||
if (next_opcode != POP_JUMP_FORWARD_IF_FALSE &&
|
||||
next_opcode != POP_JUMP_BACKWARD_IF_FALSE &&
|
||||
next_opcode != POP_JUMP_FORWARD_IF_TRUE &&
|
||||
next_opcode != POP_JUMP_BACKWARD_IF_TRUE) {
|
||||
if (next_opcode != POP_JUMP_IF_FALSE &&
|
||||
next_opcode != POP_JUMP_IF_TRUE) {
|
||||
// Can't ever combine, so don't don't bother being adaptive (unless
|
||||
// we're collecting stats, where it's more important to get accurate hit
|
||||
// counts for the unadaptive version and each of the different failure
|
||||
|
@ -2021,14 +2019,9 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
}
|
||||
assert(oparg <= Py_GE);
|
||||
int when_to_jump_mask = compare_masks[oparg];
|
||||
if (next_opcode == POP_JUMP_FORWARD_IF_FALSE ||
|
||||
next_opcode == POP_JUMP_BACKWARD_IF_FALSE) {
|
||||
if (next_opcode == POP_JUMP_IF_FALSE) {
|
||||
when_to_jump_mask = (1 | 2 | 4) & ~when_to_jump_mask;
|
||||
}
|
||||
if (next_opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
next_opcode == POP_JUMP_BACKWARD_IF_FALSE) {
|
||||
when_to_jump_mask <<= 3;
|
||||
}
|
||||
if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
|
||||
SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
|
||||
goto failure;
|
||||
|
@ -2056,7 +2049,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
}
|
||||
else {
|
||||
_Py_SET_OPCODE(*instr, COMPARE_OP_STR_JUMP);
|
||||
cache->mask = when_to_jump_mask;
|
||||
cache->mask = (when_to_jump_mask & 2) == 0;
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue