summaryrefslogtreecommitdiff
path: root/src/lopcodes.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lopcodes.js')
-rw-r--r--src/lopcodes.js214
1 files changed, 190 insertions, 24 deletions
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