From d06a6da56e3d2eeb9defda2cbc51f04fd0d3f524 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sat, 12 Feb 2022 09:52:45 -0500 Subject: [PATCH 1/2] Support negative jumps in 3.10 Adds support for negative relative jump args introduced in Python 3.10. Ports corresponding fix from dis python/cpython#31285 --- code_data/blocks.py | 13 ++++++++++++- code_data/code_data_test.py | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/code_data/blocks.py b/code_data/blocks.py index 129652b..e33de7e 100644 --- a/code_data/blocks.py +++ b/code_data/blocks.py @@ -5,6 +5,7 @@ from __future__ import annotations +import ctypes import dis import sys from dataclasses import dataclass, field @@ -61,7 +62,6 @@ def bytes_to_blocks(b: bytes) -> Blocks: # Compute a sorted list of target, to map each one to a bloc offset targets = sorted(targets_set) del targets_set - # Then, iterate through each instruction to update the jump to point to the # block offset, instead of the bytecode offset block: list[Instruction] @@ -232,6 +232,9 @@ def _parse_bytes(b: bytes) -> Iterable[tuple[int, int, int, int, int]]: n_args += 1 if opcode == dis.EXTENDED_ARG: arg = arg << 8 + # https://github.com/python/cpython/pull/31285 + if arg > _c_int_upper_limit: + arg -= _c_int_length else: first_offset = i - ((n_args - 1) * 2) next_offset = i + 2 @@ -248,3 +251,11 @@ def _instrsize(arg: int) -> int: From https://github.com/python/cpython/blob/b2e5794870eb4728ddfaafc0f79a40299576434f/Python/wordcode_helpers.h#L11-L20 """ return 1 if arg <= 0xFF else 2 if arg <= 0xFFFF else 3 if arg <= 0xFFFFFF else 4 + + +# The number of bits in a signed int +_c_int_bit_size = ctypes.sizeof(ctypes.c_int()) * 8 +# The maximum value that can be stored in a signed int +_c_int_upper_limit = (2 ** (_c_int_bit_size - 1)) - 1 +# The number of values that can be stored in a signed int +_c_int_length = 2 ** _c_int_bit_size diff --git a/code_data/code_data_test.py b/code_data/code_data_test.py index 0d722f7..ee05d65 100644 --- a/code_data/code_data_test.py +++ b/code_data/code_data_test.py @@ -183,6 +183,14 @@ def main(args): ''', id="pip._vendor.pep517.build minimal", ), + pytest.param( + """while not x < y < z: + pass""", + # Reduced from imagesize modeul + # https://bugs.python.org/issue46724 + # negative opargs in Python 3.10 + id="bpo-46724", + ), ], ) def test_examples(source): @@ -242,7 +250,6 @@ def module_codes() -> Iterable[tuple[str, str, CodeType]]: warnings.simplefilter("ignore") for mi in pkgutil.walk_packages(onerror=lambda _name: None): loader: Loader = mi.module_finder.find_module(mi.name) # type: ignore - loader.__ne__ try: code = loader.get_code(mi.name) # type: ignore except SyntaxError: From e85ff704c81b6db429f67b869ab01d56c697aad2 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sat, 12 Feb 2022 09:54:58 -0500 Subject: [PATCH 2/2] Update code_data/code_data_test.py --- code_data/code_data_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code_data/code_data_test.py b/code_data/code_data_test.py index ee05d65..9ca99e4 100644 --- a/code_data/code_data_test.py +++ b/code_data/code_data_test.py @@ -186,7 +186,7 @@ def main(args): pytest.param( """while not x < y < z: pass""", - # Reduced from imagesize modeul + # Reduced from imagesize module # https://bugs.python.org/issue46724 # negative opargs in Python 3.10 id="bpo-46724",