diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | luac.out | bin | 0 -> 192 bytes | |||
-rw-r--r-- | sandbox/hello.bc | bin | 0 -> 192 bytes | |||
-rw-r--r-- | sandbox/hello.js | 8 | ||||
-rw-r--r-- | sandbox/hello.lua | 2 | ||||
-rw-r--r-- | sandbox/hello2.lua | 7 | ||||
-rw-r--r-- | src/lundump.js | 85 |
7 files changed, 96 insertions, 7 deletions
@@ -39,4 +39,3 @@ jspm_packages # JSDoc help -sandbox diff --git a/luac.out b/luac.out Binary files differnew file mode 100644 index 0000000..25258bb --- /dev/null +++ b/luac.out diff --git a/sandbox/hello.bc b/sandbox/hello.bc Binary files differnew file mode 100644 index 0000000..25258bb --- /dev/null +++ b/sandbox/hello.bc 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; } |