From bad73671ca959f292becb8c68b73a14380aeeb56 Mon Sep 17 00:00:00 2001
From: Benoit Giannangeli <benoit.giannangeli@boursorama.fr>
Date: Thu, 2 Feb 2017 14:27:05 +0100
Subject: readFunction, readCode, readString, readInstruction

---
 src/lundump.js | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 79 insertions(+), 6 deletions(-)

(limited to 'src')

diff --git a/src/lundump.js b/src/lundump.js
index 1d1a959..c9481da 100644
--- a/src/lundump.js
+++ b/src/lundump.js
@@ -9,6 +9,8 @@ const lua_State = require('./lstate.js').lua_State;
 const LClosure  = require('./lobject.js').LClosure;
 const Proto     = require('./lfunc.js').Proto;
 
+const LUAI_MAXSHORTLEN = 40;
+
 /**
  * Parse Lua 5.3 bytecode
  * @see {@link http://www.lua.org/source/5.3/lundump.c.html|lundump.c}
@@ -54,6 +56,17 @@ class BytecodeParser {
         return integer;
     }
 
+    peekInt() {
+        return this.dataView.getInt32(this.offset, true);
+    }
+
+    readInt() {
+        let integer = this.peekInt();
+        this.offset += 4;
+
+        return integer;
+    }
+
     peekNumber() {
         return this.dataView.getFloat64(this.offset, true);
     }
@@ -66,14 +79,66 @@ class BytecodeParser {
     }
 
     readString(n) {
+        let size = typeof n !== 'undefined' ? n : this.readByte() - 1;
+
+        if (size === 0xFF) // TODO test
+            this.offset += this.size_tSize;
+
+        if (size === 0) {
+            return null;
+        }
+
         let string = "";
 
-        for (let i = 0; i < n; i++)
+        for (let i = 0; i < size; i++)
             string += String.fromCharCode(this.readByte());
 
         return string;
     }
 
+    readInstruction() {
+        let ins = new DataView(new Buffer(this.instructionSize))
+        for (let i = 0; i < this.instructionSize; i++)
+            ins.setUint8(i, this.readByte());
+
+        console.log(ins);
+
+        return ins;
+    }
+
+    readCode(f) {
+        let n = this.readInt();
+
+        for (let i = 0; i < n; i++)
+            f.code.push(this.readInstruction());
+    }
+
+    readFunction(f, psource) {
+        f.source = this.readString();
+        if (f.source == null)  /* no source in dump? */
+            f.source = psource;  /* reuse parent's source */
+        f.linedefined = this.readInt();
+        f.lastlinedefined = this.readInt();
+        f.numparams = this.readByte();
+        f.is_vararg = this.readByte();
+        f.maxstacksize = this.readByte();
+
+        console.log(`
+            f.source          = ${f.source}
+            f.linedefined     = ${f.linedefined}
+            f.lastlinedefined = ${f.lastlinedefined}
+            f.numparams       = ${f.numparams}
+            f.is_vararg       = ${f.is_vararg}
+            f.maxstacksize    = ${f.maxstacksize}
+        `);
+
+        this.readCode(f);
+        // this.readConstants(f);
+        // this.readUpvalues(f);
+        // this.readProtos(f);
+        // this.readDebug(f);
+    }
+
     checkHeader() {
         if (this.readString(4) !== "\x1bLua")
             throw new Error("bad LUA_SIGNATURE, expected '<esc>Lua'");
@@ -93,24 +158,32 @@ class BytecodeParser {
         this.integerSize     = this.readByte();
         this.numberSize      = this.readByte();
 
+        console.log(`
+            intSize         = ${this.intSize}
+            size_tSize      = ${this.size_tSize}
+            instructionSize = ${this.instructionSize}
+            integerSize     = ${this.integerSize}
+            numberSize      = ${this.numberSize}
+        `)
+
         if (this.readInteger() !== 0x5678)
             throw new Error("endianness mismatch");
 
         if (this.readNumber() !== 370.5)
-            throw new Error("float format mismatch in");
+            throw new Error("float format mismatch");
 
     }
 
     luaU_undump() {
-        checkHeader();
+        this.checkHeader();
 
         let cl = new LClosure(this.L, this.readByte());
-        L.top++;
+        this.L.top++;
         cl.p = new Proto(this.L);
 
-        loadFunction(cl.p);
+        this.readFunction(cl.p);
 
-        assert(cl.nupvalues === cl.p.upvalues.length);
+        // assert(cl.nupvalues === cl.p.upvalues.length);
 
         return cl;
     }
-- 
cgit v1.2.3-70-g09d2