bpo-27129: Use instruction offsets, not byte offsets, in bytecode and internally. (GH-25069)

* Use instruction offset, rather than bytecode offset. Streamlines interpreter dispatch a bit, and removes most EXTENDED_ARGs for jumps.

* Change some uses of PyCode_Addr2Line to PyFrame_GetLineNumber
This commit is contained in:
Mark Shannon 2021-04-01 16:00:31 +01:00 committed by GitHub
parent 2ac0515027
commit fcb55c0037
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 4568 additions and 4569 deletions

View File

@ -338,8 +338,11 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
argval, argrepr = _get_const_info(arg, constants) argval, argrepr = _get_const_info(arg, constants)
elif op in hasname: elif op in hasname:
argval, argrepr = _get_name_info(arg, names) argval, argrepr = _get_name_info(arg, names)
elif op in hasjabs:
argval = arg*2
argrepr = "to " + repr(argval)
elif op in hasjrel: elif op in hasjrel:
argval = offset + 2 + arg argval = offset + 2 + arg*2
argrepr = "to " + repr(argval) argrepr = "to " + repr(argval)
elif op in haslocal: elif op in haslocal:
argval, argrepr = _get_name_info(arg, varnames) argval, argrepr = _get_name_info(arg, varnames)
@ -437,9 +440,9 @@ def findlabels(code):
for offset, op, arg in _unpack_opargs(code): for offset, op, arg in _unpack_opargs(code):
if arg is not None: if arg is not None:
if op in hasjrel: if op in hasjrel:
label = offset + 2 + arg label = offset + 2 + arg*2
elif op in hasjabs: elif op in hasjabs:
label = arg label = arg*2
else: else:
continue continue
if label not in labels: if label not in labels:

View File

@ -314,6 +314,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.10a2 3432 (Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202) # Python 3.10a2 3432 (Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202)
# Python 3.10a2 3433 (RERAISE restores f_lasti if oparg != 0) # Python 3.10a2 3433 (RERAISE restores f_lasti if oparg != 0)
# Python 3.10a6 3434 (PEP 634: Structural Pattern Matching) # Python 3.10a6 3434 (PEP 634: Structural Pattern Matching)
# Python 3.10a7 3435 Use instruction offsets (as opposed to byte offsets).
# #
# MAGIC must change whenever the bytecode emitted by the compiler may no # MAGIC must change whenever the bytecode emitted by the compiler may no

View File

