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
28 changes: 2 additions & 26 deletions xdis/codetype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from xdis.codetype.code38 import Code38
from xdis.codetype.code310 import Code310
from xdis.codetype.code311 import Code311, Code311FieldNames
from xdis.codetype.code312 import Code312
from xdis.version_info import PYTHON_VERSION_TRIPLE


Expand Down Expand Up @@ -101,7 +100,7 @@ def codeType2Portable(code, version_tuple=PYTHON_VERSION_TRIPLE):
co_firstlineno=code.co_firstlineno,
co_linetable=line_table,
)
elif version_tuple[:2] == (3,11):
elif version_tuple[:2] >= (3,11):
return Code311(
co_argcount=code.co_argcount,
co_posonlyargcount=code.co_posonlyargcount,
Expand All @@ -122,27 +121,6 @@ def codeType2Portable(code, version_tuple=PYTHON_VERSION_TRIPLE):
co_linetable=line_table,
co_exceptiontable=code.co_exceptiontable,
)
elif version_tuple[:2] >= (3,12):
return Code312(
co_argcount=code.co_argcount,
co_posonlyargcount=code.co_posonlyargcount,
co_kwonlyargcount=code.co_kwonlyargcount,
co_nlocals=code.co_nlocals,
co_stacksize=code.co_stacksize,
co_flags=code.co_flags,
co_consts=code.co_consts,
co_code=code.co_code,
co_names=code.co_names,
co_varnames=code.co_varnames,
co_freevars=code.co_freevars,
co_cellvars=code.co_cellvars,
co_filename=code.co_filename,
co_name=code.co_name,
co_qualname=code.co_qualname,
co_firstlineno=code.co_firstlineno,
co_linetable=line_table,
co_exceptiontable=code.co_exceptiontable,
)
elif version_tuple > (2, 0):
# 2.0 .. 2.7
return Code2(
Expand Down Expand Up @@ -209,11 +187,9 @@ def portableCodeType(version_tuple=PYTHON_VERSION_TRIPLE):
elif version_tuple[:2] == (3, 10):
# 3.10
return Code310
elif version_tuple[:2] == (3,11):
elif version_tuple[:2] >= (3,11):
# 3.11 ...
return Code311
elif version_tuple[:2] >= (3,12):
return Code312
elif version_tuple > (2, 0):
# 2.0 .. 2.7
return Code2
Expand Down
50 changes: 18 additions & 32 deletions xdis/codetype/code310.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import types
from copy import deepcopy

import struct

from xdis.codetype.code38 import Code38
from xdis.cross_types import UnicodeForPython3
from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str
Expand Down Expand Up @@ -160,41 +162,25 @@ def co_lines(self):
equal to the size of the bytecode. line will
either be a positive integer, or None

Parsing implementation adapted from: https://github.com/python/cpython/blob/3.10/Objects/lnotab_notes.txt
"""
line_number = self.co_firstlineno
start_offset = 0
byte_increments = [c for c in tuple(self.co_linetable[0::2])]
line_deltas = [c for c in tuple(self.co_linetable[1::2])]

if len(byte_increments) == 0:
yield start_offset, len(self.co_code), line_number
return

byte_incr = byte_increments[0]
line_delta = line_deltas[0]
assert line_delta != -128, "the first line delta can't logically be -128"
assert isinstance(line_delta, int)
if line_delta > 127:
line_delta = 256 - line_delta
else:
line_number += line_delta

for byte_incr, line_delta in zip(byte_increments[1:], line_deltas[1:]):
line = self.co_firstlineno
end_offset = 0
# co_linetable is pairs of (offset_delta: unsigned byte, line_delta: signed byte)
for offset_delta, line_delta in struct.iter_unpack('=Bb', self.co_linetable):
assert isinstance(line_delta, int)
assert isinstance(byte_incr, int)
end_offset = start_offset + byte_incr
if line_delta > 127:
line_delta = 256 - line_delta

if line_delta == -128:
line_delta = 0
yield start_offset, end_offset, line_number
line_number += line_delta
assert isinstance(offset_delta, int)
if line_delta == 0: # No change to line number, just accumulate changes to end
end_offset += offset_delta
continue
start_offset = end_offset

end_offset = len(self.co_code)
yield start_offset, end_offset, line_number
return
end_offset = start_offset + offset_delta
if line_delta == -128: # No valid line number -- skip entry
continue
line += line_delta
if end_offset == start_offset: # Empty range, omit.
continue
yield start_offset, end_offset, line

def encode_lineno_tab(self):
"""
Expand Down
61 changes: 31 additions & 30 deletions xdis/codetype/code311.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,37 @@
from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str


# Note: order is the positional order given in the Python docs for
# 3.11 types.Codetype.
# "posonlyargcount" is not used, but it is in other Python versions, so it
# has to be included since this structure is used as the Union type
# for all code types.
Code311FieldNames = """
co_argcount
co_posonlyargcount
co_kwonlyargcount
co_nlocals
co_stacksize
co_flags
co_consts
co_code
co_names
co_varnames
co_freevars
co_cellvars
co_filename
co_name
co_qualname
co_firstlineno
co_linetable
co_exceptiontable
"""

Code311FieldTypes = deepcopy(Code310FieldTypes)
Code311FieldTypes.update({"co_qualname": str, "co_exceptiontable": bytes})


##### Parse location table #####
def parse_location_entries(location_bytes, first_line):
"""
Parses the locations table described in: https://github.com/python/cpython/blob/3.11/Objects/locations.md
Expand Down Expand Up @@ -131,36 +162,6 @@ def decode_signed_varint(s):
return entries


# Note: order is the positional order given in the Python docs for
# 3.11 types.Codetype.
# "posonlyargcount" is not used, but it is in other Python versions, so it
# has to be included since this structure is used as the Union type
# for all code types.
Code311FieldNames = """
co_argcount
co_posonlyargcount
co_kwonlyargcount
co_nlocals
co_stacksize
co_flags
co_consts
co_code
co_names
co_varnames
co_freevars
co_cellvars
co_filename
co_name
co_qualname
co_firstlineno
co_linetable
co_exceptiontable
"""

Code311FieldTypes = deepcopy(Code310FieldTypes)
Code311FieldTypes.update({"co_qualname": str, "co_exceptiontable": bytes})


##### NEW "OPAQUE" LINE TABLE PARSING #####
# See: https://github.com/python/cpython/blob/aaed91cabcedc16c089c4b1c9abb1114659a83d3/Objects/codeobject.c#L1245C1-L1245C17
PY_CODE_LOCATION_INFO_SHORT0 = 0
Expand Down
97 changes: 0 additions & 97 deletions xdis/codetype/code312.py

This file was deleted.

7 changes: 1 addition & 6 deletions xdis/opcodes/opcode_310.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,10 @@
def_op(loc, "RERAISE", 119, 3, 0)
def_op(loc, "GEN_START", 129, 1, 0)
def_op(loc, "MATCH_CLASS", 152, 2, 1)
# fmt: on


# fmt: on
opcode_arg_fmt = opcode_arg_fmt310 = opcode_arg_fmt39.copy()
opcode_extended_fmt = opcode_extended_fmt310 = opcode_extended_fmt39.copy()

# fmt: on

opcode_arg_fmt = opcode_arg_fmt10 = opcode_arg_fmt39.copy()

update_pj3(globals(), loc)
finalize_opcodes(loc)
4 changes: 0 additions & 4 deletions xdis/opcodes/opcode_311.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,6 @@ def format_BINARY_OP(arg) -> str:
del opcode_extended_fmt311["INPLACE_TRUE_DIVIDE"]
del opcode_extended_fmt311["INPLACE_XOR"]

opcode_extended_fmt = opcode_extended_fmt311

opcode_arg_fmt = opcode_arg_fmt11 = opcode_arg_fmt310.copy()

from xdis.opcodes.opcode_310 import findlinestarts

update_pj3(globals(), loc)
Expand Down
7 changes: 4 additions & 3 deletions xdis/opcodes/opcode_312.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ def format_CALL_INTRINSIC_1(arg) -> str:
def format_CALL_INTRINSIC_2(arg) -> str:
return _intrinsic_2_descs[arg]


opcode_extended_fmt = opcode_extended_fmt312 = opcode_extended_fmt311.copy()
opcode_arg_fmt = opcode_arg_fmt12 = opcode_arg_fmt311.copy()

### update arg formatting
opcode_arg_fmt312 = {
**opcode_arg_fmt311,
Expand All @@ -185,9 +189,6 @@ def format_CALL_INTRINSIC_2(arg) -> str:
"CALL_INTRINSIC_2": format_CALL_INTRINSIC_2,
},
}
opcode_extended_fmt = opcode_extended_fmt312 = opcode_extended_fmt311.copy()

opcode_arg_fmt = opcode_arg_fmt12 = opcode_arg_fmt311.copy()

from xdis.opcodes.opcode_311 import findlinestarts

Expand Down
4 changes: 2 additions & 2 deletions xdis/opcodes/opcode_313.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@
opcode_extended_fmt = opcode_312.opcode_extended_fmt312.copy()
for fmt_table in (opcode_arg_fmt, opcode_extended_fmt):
fmt_table.pop("MAKE_FUNCTION") # MAKE_FUNCTION formatting not in 3.13
opcode_arg_fmt13 = opcode_arg_fmt
opcode_extended_fmt13 = opcode_extended_fmt
opcode_arg_fmt313 = opcode_arg_fmt
opcode_extended_fmt313 = opcode_extended_fmt


# update any calls to findlinestarts to include the version tuple
Expand Down
Loading