From 90161c463fc8725d3d39b699dbf7e591874c47fb Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 3 Feb 2017 14:55:36 +0100 Subject: Use block for each case of vm dispatch --- luac.out | Bin 241 -> 241 bytes src/lvm.js | 248 +++++++++++++++++++++++++++++++++++------------------------ tests/lvm.js | 2 +- 3 files changed, 148 insertions(+), 102 deletions(-) diff --git a/luac.out b/luac.out index f5b0ee0..9973c9b 100644 Binary files a/luac.out and b/luac.out differ diff --git a/src/lvm.js b/src/lvm.js index 0c52eaf..f18ede4 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -66,19 +66,21 @@ class LuaVM { let i = ci.savedpc[ci.pcOff++]; let ra = this.RA(base, i); - var op1, op2, numberop1, numberop2, op, numberop; switch (OC.OpCodes[i.opcode]) { - case "OP_MOVE": + case "OP_MOVE": { L.stack[ra] = L.stack[this.RB(base, i)]; break; - case "OP_LOADK": + } + case "OP_LOADK": { L.stack[ra] = k[i.Bx]; break; - case "OP_LOADKX": + } + case "OP_LOADKX": { assert(OC.OpCodes[ci.savedpc[ci.pcOff].opcode] === "OP_EXTRAARG"); L.stack[ra] = k[ci.savedpc[ci.pcOff++].Ax]; break; - case "OP_LOADBOOL": + } + case "OP_LOADBOOL": { L.stack[ra] = { type: CT.LUA_TBOOLEAN, value: i.B !== 0 @@ -88,34 +90,44 @@ class LuaVM { ci.pcOff++; /* skip next instruction (if C) */ break; - case "OP_LOADNIL": + } + case "OP_LOADNIL": { for (let j = 0; j <= i.B; j++) L.stack[ra + j] = { type: CT.LUA_TNIL, value: null } break; - case "OP_GETUPVAL": + } + case "OP_GETUPVAL": { break; - case "OP_GETTABUP": + } + case "OP_GETTABUP": { break; - case "OP_GETTABLE": + } + case "OP_GETTABLE": { break; - case "OP_SETTABUP": + } + case "OP_SETTABUP": { break; - case "OP_SETUPVAL": + } + case "OP_SETUPVAL": { break; - case "OP_SETTABLE": + } + case "OP_SETTABLE": { break; - case "OP_NEWTABLE": + } + case "OP_NEWTABLE": { break; - case "OP_SELF": + } + case "OP_SELF": { break; - case "OP_ADD": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_ADD": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -132,11 +144,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_SUB": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_SUB": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -153,11 +166,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_MUL": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_MUL": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -174,11 +188,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_MOD": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_MOD": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -195,11 +210,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_POW": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_POW": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = { @@ -211,11 +227,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_DIV": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_DIV": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = { @@ -227,11 +244,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_IDIV": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_IDIV": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -248,11 +266,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_BAND": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_BAND": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -264,11 +283,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_BOR": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_BOR": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -280,11 +300,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_BXOR": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_BXOR": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -296,11 +317,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_SHL": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_SHL": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -312,11 +334,12 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_SHR": - op1 = k[i.B]; - op2 = k[i.C]; - numberop1 = LuaVM.tonumber(op1); - numberop2 = LuaVM.tonumber(op2); + } + case "OP_SHR": { + let op1 = k[i.B]; + let op2 = k[i.C]; + let numberop1 = LuaVM.tonumber(op1); + let numberop2 = LuaVM.tonumber(op2); if (op1.type === CT.LUA_TNUMINT && op2.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -328,9 +351,10 @@ class LuaVM { throw new Error(`Can't perform binary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_UNM": - op = L.stack[this.RB(base, i)]; - numberop = LuaVM.tonumber(op); + } + case "OP_UNM": { + let op = L.stack[this.RB(base, i)]; + let numberop = LuaVM.tonumber(op); if (op.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -347,9 +371,10 @@ class LuaVM { throw new Error(`Can't perform unary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_BNOT": - op = L.stack[this.RB(base, i)]; - numberop = LuaVM.tonumber(op); + } + case "OP_BNOT": { + let op = L.stack[this.RB(base, i)]; + let numberop = LuaVM.tonumber(op); if (op.type === CT.LUA_TNUMINT) { L.stack[ra] = { @@ -361,34 +386,46 @@ class LuaVM { throw new Error(`Can't perform unary operation on ${k[i.B].value} and ${k[i.C].value}`); } break; - case "OP_NOT": - op = L.stack[this.RB(base, i)]; + } + case "OP_NOT": { + let op = L.stack[this.RB(base, i)]; L.stack[ra] = { type: CT.LUA_TBOOLEAN, value: !!((op.type === CT.LUA_TBOOLEAN && !op.value) || op.type === CT.LUA_TNIL) } break; - case "OP_LEN": + } + case "OP_LEN": { break; - case "OP_CONCAT": + } + case "OP_CONCAT": { break; - case "OP_JMP": + } + case "OP_JMP": { break; - case "OP_EQ": + } + case "OP_EQ": { break; - case "OP_LT": + } + case "OP_LT": { break; - case "OP_LE": + } + case "OP_LE": { break; - case "OP_TEST": + } + case "OP_TEST": { break; - case "OP_TESTSET": + } + case "OP_TESTSET": { break; - case "OP_CALL": + } + case "OP_CALL": { break; - case "OP_TAILCALL": + } + case "OP_TAILCALL": { break; - case "OP_RETURN": + } + case "OP_RETURN": { if (i.B >= 2) { for (let j = 0; j <= i.B-2; j++) { L.stack[L.ciOff + j] = L.stack[ra + j]; @@ -404,22 +441,31 @@ class LuaVM { continue newframe; break; - case "OP_FORLOOP": + } + case "OP_FORLOOP": { break; - case "OP_FORPREP": + } + case "OP_FORPREP": { break; - case "OP_TFORCALL": + } + case "OP_TFORCALL": { break; - case "OP_TFORLOOP": + } + case "OP_TFORLOOP": { break; - case "OP_SETLIST": + } + case "OP_SETLIST": { break; - case "OP_CLOSURE": + } + case "OP_CLOSURE": { break; - case "OP_VARARG": + } + case "OP_VARARG": { break; - case "OP_EXTRAARG": + } + case "OP_EXTRAARG": { break; + } } } } diff --git a/tests/lvm.js b/tests/lvm.js index d2c716a..6a4ed9f 100644 --- a/tests/lvm.js +++ b/tests/lvm.js @@ -113,7 +113,7 @@ test('Binary op', function (t) { }); -test('Unary op', function (t) { +test('Unary op, LOADBOOL', function (t) { let luaCode = ` local a = 5 local b = false -- cgit v1.2.3-70-g09d2