@ -127,10 +127,10 @@ dis_bug708901 = """\
%3d 6 CALL_FUNCTION 2 %3d 6 CALL_FUNCTION 2
8 GET_ITER 8 GET_ITER
>> 10 FOR_ITER 4 (to 16) >> 10 FOR_ITER 2 (to 16)
12 STORE_FAST 0 (res) 12 STORE_FAST 0 (res)
%3d 14 JUMP_ABSOLUTE 10 %3d 14 JUMP_ABSOLUTE 5 (to 10)
%3d >> 16 LOAD_CONST 0 (None) %3d >> 16 LOAD_CONST 0 (None)
18 RETURN_VALUE 18 RETURN_VALUE
@ -276,11 +276,11 @@ dis_compound_stmt_str = """\
10 INPLACE_ADD 10 INPLACE_ADD
12 STORE_NAME 0 (x) 12 STORE_NAME 0 (x)
2 14 JUMP_ABSOLUTE 6 2 14 JUMP_ABSOLUTE 3 (to 6)
""" """
dis_traceback = """\ dis_traceback = """\
%3d 0 SETUP_FINALLY 14 (to 16) %3d 0 SETUP_FINALLY 7 (to 16)
%3d 2 LOAD_CONST 1 (1) %3d 2 LOAD_CONST 1 (1)
4 LOAD_CONST 2 (0) 4 LOAD_CONST 2 (0)
@ -293,11 +293,11 @@ dis_traceback = """\
%3d >> 16 DUP_TOP %3d >> 16 DUP_TOP
18 LOAD_GLOBAL 0 (Exception) 18 LOAD_GLOBAL 0 (Exception)
20 JUMP_IF_NOT_EXC_MATCH 58 20 JUMP_IF_NOT_EXC_MATCH 29 (to 58)
22 POP_TOP 22 POP_TOP
24 STORE_FAST 0 (e) 24 STORE_FAST 0 (e)
26 POP_TOP 26 POP_TOP
28 SETUP_FINALLY 20 (to 50) 28 SETUP_FINALLY 10 (to 50)
%3d 30 LOAD_FAST 0 (e) %3d 30 LOAD_FAST 0 (e)
32 LOAD_ATTR 1 (__traceback__) 32 LOAD_ATTR 1 (__traceback__)
@ -358,7 +358,7 @@ def _tryfinallyconst(b):
b() b()
dis_tryfinally = """\ dis_tryfinally = """\
%3d 0 SETUP_FINALLY 12 (to 14) %3d 0 SETUP_FINALLY 6 (to 14)
%3d 2 LOAD_FAST 0 (a) %3d 2 LOAD_FAST 0 (a)
4 POP_BLOCK 4 POP_BLOCK
@ -377,7 +377,7 @@ dis_tryfinally = """\
) )
dis_tryfinallyconst = """\ dis_tryfinallyconst = """\
%3d 0 SETUP_FINALLY 12 (to 14) %3d 0 SETUP_FINALLY 6 (to 14)
%3d 2 POP_BLOCK %3d 2 POP_BLOCK
@ -450,13 +450,13 @@ dis_nested_2 = """%s
Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>: Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>:
%3d 0 BUILD_LIST 0 %3d 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0) 2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 12 (to 18) >> 4 FOR_ITER 6 (to 18)
6 STORE_FAST 1 (z) 6 STORE_FAST 1 (z)
8 LOAD_DEREF 0 (x) 8 LOAD_DEREF 0 (x)
10 LOAD_FAST 1 (z) 10 LOAD_FAST 1 (z)
12 BINARY_ADD 12 BINARY_ADD
14 LIST_APPEND 2 14 LIST_APPEND 2
16 JUMP_ABSOLUTE 4 16 JUMP_ABSOLUTE 2 (to 4)
>> 18 RETURN_VALUE >> 18 RETURN_VALUE
""" % (dis_nested_1, """ % (dis_nested_1,
__file__, __file__,
@ -1009,7 +1009,7 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=2, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=2, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=4, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=4, starts_line=None, is_jump_target=False),
Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False), Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False),
Instruction(opname='FOR_ITER', opcode=93, arg=34, argval=44, argrepr='to 44', offset=8, starts_line=None, is_jump_target=True), Instruction(opname='FOR_ITER', opcode=93, arg=17, argval=44, argrepr='to 44', offset=8, starts_line=None, is_jump_target=True),
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=10, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=10, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=12, starts_line=4, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=12, starts_line=4, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=14, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=14, starts_line=None, is_jump_target=False),
@ -1018,21 +1018,21 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=20, starts_line=5, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=20, starts_line=5, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=22, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=22, starts_line=None, is_jump_target=False),
Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=24, starts_line=None, is_jump_target=False), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=24, starts_line=None, is_jump_target=False),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=30, argval=30, argrepr='', offset=26, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=15, argval=30, argrepr='to 30', offset=26, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=8, argval=8, argrepr='', offset=28, starts_line=6, is_jump_target=False), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=4, argval=8, argrepr='to 8', offset=28, starts_line=6, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=30, starts_line=7, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=30, starts_line=7, is_jump_target=True),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=32, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=32, starts_line=None, is_jump_target=False),
Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=34, starts_line=None, is_jump_target=False), Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=34, starts_line=None, is_jump_target=False),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=42, argval=42, argrepr='', offset=36, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=21, argval=42, argrepr='to 42', offset=36, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=8, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=8, is_jump_target=False),
Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=52, argrepr='', offset=40, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=26, argval=52, argrepr='to 52', offset=40, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=8, argval=8, argrepr='', offset=42, starts_line=7, is_jump_target=True), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=4, argval=8, argrepr='to 8', offset=42, starts_line=7, is_jump_target=True),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=44, starts_line=10, is_jump_target=True), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=44, starts_line=10, is_jump_target=True),
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=46, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=46, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=48, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=48, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=11, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=11, is_jump_target=True),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=96, argval=96, argrepr='', offset=54, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=48, argval=96, argrepr='to 96', offset=54, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=56, starts_line=12, is_jump_target=True), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=56, starts_line=12, is_jump_target=True),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=58, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=58, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=60, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=60, starts_line=None, is_jump_target=False),
@ -1044,30 +1044,30 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=14, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=14, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=74, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=74, starts_line=None, is_jump_target=False),
Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=76, starts_line=None, is_jump_target=False), Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=76, starts_line=None, is_jump_target=False),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=82, argval=82, argrepr='', offset=78, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=41, argval=82, argrepr='to 82', offset=78, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=52, argrepr='', offset=80, starts_line=15, is_jump_target=False), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=26, argval=52, argrepr='to 52', offset=80, starts_line=15, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=82, starts_line=16, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=82, starts_line=16, is_jump_target=True),
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=84, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=84, starts_line=None, is_jump_target=False),
Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=86, starts_line=None, is_jump_target=False), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=86, starts_line=None, is_jump_target=False),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=92, argval=92, argrepr='', offset=88, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=46, argval=92, argrepr='to 92', offset=88, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=104, argval=104, argrepr='', offset=90, starts_line=17, is_jump_target=False), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=104, argrepr='to 104', offset=90, starts_line=17, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=92, starts_line=11, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=92, starts_line=11, is_jump_target=True),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=56, argval=56, argrepr='', offset=94, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=28, argval=56, argrepr='to 56', offset=94, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=96, starts_line=19, is_jump_target=True), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=96, starts_line=19, is_jump_target=True),
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=98, starts_line=None, is_jump_target=False), 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=98, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=100, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=100, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False),
Instruction(opname='SETUP_FINALLY', opcode=122, arg=96, argval=202, argrepr='to 202', offset=104, starts_line=20, is_jump_target=True), Instruction(opname='SETUP_FINALLY', opcode=122, arg=48, argval=202, argrepr='to 202', offset=104, starts_line=20, is_jump_target=True),
Instruction(opname='SETUP_FINALLY', opcode=122, arg=12, argval=120, argrepr='to 120', offset=106, starts_line=None, is_jump_target=False), Instruction(opname='SETUP_FINALLY', opcode=122, arg=6, argval=120, argrepr='to 120', offset=106, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=108, starts_line=21, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=108, starts_line=21, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=110, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=110, starts_line=None, is_jump_target=False),
Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False), Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False),
Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False), Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_FORWARD', opcode=110, arg=24, argval=144, argrepr='to 144', offset=118, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=144, argrepr='to 144', offset=118, starts_line=None, is_jump_target=False),
Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=120, starts_line=22, is_jump_target=True), Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=120, starts_line=22, is_jump_target=True),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=122, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=122, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=212, argval=212, argrepr='', offset=124, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=106, argval=212, argrepr='to 212', offset=124, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False),
@ -1076,9 +1076,9 @@ expected_opinfo_jumpy = [
Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False),
Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False), Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_FORWARD', opcode=110, arg=44, argval=188, argrepr='to 188', offset=142, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_FORWARD', opcode=110, arg=22, argval=188, argrepr='to 188', offset=142, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=25, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=25, is_jump_target=True),
Instruction(opname='SETUP_WITH', opcode=143, arg=24, argval=172, argrepr='to 172', offset=146, starts_line=None, is_jump_target=False), Instruction(opname='SETUP_WITH', opcode=143, arg=12, argval=172, argrepr='to 172', offset=146, starts_line=None, is_jump_target=False),
Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=148, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=148, starts_line=None, is_jump_target=False),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=150, starts_line=26, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=150, starts_line=26, is_jump_target=False),
Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=152, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=152, starts_line=None, is_jump_target=False),
@ -1090,9 +1090,9 @@ expected_opinfo_jumpy = [
Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False), Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False),
Instruction(opname='CALL_FUNCTION', opcode=131, arg=3, argval=3, argrepr='', offset=166, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=3, argval=3, argrepr='', offset=166, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False),
Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=188, argrepr='to 188', offset=170, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_FORWARD', opcode=110, arg=8, argval=188, argrepr='to 188', offset=170, starts_line=None, is_jump_target=False),
Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=True), Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=True),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=178, argval=178, argrepr='', offset=174, starts_line=None, is_jump_target=False), Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=89, argval=178, argrepr='to 178', offset=174, starts_line=None, is_jump_target=False),
Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=176, starts_line=None, is_jump_target=False), Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=176, starts_line=None, is_jump_target=False),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=True), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=True),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False),

View File

@ -0,0 +1,3 @@
The bytecode interpreter uses instruction, rather byte, offsets internally.
This reduces the number of EXTENDED_ARG instructions needed and streamlines
instruction dispatch a bit.

View File

@ -1246,7 +1246,7 @@ PyTypeObject PyCode_Type = {
int int
PyCode_Addr2Line(PyCodeObject *co, int addrq) PyCode_Addr2Line(PyCodeObject *co, int addrq)
{ {
if (addrq == -1) { if (addrq < 0) {
return co->co_firstlineno; return co->co_firstlineno;
} }
assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code));

View File

@ -15,7 +15,6 @@ static PyMemberDef frame_memberlist[] = {
{"f_code", T_OBJECT, OFF(f_code), READONLY}, {"f_code", T_OBJECT, OFF(f_code), READONLY},
{"f_builtins", T_OBJECT, OFF(f_builtins), READONLY}, {"f_builtins", T_OBJECT, OFF(f_builtins), READONLY},
{"f_globals", T_OBJECT, OFF(f_globals), READONLY}, {"f_globals", T_OBJECT, OFF(f_globals), READONLY},
{"f_lasti", T_INT, OFF(f_lasti), READONLY},
{"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0},
{"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0}, {"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
@ -46,7 +45,7 @@ PyFrame_GetLineNumber(PyFrameObject *f)
return f->f_lineno; return f->f_lineno;
} }
else { else {
return PyCode_Addr2Line(f->f_code, f->f_lasti); return PyCode_Addr2Line(f->f_code, f->f_lasti*2);
} }
} }
@ -56,6 +55,15 @@ frame_getlineno(PyFrameObject *f, void *closure)
return PyLong_FromLong(PyFrame_GetLineNumber(f)); return PyLong_FromLong(PyFrame_GetLineNumber(f));
} }
static PyObject *
frame_getlasti(PyFrameObject *f, void *closure)
{
if (f->f_lasti < 0) {
return PyLong_FromLong(-1);
}
return PyLong_FromLong(f->f_lasti*2);
}
/* Given the index of the effective opcode, /* Given the index of the effective opcode,
scan back to construct the oparg with EXTENDED_ARG */ scan back to construct the oparg with EXTENDED_ARG */
@ -135,7 +143,7 @@ markblocks(PyCodeObject *code_obj, int len)
case POP_JUMP_IF_FALSE: case POP_JUMP_IF_FALSE:
case POP_JUMP_IF_TRUE: case POP_JUMP_IF_TRUE:
case JUMP_IF_NOT_EXC_MATCH: case JUMP_IF_NOT_EXC_MATCH:
j = get_arg(code, i) / sizeof(_Py_CODEUNIT); j = get_arg(code, i);
assert(j < len); assert(j < len);
if (blocks[j] == -1 && j < i) { if (blocks[j] == -1 && j < i) {
todo = 1; todo = 1;
@ -145,7 +153,7 @@ markblocks(PyCodeObject *code_obj, int len)
blocks[i+1] = block_stack; blocks[i+1] = block_stack;
break; break;
case JUMP_ABSOLUTE: case JUMP_ABSOLUTE:
j = get_arg(code, i) / sizeof(_Py_CODEUNIT); j = get_arg(code, i);
assert(j < len); assert(j < len);
if (blocks[j] == -1 && j < i) { if (blocks[j] == -1 && j < i) {
todo = 1; todo = 1;
@ -154,7 +162,7 @@ markblocks(PyCodeObject *code_obj, int len)
blocks[j] = block_stack; blocks[j] = block_stack;
break; break;
case SETUP_FINALLY: case SETUP_FINALLY:
j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; j = get_arg(code, i) + i + 1;
assert(j < len); assert(j < len);
except_stack = push_block(block_stack, Except); except_stack = push_block(block_stack, Except);
assert(blocks[j] == -1 || blocks[j] == except_stack); assert(blocks[j] == -1 || blocks[j] == except_stack);
@ -164,7 +172,7 @@ markblocks(PyCodeObject *code_obj, int len)
break; break;
case SETUP_WITH: case SETUP_WITH:
case SETUP_ASYNC_WITH: case SETUP_ASYNC_WITH:
j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; j = get_arg(code, i) + i + 1;
assert(j < len); assert(j < len);
except_stack = push_block(block_stack, Except); except_stack = push_block(block_stack, Except);
assert(blocks[j] == -1 || blocks[j] == except_stack); assert(blocks[j] == -1 || blocks[j] == except_stack);
@ -173,7 +181,7 @@ markblocks(PyCodeObject *code_obj, int len)
blocks[i+1] = block_stack; blocks[i+1] = block_stack;
break; break;
case JUMP_FORWARD: case JUMP_FORWARD:
j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; j = get_arg(code, i) + i + 1;
assert(j < len); assert(j < len);
assert(blocks[j] == -1 || blocks[j] == block_stack); assert(blocks[j] == -1 || blocks[j] == block_stack);
blocks[j] = block_stack; blocks[j] = block_stack;
@ -186,7 +194,7 @@ markblocks(PyCodeObject *code_obj, int len)
case FOR_ITER: case FOR_ITER:
blocks[i+1] = block_stack; blocks[i+1] = block_stack;
block_stack = pop_block(block_stack); block_stack = pop_block(block_stack);
j = get_arg(code, i) / sizeof(_Py_CODEUNIT) + i + 1; j = get_arg(code, i) + i + 1;
assert(j < len); assert(j < len);
assert(blocks[j] == -1 || blocks[j] == block_stack); assert(blocks[j] == -1 || blocks[j] == block_stack);
blocks[j] = block_stack; blocks[j] = block_stack;
@ -422,7 +430,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
int64_t target_block_stack = -1; int64_t target_block_stack = -1;
int64_t best_block_stack = -1; int64_t best_block_stack = -1;
int best_addr = -1; int best_addr = -1;
int64_t start_block_stack = blocks[f->f_lasti/sizeof(_Py_CODEUNIT)]; int64_t start_block_stack = blocks[f->f_lasti];
const char *msg = "cannot find bytecode for specified line"; const char *msg = "cannot find bytecode for specified line";
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (lines[i] == new_lineno) { if (lines[i] == new_lineno) {
@ -431,7 +439,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
msg = NULL; msg = NULL;
if (target_block_stack > best_block_stack) { if (target_block_stack > best_block_stack) {
best_block_stack = target_block_stack; best_block_stack = target_block_stack;
best_addr = i*sizeof(_Py_CODEUNIT); best_addr = i;
} }
} }
else if (msg) { else if (msg) {
@ -511,6 +519,7 @@ static PyGetSetDef frame_getsetlist[] = {
{"f_lineno", (getter)frame_getlineno, {"f_lineno", (getter)frame_getlineno,
(setter)frame_setlineno, NULL}, (setter)frame_setlineno, NULL},
{"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL}, {"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL},
{"f_lasti", (getter)frame_getlasti, NULL, NULL},
{0} {0}
}; };

View File

@ -357,7 +357,7 @@ _PyGen_yf(PyGenObject *gen)
return NULL; return NULL;
} }
if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM) if (code[(f->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM)
return NULL; return NULL;
assert(f->f_stackdepth > 0); assert(f->f_stackdepth > 0);
yf = f->f_valuestack[f->f_stackdepth-1]; yf = f->f_valuestack[f->f_stackdepth-1];
@ -481,7 +481,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
Py_DECREF(ret); Py_DECREF(ret);
/* Termination repetition of YIELD_FROM */ /* Termination repetition of YIELD_FROM */
assert(gen->gi_frame->f_lasti >= 0); assert(gen->gi_frame->f_lasti >= 0);
gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); gen->gi_frame->f_lasti += 1;
if (_PyGen_FetchStopIterationValue(&val) == 0) { if (_PyGen_FetchStopIterationValue(&val) == 0) {
ret = gen_send(gen, val); ret = gen_send(gen, val);
Py_DECREF(val); Py_DECREF(val);

View File

@ -1338,16 +1338,15 @@ eval_frame_handle_pending(PyThreadState *tstate)
/* Code access macros */ /* Code access macros */
/* The integer overflow is checked by an assertion below. */ /* The integer overflow is checked by an assertion below. */
#define INSTR_OFFSET() \ #define INSTR_OFFSET() ((int)(next_instr - first_instr))
(sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr))
#define NEXTOPARG() do { \ #define NEXTOPARG() do { \
_Py_CODEUNIT word = *next_instr; \ _Py_CODEUNIT word = *next_instr; \
opcode = _Py_OPCODE(word); \ opcode = _Py_OPCODE(word); \
oparg = _Py_OPARG(word); \ oparg = _Py_OPARG(word); \
next_instr++; \ next_instr++; \
} while (0) } while (0)
#define JUMPTO(x) (next_instr = first_instr + (x) / sizeof(_Py_CODEUNIT)) #define JUMPTO(x) (next_instr = first_instr + (x))
#define JUMPBY(x) (next_instr += (x) / sizeof(_Py_CODEUNIT)) #define JUMPBY(x) (next_instr += (x))
/* OpCode prediction macros /* OpCode prediction macros
Some opcodes tend to come in pairs thus making it possible to Some opcodes tend to come in pairs thus making it possible to
@ -1699,11 +1698,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
to the beginning of the combined pair.) to the beginning of the combined pair.)
*/ */
assert(f->f_lasti >= -1); assert(f->f_lasti >= -1);
next_instr = first_instr; next_instr = first_instr + f->f_lasti + 1;
if (f->f_lasti >= 0) {
assert(f->f_lasti % sizeof(_Py_CODEUNIT) == 0);
next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1;
}
stack_pointer = f->f_valuestack + f->f_stackdepth; stack_pointer = f->f_valuestack + f->f_stackdepth;
/* Set f->f_stackdepth to -1. /* Set f->f_stackdepth to -1.
* Update when returning or calling trace function. * Update when returning or calling trace function.
@ -2627,8 +2622,8 @@ main_loop:
assert (gen_status == PYGEN_NEXT); assert (gen_status == PYGEN_NEXT);
/* receiver remains on stack, retval is value to be yielded */ /* receiver remains on stack, retval is value to be yielded */
/* and repeat... */ /* and repeat... */
assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); assert(f->f_lasti > 0);
f->f_lasti -= sizeof(_Py_CODEUNIT); f->f_lasti -= 1;
f->f_state = FRAME_SUSPENDED; f->f_state = FRAME_SUSPENDED;
f->f_stackdepth = (int)(stack_pointer - f->f_valuestack); f->f_stackdepth = (int)(stack_pointer - f->f_valuestack);
goto exiting; goto exiting;
@ -5511,7 +5506,7 @@ call_trace(Py_tracefunc func, PyObject *obj,
} }
else { else {
initialize_trace_info(trace_info, frame); initialize_trace_info(trace_info, frame);
frame->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti, &trace_info->bounds); frame->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*2, &trace_info->bounds);
} }
result = func(obj, frame, what, arg); result = func(obj, frame, what, arg);
frame->f_lineno = 0; frame->f_lineno = 0;
@ -5552,11 +5547,11 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
*/ */
initialize_trace_info(trace_info, frame); initialize_trace_info(trace_info, frame);
int lastline = trace_info->bounds.ar_line; int lastline = trace_info->bounds.ar_line;
int line = _PyCode_CheckLineNumber(frame->f_lasti, &trace_info->bounds); int line = _PyCode_CheckLineNumber(frame->f_lasti*2, &trace_info->bounds);
if (line != -1 && frame->f_trace_lines) { if (line != -1 && frame->f_trace_lines) {
/* Trace backward edges or first instruction of a new line */ /* Trace backward edges or first instruction of a new line */
if (frame->f_lasti < trace_info->instr_prev || if (frame->f_lasti < trace_info->instr_prev ||
(line != lastline && frame->f_lasti == trace_info->bounds.ar_start)) (line != lastline && frame->f_lasti*2 == trace_info->bounds.ar_start))
{ {
result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_LINE, Py_None); result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_LINE, Py_None);
} }
@ -6475,7 +6470,7 @@ dtrace_function_entry(PyFrameObject *f)
PyCodeObject *code = f->f_code; PyCodeObject *code = f->f_code;
filename = PyUnicode_AsUTF8(code->co_filename); filename = PyUnicode_AsUTF8(code->co_filename);
funcname = PyUnicode_AsUTF8(code->co_name); funcname = PyUnicode_AsUTF8(code->co_name);
lineno = PyCode_Addr2Line(code, f->f_lasti); lineno = PyFrame_GetLineNumber(f);
PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno);
} }
@ -6490,7 +6485,7 @@ dtrace_function_return(PyFrameObject *f)
PyCodeObject *code = f->f_code; PyCodeObject *code = f->f_code;
filename = PyUnicode_AsUTF8(code->co_filename); filename = PyUnicode_AsUTF8(code->co_filename);
funcname = PyUnicode_AsUTF8(code->co_name); funcname = PyUnicode_AsUTF8(code->co_name);
lineno = PyCode_Addr2Line(code, f->f_lasti); lineno = PyFrame_GetLineNumber(f);
PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); PyDTrace_FUNCTION_RETURN(filename, funcname, lineno);
} }
@ -6506,7 +6501,7 @@ maybe_dtrace_line(PyFrameObject *frame,
instruction window, reset the window. instruction window, reset the window.
*/ */
initialize_trace_info(trace_info, frame); initialize_trace_info(trace_info, frame);
int line = _PyCode_CheckLineNumber(frame->f_lasti, &trace_info->bounds); int line = _PyCode_CheckLineNumber(frame->f_lasti*2, &trace_info->bounds);
/* If the last instruction falls at the start of a line or if /* If the last instruction falls at the start of a line or if
it represents a jump backwards, update the frame's line it represents a jump backwards, update the frame's line
number and call the trace function. */ number and call the trace function. */

View File

@ -6398,7 +6398,6 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
if (is_relative_jump(instr)) { if (is_relative_jump(instr)) {
instr->i_oparg -= bsize; instr->i_oparg -= bsize;
} }
instr->i_oparg *= sizeof(_Py_CODEUNIT);
if (instrsize(instr->i_oparg) != isize) { if (instrsize(instr->i_oparg) != isize) {
extended_arg_recompile = 1; extended_arg_recompile = 1;
} }

2175
Python/importlib.h generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -233,7 +233,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame)
assert(tb_next == NULL || PyTraceBack_Check(tb_next)); assert(tb_next == NULL || PyTraceBack_Check(tb_next));
assert(frame != NULL); assert(frame != NULL);
return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti, return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti*2,
PyFrame_GetLineNumber(frame)); PyFrame_GetLineNumber(frame));
} }
@ -763,8 +763,7 @@ dump_frame(int fd, PyFrameObject *frame)
PUTS(fd, "???"); PUTS(fd, "???");
} }
/* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ int lineno = PyFrame_GetLineNumber(frame);
int lineno = PyCode_Addr2Line(code, frame->f_lasti);
PUTS(fd, ", line "); PUTS(fd, ", line ");
if (lineno >= 0) { if (lineno >= 0) {
_Py_DumpDecimal(fd, (size_t)lineno); _Py_DumpDecimal(fd, (size_t)lineno);

View File

@ -947,7 +947,7 @@ class PyFrameObjectPtr(PyObjectPtr):
return self.f_lineno return self.f_lineno
try: try:
return self.co.addr2line(self.f_lasti) return self.co.addr2line(self.f_lasti*2)
except Exception: except Exception:
# bpo-34989: addr2line() is a complex function, it can fail in many # bpo-34989: addr2line() is a complex function, it can fail in many
# ways. For example, it fails with a TypeError on "FakeRepr" if # ways. For example, it fails with a TypeError on "FakeRepr" if