From fa7ce109418aca2fd60fdb65b4b2451c4854dd09 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 2 Feb 2017 07:36:14 +0100 Subject: Following Lua's source code as closely as possible --- .gitignore | 2 ++ src/bytecodeparser.js | 28 --------------------- src/lobject.js | 15 ++++++++++++ src/lstate.js | 36 +++++++++++++++++++++++++++ src/lundump.js | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 28 deletions(-) delete mode 100644 src/bytecodeparser.js create mode 100644 src/lobject.js create mode 100644 src/lstate.js create mode 100644 src/lundump.js diff --git a/.gitignore b/.gitignore index 9dda96a..c926fad 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ jspm_packages # JSDoc help + +sandbox diff --git a/src/bytecodeparser.js b/src/bytecodeparser.js deleted file mode 100644 index 595158e..0000000 --- a/src/bytecodeparser.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; - -const DataView = require('buffer-dataview'); - -/** - * Parse Lua 5.3 bytecode - */ -class BytecodeParser { - - constructor(dataView) { - this.dataView = dataView; - this.offset = 0; - } - - _read(offset, nbytes) { - let bytes = new Uint8Array(nbytes); - - for (let i = 0; i < nbytes; i++) - bytes[i] = this.dataView.getUint8(offset, true); - - return bytes.length === 1 ? bytes[0] : bytes; - } - - readByte() { - return read(this.offset++, 1); - } - -} \ No newline at end of file diff --git a/src/lobject.js b/src/lobject.js new file mode 100644 index 0000000..2e21f16 --- /dev/null +++ b/src/lobject.js @@ -0,0 +1,15 @@ +/*jshint esversion: 6 */ +"use strict"; + +class LClosure { + + constructor(L, n) { + this.p = []; + this.nupvalues = n; + } + +} + +module.exports = { + LClosure: LClosure +}; \ No newline at end of file diff --git a/src/lstate.js b/src/lstate.js new file mode 100644 index 0000000..b0002c3 --- /dev/null +++ b/src/lstate.js @@ -0,0 +1,36 @@ +/*jshint esversion: 6 */ +"use strict"; + +class lua_State { + + constructor() { + // CommonHeader; + // unsigned short nci; /* number of items in 'ci' list */ + // lu_byte status; + // StkId top; /* first free slot in the stack */ + // global_State *l_G; + // CallInfo *ci; /* call info for current function */ + // const Instruction *oldpc; /* last pc traced */ + // StkId stack_last; /* last free slot in the stack */ + // StkId stack; /* stack base */ + // UpVal *openupval; /* list of open upvalues in this stack */ + // GCObject *gclist; + // struct lua_State *twups; list of threads with open upvalues + // struct lua_longjmp *errorJmp; /* current error recover point */ + // CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + // volatile lua_Hook hook; + // ptrdiff_t errfunc; /* current error handling function (stack index) */ + // int stacksize; + // int basehookcount; + // int hookcount; + // unsigned short nny; /* number of non-yieldable calls in stack */ + // unsigned short nCcalls; /* number of nested C calls */ + // l_signalT hookmask; + // lu_byte allowhook; + } + +} + +module.exports = { + lua_State: lua_State +}; \ No newline at end of file diff --git a/src/lundump.js b/src/lundump.js new file mode 100644 index 0000000..69445d4 --- /dev/null +++ b/src/lundump.js @@ -0,0 +1,67 @@ +/*jshint esversion: 6 */ +"use strict"; + +const DataView = require('buffer-dataview'); +const fs = require('fs'); +const lua_State = require('./lstate.js').lua_State; +const LClosure = require('./lobject.js').LClosure; + +/** + * Parse Lua 5.3 bytecode + * @see {@link http://www.lua.org/source/5.3/lundump.c.html|lundump.c} + */ +class BytecodeParser { + + /** + * Initilialize bytecode parser + * @constructor + * @param {DataView} dataView Contains the binary data + */ + constructor(dataView) { + this.dataView = dataView; + this.offset = 0; + } + + peekByte() { + return this.dataView.getUint8(this.offset, true); + } + + readByte() { + let byte = this.peekByte(); + this.offset++; + return byte; + } + + peekWord() { + return this.dataView.getUint32(this.offset, true); + } + + readWord() { + let word = this.peekWord(); + this.offset += 4; + + return word; + } + + checkHeader() { + if (this.readByte() !== 0x1b + || this.readByte() !== 0x4c + || this.readByte() !== 0x75 + || this.readByte() !== 0x61) + throw new Error("Bad LUA_SIGNATURE, expected [1b 4c 75 61]"); + + if (this.readByte() !== 0x53) + throw new Error("Bad Lua version, expected 5.3"); + + if (this.readByte() !== 0) + throw new Error("Supports only official PUC-Rio implementation") + } + + luaU_undump() { + checkHeader(); + let cl = new LClosure(L, this.readByte()); + + return cl; + } + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2