unidecompiler-plugin-lua 0.1.1__tar.gz → 0.1.3__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.
Files changed (19) hide show
  1. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/PKG-INFO +2 -2
  2. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/pyproject.toml +2 -2
  3. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/chunk54.py +3 -0
  4. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/lifter.py +76 -5
  5. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/luac.py +2 -0
  6. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua.egg-info/PKG-INFO +2 -2
  7. unidecompiler_plugin_lua-0.1.3/src/unidecompiler_plugin_lua.egg-info/requires.txt +1 -0
  8. unidecompiler_plugin_lua-0.1.1/src/unidecompiler_plugin_lua.egg-info/requires.txt +0 -1
  9. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/README.md +0 -0
  10. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/setup.cfg +0 -0
  11. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/__init__.py +0 -0
  12. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/normalize.py +0 -0
  13. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/plugin.py +0 -0
  14. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/simulation.py +0 -0
  15. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua/support.py +0 -0
  16. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua.egg-info/SOURCES.txt +0 -0
  17. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua.egg-info/dependency_links.txt +0 -0
  18. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua.egg-info/entry_points.txt +0 -0
  19. {unidecompiler_plugin_lua-0.1.1 → unidecompiler_plugin_lua-0.1.3}/src/unidecompiler_plugin_lua.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unidecompiler-plugin-lua
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Lua 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.1
12
+ Requires-Dist: unidecompiler<0.2.0,>=0.1.9
13
13
 
14
14
  # unidecompiler-plugin-lua
15
15
 
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "unidecompiler-plugin-lua"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "Lua 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.1,<0.2.0"]
13
+ dependencies = ["unidecompiler>=0.1.9,<0.2.0"]
14
14
 
15
15
  [project.urls]
16
16
  Homepage = "https://github.com/Wker666/unidecompiler"
@@ -198,6 +198,7 @@ def _read_code(reader: _Reader) -> tuple[LuaInstructionListing, ...]:
198
198
  count = reader.varint()
199
199
  instructions: list[LuaInstructionListing] = []
200
200
  for pc in range(1, count + 1):
201
+ artifact_offset = reader.offset
201
202
  raw = reader.unpack("I")
202
203
  opcode = _OPCODES[raw & 0x7F]
203
204
  instructions.append(
@@ -206,6 +207,8 @@ def _read_code(reader: _Reader) -> tuple[LuaInstructionListing, ...]:
206
207
  line=None,
207
208
  opcode=opcode,
208
209
  operands=_decode_operands(opcode, raw),
210
+ artifact_offset=artifact_offset,
211
+ size=4,
209
212
  )
210
213
  )
211
214
  return tuple(instructions)
