aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-05-29 13:28:24 +1000
committerdaurnimator <quae@daurnimator.com>2017-05-29 13:43:11 +1000
commitb3f5b92b221c0ad8a94b8cb95081bb85d235c39f (patch)
treeddfacca952778520fe74976a88bd97b3cdb68785 /src
parent587b5c78d193426410c45c6f055272acf4a8bc7c (diff)
downloadfengari-b3f5b92b221c0ad8a94b8cb95081bb85d235c39f.tar.gz
fengari-b3f5b92b221c0ad8a94b8cb95081bb85d235c39f.tar.bz2
fengari-b3f5b92b221c0ad8a94b8cb95081bb85d235c39f.zip
Have lua closures point to directly to their upvalues on stack
Diffstat (limited to 'src')
-rw-r--r--src/lapi.js4
-rw-r--r--src/ldebug.js2
-rw-r--r--src/lfunc.js39
-rw-r--r--src/lvm.js26
4 files changed, 31 insertions, 40 deletions
diff --git a/src/lapi.js b/src/lapi.js
index f24c4af..529a009 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -538,7 +538,7 @@ const aux_upvalue = function(L, fi, n) {
let name = p.upvalues[n-1].name;
return {
name: name ? name.getstr() : defs.to_luastring("(*no name)", true),
- val: f.upvals[n-1].val()
+ val: f.upvals[n-1].v
};
}
default: return null; /* not a closure */
@@ -926,7 +926,7 @@ const lua_load = function(L, reader, data, chunkname, mode) {
/* get global table from registry */
let gt = ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
- f.upvals[0].value.setfrom(gt);
+ f.upvals[0].v.setfrom(gt);
}
}
return status;
diff --git a/src/ldebug.js b/src/ldebug.js
index 45d126f..510221f 100644
--- a/src/ldebug.js
+++ b/src/ldebug.js
@@ -518,7 +518,7 @@ const isinstack = function(L, ci, o) {
const getupvalname = function(L, ci, o) {
let c = ci.func.value;
for (let i = 0; i < c.nupvalues; i++) {
- if (c.upvals[i].val() === o) {
+ if (c.upvals[i].v === o) {
return {
name: upvalname(c.p, i),
funcname: defs.to_luastring('upvalue', true)
diff --git a/src/lfunc.js b/src/lfunc.js
index 663f614..97e5f02 100644
--- a/src/lfunc.js
+++ b/src/lfunc.js
@@ -30,19 +30,14 @@ class Proto {
class UpVal {
constructor() {
- this.L = null; /* Keep track of the thread it comes from */
- this.v = null; /* if open: stack index. if closed: null (find it in this.value) */
- this.open_next = null; /* linked list (when open) */
+ this.v = void 0; /* if open: reference to TValue on stack. if closed: TValue */
+ this.vOff = void 0; /* if open: index on stack. if closed: undefined */
this.refcount = 0;
- this.value = null; /* the TValue (when closed) */
- }
-
- val() {
- return this.v !== null ? this.L.stack[this.v] : this.value;
+ this.open_next = null; /* linked list (when open) */
}
isopen() {
- return this.v !== null;
+ return this.vOff !== void 0;
}
}
@@ -56,9 +51,9 @@ const luaF_newLclosure = function(L, n) {
const luaF_findupval = function(L, level) {
let prevp;
let p = L.openupval;
- while (p !== null && p.v >= level) {
+ while (p !== null && p.vOff >= level) {
assert(p.isopen());
- if (p.v === level) /* found a corresponding upvalue? */
+ if (p.vOff === level) /* found a corresponding upvalue? */
return p; /* return it */
prevp = p;
p = p.open_next;
@@ -71,23 +66,25 @@ const luaF_findupval = function(L, level) {
prevp.open_next = uv;
else
L.openupval = uv;
- /* current value lives in the stack */
- uv.L = L;
- uv.v = level;
+ uv.v = L.stack[level]; /* current value lives in the stack */
+ uv.vOff = level;
return uv;
};
const luaF_close = function(L, level) {
- while (L.openupval !== null && L.openupval.v >= level) {
+ while (L.openupval !== null && L.openupval.vOff >= level) {
let uv = L.openupval;
assert(uv.isopen());
L.openupval = uv.open_next; /* remove from 'open' list */
- if (uv.refcount > 0) {
- let from = uv.L.stack[uv.v];
- uv.L = null;
- uv.v = null;
- uv.value = new lobject.TValue(from.type, from.value);
+ if (uv.refcount === 0) { /* no references? */
+ /* free upvalue */
+ uv.v = void 0;
+ uv.open_next = null;
+ } else {
+ let from = uv.v;
+ uv.v = new lobject.TValue(from.type, from.value);
}
+ uv.vOff = void 0;
}
};
@@ -98,7 +95,7 @@ const luaF_initupvals = function(L, cl) {
for (let i = 0; i < cl.nupvalues; i++) {
let uv = new UpVal(L);
uv.refcount = 1;
- uv.value = new lobject.TValue(CT.LUA_TNIL, null);
+ uv.v = new lobject.TValue(CT.LUA_TNIL, null);
cl.upvals[i] = uv;
}
};
diff --git a/src/lvm.js b/src/lvm.js
index af8984f..b7b1358 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -171,32 +171,26 @@ const luaV_execute = function(L) {
break;
}
case OCi.OP_GETUPVAL: {
- let o = cl.upvals[i.B].val();
- lobject.setobj2s(L, ra, o);
+ let b = i.B;
+ lobject.setobj2s(L, ra, cl.upvals[b].v);
break;
}
case OCi.OP_SETUPVAL: {
let uv = cl.upvals[i.B];
- if (uv.isopen()) {
- uv.L.stack[uv.v].setfrom(L.stack[ra]);
- } else {
- uv.value.setfrom(L.stack[ra]);
- }
+ uv.v.setfrom(L.stack[ra]);
break;
}
case OCi.OP_GETTABUP: {
- let table = cl.upvals[i.B].val();
- let key = RKC(L, base, k, i);
-
- gettable(L, table, key, ra);
+ let upval = cl.upvals[i.B].v;
+ let rc = RKC(L, base, k, i);
+ gettable(L, upval, rc, ra);
break;
}
case OCi.OP_SETTABUP: {
- let table = cl.upvals[i.A].val();
- let key = RKB(L, base, k, i);
- let v = RKC(L, base, k, i);
-
- settable(L, table, key, v);
+ let upval = cl.upvals[i.A].v;
+ let rb = RKB(L, base, k, i);
+ let rc = RKC(L, base, k, i);
+ settable(L, upval, rb, rc);
break;
}
case OCi.OP_GETTABLE: {