1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
From: Fabio Zadrozny <fabiofz@gmail.com>
Date: Wed, 14 Dec 2022 19:47:25 +0100
Subject: Add offset to instructions from bytecode library.
Last-Update: 2025-02-20
Origin: https://github.com/fabioz/PyDev.Debugger/commit/ab9958b70c69f14e69fda6023ec26106b921b13d
Forwarded: not-needed
This is based on the pydevd patch referenced in the Origin field, but
simplified to produce the minimum possible patch.
---
src/bytecode/concrete.py | 15 +++++++++++----
src/bytecode/instr.py | 6 ++++--
2 files changed, 15 insertions(+), 6 deletions(-)
--- a/src/bytecode/concrete.py
+++ b/src/bytecode/concrete.py
@@ -83,7 +83,7 @@
# For ConcreteInstr the argument is always an integer
_arg: int
- __slots__ = ("_extended_args", "_size")
+ __slots__ = ("_extended_args", "_size", "offset")
def __init__(
self,
@@ -93,12 +93,14 @@
lineno: Union[int, None, _UNSET] = UNSET,
location: Optional[InstrLocation] = None,
extended_args: Optional[int] = None,
+ offset: Optional[int] = None,
):
# Allow to remember a potentially meaningless EXTENDED_ARG emitted by
# Python to properly compute the size and avoid messing up the jump
# targets
self._extended_args = extended_args
- super().__init__(name, arg, lineno=lineno, location=location)
+ self.offset = offset
+ super().__init__(name, arg, lineno=lineno, location=location, offset=offset)
def _check_arg(self, name: str, opcode: int, arg: int) -> None:
if opcode_has_argument(opcode):
@@ -178,7 +180,11 @@
else:
arg = UNSET
name = _opcode.opname[op]
- return cls(name, arg, lineno=lineno)
+ # fabioz: added offset to ConcreteBytecode
+ # Need to keep an eye on https://github.com/MatthieuDartiailh/bytecode/issues/48 in
+ # case the library decides to add this in some other way.
+ return cls(name, arg, lineno=lineno, offset=index)
+
def use_cache_opcodes(self) -> int:
if sys.version_info >= (3, 13):
@@ -781,6 +787,7 @@
arg,
location=instr.location,
extended_args=nb_extended_args,
+ offset=instr.offset,
)
instructions[index] = instr
nb_extended_args = 0
@@ -1092,7 +1099,7 @@
instr_index = len(instructions)
jumps.append((instr_index, jump_target))
- instructions.append(Instr(c_instr.name, arg, location=location))
+ instructions.append(Instr(c_instr.name, arg, location=location, offset=c_instr.offset))
# We now insert the TryEnd entries
if current_instr_offset in ex_end:
--- a/src/bytecode/instr.py
+++ b/src/bytecode/instr.py
@@ -555,7 +555,7 @@
class BaseInstr(Generic[A]):
"""Abstract instruction."""
- __slots__ = ("_arg", "_location", "_name", "_opcode")
+ __slots__ = ("_arg", "_location", "_name", "_opcode", "offset")
# Work around an issue with the default value of arg
def __init__(
@@ -565,8 +565,10 @@
*,
lineno: Union[int, None, _UNSET] = UNSET,
location: Optional[InstrLocation] = None,
+ offset: Optional[InstrLocation] = None,
) -> None:
self._set(name, arg)
+ self.offset = offset
if location:
self._location = location
elif lineno is UNSET:
@@ -691,7 +693,7 @@
return (_effect, 0)
def copy(self: T) -> T:
- return self.__class__(self._name, self._arg, location=self._location)
+ return self.__class__(self._name, self._arg, location=self._location, offset=self.offset)
def has_jump(self) -> bool:
return self._has_jump(self._opcode)
|