unidecompiler-plugin-python-pyc 0.1.2__tar.gz → 0.1.4__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.2 → unidecompiler_plugin_python_pyc-0.1.4}/PKG-INFO +2 -2
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/pyproject.toml +2 -2
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/lifter.py +146 -145
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc.egg-info/PKG-INFO +2 -2
- unidecompiler_plugin_python_pyc-0.1.4/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt +1 -0
- unidecompiler_plugin_python_pyc-0.1.2/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt +0 -1
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/README.md +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/setup.cfg +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/__init__.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/plugin.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/pyc.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/simulation.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc/support.py +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc.egg-info/SOURCES.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc.egg-info/dependency_links.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/src/unidecompiler_plugin_python_pyc.egg-info/entry_points.txt +0 -0
- {unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/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.1.
|
|
3
|
+
Version: 0.1.4
|
|
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.2.0,>=0.1.
|
|
12
|
+
Requires-Dist: unidecompiler<0.2.0,>=0.1.9
|
|
13
13
|
|
|
14
14
|
# unidecompiler-plugin-python-pyc
|
|
15
15
|
|
{unidecompiler_plugin_python_pyc-0.1.2 → unidecompiler_plugin_python_pyc-0.1.4}/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.1.
|
|
7
|
+
version = "0.1.4"
|
|
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.1.
|
|
13
|
+
dependencies = ["unidecompiler>=0.1.9,<0.2.0"]
|
|
14
14
|
|
|
15
15
|
[project.urls]
|
|
16
16
|
Homepage = "https://github.com/Wker666/unidecompiler"
|
|
@@ -13,6 +13,10 @@ from unidecompiler.core.effects import (
|
|
|
13
13
|
BuildArrayCall,
|
|
14
14
|
CallTopAs,
|
|
15
15
|
Copy,
|
|
16
|
+
DeleteAttr,
|
|
17
|
+
DeleteGlobal,
|
|
18
|
+
DeleteItem,
|
|
19
|
+
DeleteLocal,
|
|
16
20
|
DropBelowTop,
|
|
17
21
|
Effect,
|
|
18
22
|
Compare,
|
|
@@ -32,14 +36,17 @@ from unidecompiler.core.effects import (
|
|
|
32
36
|
Iterate,
|
|
33
37
|
MakeFunctionValue,
|
|
34
38
|
MergeMap,
|
|
39
|
+
OfferImplicitCallArguments,
|
|
35
40
|
Pop,
|
|
36
41
|
Push,
|
|
37
42
|
RaiseTop,
|
|
38
43
|
RaiseWithCause,
|
|
39
44
|
ReraiseTop,
|
|
45
|
+
ResumeValue,
|
|
40
46
|
ReturnTop,
|
|
41
47
|
ReturnVoid,
|
|
42
48
|
StoreAttr,
|
|
49
|
+
StoreGlobal,
|
|
43
50
|
StoreLocal,
|
|
44
51
|
StoreMany,
|
|
45
52
|
StoreManyFromPopOrder,
|
|
@@ -55,7 +62,6 @@ from unidecompiler.core.effects import (
|
|
|
55
62
|
)
|
|
56
63
|
from unidecompiler.core.vm_module import assemble_vm_module
|
|
57
64
|
from unidecompiler.core.ir import (
|
|
58
|
-
Assign,
|
|
59
65
|
BinaryOp,
|
|
60
66
|
CapturedVar,
|
|
61
67
|
Const,
|
|
@@ -83,15 +89,13 @@ from unidecompiler.provenance import ByteRange
|
|
|
83
89
|
from unidecompiler.core.vm_region import (
|
|
84
90
|
VMLinearState,
|
|
85
91
|
VMRegionCallbacks,
|
|
92
|
+
VMRegionSlice,
|
|
86
93
|
VMRegionOpcodeClasses,
|
|
87
94
|
VMRegionProfile,
|
|
88
95
|
VMStatefulCallbacks,
|
|
89
96
|
build_hint_region_profile,
|
|
90
97
|
lift_control_region as lift_vm_control_region,
|
|
91
98
|
)
|
|
92
|
-
from unidecompiler.core.vm_structures import (
|
|
93
|
-
vm_unsupported,
|
|
94
|
-
)
|
|
95
99
|
from unidecompiler_plugin_python_pyc.pyc import PycCodeObject, PycExceptionRegion, PycModule
|
|
96
100
|
|
|
97
101
|
|
|
@@ -102,6 +106,10 @@ BINARY_SYMBOLS = {
|
|
|
102
106
|
"-=": "-",
|
|
103
107
|
"*": "*",
|
|
104
108
|
"*=": "*",
|
|
109
|
+
"**": "**",
|
|
110
|
+
"**=": "**",
|
|
111
|
+
"@": "@",
|
|
112
|
+
"@=": "@",
|
|
105
113
|
"/": "/",
|
|
106
114
|
"/=": "/",
|
|
107
115
|
"//": "//",
|
|
@@ -122,7 +130,6 @@ BINARY_SYMBOLS = {
|
|
|
122
130
|
COMPLEX_OPS = {
|
|
123
131
|
}
|
|
124
132
|
IGNORED_OPS = {
|
|
125
|
-
"RESUME",
|
|
126
133
|
"CACHE",
|
|
127
134
|
"NOP",
|
|
128
135
|
"EXTENDED_ARG",
|
|
@@ -130,7 +137,7 @@ IGNORED_OPS = {
|
|
|
130
137
|
"COPY_FREE_VARS",
|
|
131
138
|
}
|
|
132
139
|
PYTHON_REGION_OPCODE_CLASSES = VMRegionOpcodeClasses(
|
|
133
|
-
noise=frozenset({"END_FOR", "POP_TOP", "NOP"
|
|
140
|
+
noise=frozenset({"END_FOR", "POP_TOP", "NOP"}),
|
|
134
141
|
control=frozenset(
|
|
135
142
|
{
|
|
136
143
|
"POP_JUMP_IF_FALSE",
|
|
@@ -190,8 +197,7 @@ def _load_build_class(_context, _instruction, source: SourceRef) -> tuple[Effect
|
|
|
190
197
|
|
|
191
198
|
def _import_name(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
192
199
|
return (
|
|
193
|
-
|
|
194
|
-
Push(source=source, value=Global(name=str(instruction.argval), source=source)),
|
|
200
|
+
BuildCall(source=source, callee=Global(name=f"__import__:{instruction.argval}", source=source), arg_count=2, returns=1),
|
|
195
201
|
)
|
|
196
202
|
|
|
197
203
|
|
|
@@ -219,6 +225,14 @@ def _load_local(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
|
219
225
|
return (LoadLocal(source=source, name=name, fallback=Var(name=name, source=source)),)
|
|
220
226
|
|
|
221
227
|
|
|
228
|
+
def _load_and_clear_local(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
229
|
+
name = str(instruction.argval)
|
|
230
|
+
return (
|
|
231
|
+
LoadLocal(source=source, name=name, fallback=Var(name=name, source=source)),
|
|
232
|
+
DeleteLocal(source=source, name=name),
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
222
236
|
def _load_closure(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
223
237
|
name = str(instruction.argval)
|
|
224
238
|
return (Push(source=source, value=CapturedVar(name=name, source=source)),)
|
|
@@ -243,12 +257,25 @@ def _load_global(_context, instruction, source: SourceRef) -> tuple[Effect, ...]
|
|
|
243
257
|
|
|
244
258
|
def _load_from_dict_or_globals(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
245
259
|
name = str(instruction.argval)
|
|
260
|
+
return (BuildCall(source=source, callee=Global(name=f"load_from_dict_or_globals:{name}", source=source), arg_count=1, returns=1),)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def _call_intrinsic_1(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
264
|
+
return (CallTopAs(source=source, callee_name=str(instruction.argval or instruction.argrepr or "intrinsic")),)
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _before_with(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
268
|
+
name = "before_async_with" if "ASYNC" in instruction.opname else "before_with"
|
|
246
269
|
return (
|
|
247
|
-
|
|
248
|
-
|
|
270
|
+
BuildCall(source=source, callee=Global(name=name, source=source), arg_count=1, returns=1),
|
|
271
|
+
Unpack(source=source, count=2),
|
|
249
272
|
)
|
|
250
273
|
|
|
251
274
|
|
|
275
|
+
def _set_function_attribute(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
276
|
+
return (BuildCall(source=source, callee=Global(name=f"set_function_attribute:{instruction.argval or instruction.argrepr}", source=source), arg_count=2, returns=1),)
|
|
277
|
+
|
|
278
|
+
|
|
252
279
|
def _make_function(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
253
280
|
return (MakeFunctionValue(source=source, fallback_name=str(instruction.argval or instruction.argrepr or "<function>")),)
|
|
254
281
|
|
|
@@ -283,7 +310,10 @@ def _build_set(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
|
283
310
|
|
|
284
311
|
|
|
285
312
|
def _get_iter(_context, _instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
286
|
-
return (
|
|
313
|
+
return (
|
|
314
|
+
Iterate(source=source),
|
|
315
|
+
OfferImplicitCallArguments(source=source, max_explicit_arg_count=0),
|
|
316
|
+
)
|
|
287
317
|
|
|
288
318
|
|
|
289
319
|
def _unpack_sequence(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -321,7 +351,7 @@ def _unary(op: str):
|
|
|
321
351
|
|
|
322
352
|
def _store_global(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
323
353
|
name = str(instruction.argval)
|
|
324
|
-
return (
|
|
354
|
+
return (StoreGlobal(source=source, name=name),)
|
|
325
355
|
|
|
326
356
|
|
|
327
357
|
def _store_deref(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -336,16 +366,32 @@ def _store_deref(_context, instruction, source: SourceRef) -> tuple[Effect, ...]
|
|
|
336
366
|
)
|
|
337
367
|
|
|
338
368
|
|
|
339
|
-
def
|
|
340
|
-
|
|
369
|
+
def _delete_local(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
370
|
+
name = str(instruction.argval)
|
|
371
|
+
return (DeleteLocal(source=source, name=name),)
|
|
341
372
|
|
|
342
373
|
|
|
343
|
-
def
|
|
344
|
-
|
|
374
|
+
def _delete_deref(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
375
|
+
name = str(instruction.argval)
|
|
376
|
+
return (
|
|
377
|
+
DeleteLocal(
|
|
378
|
+
source=source,
|
|
379
|
+
name=name,
|
|
380
|
+
target=CapturedVar(name=name, source=source),
|
|
381
|
+
),
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _delete_global(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
386
|
+
return (DeleteGlobal(source=source, name=str(instruction.argval)),)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _delete_attr(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
390
|
+
return (DeleteAttr(source=source, attr=str(instruction.argval)),)
|
|
345
391
|
|
|
346
392
|
|
|
347
393
|
def _delete_subscr(_context, _instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
348
|
-
return (
|
|
394
|
+
return (DeleteItem(source=source),)
|
|
349
395
|
|
|
350
396
|
|
|
351
397
|
def _build_slice(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -360,7 +406,10 @@ def _binary_slice(_context, _instruction, source: SourceRef) -> tuple[Effect, ..
|
|
|
360
406
|
|
|
361
407
|
|
|
362
408
|
def _store_slice(_context, _instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
363
|
-
return (
|
|
409
|
+
return (
|
|
410
|
+
BuildCall(source=source, arg_count=2, callee=Global(name="slice", source=source)),
|
|
411
|
+
StoreItemEffect(source=source, order="value-obj-key"),
|
|
412
|
+
)
|
|
364
413
|
|
|
365
414
|
|
|
366
415
|
def _list_extend(_context, _instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -443,8 +492,8 @@ def _map_add(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
|
443
492
|
return (StoreItemAtDepth(source=source, depth=_instruction_count(instruction)),)
|
|
444
493
|
|
|
445
494
|
|
|
446
|
-
def _set_add(_context,
|
|
447
|
-
return (SetAdd(source=source),)
|
|
495
|
+
def _set_add(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
496
|
+
return (SetAdd(source=source, depth=_instruction_count(instruction)),)
|
|
448
497
|
|
|
449
498
|
|
|
450
499
|
def _store_local(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
@@ -484,6 +533,13 @@ def _yield_value(_context, instruction, source: SourceRef) -> tuple[Effect, ...]
|
|
|
484
533
|
return (YieldTop(source=source, default=Const(value=None, source=source)),)
|
|
485
534
|
|
|
486
535
|
|
|
536
|
+
def _resume(_context, instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
537
|
+
# CPython's resume mode 5 continues a ``yield`` expression, whose value
|
|
538
|
+
# is supplied by the caller. Await/send modes manage their result in the
|
|
539
|
+
# surrounding protocol and must not manufacture an extra stack value.
|
|
540
|
+
return (ResumeValue(source=source),) if _instruction_count(instruction) == 5 else ()
|
|
541
|
+
|
|
542
|
+
|
|
487
543
|
def _send(_context, _instruction, source: SourceRef) -> tuple[Effect, ...]:
|
|
488
544
|
return (Pop(source=source, count=1, allow_missing=True),)
|
|
489
545
|
|
|
@@ -521,24 +577,17 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
521
577
|
"JUMP_NO_INTERRUPT",
|
|
522
578
|
"INSTRUMENTED_JUMP_BACKWARD",
|
|
523
579
|
"INSTRUMENTED_JUMP_FORWARD",
|
|
524
|
-
"CALL_INTRINSIC_1",
|
|
525
|
-
"BEFORE_WITH",
|
|
526
580
|
"CLEANUP_THROW",
|
|
527
581
|
"CHECK_EG_MATCH",
|
|
528
582
|
"END_ASYNC_FOR",
|
|
529
583
|
"LOOKUP_METHOD",
|
|
530
584
|
"PUSH_EXC_INFO",
|
|
531
585
|
"WITH_EXCEPT_START",
|
|
532
|
-
"DELETE_FAST",
|
|
533
|
-
"DELETE_NAME",
|
|
534
|
-
"DELETE_DEREF",
|
|
535
|
-
"DELETE_GLOBAL",
|
|
536
586
|
"ENTER_EXECUTOR",
|
|
537
587
|
"EXIT_INIT_CHECK",
|
|
538
588
|
"INSTRUMENTED_INSTRUCTION",
|
|
539
589
|
"INSTRUMENTED_LINE",
|
|
540
590
|
"INSTRUMENTED_RESUME",
|
|
541
|
-
"INTERPRETER_EXIT",
|
|
542
591
|
"POP_BLOCK",
|
|
543
592
|
"RESERVED",
|
|
544
593
|
"SETUP_CLEANUP",
|
|
@@ -559,12 +608,15 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
559
608
|
"LOAD_CLOSURE": _load_closure,
|
|
560
609
|
"LOAD_FAST": _load_local,
|
|
561
610
|
"LOAD_FAST_CHECK": _load_local,
|
|
562
|
-
"LOAD_FAST_AND_CLEAR":
|
|
611
|
+
"LOAD_FAST_AND_CLEAR": _load_and_clear_local,
|
|
563
612
|
"LOAD_FAST_LOAD_FAST": _load_fast_pair,
|
|
564
613
|
"LOAD_FROM_DICT_OR_GLOBALS": _load_from_dict_or_globals,
|
|
565
614
|
"LOAD_GLOBAL": _load_global,
|
|
566
615
|
"MAKE_FUNCTION": _make_function,
|
|
567
616
|
"STORE_GLOBAL": _store_global,
|
|
617
|
+
"DELETE_FAST": _delete_local,
|
|
618
|
+
"DELETE_NAME": _delete_local,
|
|
619
|
+
"DELETE_DEREF": _delete_deref,
|
|
568
620
|
"DELETE_GLOBAL": _delete_global,
|
|
569
621
|
"DELETE_ATTR": _delete_attr,
|
|
570
622
|
"DELETE_SUBSCR": _delete_subscr,
|
|
@@ -577,7 +629,12 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
577
629
|
"CALL_FUNCTION_EX": _call_function_ex,
|
|
578
630
|
"INSTRUMENTED_CALL_FUNCTION_EX": _call_function_ex,
|
|
579
631
|
"LOAD_LOCALS": _load_locals,
|
|
580
|
-
"SET_FUNCTION_ATTRIBUTE":
|
|
632
|
+
"SET_FUNCTION_ATTRIBUTE": _set_function_attribute,
|
|
633
|
+
"CALL_INTRINSIC_1": _call_intrinsic_1,
|
|
634
|
+
"BEFORE_WITH": _before_with,
|
|
635
|
+
"BEFORE_ASYNC_WITH": _before_with,
|
|
636
|
+
"EXIT_INIT_CHECK": lambda _context, _instruction, source: (BuildCall(source=source, callee=Global(name="exit_init_check", source=source), arg_count=1, returns=0),),
|
|
637
|
+
"INTERPRETER_EXIT": lambda _context, _instruction, source: (ReturnTop(source=source),),
|
|
581
638
|
"COPY": _copy,
|
|
582
639
|
"SWAP": _swap,
|
|
583
640
|
"LOAD_ATTR": _load_attr,
|
|
@@ -605,6 +662,7 @@ PYTHON_EFFECT_TABLE = VMEffectTable(
|
|
|
605
662
|
"BUILD_TUPLE": _build_tuple,
|
|
606
663
|
"BUILD_SET": _build_set,
|
|
607
664
|
"SET_ADD": _set_add,
|
|
665
|
+
"RESUME": _resume,
|
|
608
666
|
"GET_ITER": _get_iter,
|
|
609
667
|
"GET_YIELD_FROM_ITER": _get_iter,
|
|
610
668
|
"UNPACK_SEQUENCE": _unpack_sequence,
|
|
@@ -684,8 +742,8 @@ def lift_code_object(code: PycCodeObject) -> FunctionIR:
|
|
|
684
742
|
_python_function_spec(code),
|
|
685
743
|
steps,
|
|
686
744
|
profile=_python_region_profile(steps, instructions),
|
|
687
|
-
|
|
688
|
-
|
|
745
|
+
callbacks_factory=lambda normalized_steps: _python_region_callbacks(code, normalized_steps),
|
|
746
|
+
stateful_callbacks_factory=lambda normalized_steps: _python_stateful_callbacks(code, normalized_steps),
|
|
689
747
|
initial_locals=_python_initial_locals(code),
|
|
690
748
|
raw_window=lambda index: _raw_instruction_window(instructions, index),
|
|
691
749
|
)
|
|
@@ -884,21 +942,40 @@ def _python_initial_locals(code: PycCodeObject) -> dict[str, Expr]:
|
|
|
884
942
|
|
|
885
943
|
def _python_region_callbacks(
|
|
886
944
|
code: PycCodeObject,
|
|
887
|
-
|
|
945
|
+
prepared_steps: tuple[VMBytecodeStep, ...],
|
|
888
946
|
) -> VMRegionCallbacks[VMBytecodeStep]:
|
|
947
|
+
def lift_slice(slice_start, slice_end, stack):
|
|
948
|
+
slice_steps = prepared_steps[slice_start:slice_end]
|
|
949
|
+
result = lift_steps(
|
|
950
|
+
slice_steps,
|
|
951
|
+
initial_locals=_python_initial_locals(code),
|
|
952
|
+
initial_stack=stack,
|
|
953
|
+
)
|
|
954
|
+
if result.state.diagnostics:
|
|
955
|
+
return VMRegionSlice(stopped_at=slice_start)
|
|
956
|
+
output: list[object] = list(result.state.statements)
|
|
957
|
+
if result.stopped_at is not None and result.state.terminator is None:
|
|
958
|
+
return VMRegionSlice(
|
|
959
|
+
statements=tuple(output),
|
|
960
|
+
stopped_at=slice_start + slice_steps.index(result.stopped_at),
|
|
961
|
+
)
|
|
962
|
+
if result.state.terminator is not None:
|
|
963
|
+
output.append(result.state.terminator)
|
|
964
|
+
return VMRegionSlice(statements=tuple(output))
|
|
965
|
+
|
|
966
|
+
def lift_expr(slice_start, slice_end, stack):
|
|
967
|
+
result = lift_steps(
|
|
968
|
+
prepared_steps[slice_start:slice_end],
|
|
969
|
+
initial_locals=_python_initial_locals(code),
|
|
970
|
+
initial_stack=stack,
|
|
971
|
+
)
|
|
972
|
+
if result.state.diagnostics or not result.state.stack:
|
|
973
|
+
return None
|
|
974
|
+
return result.state.stack[-1]
|
|
975
|
+
|
|
889
976
|
return VMRegionCallbacks(
|
|
890
|
-
lift_slice=
|
|
891
|
-
|
|
892
|
-
instructions[slice_start:slice_end],
|
|
893
|
-
[],
|
|
894
|
-
stack,
|
|
895
|
-
),
|
|
896
|
-
lift_expr=lambda slice_start, slice_end, stack: _lift_stack_expr(
|
|
897
|
-
code,
|
|
898
|
-
instructions[slice_start:slice_end],
|
|
899
|
-
[],
|
|
900
|
-
stack,
|
|
901
|
-
),
|
|
977
|
+
lift_slice=lift_slice,
|
|
978
|
+
lift_expr=lift_expr,
|
|
902
979
|
lift_iter_loop=lambda _get_iter_index, _iterable: None,
|
|
903
980
|
lift_async_iter_loop=lambda _prefix_start, _get_aiter_index, _region_end: None,
|
|
904
981
|
lift_comprehension=lambda _prefix_start, _get_iter_index, _region_end, _iterable: None,
|
|
@@ -907,45 +984,38 @@ def _python_region_callbacks(
|
|
|
907
984
|
|
|
908
985
|
def _python_stateful_callbacks(
|
|
909
986
|
code: PycCodeObject,
|
|
910
|
-
|
|
987
|
+
prepared_steps: tuple[VMBytecodeStep, ...],
|
|
911
988
|
) -> VMStatefulCallbacks[VMBytecodeStep]:
|
|
989
|
+
def lift_linear(start, end, locals_, stack):
|
|
990
|
+
slice_steps = prepared_steps[start:end]
|
|
991
|
+
result = lift_steps(
|
|
992
|
+
slice_steps,
|
|
993
|
+
initial_locals=locals_,
|
|
994
|
+
initial_stack=stack,
|
|
995
|
+
)
|
|
996
|
+
stopped_at_terminal_end = (
|
|
997
|
+
result.stopped_at is slice_steps[-1]
|
|
998
|
+
if slice_steps and result.state.terminator is not None
|
|
999
|
+
else False
|
|
1000
|
+
)
|
|
1001
|
+
if result.state.diagnostics or (
|
|
1002
|
+
result.stopped_at is not None and not stopped_at_terminal_end
|
|
1003
|
+
):
|
|
1004
|
+
return None
|
|
1005
|
+
return VMLinearState(
|
|
1006
|
+
locals=result.state.locals,
|
|
1007
|
+
stack=tuple(result.state.stack),
|
|
1008
|
+
statements=tuple(result.state.statements),
|
|
1009
|
+
terminator=result.state.terminator,
|
|
1010
|
+
)
|
|
1011
|
+
|
|
912
1012
|
return VMStatefulCallbacks(
|
|
913
1013
|
initial_locals=lambda: _python_initial_locals(code),
|
|
914
|
-
lift_linear=
|
|
915
|
-
instructions[start:end],
|
|
916
|
-
locals,
|
|
917
|
-
stack,
|
|
918
|
-
),
|
|
1014
|
+
lift_linear=lift_linear,
|
|
919
1015
|
branch_condition=_python_branch_condition,
|
|
920
1016
|
)
|
|
921
1017
|
|
|
922
1018
|
|
|
923
|
-
def _python_linear_state(
|
|
924
|
-
instructions: tuple[object, ...],
|
|
925
|
-
initial_locals: dict[str, Expr],
|
|
926
|
-
initial_stack: tuple[Expr, ...],
|
|
927
|
-
) -> VMLinearState | None:
|
|
928
|
-
result = _run_python_stack_slice(
|
|
929
|
-
_PycLinearLocals(tuple(initial_locals)),
|
|
930
|
-
instructions,
|
|
931
|
-
dict(initial_locals),
|
|
932
|
-
initial_stack,
|
|
933
|
-
)
|
|
934
|
-
stopped_at_terminal_end = (
|
|
935
|
-
getattr(result.stopped_at, "source", None) == _python_source(instructions[-1])
|
|
936
|
-
if instructions and result.state.terminator is not None
|
|
937
|
-
else False
|
|
938
|
-
)
|
|
939
|
-
if result.state.diagnostics or (result.stopped_at is not None and not stopped_at_terminal_end):
|
|
940
|
-
return None
|
|
941
|
-
return VMLinearState(
|
|
942
|
-
locals=result.state.locals,
|
|
943
|
-
stack=tuple(result.state.stack),
|
|
944
|
-
statements=tuple(result.state.statements),
|
|
945
|
-
terminator=result.state.terminator,
|
|
946
|
-
)
|
|
947
|
-
|
|
948
|
-
|
|
949
1019
|
def _python_branch_condition(branch: VMBytecodeStep, stack: tuple[Expr, ...]) -> Expr | None:
|
|
950
1020
|
if not stack:
|
|
951
1021
|
return None
|
|
@@ -962,11 +1032,6 @@ def _python_branch_condition(branch: VMBytecodeStep, stack: tuple[Expr, ...]) ->
|
|
|
962
1032
|
return condition
|
|
963
1033
|
|
|
964
1034
|
|
|
965
|
-
class _PycLinearLocals:
|
|
966
|
-
def __init__(self, varnames: tuple[str, ...]) -> None:
|
|
967
|
-
self.varnames = varnames
|
|
968
|
-
|
|
969
|
-
|
|
970
1035
|
def _python_region_profile(
|
|
971
1036
|
steps: tuple[VMBytecodeStep, ...],
|
|
972
1037
|
instructions: tuple[object, ...],
|
|
@@ -999,70 +1064,6 @@ def _await_region_end(instructions: tuple[object, ...], start: int, end: int) ->
|
|
|
999
1064
|
return None
|
|
1000
1065
|
|
|
1001
1066
|
|
|
1002
|
-
def _lift_instruction_slice(
|
|
1003
|
-
code: PycCodeObject,
|
|
1004
|
-
instructions: tuple[object, ...],
|
|
1005
|
-
assignments: list[Assign],
|
|
1006
|
-
preloaded_stack: tuple[Expr, ...] = (),
|
|
1007
|
-
) -> tuple[object, ...]:
|
|
1008
|
-
if not instructions:
|
|
1009
|
-
return ()
|
|
1010
|
-
initial_locals = {
|
|
1011
|
-
name: Var(name=name, source=SourceRef(frontend="python-pyc", detail=f"local:{name}"))
|
|
1012
|
-
for name in code.varnames
|
|
1013
|
-
}
|
|
1014
|
-
for assignment in assignments:
|
|
1015
|
-
initial_locals[assignment.target.name] = assignment.target
|
|
1016
|
-
result = _run_python_stack_slice(code, instructions, initial_locals, preloaded_stack)
|
|
1017
|
-
if result.state.diagnostics:
|
|
1018
|
-
return ()
|
|
1019
|
-
output: list[object] = list(result.state.statements)
|
|
1020
|
-
if result.stopped_at is not None and result.state.terminator is None:
|
|
1021
|
-
try:
|
|
1022
|
-
stopped_index = instructions.index(result.stopped_at)
|
|
1023
|
-
except ValueError:
|
|
1024
|
-
stopped_index = 0
|
|
1025
|
-
output.append(
|
|
1026
|
-
vm_unsupported(
|
|
1027
|
-
source=result.stopped_at.source,
|
|
1028
|
-
message="unsupported region",
|
|
1029
|
-
detail=f"stopped at {result.stopped_at.opcode}",
|
|
1030
|
-
raw=(result.stopped_at.raw,) if result.stopped_at.raw else _raw_instruction_window(instructions, stopped_index),
|
|
1031
|
-
)
|
|
1032
|
-
)
|
|
1033
|
-
if result.state.terminator is not None:
|
|
1034
|
-
output.append(result.state.terminator)
|
|
1035
|
-
return tuple(output)
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
def _lift_stack_expr(
|
|
1039
|
-
code: PycCodeObject,
|
|
1040
|
-
instructions: tuple[object, ...],
|
|
1041
|
-
assignments: list[Assign],
|
|
1042
|
-
preloaded_stack: tuple[Expr, ...] = (),
|
|
1043
|
-
) -> Expr | None:
|
|
1044
|
-
initial_locals = {
|
|
1045
|
-
name: Var(name=name, source=SourceRef(frontend="python-pyc", detail=f"local:{name}"))
|
|
1046
|
-
for name in code.varnames
|
|
1047
|
-
}
|
|
1048
|
-
for assignment in assignments:
|
|
1049
|
-
initial_locals[assignment.target.name] = assignment.target
|
|
1050
|
-
result = _run_python_stack_slice(code, instructions, initial_locals, preloaded_stack)
|
|
1051
|
-
if result.state.diagnostics or not result.state.stack:
|
|
1052
|
-
return None
|
|
1053
|
-
return result.state.stack[-1]
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
def _run_python_stack_slice(
|
|
1057
|
-
code: PycCodeObject,
|
|
1058
|
-
instructions: tuple[object, ...],
|
|
1059
|
-
initial_locals: dict[str, Expr],
|
|
1060
|
-
initial_stack: tuple[Expr, ...] = (),
|
|
1061
|
-
):
|
|
1062
|
-
steps = _python_bytecode_steps(instructions)
|
|
1063
|
-
return lift_steps(steps, initial_locals=initial_locals, initial_stack=initial_stack)
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
1067
|
def _instruction_count(instruction) -> int:
|
|
1067
1068
|
return instruction.arg if isinstance(instruction.arg, int) else 0
|
|
1068
1069
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unidecompiler-plugin-python-pyc
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
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.2.0,>=0.1.
|
|
12
|
+
Requires-Dist: unidecompiler<0.2.0,>=0.1.9
|
|
13
13
|
|
|
14
14
|
# unidecompiler-plugin-python-pyc
|
|
15
15
|
|
unidecompiler_plugin_python_pyc-0.1.4/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
unidecompiler<0.2.0,>=0.1.9
|
unidecompiler_plugin_python_pyc-0.1.2/src/unidecompiler_plugin_python_pyc.egg-info/requires.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
unidecompiler<0.2.0,>=0.1.2
|
|
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
|
|
File without changes
|