From 7b844c5caf81ac843a210477ef47fd16e8af2f2c Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 2 Feb 2017 22:38:35 +0100 Subject: Lua VM --- src/lundump.js | 63 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 21 deletions(-) (limited to 'src/lundump.js') diff --git a/src/lundump.js b/src/lundump.js index 46a9d70..07d86df 100644 --- a/src/lundump.js +++ b/src/lundump.js @@ -1,14 +1,14 @@ /*jshint esversion: 6 */ "use strict"; -const DataView = require('buffer-dataview'); -const fs = require('fs'); -const assert = require('assert'); +const DataView = require('buffer-dataview'); +const fs = require('fs'); +const assert = require('assert'); -const lua_State = require('./lstate.js').lua_State; -const LClosure = require('./lobject.js').LClosure; -const Proto = require('./lfunc.js').Proto; +const LClosure = require('./lobject.js').LClosure; +const Proto = require('./lfunc.js').Proto; const constant_types = require('./lua.js').constant_types; +const OpCodes = require('./lopcodes.js'); const LUAI_MAXSHORTLEN = 40; @@ -24,14 +24,13 @@ class BytecodeParser { * @param {lua_State} Lua state object * @param {DataView} dataView Contains the binary data */ - constructor(L, dataView) { + constructor(dataView) { this.intSize = 4; this.size_tSize = 8; this.instructionSize = 4; this.integerSize = 8; this.numberSize = 8; - this.L = L; this.dataView = dataView; this.offset = 0; } @@ -97,21 +96,44 @@ class BytecodeParser { return string; } + /* creates a mask with 'n' 1 bits at position 'p' */ + static MASK1(n, p) { + return ((~((~0)<<(n)))<<(p)); + } + + /* creates a mask with 'n' 0 bits at position 'p' */ + static MASK0(n, p) { + return (~MASK1(n,p)); + } + 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; + return ins.getUint32(0, true); } readCode(f) { let n = this.readInt(); + let o = OpCodes; + let p = BytecodeParser; - for (let i = 0; i < n; i++) - f.code.push(this.readInstruction()); + for (let i = 0; i < n; i++) { + let ins = this.readInstruction(); + f.code[i] = { + code: ins, + opcode: (ins >> o.POS_OP) & p.MASK1(o.SIZE_OP, 0), + A: (ins >> o.POS_A) & p.MASK1(o.SIZE_A, 0), + B: (ins >> o.POS_B) & p.MASK1(o.SIZE_B, 0), + C: (ins >> o.POS_C) & p.MASK1(o.SIZE_C, 0), + Bx: (ins >> o.POS_Bx) & p.MASK1(o.SIZE_Bx, 0), + Ax: (ins >> o.POS_Ax) & p.MASK1(o.SIZE_Ax, 0), + sBx: (ins >> o.POS_Bx) & p.MASK1(o.SIZE_Bx, 0) - o.MAXARG_sBx + }; + + console.log(` [${i}] Op: ${o.OpCodes[f.code[i].opcode]} A: ${f.code[i].A} B: ${f.code[i].B} C: ${f.code[i].C} Ax: ${f.code[i].Ax} Bx: ${f.code[i].Bx} sBx: ${f.code[i].sBx}`); + } } readUpvalues(f) { @@ -144,28 +166,28 @@ class BytecodeParser { type: constant_types.LUA_TNIL, value: null }); - console.log(`LUA_TNIL = ${f.k[f.k.length - 1].value}`); + console.log(` LUA_TNIL = ${f.k[f.k.length - 1].value}`); break; case constant_types.LUA_TBOOLEAN: f.k.push({ type: constant_types.LUA_TBOOLEAN, value: this.readByte() }); - console.log(`LUA_TBOOLEAN = ${f.k[f.k.length - 1].value}`); + console.log(` LUA_TBOOLEAN = ${f.k[f.k.length - 1].value}`); break; case constant_types.LUA_TNUMFLT: f.k.push({ type: constant_types.LUA_TNUMFLT, value: this.readNumber() }); - console.log(`LUA_TNUMFLT = ${f.k[f.k.length - 1].value}`); + console.log(` LUA_TNUMFLT = ${f.k[f.k.length - 1].value}`); break; case constant_types.LUA_TNUMINT: f.k.push({ type: constant_types.LUA_TNUMINT, value: this.readInteger() }); - console.log(`LUA_TNUMINT = ${f.k[f.k.length - 1].value}`); + console.log(` LUA_TNUMINT = ${f.k[f.k.length - 1].value}`); break; case constant_types.LUA_TSHRSTR: case constant_types.LUA_TLNGSTR: @@ -173,7 +195,7 @@ class BytecodeParser { type: constant_types.LUA_TLNGSTR, value: this.readString() }); - console.log(`LUA_TLNGSTR = ${f.k[f.k.length - 1].value}`); + console.log(` LUA_TLNGSTR = ${f.k[f.k.length - 1].value}`); break; default: throw new Error(`unrecognized constant '${t}'`); @@ -284,9 +306,8 @@ class BytecodeParser { luaU_undump() { this.checkHeader(); - let cl = new LClosure(this.L, this.readByte()); - this.L.top++; - cl.p = new Proto(this.L); + let cl = new LClosure(this.readByte()); + cl.p = new Proto(); this.readFunction(cl.p); -- cgit v1.2.3-54-g00ecf