From 0e5585bd7078d6727382c0de51161fe377c1d81d Mon Sep 17 00:00:00 2001 From: daurnimator Date: Fri, 5 May 2017 17:08:04 +1000 Subject: Simplify UpVal structure No longer follows C api as closely (it is the way it is because C has unions) Instead, have a flat object. Also remove the 'setval' method, as it wasn't used from all call-sites and couldn't be extended to them (setval's body only worked with source TValue on a stack) --- src/lapi.js | 3 +-- src/lfunc.js | 43 +++++++++++++++---------------------------- src/lvm.js | 7 ++++++- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/lapi.js b/src/lapi.js index d3e4119..9347d84 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -822,7 +822,7 @@ const lua_load = function(L, reader, data, chunckname, 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].u.value = new TValue(gt.type, gt.value); + f.upvals[0].value.setfrom(gt); } } return status; @@ -1001,7 +1001,6 @@ const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) { let f1 = ref1.closure; f1.upvals[up1] = up2; - up2.u.open.touched = true; // TODO: useful }; // This functions are only there for compatibility purposes diff --git a/src/lfunc.js b/src/lfunc.js index 0b78bd3..cf2cfe0 100644 --- a/src/lfunc.js +++ b/src/lfunc.js @@ -28,29 +28,16 @@ class Proto { class UpVal { - constructor(L) { - this.L = L; // Keep track of the thread it comes from - this.v = null; /* if open: stack index. if closed: null (find value in this.u.value) */ + 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.refcount = 0; - this.u = { - open: { /* (when open) */ - next: null, /* linked list */ - touched: false /* mark to avoid cycles with dead threads */ - }, - value: null /* the value (when closed) */ - }; + this.value = null; /* the TValue (when closed) */ } val() { - return this.v !== null ? this.L.stack[this.v] : this.u.value; - } - - setval(L, ra) { - if (this.v !== null) { - this.L.stack[this.v] = L.stack[ra]; - } else { - this.u.value.setfrom(L.stack[ra]); - } + return this.v !== null ? this.L.stack[this.v] : this.value; } isopen() { @@ -67,22 +54,22 @@ const luaF_newLclosure = function(L, n) { const findupval = function(L, level) { let pp = L.openupval; - + while(pp !== null && pp.v >= level) { let p = pp; if (p.v === level) return p; - pp = p.u.open.next; + pp = p.open_next; } - let uv = new UpVal(L); - uv.u.open.next = pp; - uv.u.open.touched = true; + let uv = new UpVal(); + uv.open_next = pp; L.openupval = uv; + uv.L = L; uv.v = level; return uv; @@ -92,11 +79,12 @@ const luaF_close = function(L, level) { while (L.openupval !== null && L.openupval.v >= level) { let uv = L.openupval; assert(uv.isopen()); - L.openupval = uv.u.open.next; /* remove from 'open' list */ + L.openupval = uv.open_next; /* remove from 'open' list */ if (uv.refcount > 0) { let from = uv.L.stack[uv.v]; - uv.u.value = new lobject.TValue(from.type, from.value); + uv.L = null; uv.v = null; + uv.value = new lobject.TValue(from.type, from.value); } } }; @@ -108,8 +96,7 @@ const luaF_initupvals = function(L, cl) { for (let i = 0; i < cl.nupvalues; i++) { let uv = new UpVal(L); uv.refcount = 1; - uv.u.value = new lobject.TValue(CT.LUA_TNIL, null); - uv.v = null; + uv.value = new lobject.TValue(CT.LUA_TNIL, null); cl.upvals[i] = uv; } }; diff --git a/src/lvm.js b/src/lvm.js index bd38575..d45ecec 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -166,7 +166,12 @@ const luaV_execute = function(L) { break; } case OCi.OP_SETUPVAL: { - cl.upvals[i.B].setval(L, ra); + let uv = cl.upvals[i.B]; + if (uv.v !== null) { + uv.L.stack[uv.v] = L.stack[ra]; + } else { + uv.value.setfrom(L.stack[ra]); + } break; } case OCi.OP_GETTABUP: { -- cgit v1.2.3-54-g00ecf