diff --git a/README.md b/README.md index f8821a7..432abf6 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,22 @@ Lua has a relatively small instruction set (only 38 different opcodes!). This ma ```sh > cat example.lua && luac5.1 -o example.luac example.lua -local i, x = 0, 2 +local i, x = 10, 2 repeat print(i + x) - i = i + 1 -until i < 10 - + i = i - 1 +until i < 0 > python main.py example.luac example.luac ==== [[example.lua's constants]] ==== -0: [NUMBER] 0.0 +0: [NUMBER] 10.0 1: [NUMBER] 2.0 2: [STRING] print 3: [NUMBER] 1.0 -4: [NUMBER] 10.0 +4: [NUMBER] 0.0 ==== [[example.lua's locals]] ==== @@ -37,23 +36,23 @@ R[1]: x ==== [[example.lua's dissassembly]] ==== -[ 0] LOADK : R[0] K[0] ; load 0.0 into R[0] +[ 0] LOADK : R[0] K[0] ; load 10.0 into R[0] [ 1] LOADK : R[1] K[1] ; load 2.0 into R[1] -[ 2] GETGLOBAL : R[2] K[2] ; -[ 3] ADD : R[3] R[0] R[1] ; -[ 4] CALL : R[2] 2 1 ; -[ 5] ADD : R[0] R[0] K[3] ; +[ 2] GETGLOBAL : R[2] K[2] ; move _G["print"] into R[2] +[ 3] ADD : R[3] R[0] R[1] ; add R[1] to R[0], place into R[3] +[ 4] CALL : 2 2 1 ; +[ 5] SUB : R[0] R[0] K[3] ; sub K[3] from R[0], place into R[0] [ 6] LT : R[0] R[0] K[4] ; [ 7] JMP : R[0] -6 ; -[ 8] RETURN : R[0] 1 0 ; +[ 8] RETURN : 0 1 0 ; ==== [[example.lua's decompiled source]] ==== -local i = 0.0 +local i = 10.0 local x = 2.0 repeat print((i + x)) - i = (i + 1.0) -until i < 10.0 + i = (i - 1.0) +until i < 0.0 ``` \ No newline at end of file diff --git a/lundump.py b/lundump.py index 9cbbe4d..7fef536 100644 --- a/lundump.py +++ b/lundump.py @@ -100,15 +100,17 @@ class Instruction: if self.type == InstructionType.ABC: # by default, treat them as registers - A = "R[%d]" % self.A + A = "%d" % self.A B = "%d" % self.B C = "%d" % self.C # these opcodes have RKs for B & C if self.opcode in _RKBCInstr: + A = "R[%d]" % self.A B = self.__formatRK(self.B) C = self.__formatRK(self.C) elif self.opcode in _RKCInstr: # just for C + A = "R[%d]" % self.A C = self.__formatRK(self.C) regs = "%6s %6s %6s" % (A, B, C) @@ -128,6 +130,16 @@ class Instruction: return "move R[%d] into R[%d]" % (self.B, self.A) elif self.opcode == Opcodes.LOADK: return "load %s into R[%d]" % (chunk.getConstant(self.B).toCode(), self.A) + elif self.opcode == Opcodes.GETGLOBAL: + return 'move _G[%s] into R[%d]' % (chunk.getConstant(self.B).toCode(), self.A) + elif self.opcode == Opcodes.ADD: + return 'add %s to %s, place into R[%d]' % (self.__formatRK(self.C), self.__formatRK(self.B), self.A) + elif self.opcode == Opcodes.SUB: + return 'sub %s from %s, place into R[%d]' % (self.__formatRK(self.C), self.__formatRK(self.B), self.A) + elif self.opcode == Opcodes.MUL: + return 'mul %s to %s, place into R[%d]' % (self.__formatRK(self.C), self.__formatRK(self.B), self.A) + elif self.opcode == Opcodes.DIV: + return 'div %s from %s, place into R[%d]' % (self.__formatRK(self.C), self.__formatRK(self.B), self.A) elif self.opcode == Opcodes.CONCAT: count = self.C - self.B + 1 return "concat %d values from R[%d] to R[%d], store into R[%d]" % (count, self.B, self.C, self.A)