summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-07 08:40:43 +0100
committerBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-07 11:46:03 +0100
commitc7b6e2364b3ff9bed781215f57a6398979b287d4 (patch)
treef8f8f131b61769c76a21b8791dccc78236ead80f
parentba36e0249a7c3209b9cf64aef69d75bce4c4f726 (diff)
downloadfengari-c7b6e2364b3ff9bed781215f57a6398979b287d4.tar.gz
fengari-c7b6e2364b3ff9bed781215f57a6398979b287d4.tar.bz2
fengari-c7b6e2364b3ff9bed781215f57a6398979b287d4.zip
GETUPVAL, SETUPVAL
-rw-r--r--README.md4
-rw-r--r--src/lvm.js15
-rw-r--r--tests/lvm.js31
3 files changed, 43 insertions, 7 deletions
diff --git a/README.md b/README.md
index 67dc810..428f556 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@
- [ ] OP_LOADKX
- [x] OP_LOADBOOL
- [x] OP_LOADNIL
- - [ ] OP_GETUPVAL
+ - [x] OP_GETUPVAL
+ - [x] OP_SETUPVAL
- [ ] OP_GETTABUP
- [ ] OP_GETTABLE
- [ ] OP_SETTABUP
- - [ ] OP_SETUPVAL
- [ ] OP_SETTABLE
- [ ] OP_NEWTABLE
- [ ] OP_SELF
diff --git a/src/lvm.js b/src/lvm.js
index c73e95f..cb2a795 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -70,6 +70,8 @@ class LuaVM {
let i = ci.u.l.savedpc[ci.pcOff++];
let ra = this.RA(base, i);
+ console.log(`Before ${OC.OpCodes[i.opcode]} L.top is ${L.top}`);
+
switch (OC.OpCodes[i.opcode]) {
case "OP_MOVE": {
L.stack[ra] = L.stack[this.RB(base, i)];
@@ -98,15 +100,17 @@ class LuaVM {
break;
}
case "OP_GETUPVAL": {
+ L.stack[ra] = L.stack[cl.upvals[i.B].v];
break;
}
- case "OP_GETTABUP": {
+ case "OP_SETUPVAL": {
+ L.stack[cl.upvals[i.B].v] = L.stack[ra];
break;
}
- case "OP_SETTABUP": {
+ case "OP_GETTABUP": {
break;
}
- case "OP_SETUPVAL": {
+ case "OP_SETTABUP": {
break;
}
case "OP_GETTABLE": {
@@ -442,7 +446,7 @@ class LuaVM {
L.stack[ra] = ncl;
- for (let i = 0; i < nup; i++) { // TODO test
+ for (let i = 0; i < nup; i++) {
if (uv[i].instack)
ncl.upvals[i] = this.findupval(base + uv[i].idx);
else
@@ -571,7 +575,8 @@ class LuaVM {
return true;
}
- findupval(level) { // TODO test
+ findupval(level) {
+ let L = this.L;
let pp = L.openupval;
while(pp !== null && pp.v >= level) {
diff --git a/tests/lvm.js b/tests/lvm.js
index e10ddb2..084a9ad 100644
--- a/tests/lvm.js
+++ b/tests/lvm.js
@@ -270,4 +270,35 @@ test('VARARG', function (t) {
[1, 2, 3],
"Program output is correct"
);
+});
+
+
+test('GETUPVAL, SETUPVAL', function (t) {
+ let luaCode = `
+ local a = 1
+
+ local f = function ()
+ a = a + 1
+ return a
+ end
+
+ f()
+
+ return a
+ `, vm;
+
+ t.plan(2);
+
+ t.comment("Running following code: \n" + luaCode);
+
+ t.doesNotThrow(function () {
+ vm = getVM(luaCode);
+ vm.execute();
+ }, "Program executed without errors");
+
+ t.strictEqual(
+ vm.L.stack[vm.L.top - 1].value,
+ 2,
+ "Program output is correct"
+ );
}); \ No newline at end of file