Skip to content

Commit 48c7ea7

Browse files
author
rocky
committed
Fill out graal codeUnit to update fp read pointer
1 parent cbdf3cc commit 48c7ea7

File tree

1 file changed

+81
-23
lines changed

1 file changed

+81
-23
lines changed

xdis/unmarshal.py

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ def __init__(self, fp, magic_int, bytes_for_s, code_objects={}) -> None:
205205
self.is_pypy = magic_int in PYPY3_MAGICS
206206
self.is_rust = magic_int in RUSTPYTHON_MAGICS
207207

208+
# Graal code data seems to be split in two places.
209+
# The outer part is a TYPE_GRAALPYTHON_CODE,
210+
# while the inner part is in TYPE_GRAALPYTHON_CODE_UNIT
211+
# Save the out information so that the inner information
212+
# can use this when building a code type.
213+
214+
# in a TYPE_GRAAL
215+
self.graal_code_info = {}
216+
208217
if magic_int in RUSTPYTHON_MAGICS:
209218
raise NotImplementedError(
210219
f"RustPython {version_tuple_to_str(self.version_triple)} is not supported yet."
@@ -239,8 +248,8 @@ def t_graal_readArray(self, save_ref: bool, bytes_for_s: bool) -> tuple:
239248
ret = self.graal_readIntArray()
240249
case "o":
241250
ret = self.graal_readObjectArray()
242-
# case "l":
243-
# return "Internal server error"
251+
case "l":
252+
ret = self.graal_readLongArray()
244253
# case "s":
245254
# return "Internal server error"
246255
case "S":
@@ -252,7 +261,6 @@ def t_graal_readArray(self, save_ref: bool, bytes_for_s: bool) -> tuple:
252261
ret = tuple()
253262
if save_ref:
254263
n = len(self.intern_objects)
255-
print("appending at %d: %s" % (n, ret))
256264
self.intern_objects.append(ret)
257265
return ret
258266

@@ -271,16 +279,16 @@ def graal_readBytes(self) -> bytes:
271279
length: int = unpack("<i", self.fp.read(4))[0]
272280
return bytes([self.graal_readByte() for _ in range(length)])
273281

274-
def graal_readDouble(self) -> int:
282+
def graal_readDouble(self) -> float:
275283
"""
276284
Python equivalent of Python Graal's readDouble() from
277285
MarshalModuleBuiltins.java
278286
"""
279-
return unpack("<q", self.fp.read(8))[0]
287+
return unpack("<d", self.fp.read(8))[0]
280288

281-
def graal_readDoubleArray(self) -> tuple[int, ...]:
289+
def graal_readDoubleArray(self) -> tuple[float, ...]:
282290
"""
283-
Python equivalent of Python Graal's readIntArray() from
291+
Python equivalent of Python Graal's readDoubleArray() from
284292
MarshalModuleBuiltins.java
285293
"""
286294
length: int = int(unpack("<i", self.fp.read(4))[0])
@@ -301,9 +309,36 @@ def graal_readIntArray(self) -> tuple[int, ...]:
301309
length: int = int(unpack("<i", self.fp.read(4))[0])
302310
return tuple([self.graal_readInt() for _ in range(length)])
303311

304-
def graal_readObjectArray(self) -> tuple:
305-
""" """
312+
def graal_readLong(self) -> int:
313+
"""
314+
Python equivalent of Python Graal's readLongt() from
315+
MarshalModuleBuiltins.java
316+
"""
317+
return int(unpack("<q", self.fp.read(8))[0])
318+
319+
def graal_readLongArray(self) -> tuple[int, ...]:
320+
"""
321+
Python equivalent of Python Graal's readLongt() from
322+
MarshalModuleBuiltins.java
323+
"""
306324
length: int = int(unpack("<i", self.fp.read(4))[0])
325+
return tuple([self.graal_readLong() for _ in range(length)])
326+
327+
def graal_readObjectArray(self) -> tuple:
328+
"""
329+
Python equivalent of Python Graal's readObjectArray() from
330+
MarshalModuleBuiltins.java
331+
"""
332+
333+
# # Debug code
334+
# length: int = int(unpack("<i", self.fp.read(4))[0])
335+
# result = []
336+
# for i in range(length):
337+
# try:
338+
# result.append(self.r_object(bytes_for_s=False))
339+
# except:
340+
# breakpoint()
341+
# return tuple(result)
307342
return tuple([self.r_object(bytes_for_s=False) for _ in range(length)])
308343

309344
def graal_readString(self) -> str:
@@ -819,33 +854,37 @@ def t_code_graal(self, save_ref, bytes_for_s: bool = False):
819854
# }
820855
# writeBytes(lnotab);
821856

822-
co_filename = self.graal_readString()
823-
co_flags = self.t_int32(False, bytes_for_s=False)
824-
co_codeunit_position = self.fp.tell() + 4
825-
co_codeunit_string = self.t_string(False, bytes_for_s=True)
857+
self.graal_code_info["co_filename"] = self.graal_readString()
858+
self.graal_code_info["co_flags"] = self.t_int32(False, bytes_for_s=False)
859+
co_codeunit_position = self.graal_code_info["co_codeunit_position"] = (
860+
self.fp.tell() + 4
861+
)
862+
co_codeunit_string = self.graal_readBytes()
826863
self.version_triple = (3, 12, 8)
827864
if chr(co_codeunit_string[0]) != TYPE_GRAALPYTHON_CODE_UNIT:
828865
# Version is graal 3.11 not graal 3.12
829866
self.version_triple = (3, 11, 7)
830867

831-
co_firstlineno = self.t_int32(False, bytes_for_s=False)
832-
co_lnotab = self.t_string(False, bytes_for_s=True)
868+
self.graal_code_info["co_firstlineno"] = self.t_int32(False, bytes_for_s=False)
869+
self.graal_code_info["co_lnotab"] = self.t_string(False, bytes_for_s=True)
833870

834871
# Go back to code position and parse CodeUnit
872+
saved_position = self.fp.tell()
835873
self.fp.seek(co_codeunit_position)
836874
if self.version_triple == (3, 12, 8):
837-
code_unit = self.r_object(bytes_for_s=False)
875+
code = self.r_object(bytes_for_s=False)
838876
else:
839-
code_unit = self.t_graal_CodeUnit(save_ref=False, bytes_for_s=False)
877+
code = self.t_graal_CodeUnit(save_ref=False, bytes_for_s=False)
840878
assert co_flags == code_unit.co_flags
879+
self.fp.seek(saved_position)
841880

842881
code = to_portable(
843882
co_argcount=code_unit.co_argcount,
844883
co_posonlyargcount=code_unit.co_posonlyargcount,
845884
co_kwonlyargcount=code_unit.co_kwonlyargcount,
846-
co_nlocals=code_unit.co_nlocals,
885+
co_nlocals=0,
847886
co_stacksize=code_unit.co_stacksize,
848-
co_flags=co_flags, # codeunit.co_stackize?
887+
co_flags=co_flags,
849888
co_code=code_unit.co_code,
850889
co_consts=code_unit.co_consts,
851890
co_names=code_unit.co_names,
@@ -1037,11 +1076,11 @@ def t_graal_CodeUnit(self, save_ref, bytes_for_s: bool = False):
10371076
co_consts=co_consts,
10381077
co_names=co_names,
10391078
co_varnames=co_varnames,
1040-
co_filename="??", # filled in by caller
1079+
co_filename=self.graal_code_info["co_filename"],
10411080
co_name=co_name,
10421081
co_qualname=co_qualname,
1043-
co_firstlineno=0,
1044-
co_lnotab="",
1082+
co_firstlineno=self.graal_code_info["co_firstlineno"],
1083+
co_lnotab=self.graal_code_info["co_lnotab"],
10451084
co_freevars=co_freevars,
10461085
co_cellvars=co_cellvars,
10471086
co_exceptiontable="",
@@ -1050,7 +1089,9 @@ def t_graal_CodeUnit(self, save_ref, bytes_for_s: bool = False):
10501089
reference_objects=set(),
10511090
)
10521091

1053-
self.code_to_file_offsets[code] = tuple([co_code_offset_in_file])
1092+
self.code_to_file_offsets[code] = tuple(
1093+
[self.graal_code_info["co_codeunit_position"], co_code_offset_in_file]
1094+
)
10541095

10551096
# writeLongArray(code.primitiveConstants);
10561097
# writeIntArray(code.exceptionHandlerRanges);
@@ -1064,6 +1105,23 @@ def t_graal_CodeUnit(self, save_ref, bytes_for_s: bool = False):
10641105
# writeSparseTable(code.generalizeInputsMap);
10651106
# writeSparseTable(code.generalizeVarsMap);
10661107

1108+
# The data from the below is not used, but we run the
1109+
# the extraction to keep the self.fp location where it should for
1110+
# the situation that we have code objects inside the codes' co_consts
1111+
# table marshaled as an ObjectArray.
1112+
1113+
primitive_constants = self.graal_readLongArray()
1114+
exception_handler_ranges = self.graal_readIntArray()
1115+
condition_profileCount = self.graal_readInt()
1116+
start_line = self.graal_readInt()
1117+
start_column = self.graal_readInt()
1118+
end_line = self.graal_readInt()
1119+
end_column = self.graal_readInt()
1120+
outputCanQuicken = self.graal_readBytes()
1121+
variableShouldUnbox = self.graal_readBytes()
1122+
generalizeInputsMap = self.graal_readSparseTable()
1123+
generalizeVarsMap = self.graal_readSparseTable()
1124+
10671125
return code
10681126

10691127
# Since Python 3.4

0 commit comments

Comments
 (0)