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 103 104 105 106 107
|
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(-)
diff --git a/src/bytecode/concrete.py b/src/bytecode/concrete.py
index 32c6452..b52ea79 100644
--- a/src/bytecode/concrete.py
+++ b/src/bytecode/concrete.py
@@ -91,7 +91,7 @@ class ConcreteInstr(BaseInstr[int]):
# For ConcreteInstr the argument is always an integer
_arg: int
- __slots__ = ("_extended_args", "_size")
+ __slots__ = ("_extended_args", "_size", "offset")
def __init__(
self,
@@ -101,12 +101,14 @@ class ConcreteInstr(BaseInstr[int]):
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):
@@ -186,7 +188,11 @@ class ConcreteInstr(BaseInstr[int]):
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):
@@ -789,6 +795,7 @@ class ConcreteBytecode(_bytecode._BaseBytecodeList[Union[ConcreteInstr, SetLinen
arg,
location=instr.location,
extended_args=nb_extended_args,
+ offset=instr.offset,
)
instructions[index] = instr
nb_extended_args = 0
@@ -1117,7 +1124,7 @@ class ConcreteBytecode(_bytecode._BaseBytecodeList[Union[ConcreteInstr, SetLinen
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:
diff --git a/src/bytecode/instr.py b/src/bytecode/instr.py
index ac13f77..bf7446d 100644
--- a/src/bytecode/instr.py
+++ b/src/bytecode/instr.py
@@ -620,7 +620,7 @@ A = TypeVar("A", bound=object)
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__(
@@ -630,8 +630,10 @@ class BaseInstr(Generic[A]):
*,
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:
@@ -757,7 +759,7 @@ class BaseInstr(Generic[A]):
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)
|