summaryrefslogtreecommitdiff
path: root/src/lfunc.js
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2018-01-29 19:01:22 +1100
committerdaurnimator <quae@daurnimator.com>2018-01-29 22:07:00 +1100
commit313f55905253697fe4966f979865296aeaa7a801 (patch)
treea8f060a377d45943952ade62507951cd4555a21b /src/lfunc.js
parent62b07567d9f39fa746ea35d9c08cd1dcf37dc67a (diff)
downloadfengari-313f55905253697fe4966f979865296aeaa7a801.tar.gz
fengari-313f55905253697fe4966f979865296aeaa7a801.tar.bz2
fengari-313f55905253697fe4966f979865296aeaa7a801.zip
src/: Upvalues are now just TValues (possibly referencing on-stack)
- Removes `Upval` class - closing over upvalues is now done by creating new on-stack TValue objects - No more `openupval` linked list With this fix, upvalues from collected coroutines will no longer keep other values alive Closes #44
Diffstat (limited to 'src/lfunc.js')
-rw-r--r--src/lfunc.js64
1 files changed, 8 insertions, 56 deletions
diff --git a/src/lfunc.js b/src/lfunc.js
index 2f28d0e..198c4b9 100644
--- a/src/lfunc.js
+++ b/src/lfunc.js
@@ -1,7 +1,6 @@
"use strict";
const { constant_types: { LUA_TNIL } } = require('./defs.js');
-const { lua_assert } = require('./llimits.js');
const lobject = require('./lobject.js');
class Proto {
@@ -25,22 +24,6 @@ class Proto {
}
-class UpVal {
-
- constructor(L) {
- this.id = L.l_G.id_counter++;
- 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.open_next = null; /* linked list (when open) */
- }
-
- isopen() {
- return this.vOff !== void 0;
- }
-
-}
-
const luaF_newLclosure = function(L, n) {
let c = new lobject.LClosure(L, n);
return c;
@@ -48,54 +31,24 @@ const luaF_newLclosure = function(L, n) {
const luaF_findupval = function(L, level) {
- let prevp;
- let p = L.openupval;
- while (p !== null && p.vOff >= level) {
- lua_assert(p.isopen());
- if (p.vOff === level) /* found a corresponding upvalue? */
- return p; /* return it */
- prevp = p;
- p = p.open_next;
- }
- /* not found: create a new upvalue */
- let uv = new UpVal(L);
- /* link it to list of open upvalues */
- uv.open_next = p;
- if (prevp)
- prevp.open_next = uv;
- else
- L.openupval = uv;
- uv.v = L.stack[level]; /* current value lives in the stack */
- uv.vOff = level;
- return uv;
+ return L.stack[level];
};
const luaF_close = function(L, level) {
- while (L.openupval !== null && L.openupval.vOff >= level) {
- let uv = L.openupval;
- lua_assert(uv.isopen());
- L.openupval = uv.open_next; /* remove from 'open' list */
- 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;
+ /* Create new TValues on stack;
+ * any closures will keep referencing old TValues */
+ for (let i=level; i<L.top; i++) {
+ let old = L.stack[i];
+ L.stack[i] = new lobject.TValue(old.type, old.value);
}
};
/*
-** fill a closure with new closed upvalues
+** fill a closure with new upvalues
*/
const luaF_initupvals = function(L, cl) {
for (let i = 0; i < cl.nupvalues; i++) {
- let uv = new UpVal(L);
- uv.refcount = 1;
- uv.v = new lobject.TValue(LUA_TNIL, null);
- cl.upvals[i] = uv;
+ cl.upvals[i] = new lobject.TValue(LUA_TNIL, null);
}
};
@@ -117,7 +70,6 @@ const luaF_getlocalname = function(f, local_number, pc) {
module.exports.MAXUPVAL = 255;
module.exports.Proto = Proto;
-module.exports.UpVal = UpVal;
module.exports.luaF_findupval = luaF_findupval;
module.exports.luaF_close = luaF_close;
module.exports.luaF_getlocalname = luaF_getlocalname;