Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions src/bytecode/concrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
DUAL_ARG_OPCODES_SINGLE_OPS,
EXTENDEDARG_OPCODE,
FORMAT_VALUE_OPS,
HAS_JUMP,
INTRINSIC,
INTRINSIC_1OP,
INTRINSIC_2OP,
Expand Down Expand Up @@ -193,6 +194,7 @@ def _from_opcode(
new = object.__new__(cls)
new._name = name
new._opcode = opcode
new._is_jump = opcode in HAS_JUMP
new._arg = arg
new._location = location
new._extended_args = None
Expand All @@ -211,6 +213,7 @@ def _from_trusted(
new = object.__new__(cls)
new._name = name
new._opcode = opcode
new._is_jump = opcode in HAS_JUMP
new._arg = arg
new._location = location
new._extended_args = None
Expand Down Expand Up @@ -491,10 +494,8 @@ def _pack_location_header(code: int, size: int) -> int:
return (1 << 7) + (code << 3) + (size - 1 if size <= 8 else 7)

def _pack_location(
self, size: int, lineno: int, location: Optional[InstrLocation]
) -> bytearray:
packed = bytearray()

self, buf: bytearray, size: int, lineno: int, location: Optional[InstrLocation]
) -> None:
l_lineno: Optional[int]
# The location was not set so we infer a line.
if location is None:
Expand All @@ -514,7 +515,7 @@ def _pack_location(

# We have no location information so the code is 15
if l_lineno is None:
packed.append(self._pack_location_header(15, size))
buf.append(self._pack_location_header(15, size))

# No column info, code 13
elif col_offset is None:
Expand All @@ -523,7 +524,7 @@ def _pack_location(
"An instruction cannot have no column offset and span "
f"multiple lines (lineno: {l_lineno}, end lineno: {end_lineno}"
)
packed.extend(
buf.extend(
(
self._pack_location_header(13, size),
*self._encode_location_svarint(l_lineno - lineno),
Expand All @@ -541,7 +542,7 @@ def _pack_location(
and col_offset < 72
and (end_col_offset - col_offset) <= 15
):
packed.extend(
buf.extend(
(
self._pack_location_header(col_offset // 8, size),
((col_offset % 8) << 4) + (end_col_offset - col_offset),
Expand All @@ -555,7 +556,7 @@ def _pack_location(
and col_offset < 256
and end_col_offset < 256
):
packed.extend(
buf.extend(
(
self._pack_location_header(10 + l_lineno - lineno, size),
col_offset,
Expand All @@ -567,7 +568,7 @@ def _pack_location(
else:
assert end_lineno is not None

packed.extend(
buf.extend(
(
self._pack_location_header(14, size),
*self._encode_location_svarint(l_lineno - lineno),
Expand All @@ -579,11 +580,9 @@ def _pack_location(
)
)

return packed

def _push_locations(
self,
locations: List[bytearray],
buf: bytearray,
size: int,
lineno: int,
location: InstrLocation,
Expand All @@ -595,7 +594,7 @@ def _push_locations(
# elements. We recompute each time since in practice we will
# rarely loop.
while True:
locations.append(self._pack_location(size, lineno, location))
self._pack_location(buf, size, lineno, location)
# Update the lineno since if we need more than one entry the
# reference for the delta of the lineno change
lineno = location.lineno if location.lineno is not None else lineno
Expand All @@ -613,7 +612,7 @@ def _assemble_locations(
if not linenos:
return b""

locations: List[bytearray] = []
buf = bytearray()

iter_in = iter(linenos)

Expand All @@ -634,15 +633,15 @@ def _assemble_locations(
size += i_size
continue

lineno = self._push_locations(locations, size, lineno, old_location)
lineno = self._push_locations(buf, size, lineno, old_location)

size = i_size
old_location = location

# Pack the line of the last instruction.
self._push_locations(locations, size, lineno, old_location)
self._push_locations(buf, size, lineno, old_location)

return b"".join(locations)
return bytes(buf)

@staticmethod
def _remove_extended_args(
Expand Down
7 changes: 5 additions & 2 deletions src/bytecode/instr.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def copy(self) -> TryEnd:
class BaseInstr(Generic[A]):
"""Abstract instruction."""

__slots__ = ("_arg", "_location", "_name", "_opcode")
__slots__ = ("_arg", "_is_jump", "_location", "_name", "_opcode")

# Work around an issue with the default value of arg
def __init__(
Expand Down Expand Up @@ -831,6 +831,7 @@ def copy(self: T) -> T:
new = object.__new__(self.__class__)
new._name = self._name
new._opcode = self._opcode
new._is_jump = self._is_jump
new._arg = self._arg
new._location = self._location
return new
Expand All @@ -847,12 +848,13 @@ def _from_trusted(
new = object.__new__(cls)
new._name = name
new._opcode = opcode
new._is_jump = opcode in HAS_JUMP
new._arg = arg
new._location = location
return new

def has_jump(self) -> bool:
return self._has_jump(self._opcode)
return self._is_jump

def is_cond_jump(self) -> bool:
"""Is a conditional jump?"""
Expand Down Expand Up @@ -916,6 +918,7 @@ def _set(self, name: str, arg: A) -> None:

self._name = name
self._opcode = opcode
self._is_jump = opcode in HAS_JUMP
self._arg = arg

@staticmethod
Expand Down