From 8285c78283f922e5b5569ce5c28fb25074db0af3 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Mon, 27 Feb 2017 21:49:27 +0100 Subject: parsing --- src/lopcodes.js | 214 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 190 insertions(+), 24 deletions(-) (limited to 'src/lopcodes.js') diff --git a/src/lopcodes.js b/src/lopcodes.js index 5723abb..d83897c 100644 --- a/src/lopcodes.js +++ b/src/lopcodes.js @@ -51,6 +51,56 @@ const OpCodes = [ "OP_EXTRAARG" ]; +const OpCodesI = { + OP_MOVE: 0, + OP_LOADK: 1, + OP_LOADKX: 2, + OP_LOADBOOL: 3, + OP_LOADNIL: 4, + OP_GETUPVAL: 5, + OP_GETTABUP: 6, + OP_GETTABLE: 7, + OP_SETTABUP: 8, + OP_SETUPVAL: 9, + OP_SETTABLE: 10, + OP_NEWTABLE: 11, + OP_SELF: 12, + OP_ADD: 13, + OP_SUB: 14, + OP_MUL: 15, + OP_MOD: 16, + OP_POW: 17, + OP_DIV: 18, + OP_IDIV: 19, + OP_BAND: 20, + OP_BOR: 21, + OP_BXOR: 22, + OP_SHL: 23, + OP_SHR: 24, + OP_UNM: 25, + OP_BNOT: 26, + OP_NOT: 27, + OP_LEN: 28, + OP_CONCAT: 29, + OP_JMP: 30, + OP_EQ: 31, + OP_LT: 32, + OP_LE: 33, + OP_TEST: 34, + OP_TESTSET: 35, + OP_CALL: 36, + OP_TAILCALL: 37, + OP_RETURN: 38, + OP_FORLOOP: 39, + OP_FORPREP: 40, + OP_TFORCALL: 41, + OP_TFORLOOP: 42, + OP_SETLIST: 43, + OP_CLOSURE: 44, + OP_VARARG: 45, + OP_EXTRAARG: 46 +}; + /* ** masks for instruction properties. The format is: ** bits 0-1: op mode @@ -120,10 +170,26 @@ const luaP_opmodes = [ 0 << 7 | 0 << 6 | OpArgU << 4 | OpArgU << 2 | iAx /* OP_EXTRAARG */ ]; +const getOpMode = function(m) { + return luaP_opmodes[m] & 3; +}; + +const getBMode = function(m) { + return (luaP_opmodes[m] >> 4) & 3; +}; + +const getCMode = function(m) { + return (luaP_opmodes[m] >> 2) & 3; +}; + const testAMode = function(m) { return luaP_opmodes[m] & (1 << 6); }; +const testTMode = function(m) { + return luaP_opmodes[m] & (1 << 7); +}; + const SIZE_C = 9; const SIZE_B = 9; const SIZE_Bx = (SIZE_C + SIZE_B); @@ -145,6 +211,11 @@ const MAXARG_C = ((1 << SIZE_C) - 1); const BITRK = (1 << (SIZE_B - 1)); +/* +** invalid register that fits in 8 bits +*/ +const NO_REG = MAXARG_A; + const ISK = function (x) { return x & BITRK; }; @@ -153,30 +224,125 @@ const INDEXK = function (r) { return r & ~BITRK; }; +/* creates a mask with 'n' 1 bits at position 'p' */ +const MASK1 = function(n, p) { + return ((~((~0)<<(n)))<<(p)); +}; + +/* creates a mask with 'n' 0 bits at position 'p' */ +const MASK0 = function(n, p) { + return (~MASK1(n, p)); +}; + +const setarg = function(i, v, pos, size) { + i.code = (i.code & MASK0(size, pos)) | ((v << pos) & MASK1(size, pos)); + fullins(i); +}; + +const SETARG_A = function(i,v) { + setarg(i, v, POS_A, SIZE_A); +}; + +const SETARG_B = function(i,v) { + setarg(i, v, POS_B, SIZE_B); +}; + +const SETARG_C = function(i,v) { + setarg(i, v, POS_C, SIZE_C); +}; + +const SETARG_Bx = function(i,v) { + setarg(i, v, POS_Bx, SIZE_Bx); +}; + +const SETARG_Ax = function(i,v) { + setarg(i, v, POS_Ax, SIZE_Ax); +}; + +const SETARG_sBx = function(i, b) { + SETARG_Bx(i, b + MAXARG_sBx); +}; + +/* +** Pre-calculate all possible part of the instruction +*/ +const fullins = function(ins) { + if (typeof ins === "integer") { + return { + code: ins, + opcode: (ins >> POS_OP) & MASK1(SIZE_OP, 0), + A: (ins >> POS_A) & MASK1(SIZE_A, 0), + B: (ins >> POS_B) & MASK1(SIZE_B, 0), + C: (ins >> POS_C) & MASK1(SIZE_C, 0), + Bx: (ins >> POS_Bx) & MASK1(SIZE_Bx, 0), + Ax: (ins >> POS_Ax) & MASK1(SIZE_Ax, 0), + sBx: ((ins >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx + }; + } else { + let i = ins.code; + ins.opcode = (i >> POS_OP) & MASK1(SIZE_OP, 0), + ins.A = (i >> POS_A) & MASK1(SIZE_A, 0), + ins.B = (i >> POS_B) & MASK1(SIZE_B, 0), + ins.C = (i >> POS_C) & MASK1(SIZE_C, 0), + ins.Bx = (i >> POS_Bx) & MASK1(SIZE_Bx, 0), + ins.Ax = (i >> POS_Ax) & MASK1(SIZE_Ax, 0), + ins.sBx = ((i >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx + return ins; + } +}; + +const CREATE_ABC = function(o, a, b, c) { + return fullins(o << POS_OP | a << POS_A | b << POS_B | c << POS_C); +}; + +const CREATE_ABx = function(o, a, bc) { + return fullins(o << POS_OP | a << POS_A | bc << POS_Bx); +}; + +const CREATE_Ax = function(o a) { + return fullins(o << POS_OP | a << POS_Ax); +}; + /* number of list items to accumulate before a SETLIST instruction */ const LFIELDS_PER_FLUSH = 50; -module.exports.OpCodes = OpCodes; -module.exports.SIZE_C = SIZE_C; -module.exports.SIZE_B = SIZE_B; -module.exports.SIZE_Bx = SIZE_Bx; -module.exports.SIZE_A = SIZE_A; -module.exports.SIZE_Ax = SIZE_Ax; -module.exports.SIZE_OP = SIZE_OP; -module.exports.POS_OP = POS_OP; -module.exports.POS_A = POS_A; -module.exports.POS_C = POS_C; -module.exports.POS_B = POS_B; -module.exports.POS_Bx = POS_Bx; -module.exports.POS_Ax = POS_Ax; -module.exports.MAXARG_Bx = MAXARG_Bx; -module.exports.MAXARG_sBx = MAXARG_sBx; -module.exports.MAXARG_Ax = MAXARG_Ax; -module.exports.MAXARG_A = MAXARG_A; -module.exports.MAXARG_B = MAXARG_B; -module.exports.MAXARG_C = MAXARG_C; -module.exports.BITRK = BITRK; -module.exports.ISK = ISK; -module.exports.INDEXK = INDEXK; -module.exports.LFIELDS_PER_FLUSH = LFIELDS_PER_FLUSH; -module.exports.testAMode = testAMode; \ No newline at end of file +module.exports.BITRK = BITRK; +module.exports.CREATE_ABC = CREATE_ABC; +module.exports.CREATE_ABx = CREATE_ABx; +module.exports.CREATE_Ax = CREATE_Ax; +module.exports.INDEXK = INDEXK; +module.exports.ISK = ISK; +module.exports.LFIELDS_PER_FLUSH = LFIELDS_PER_FLUSH; +module.exports.MAXARG_A = MAXARG_A; +module.exports.MAXARG_Ax = MAXARG_Ax; +module.exports.MAXARG_B = MAXARG_B; +module.exports.MAXARG_Bx = MAXARG_Bx; +module.exports.MAXARG_C = MAXARG_C; +module.exports.MAXARG_sBx = MAXARG_sBx; +module.exports.NO_REG = NO_REG; +module.exports.OpCodes = OpCodes; +module.exports.OpCodesI = OpCodesI; +module.exports.POS_A = POS_A; +module.exports.POS_Ax = POS_Ax; +module.exports.POS_B = POS_B; +module.exports.POS_Bx = POS_Bx; +module.exports.POS_C = POS_C; +module.exports.POS_OP = POS_OP; +module.exports.SETARG_A = SETARG_A; +module.exports.SETARG_Ax = SETARG_Ax; +module.exports.SETARG_B = SETARG_B; +module.exports.SETARG_Bx = SETARG_Bx; +module.exports.SETARG_C = SETARG_C; +module.exports.SETARG_sBx = SETARG_sBx; +module.exports.SIZE_A = SIZE_A; +module.exports.SIZE_Ax = SIZE_Ax; +module.exports.SIZE_B = SIZE_B; +module.exports.SIZE_Bx = SIZE_Bx; +module.exports.SIZE_C = SIZE_C; +module.exports.SIZE_OP = SIZE_OP; +module.exports.fullins = fullins; +module.exports.getBMode = getBMode; +module.exports.getCMode = getCMode; +module.exports.getOpMode = getOpMode; +module.exports.testAMode = testAMode; +module.exports.testTMode = testTMode; \ No newline at end of file -- cgit v1.2.3-54-g00ecf