summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-02-11 16:10:47 +0100
committerBenoit Giannangeli <giann008@gmail.com>2017-02-11 16:18:42 +0100
commit51ffdbeb0cfc206692ea4e5f71d1fe6d10f61455 (patch)
tree8a3b79c1bbeb63c785f4c6d61e882f5be26ad3ca /src
parent4650ac9ab96eadcd5918c56c6eb93618ac054bba (diff)
downloadfengari-51ffdbeb0cfc206692ea4e5f71d1fe6d10f61455.tar.gz
fengari-51ffdbeb0cfc206692ea4e5f71d1fe6d10f61455.tar.bz2
fengari-51ffdbeb0cfc206692ea4e5f71d1fe6d10f61455.zip
SETLIST
Diffstat (limited to 'src')
-rw-r--r--src/lopcodes.js48
-rw-r--r--src/lvm.js18
2 files changed, 44 insertions, 22 deletions
diff --git a/src/lopcodes.js b/src/lopcodes.js
index 05eb0d5..383e9c5 100644
--- a/src/lopcodes.js
+++ b/src/lopcodes.js
@@ -80,27 +80,31 @@ const INDEXK = function (r) {
return r & ~BITRK;
}
+/* number of list items to accumulate before a SETLIST instruction */
+const LFIELDS_PER_FLUSH = 50
+
module.exports = {
- OpCodes: OpCodes,
- SIZE_C: SIZE_C,
- SIZE_B: SIZE_B,
- SIZE_Bx: SIZE_Bx,
- SIZE_A: SIZE_A,
- SIZE_Ax: SIZE_Ax,
- SIZE_OP: SIZE_OP,
- POS_OP: POS_OP,
- POS_A: POS_A,
- POS_C: POS_C,
- POS_B: POS_B,
- POS_Bx: POS_Bx,
- POS_Ax: POS_Ax,
- MAXARG_Bx: MAXARG_Bx,
- MAXARG_sBx: MAXARG_sBx,
- MAXARG_Ax: MAXARG_Ax,
- MAXARG_A: MAXARG_A,
- MAXARG_B: MAXARG_B,
- MAXARG_C: MAXARG_C,
- BITRK: BITRK,
- ISK: ISK,
- INDEXK: INDEXK
+ OpCodes: OpCodes,
+ SIZE_C: SIZE_C,
+ SIZE_B: SIZE_B,
+ SIZE_Bx: SIZE_Bx,
+ SIZE_A: SIZE_A,
+ SIZE_Ax: SIZE_Ax,
+ SIZE_OP: SIZE_OP,
+ POS_OP: POS_OP,
+ POS_A: POS_A,
+ POS_C: POS_C,
+ POS_B: POS_B,
+ POS_Bx: POS_Bx,
+ POS_Ax: POS_Ax,
+ MAXARG_Bx: MAXARG_Bx,
+ MAXARG_sBx: MAXARG_sBx,
+ MAXARG_Ax: MAXARG_Ax,
+ MAXARG_A: MAXARG_A,
+ MAXARG_B: MAXARG_B,
+ MAXARG_C: MAXARG_C,
+ BITRK: BITRK,
+ ISK: ISK,
+ INDEXK: INDEXK,
+ LFIELDS_PER_FLUSH: LFIELDS_PER_FLUSH
}; \ No newline at end of file
diff --git a/src/lvm.js b/src/lvm.js
index 7ca6921..bd3e2c4 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -559,6 +559,24 @@ class LuaVM {
break;
}
case "OP_SETLIST": {
+ let n = i.B;
+ let c = i.C;
+
+ if (n === 0) n = L.top - ra - 1;
+
+ if (c === 0) {
+ assert(OC.OpCodes[ci.u.l.savedpc[ci.pcOff].opcode] === "OP_EXTRAARG");
+ c = ci.u.l.savedpc[ci.pcOff++].Ax;
+ }
+
+ let table = L.stack[ra].value;
+ let last = ((c - 1) * OC.LFIELDS_PER_FLUSH) + n;
+
+ for (; n > 0; n--) {
+ table.array[last--] = L.stack[ra + n];
+ }
+
+ L.top = ci.top; /* correct top (in case of previous open call) */
break;
}
case "OP_CLOSURE": {