summaryrefslogtreecommitdiff
path: root/src/lundump.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lundump.js')
-rw-r--r--src/lundump.js85
1 files changed, 79 insertions, 6 deletions
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;
}