Last active
September 25, 2022 12:17
-
-
Save zhuowei/56ffdda8913d603bf99b874d4be33984 to your computer and use it in GitHub Desktop.
Patches for unluac to disassemble (and partially decompile) Playdate's Lua 5.4.0 beta bytecode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Zhuowei Zhang <zhuowei@worthdoingbadly.com> | |
# Date 1633490863 14400 | |
# Tue Oct 05 23:27:43 2021 -0400 | |
# Node ID 9a209bac7961ed4cc661f1a358d8ef2e23c74d7b | |
# Parent 0390d042f93125be8257ae3a0520aa6b1003145c | |
Add PlayDate's 0x23 integer type, fix boolean parsing for Lua 5.4 beta | |
diff --git a/src/unluac/parse/LConstantType.java b/src/unluac/parse/LConstantType.java | |
--- a/src/unluac/parse/LConstantType.java | |
+++ b/src/unluac/parse/LConstantType.java | |
@@ -167,13 +167,23 @@ class LConstantType54 extends LConstantT | |
case 0: | |
return LNil.NIL; | |
case 1: | |
+ return header.bool.parse(buffer, header); | |
+/* | |
+PlayDate: 5.4 beta doesn't have 0x11 | |
return LBoolean.LFALSE; | |
case 0x11: | |
return LBoolean.LTRUE; | |
+*/ | |
case 3: | |
return header.linteger.parse(buffer, header); | |
case 0x13: | |
return header.lfloat.parse(buffer, header); | |
+ // PlayDate: unsigned integer, maybe? | |
+ case 0x23: | |
+ if (header.debug) { | |
+ System.out.println("A 0x23 integer!"); | |
+ } | |
+ return header.linteger.parse(buffer, header); | |
case 4: | |
return header.string.parse(buffer, header); | |
case 0x14: { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Zhuowei Zhang <zhuowei@worthdoingbadly.com> | |
# Date 1633486956 14400 | |
# Tue Oct 05 22:22:36 2021 -0400 | |
# Node ID 0390d042f93125be8257ae3a0520aa6b1003145c | |
# Parent ed6eba8fa5792efc3b1c7c30532a145d64957362 | |
Support Lua 5.4.0 beta header | |
diff --git a/src/unluac/parse/BHeader.java b/src/unluac/parse/BHeader.java | |
--- a/src/unluac/parse/BHeader.java | |
+++ b/src/unluac/parse/BHeader.java | |
@@ -84,6 +84,15 @@ public class BHeader { | |
int versionNumber = 0xFF & buffer.get(); | |
int major = versionNumber >> 4; | |
int minor = versionNumber & 0x0F; | |
+ | |
+ if (versionNumber == 0x03) { | |
+ // HACK: Lua 5.4 beta, PlayDate | |
+ // https://twitter.com/davehayden/status/1425959793504702466 | |
+ int tempNumber = (versionNumber << 7) | (0x7F & buffer.get()); | |
+ major = tempNumber / 100; | |
+ minor = tempNumber % 100; | |
+ versionNumber = major << 4 | minor; | |
+ } | |
version = Version.getVersion(major, minor); | |
if(version == null) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Zhuowei Zhang <zhuowei@worthdoingbadly.com> | |
# Date 1633494188 14400 | |
# Wed Oct 06 00:23:08 2021 -0400 | |
# Node ID ad22b05f3653ef1de6bf3455f22e791d1f33e4f9 | |
# Parent 9a209bac7961ed4cc661f1a358d8ef2e23c74d7b | |
OpcodeMap: partial fix for Playdate's Lua 5.4.0 beta; still crashes during decompile | |
diff --git a/src/unluac/decompile/OpcodeMap.java b/src/unluac/decompile/OpcodeMap.java | |
--- a/src/unluac/decompile/OpcodeMap.java | |
+++ b/src/unluac/decompile/OpcodeMap.java | |
@@ -198,90 +198,96 @@ public class OpcodeMap { | |
map[46] = Op.EXTRAARG; | |
break; | |
case LUA54: | |
- map = new Op[83]; | |
+ // Hack: PlayDate 5.4.0 beta doesn't have LFALSESKIP | |
+ // https://github.com/lua/lua/commit/9b7987a9d1471ba94764286b28e0998f73deb46a#diff-239329feffa8b7a9b93ec0d6e11d14279def61a1c351b52694f905b367368d10 | |
+ //map = new Op[83]; | |
+ map = new Op[81]; | |
map[0] = Op.MOVE; | |
map[1] = Op.LOADI; | |
map[2] = Op.LOADF; | |
map[3] = Op.LOADK; | |
map[4] = Op.LOADKX; | |
- map[5] = Op.LOADFALSE; | |
- map[6] = Op.LFALSESKIP; | |
- map[7] = Op.LOADTRUE; | |
- map[8] = Op.LOADNIL52; | |
- map[9] = Op.GETUPVAL; | |
- map[10] = Op.SETUPVAL; | |
- map[11] = Op.GETTABUP54; | |
- map[12] = Op.GETTABLE54; | |
- map[13] = Op.GETI; | |
- map[14] = Op.GETFIELD; | |
- map[15] = Op.SETTABUP54; | |
- map[16] = Op.SETTABLE54; | |
- map[17] = Op.SETI; | |
- map[18] = Op.SETFIELD; | |
- map[19] = Op.NEWTABLE54; | |
- map[20] = Op.SELF54; | |
- map[21] = Op.ADDI; | |
- map[22] = Op.ADDK; | |
- map[23] = Op.SUBK; | |
- map[24] = Op.MULK; | |
- map[25] = Op.MODK; | |
- map[26] = Op.POWK; | |
- map[27] = Op.DIVK; | |
- map[28] = Op.IDIVK; | |
- map[29] = Op.BANDK; | |
- map[30] = Op.BORK; | |
- map[31] = Op.BXORK; | |
- map[32] = Op.SHRI; | |
- map[33] = Op.SHLI; | |
- map[34] = Op.ADD54; | |
- map[35] = Op.SUB54; | |
- map[36] = Op.MUL54; | |
- map[37] = Op.MOD54; | |
- map[38] = Op.POW54; | |
- map[39] = Op.DIV54; | |
- map[40] = Op.IDIV54; | |
- map[41] = Op.BAND54; | |
- map[42] = Op.BOR54; | |
- map[43] = Op.BXOR54; | |
- map[44] = Op.SHL54; | |
- map[45] = Op.SHR54; | |
- map[46] = Op.MMBIN; | |
- map[47] = Op.MMBINI; | |
- map[48] = Op.MMBINK; | |
- map[49] = Op.UNM; | |
- map[50] = Op.BNOT; | |
- map[51] = Op.NOT; | |
- map[52] = Op.LEN; | |
- map[53] = Op.CONCAT54; | |
- map[54] = Op.CLOSE; | |
- map[55] = Op.TBC; | |
- map[56] = Op.JMP54; | |
- map[57] = Op.EQ54; | |
- map[58] = Op.LT54; | |
- map[59] = Op.LE54; | |
- map[60] = Op.EQK; | |
- map[61] = Op.EQI; | |
- map[62] = Op.LTI; | |
- map[63] = Op.LEI; | |
- map[64] = Op.GTI; | |
- map[65] = Op.GEI; | |
- map[66] = Op.TEST54; | |
- map[67] = Op.TESTSET54; | |
- map[68] = Op.CALL; | |
- map[69] = Op.TAILCALL54; | |
- map[70] = Op.RETURN54; | |
- map[71] = Op.RETURN0; | |
- map[72] = Op.RETURN1; | |
- map[73] = Op.FORLOOP54; | |
- map[74] = Op.FORPREP54; | |
- map[75] = Op.TFORPREP54; | |
- map[76] = Op.TFORCALL54; | |
- map[77] = Op.TFORLOOP54; | |
- map[78] = Op.SETLIST54; | |
- map[79] = Op.CLOSURE; | |
- map[80] = Op.VARARG54; | |
- map[81] = Op.VARARGPREP; | |
- map[82] = Op.EXTRAARG; | |
+ //map[5] = Op.LOADFALSE; | |
+ //map[6] = Op.LFALSESKIP; | |
+ //map[7] = Op.LOADTRUE; | |
+ int opc = 5; | |
+ // HACK: probably not load false (load unsigned int?) | |
+ map[opc++] = Op.LOADFALSE; | |
+ map[opc++] = Op.LOADNIL52; | |
+ map[opc++] = Op.GETUPVAL; | |
+ map[opc++] = Op.SETUPVAL; | |
+ map[opc++] = Op.GETTABUP54; | |
+ map[opc++] = Op.GETTABLE54; | |
+ map[opc++] = Op.GETI; | |
+ map[opc++] = Op.GETFIELD; | |
+ map[opc++] = Op.SETTABUP54; | |
+ map[opc++] = Op.SETTABLE54; | |
+ map[opc++] = Op.SETI; | |
+ map[opc++] = Op.SETFIELD; | |
+ map[opc++] = Op.NEWTABLE54; | |
+ map[opc++] = Op.SELF54; | |
+ map[opc++] = Op.ADDI; | |
+ map[opc++] = Op.ADDK; | |
+ map[opc++] = Op.SUBK; | |
+ map[opc++] = Op.MULK; | |
+ map[opc++] = Op.MODK; | |
+ map[opc++] = Op.POWK; | |
+ map[opc++] = Op.DIVK; | |
+ map[opc++] = Op.IDIVK; | |
+ map[opc++] = Op.BANDK; | |
+ map[opc++] = Op.BORK; | |
+ map[opc++] = Op.BXORK; | |
+ map[opc++] = Op.SHRI; | |
+ map[opc++] = Op.SHLI; | |
+ map[opc++] = Op.ADD54; | |
+ map[opc++] = Op.SUB54; | |
+ map[opc++] = Op.MUL54; | |
+ map[opc++] = Op.MOD54; | |
+ map[opc++] = Op.POW54; | |
+ map[opc++] = Op.DIV54; | |
+ map[opc++] = Op.IDIV54; | |
+ map[opc++] = Op.BAND54; | |
+ map[opc++] = Op.BOR54; | |
+ map[opc++] = Op.BXOR54; | |
+ map[opc++] = Op.SHL54; | |
+ map[opc++] = Op.SHR54; | |
+ map[opc++] = Op.MMBIN; | |
+ map[opc++] = Op.MMBINI; | |
+ map[opc++] = Op.MMBINK; | |
+ map[opc++] = Op.UNM; | |
+ map[opc++] = Op.BNOT; | |
+ map[opc++] = Op.NOT; | |
+ map[opc++] = Op.LEN; | |
+ map[opc++] = Op.CONCAT54; | |
+ map[opc++] = Op.CLOSE; | |
+ map[opc++] = Op.TBC; | |
+ map[opc++] = Op.JMP54; | |
+ map[opc++] = Op.EQ54; | |
+ map[opc++] = Op.LT54; | |
+ map[opc++] = Op.LE54; | |
+ map[opc++] = Op.EQK; | |
+ map[opc++] = Op.EQI; | |
+ map[opc++] = Op.LTI; | |
+ map[opc++] = Op.LEI; | |
+ map[opc++] = Op.GTI; | |
+ map[opc++] = Op.GEI; | |
+ map[opc++] = Op.TEST54; | |
+ map[opc++] = Op.TESTSET54; | |
+ map[opc++] = Op.CALL; | |
+ map[opc++] = Op.TAILCALL54; | |
+ map[opc++] = Op.RETURN54; | |
+ map[opc++] = Op.RETURN0; | |
+ map[opc++] = Op.RETURN1; | |
+ map[opc++] = Op.FORLOOP54; | |
+ map[opc++] = Op.FORPREP54; | |
+ map[opc++] = Op.TFORPREP54; | |
+ map[opc++] = Op.TFORCALL54; | |
+ map[opc++] = Op.TFORLOOP54; | |
+ map[opc++] = Op.SETLIST54; | |
+ map[opc++] = Op.CLOSURE; | |
+ map[opc++] = Op.VARARG54; | |
+ map[opc++] = Op.VARARGPREP; | |
+ map[opc++] = Op.EXTRAARG; | |
break; | |
default: | |
throw new IllegalStateException(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Zhuowei Zhang <zhuowei@worthdoingbadly.com> | |
# Date 1633495233 14400 | |
# Wed Oct 06 00:40:33 2021 -0400 | |
# Node ID 8f52eb1ea0af2abe900aca803fd0e8c3253e957b | |
# Parent ad22b05f3653ef1de6bf3455f22e791d1f33e4f9 | |
Hack: work around too few registers error by just taking the max of register and declarations | |
diff --git a/src/unluac/decompile/Registers.java b/src/unluac/decompile/Registers.java | |
--- a/src/unluac/decompile/Registers.java | |
+++ b/src/unluac/decompile/Registers.java | |
@@ -22,6 +22,7 @@ public class Registers { | |
private final int[][] updated; | |
public Registers(int registers, int length, Declaration[] declList, Function f, boolean isNoDebug) { | |
+ if (registers < declList.length) registers = declList.length; | |
this.registers = registers; | |
this.length = length; | |
decls = new Declaration[registers][length + 1]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment