summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--luac.outbin0 -> 192 bytes
-rw-r--r--sandbox/hello.bcbin0 -> 192 bytes
-rw-r--r--sandbox/hello.js8
-rw-r--r--sandbox/hello.lua2
-rw-r--r--sandbox/hello2.lua7
-rw-r--r--src/lundump.js85
7 files changed, 96 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index c926fad..16699e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,4 +39,3 @@ jspm_packages
# JSDoc
help
-sandbox
diff --git a/luac.out b/luac.out
new file mode 100644
index 0000000..25258bb
--- /dev/null
+++ b/luac.out
Binary files differ
diff --git a/sandbox/hello.bc b/sandbox/hello.bc
new file mode 100644
index 0000000..25258bb
--- /dev/null
+++ b/sandbox/hello.bc
Binary files differ
diff --git a/sandbox/hello.js b/sandbox/hello.js
new file mode 100644
index 0000000..f8f6e15
--- /dev/null
+++ b/sandbox/hello.js
@@ -0,0 +1,8 @@
+const DataView = require('buffer-dataview');
+const fs = require('fs');
+
+const BytecodeParser = require("../src/lundump.js");
+const lua_State = require('../src/lstate.js').lua_State;
+
+let p = new BytecodeParser(new lua_State(), new DataView(fs.readFileSync("./sandbox/hello.bc")))
+p.luaU_undump(); \ No newline at end of file
diff --git a/sandbox/hello.lua b/sandbox/hello.lua
new file mode 100644
index 0000000..b2bf135
--- /dev/null
+++ b/sandbox/hello.lua
@@ -0,0 +1,2 @@
+local hello = "Hello"
+print (hello.." World!")
diff --git a/sandbox/hello2.lua b/sandbox/hello2.lua
new file mode 100644
index 0000000..bcbc1e0
--- /dev/null
+++ b/sandbox/hello2.lua
@@ -0,0 +1,7 @@
+local a = 1;
+local b = 2;
+print(a, b);
+
+function c(a, b)
+ return a + b
+end \ No newline at end of file
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;
}