@@ -10,6 +10,7 @@ from unidecompiler.core.ir import (
10
10
  CapturedVar,
11
11
  Const,
12
12
  Expr,
13
+ ExprStmt,
13
14
  Global,
14
15
  GetItem,
15
16
  MapLiteral,
@@ -32,6 +33,7 @@ from unidecompiler.core.vm_function import (
32
33
  from unidecompiler.core.vm_bytecode import VMBytecodeStep
33
34
  from unidecompiler.core.vm_hints import VMHint
34
35
  from unidecompiler.core.vm_operands import VMDecodedInstruction, VMOperand
36
+ from unidecompiler.provenance import ByteRange
35
37
  from unidecompiler.core.vm_region import (
36
38
  VMLinearState,
37
39
  VMRegionOpcodeClasses,
@@ -95,9 +97,6 @@ IGNORED_OPS = {
95
97
  "MMBINK",
96
98
  "VARARGPREP",
97
99
  "EXTRAARG",
98
- "LFALSESKIP",
99
- "CLOSE",
100
- "TBC",
101
100
  *(CONTROL_OPS - frozenset({"FORPREP", "FORLOOP", "TESTSET", "TFORPREP", "TFORLOOP"})),
102
101
  }
103
102
  @dataclass(frozen=True)
@@ -500,7 +499,20 @@ def _lua_set_list(context: LuaEffectContext, instruction, source: SourceRef) ->
500
499
  base = int(operands[0])
501
500
  count = int(operands[1])
502
501
  if count <= 0:
503
- return ()
502
+ return (
503
+ Emit(
504
+ source=source,
505
+ statement=ExprStmt(
506
+ source=source,
507
+ value=Call(
508
+ source=source,
509
+ callee=Global(name="lua_setlist", source=source),
510
+ args=(Var(name=_read_register_name(context.listing, base, instruction.pc), source=source),),
511
+ returns=0,
512
+ ),
513
+ ),
514
+ ),
515
+ )
504
516
  table = Var(name=_read_register_name(context.listing, base, instruction.pc), source=source)
505
517
  return tuple(
506
518
  Emit(
@@ -600,7 +612,24 @@ def _lua_tforcall_effect(context: LuaEffectContext, instruction, source: SourceR
600
612
  base = int(operands[0])
601
613
  count = int(operands[2])
602
614
  if count <= 0:
603
- return ()
615
+ base = int(operands[0])
616
+ return (
617
+ Emit(
618
+ source=source,
619
+ statement=ExprStmt(
620
+ source=source,
621
+ value=Call(
622
+ source=source,
623
+ callee=Global(name="lua_generic_for_next", source=source),
624
+ args=tuple(
625
+ Var(name=_read_register_name(context.listing, base + index, instruction.pc), source=source)
626
+ for index in range(3)
627
+ ),
628
+ returns=0,
629
+ ),
630
+ ),
631
+ ),
632
+ )
604
633
  names = tuple(
605
634
  _write_register_name(context.listing, register, instruction.pc)
606
635
  for register in range(base + 4, base + 4 + count)
@@ -628,6 +657,28 @@ def _lua_tforcall_effect(context: LuaEffectContext, instruction, source: SourceR
628
657
  )
629
658
 
630
659
 
660
+ def _lua_runtime_marker(name: str):
661
+ """Represent a runtime-only Lua lifecycle operation without dropping stack values."""
662
+
663
+ def factory(_context: LuaEffectContext, _instruction, source: SourceRef) -> tuple:
664
+ return (
665
+ Emit(
666
+ source=source,
667
+ statement=ExprStmt(
668
+ source=source,
669
+ value=Call(
670
+ source=source,
671
+ callee=Global(name=name, source=source),
672
+ args=(),
673
+ returns=0,
674
+ ),
675
+ ),
676
+ ),
677
+ )
678
+
679
+ return factory
680
+
681
+
631
682
  def _lua_tforloop_effect(context: LuaEffectContext, instruction, source: SourceRef) -> tuple | None:
632
683
  operands = instruction.operands
633
684
  if not operands:
@@ -850,6 +901,11 @@ LUA_EFFECT_TABLE = VMEffectTable(
850
901
  "FORLOOP": _lua_forloop_effect,
851
902
  "TFORPREP": _lua_no_effect,
852
903
  "TFORCALL": _lua_tforcall_effect,
904
+ "LFALSESKIP": lambda context, instruction, source: (
905
+ _lua_assign(context.listing, int(instruction.operands[0]), instruction.pc, Const(value=False, source=source), source),
906
+ ) if instruction.operands else (UnknownOpcode(source=source, opcode="LFALSESKIP", raw="missing register"),),
907
+ "CLOSE": _lua_runtime_marker("lua_close"),
908
+ "TBC": _lua_runtime_marker("lua_tbc"),
853
909
  "TFORLOOP": _lua_tforloop_effect,
854
910
  "TESTSET": _lua_testset_effect,
855
911
  "RETURN1": _lua_return1,
@@ -1105,6 +1161,7 @@ def _lua_decoded_instruction(instruction, source: SourceRef) -> VMDecodedInstruc
1105
1161
  source=source,
1106
1162
  operands=tuple(VMOperand(role=_lua_operand_role(operand), value=operand, text=operand) for operand in instruction.operands),
1107
1163
  raw=f"{instruction.pc}: {instruction.opcode} {' '.join(instruction.operands)}".strip(),
1164
+ artifact_range=(None if instruction.artifact_offset is None or instruction.size is None else ByteRange(instruction.artifact_offset, instruction.size)),
1108
1165
  )
1109
1166
 
1110
1167
 
@@ -1117,6 +1174,20 @@ def _lua_operand_role(operand: str):
1117
1174
 
1118
1175
 
1119
1176
  def _lua_instruction_hints(listing: LuaFunctionListing, instruction, source: SourceRef) -> tuple[VMHint, ...]:
1177
+ if instruction.opcode == "LFALSESKIP":
1178
+ # Lua's skip instruction advances over the following instruction when
1179
+ # the assigned false value is consumed. Preserve that edge as a
1180
+ # neutral hint; core owns the actual CFG recovery.
1181
+ return (
1182
+ VMHint(
1183
+ kind="branch-target",
1184
+ source=source,
1185
+ target=instruction.pc + 2,
1186
+ label=instruction.opcode,
1187
+ detail="target-if-false",
1188
+ flow="unconditional",
1189
+ ),
1190
+ )
1120
1191
  if instruction.opcode in CONDITIONAL_OPS:
1121
1192
  return (
1122
1193
  VMHint(
@@ -54,6 +54,8 @@ class LuaInstructionListing:
54
54
  opcode: str
55
55
  operands: tuple[str, ...]
56
56
  comment: str | None = None
57
+ artifact_offset: int | None = None
58
+ size: int | None = None
57
59
 
58
60
 
59
61
  @dataclass(frozen=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unidecompiler-plugin-lua
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Lua 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.1
12
+ Requires-Dist: unidecompiler<0.2.0,>=0.1.9
13
13
 
14
14
  # unidecompiler-plugin-lua
15
15
 
@@ -0,0 +1 @@
1
+ unidecompiler<0.2.0,>=0.1.9
@@ -1 +0,0 @@
1
- unidecompiler<0.2.0,>=0.1.1