unidecompiler-plugin-python-pyc 0.1.4__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/PKG-INFO +2 -2
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/pyproject.toml +2 -2
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/lifter.py +76 -6
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/plugin.py +6 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc.egg-info/PKG-INFO +2 -2
- unidecompiler_plugin_python_pyc-0.2.0/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt +1 -0
- unidecompiler_plugin_python_pyc-0.1.4/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt +0 -1
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/README.md +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/setup.cfg +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/__init__.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/pyc.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/simulation.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc/support.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc.egg-info/SOURCES.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc.egg-info/dependency_links.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc.egg-info/entry_points.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/src/unidecompiler_plugin_python_pyc.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unidecompiler-plugin-python-pyc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python bytecode frontend plugin for unidecompiler
|
|
5
5
|
Author-email: Wker <1670133844@qq.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/Wker666/unidecompiler
|
|
|
9
9
|
Project-URL: Issues, https://github.com/Wker666/unidecompiler/issues
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: unidecompiler<0.
|
|
12
|
+
Requires-Dist: unidecompiler<0.3.0,>=0.2.0
|
|
13
13
|
|
|
14
14
|
# unidecompiler-plugin-python-pyc
|
|
15
15
|
|
{unidecompiler_plugin_python_pyc-0.1.4 → unidecompiler_plugin_python_pyc-0.2.0}/pyproject.toml
RENAMED
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unidecompiler-plugin-python-pyc"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Python bytecode frontend plugin for unidecompiler"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0-or-later"
|
|
11
11
|
authors = [{ name = "Wker", email = "1670133844@qq.com" }]
|
|
12
12
|
requires-python = ">=3.11"
|
|
13
|
-
dependencies = ["unidecompiler>=0.
|
|
13
|
+
dependencies = ["unidecompiler>=0.2.0,<0.3.0"]
|
|
14
14
|
|
|
15
15
|
[project.urls]
|
|
16
16
|
Homepage = "https://github.com/Wker666/unidecompiler"
|
|
@@ -42,6 +42,7 @@ from unidecompiler.core.effects import (
|
|
|
42
42
|
RaiseTop,
|
|
43
43
|
RaiseWithCause,
|
|
44
44
|
ReraiseTop,
|
|
45
|
+
RewriteException,
|
|
45
46
|
ResumeValue,
|
|
46
47
|
ReturnTop,
|
|
47
48
|
ReturnVoid,
|
|
@@ -96,6 +97,7 @@ from unidecompiler.core.vm_region import (
|
|
|
96
97
|
build_hint_region_profile,
|
|
97
98
|
lift_control_region as lift_vm_control_region,
|
|
98
99
|
)
|
|
100
|
+
from unidecompiler.progress import ProgressReporter, report_progress
|
|
99
101
|
from unidecompiler_plugin_python_pyc.pyc import PycCodeObject, PycExceptionRegion, PycModule
|
|
100
102
|
|
|
101
103
|
|
|
@@ -261,7 +263,29 @@ def _load_from_dict_or_globals(_context, instruction, source: SourceRef) -> tupl
|
|
|
261
263
|
|
|
262
264
|
|
|
263
265
|
def _call_intrinsic_1(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
264
|
-
|
|
266
|
+
name = str(instruction.argrepr or instruction.argval or "intrinsic")
|
|
267
|
+
if name == "INTRINSIC_STOPITERATION_ERROR":
|
|
268
|
+
# CPython conditionally replaces StopIteration-family exceptions and
|
|
269
|
+
# retains the original as cause/context. This remains a generic
|
|
270
|
+
# value rewrite; core owns its stack lift and conservative rendering.
|
|
271
|
+
return (
|
|
272
|
+
RewriteException(
|
|
273
|
+
source=source,
|
|
274
|
+
predicate=Const(value="stop-iteration-family", source=source),
|
|
275
|
+
replacement=Const(value="runtime-error-from-input", source=source),
|
|
276
|
+
retain_input_as_cause=True,
|
|
277
|
+
),
|
|
278
|
+
)
|
|
279
|
+
# ``arg``/``argval`` is an implementation ordinal. The decoded text is
|
|
280
|
+
# the only presentation-safe identity for an opaque intrinsic operation;
|
|
281
|
+
# retain it as data and leave any execution semantics outside this thin
|
|
282
|
+
# effect table.
|
|
283
|
+
return (
|
|
284
|
+
CallTopAs(
|
|
285
|
+
source=source,
|
|
286
|
+
callee_name=name,
|
|
287
|
+
),
|
|
288
|
+
)
|
|
265
289
|
|
|
266
290
|
|
|
267
291
|
def _before_with(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -527,6 +551,17 @@ def _raise_varargs(_context, instruction, source: SourceRef) -> tuple[Effect, ..
|
|
|
527
551
|
return (RaiseTop(source=source),)
|
|
528
552
|
|
|
529
553
|
|
|
554
|
+
def _reraise(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
555
|
+
count = _instruction_count(instruction)
|
|
556
|
+
return (
|
|
557
|
+
ReraiseTop(
|
|
558
|
+
source=source,
|
|
559
|
+
consume_stack_exception=True,
|
|
560
|
+
resume_slot_count=count,
|
|
561
|
+
),
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
|
|
530
565
|
def _yield_value(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
531
566
|
if instruction.arg in {1, 2}:
|
|
532
567
|
return ()
|
|
@@ -704,7 +739,7 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
704
739
|
"RETURN_CONST": _return_const,
|
|
705
740
|
"INSTRUMENTED_RETURN_CONST": _return_const,
|
|
706
741
|
"RAISE_VARARGS": _raise_varargs,
|
|
707
|
-
"RERAISE":
|
|
742
|
+
"RERAISE": _reraise,
|
|
708
743
|
"YIELD_VALUE": _yield_value,
|
|
709
744
|
"INSTRUMENTED_YIELD_VALUE": _yield_value,
|
|
710
745
|
"SEND": _send,
|
|
@@ -722,8 +757,15 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
722
757
|
)
|
|
723
758
|
|
|
724
759
|
|
|
725
|
-
def lift_pyc_module(
|
|
726
|
-
|
|
760
|
+
def lift_pyc_module(
|
|
761
|
+
pyc_module: PycModule,
|
|
762
|
+
metadata: dict,
|
|
763
|
+
*,
|
|
764
|
+
reporter: ProgressReporter | None = None,
|
|
765
|
+
) -> ModuleIR:
|
|
766
|
+
total = _code_object_count(pyc_module.code)
|
|
767
|
+
report_progress(reporter, phase="lift", status="started", completed=0, total=total, unit="function", message="lifting Python code objects")
|
|
768
|
+
functions = list(_lift_code_object_tree(pyc_module.code, reporter=reporter, total=total, progress=[0]))
|
|
727
769
|
return assemble_vm_module(
|
|
728
770
|
name=pyc_module.filename or "<python-pyc>",
|
|
729
771
|
source_language="python",
|
|
@@ -750,7 +792,13 @@ def lift_code_object(code: PycCodeObject) -> FunctionIR:
|
|
|
750
792
|
return function
|
|
751
793
|
|
|
752
794
|
|
|
753
|
-
def _lift_code_object_tree(
|
|
795
|
+
def _lift_code_object_tree(
|
|
796
|
+
code: PycCodeObject,
|
|
797
|
+
*,
|
|
798
|
+
reporter: ProgressReporter | None = None,
|
|
799
|
+
total: int | None = None,
|
|
800
|
+
progress: list[int] | None = None,
|
|
801
|
+
) -> tuple[FunctionIR, ...]:
|
|
754
802
|
spec = _python_function_spec(code)
|
|
755
803
|
functions = [
|
|
756
804
|
recover_vm_function(
|
|
@@ -759,11 +807,25 @@ def _lift_code_object_tree(code: PycCodeObject) -> tuple[FunctionIR, ...]:
|
|
|
759
807
|
raw=tuple(_raw_instruction_line(instruction) for instruction in code.instructions),
|
|
760
808
|
)
|
|
761
809
|
]
|
|
810
|
+
if reporter is not None and total is not None and progress is not None:
|
|
811
|
+
progress[0] += 1
|
|
812
|
+
report_progress(reporter, phase="lift", completed=progress[0], total=total, unit="function", message=f"lifting code object {progress[0]}/{total}")
|
|
762
813
|
for child in code.children:
|
|
763
|
-
functions.extend(
|
|
814
|
+
functions.extend(
|
|
815
|
+
_lift_code_object_tree(
|
|
816
|
+
child,
|
|
817
|
+
reporter=reporter,
|
|
818
|
+
total=total,
|
|
819
|
+
progress=progress,
|
|
820
|
+
)
|
|
821
|
+
)
|
|
764
822
|
return tuple(functions)
|
|
765
823
|
|
|
766
824
|
|
|
825
|
+
def _code_object_count(code: PycCodeObject) -> int:
|
|
826
|
+
return 1 + sum(_code_object_count(child) for child in code.children)
|
|
827
|
+
|
|
828
|
+
|
|
767
829
|
def _python_low_effects(instruction, source: SourceRef) -> tuple[Effect, ...] | None:
|
|
768
830
|
return PYTHON_EFFECT_TABLE.effects_for(None, instruction, source)
|
|
769
831
|
|
|
@@ -808,6 +870,14 @@ def _python_bytecode_steps(
|
|
|
808
870
|
"target": region.target,
|
|
809
871
|
"depth": region.depth,
|
|
810
872
|
"lasti": region.lasti,
|
|
873
|
+
# The exception table declares the handler's input stack
|
|
874
|
+
# layout. These are VM-neutral stack facts; core owns
|
|
875
|
+
# all CFG construction and recovery decisions.
|
|
876
|
+
"stack_depth": region.depth,
|
|
877
|
+
"stack_suffix": (
|
|
878
|
+
*(("resume-position",) if region.lasti else ()),
|
|
879
|
+
"exception",
|
|
880
|
+
),
|
|
811
881
|
},
|
|
812
882
|
label="protected-region",
|
|
813
883
|
)
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from unidecompiler.core.ir import ModuleIR
|
|
4
4
|
from unidecompiler.plugins import FrontendModule
|
|
5
|
+
from unidecompiler.progress import ProgressReporter
|
|
5
6
|
from unidecompiler_plugin_python_pyc.lifter import lift_pyc_module
|
|
6
7
|
from unidecompiler_plugin_python_pyc.pyc import decode_pyc, looks_like_pyc
|
|
7
8
|
from unidecompiler_plugin_python_pyc.simulation import PythonPycSimulationAdapter
|
|
@@ -45,3 +46,8 @@ class PythonPycFrontendPlugin:
|
|
|
45
46
|
)
|
|
46
47
|
|
|
47
48
|
return lift_pyc_module(module.payload, module.metadata)
|
|
49
|
+
|
|
50
|
+
def lift_with_progress(self, module: FrontendModule, reporter: ProgressReporter) -> ModuleIR:
|
|
51
|
+
if module.frontend_id != self.id:
|
|
52
|
+
raise TypeError(f"Python pyc frontend cannot lift module from {module.frontend_id!r}")
|
|
53
|
+
return lift_pyc_module(module.payload, module.metadata, reporter=reporter)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unidecompiler-plugin-python-pyc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python bytecode frontend plugin for unidecompiler
|
|
5
5
|
Author-email: Wker <1670133844@qq.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -9,7 +9,7 @@ Project-URL: Repository, https://github.com/Wker666/unidecompiler
|
|
|
9
9
|
Project-URL: Issues, https://github.com/Wker666/unidecompiler/issues
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: unidecompiler<0.
|
|
12
|
+
Requires-Dist: unidecompiler<0.3.0,>=0.2.0
|
|
13
13
|
|
|
14
14
|
# unidecompiler-plugin-python-pyc
|
|
15
15
|
|
unidecompiler_plugin_python_pyc-0.2.0/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
unidecompiler<0.3.0,>=0.2.0
|
unidecompiler_plugin_python_pyc-0.1.4/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
unidecompiler<0.2.0,>=0.1.9
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|