aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lopcodes.js15
-rw-r--r--src/lstate.js34
-rw-r--r--src/lundump.js1
-rw-r--r--src/lvm.js133
4 files changed, 178 insertions, 5 deletions
diff --git a/src/lopcodes.js b/src/lopcodes.js
index b7dfb0f..8df67a3 100644
--- a/src/lopcodes.js
+++ b/src/lopcodes.js
@@ -86,6 +86,16 @@ const MAXARG_A = ((1 << SIZE_A) - 1);
const MAXARG_B = ((1 << SIZE_B) - 1);
const MAXARG_C = ((1 << SIZE_C) - 1);
+const BITRK = (1 << (SIZE_B - 1));
+
+const ISK = function (x) {
+ return x & BITRK;
+};
+
+const INDEXK = function (r) {
+ return r & ~BITRK;
+}
+
module.exports = {
OpCodes: OpCodes,
SIZE_C: SIZE_C,
@@ -105,5 +115,8 @@ module.exports = {
MAXARG_Ax: MAXARG_Ax,
MAXARG_A: MAXARG_A,
MAXARG_B: MAXARG_B,
- MAXARG_C: MAXARG_C
+ MAXARG_C: MAXARG_C,
+ BITRK: BITRK,
+ ISK: ISK,
+ INDEXK: INDEXK
}; \ No newline at end of file
diff --git a/src/lstate.js b/src/lstate.js
new file mode 100644
index 0000000..9c7eec3
--- /dev/null
+++ b/src/lstate.js
@@ -0,0 +1,34 @@
+/*jshint esversion: 6 */
+"use strict";
+
+
+class CallInfo {
+
+ constructor(func, top, base, previous, next) {
+ this.func = func;
+ this.top = top;
+ this.base = base;
+ this.previous = previous;
+ this.next = next;
+ this.savedpc = [];
+ this.pcOff = 0;
+ }
+
+}
+
+class lua_State {
+
+ constructor(cl) {
+ this.top = 1;
+ this.ci = [
+ new CallInfo(0, 1, 1, null, null);
+ ];
+ this.ci[0].savedpc = cl.p.code;
+ this.ciOff = 0;
+ this.stack = [
+ closure
+ ];
+ this.openupval = [];
+ }
+
+} \ No newline at end of file
diff --git a/src/lundump.js b/src/lundump.js
index 07d86df..896fb31 100644
--- a/src/lundump.js
+++ b/src/lundump.js
@@ -78,6 +78,7 @@ class BytecodeParser {
return number;
}
+ // TODO: 8-bit clean strings
readString(n) {
let size = typeof n !== 'undefined' ? n : this.readByte() - 1;
diff --git a/src/lvm.js b/src/lvm.js
index 0ea3342..349cccf 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -2,23 +2,148 @@
"use strict";
const BytecodeParser = require("./lundump.js");
+const OC = require('./lopcodes.js');
class LuaVM {
- constructor(cl) {
- this.cl = cl
+ constructor(L) {
+ this.L = L;
+ }
+
+ RA(base, a) {
+ return base + a;
+ }
+
+ RB(base, opcode, base, b) {
+ return base + b;
+ }
+
+ RC(base, c) {
+ return base + c;
+ }
+
+ RKB(base, k, b) {
+ return OC.ISK(b) ? k[OC.INDEXK(b)] : base + b;
+ }
+
+ RKC(base, k, c) {
+ return OC.ISK(c) ? k[OC.INDEXK(c)] : base + c;
}
execute() {
+ let L = this.L;
+ let ci = L.ci[this.L.ciOff];
+
newframe:
+ let cl = ci.func;
+ let k = cl.p.k;
+ let base = ci.base;
+
for (;;) {
+ let i = ci.savedpc[ci.pcOff++];
+ let ra = this.RA(base, i.a);
+ switch (OC.OpCodes[i.opcode]) {
+ case "OP_MOVE":
+ break;
+ case "OP_LOADK":
+ break;
+ case "OP_LOADKX":
+ break;
+ case "OP_LOADBOOL":
+ break;
+ case "OP_LOADNIL":
+ break;
+ case "OP_GETUPVAL":
+ break;
+ case "OP_GETTABUP":
+ break;
+ case "OP_GETTABLE":
+ break;
+ case "OP_SETTABUP":
+ break;
+ case "OP_SETUPVAL":
+ break;
+ case "OP_SETTABLE":
+ break;
+ case "OP_NEWTABLE":
+ break;
+ case "OP_SELF":
+ break;
+ case "OP_ADD":
+ break;
+ case "OP_SUB":
+ break;
+ case "OP_MUL":
+ break;
+ case "OP_MOD":
+ break;
+ case "OP_POW":
+ break;
+ case "OP_DIV":
+ break;
+ case "OP_IDIV":
+ break;
+ case "OP_BAND":
+ break;
+ case "OP_BOR":
+ break;
+ case "OP_BXOR":
+ break;
+ case "OP_SHL":
+ break;
+ case "OP_SHR":
+ break;
+ case "OP_UNM":
+ break;
+ case "OP_BNOT":
+ break;
+ case "OP_NOT":
+ break;
+ case "OP_LEN":
+ break;
+ case "OP_CONCAT":
+ break;
+ case "OP_JMP":
+ break;
+ case "OP_EQ":
+ break;
+ case "OP_LT":
+ break;
+ case "OP_LE":
+ break;
+ case "OP_TEST":
+ break;
+ case "OP_TESTSET":
+ break;
+ case "OP_CALL":
+ break;
+ case "OP_TAILCALL":
+ break;
+ case "OP_RETURN":
+ break;
+ case "OP_FORLOOP":
+ break;
+ case "OP_FORPREP":
+ break;
+ case "OP_TFORCALL":
+ break;
+ case "OP_TFORLOOP":
+ break;
+ case "OP_SETLIST":
+ break;
+ case "OP_CLOSURE":
+ break;
+ case "OP_VARARG":
+ break;
+ case "OP_EXTRAARG":
+ break;
+ }
}
}
}
module.exports = {
- LuaVM: LuaVM,
- OpCodes: OpCodes
+ LuaVM: LuaVM
}; \ No newline at end of file