mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									2ac0515027
								
							
						
					
					
						commit
						fcb55c0037
					
				
					 14 changed files with 4568 additions and 4569 deletions
				
			
		| 
						 | 
					@ -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:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -314,6 +314,7 @@ def _write_atomic(path, data, mode=0o666):
 | 
				
			||||||
#     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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,10 +127,10 @@ def 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 @@ def bug42562():
 | 
				
			||||||
             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 @@ def bug42562():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%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 @@ def _tryfinallyconst(b):
 | 
				
			||||||
       )
 | 
					       )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 @@ def foo(x):
 | 
				
			||||||
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 @@ def 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 @@ def 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 @@ def 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 @@ def 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 @@ def 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),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.
 | 
				
			||||||
| 
						 | 
					@ -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));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
 | 
				
			||||||
            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. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
									
									
									
								
							
							
						
						
									
										2175
									
								
								Python/importlib.h
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										5285
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										5285
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -947,7 +947,7 @@ def current_line_num(self):
 | 
				
			||||||
            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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue