From e602b73c35b74178a1dc36e4b0d0b442e63264d5 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 30 May 2017 16:02:52 +1000 Subject: Introduce function to adjust L.top --- src/lapi.js | 8 +--- src/ldo.js | 27 ++++++------- src/lvm.js | 128 +++++++----------------------------------------------------- 3 files changed, 29 insertions(+), 134 deletions(-) diff --git a/src/lapi.js b/src/lapi.js index ceafa4a..4b5be04 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -151,13 +151,7 @@ const lua_settop = function(L, idx) { assert(-(idx + 1) <= L.top - (func + 1), "invalid new top"); newtop = L.top + idx + 1; /* 'subtract' index (index is negative) */ } - if (L.top < newtop) { - while (L.top < newtop) - L.stack[L.top++] = new TValue(CT.LUA_TNIL, null); - } else { - while (L.top > newtop) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, newtop); }; const lua_pop = function(L, n) { diff --git a/src/ldo.js b/src/ldo.js index 0f7a2d3..5e3e30a 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -21,6 +21,16 @@ const lzio = require('./lzio.js'); const CT = defs.constant_types; const TS = defs.thread_status; +const adjust_top = function(L, newtop) { + if (L.top < newtop) { + while (L.top < newtop) + L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); + } else { + while (L.top > newtop) + delete L.stack[--L.top]; + } +}; + const seterrorobj = function(L, errcode, oldtop) { let current_top = L.top; @@ -159,13 +169,7 @@ const luaD_precall = function(L, off, nresults) { ci.func = func; ci.l_base = base; ci.top = base + fsize; - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + adjust_top(L, ci.top); ci.l_code = p.code; ci.l_savedpc = 0; ci.callstatus = lstate.CIST_LUA; @@ -263,13 +267,7 @@ const luaD_hook = function(L, event, line) { assert(!L.allowhook); L.allowhook = 1; ci.top = ci_top; - if (L.top < top) { - while (L.top < top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > top) - delete L.stack[--L.top]; - } + adjust_top(L, top); ci.callstatus &= ~lstate.CIST_HOOKED; } }; @@ -693,6 +691,7 @@ const luaD_protectedparser = function(L, z, name, mode) { return status; }; +module.exports.adjust_top = adjust_top; module.exports.luaD_call = luaD_call; module.exports.luaD_callnoyield = luaD_callnoyield; module.exports.luaD_checkstack = luaD_checkstack; diff --git a/src/lvm.js b/src/lvm.js index 409f99f..29e646e 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -62,39 +62,17 @@ const luaV_finishOp = function(L) { } /* move final result to final position */ lobject.setobjs2s(L, ci.l_base + inst.A, L.top - 1); - /* restore top */ - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, ci.top); /* restore top */ break; } case OCi.OP_TFORCALL: { assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_TFORLOOP); - /* correct top */ - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, ci.top); /* correct top */ break; } case OCi.OP_CALL: { - if (inst.C - 1 >= 0) { /* nresults >= 0? */ - /* adjust results */ - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } - } + if (inst.C - 1 >= 0) /* nresults >= 0? */ + ldo.adjust_top(L, ci.top); /* adjust results */ break; } } @@ -424,14 +402,7 @@ const luaV_execute = function(L) { luaV_concat(L, c - b + 1); let rb = base + b; lobject.setobjs2s(L, ra, rb); - /* restore top */ - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, ci.top); /* restore top */ break; } case OCi.OP_JMP: { @@ -480,27 +451,10 @@ const luaV_execute = function(L) { case OCi.OP_CALL: { let b = i.B; let nresults = i.C - 1; - - if (b !== 0) { - if (L.top < ra+b) { - while (L.top < ra+b) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ra+b) - delete L.stack[--L.top]; - } - } - + if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */ if (ldo.luaD_precall(L, ra, nresults)) { - if (nresults >= 0) { - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } - } + if (nresults >= 0) + ldo.adjust_top(L, ci.top); /* adjust results */ } else { ci = L.ci; continue newframe; @@ -510,15 +464,7 @@ const luaV_execute = function(L) { } case OCi.OP_TAILCALL: { let b = i.B; - if (b !== 0) { - if (L.top < ra+b) { - while (L.top < ra+b) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ra+b) - delete L.stack[--L.top]; - } - } /* else previous instruction set top */ + if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */ if (ldo.luaD_precall(L, ra, LUA_MULTRET)) { // JS function } else { /* tail call: put called frame (n) in place of caller one (o) */ @@ -533,13 +479,7 @@ const luaV_execute = function(L) { lobject.setobjs2s(L, ofuncOff + aux, nfuncOff + aux); oci.l_base = ofuncOff + (nci.l_base - nfuncOff); oci.top = ofuncOff + (L.top - nfuncOff); - if (L.top < nci.top) { - while (L.top < oci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > oci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, oci.top); /* correct top */ oci.l_code = nci.l_code; oci.l_savedpc = nci.l_savedpc; oci.callstatus |= lstate.CIST_TAIL; @@ -560,15 +500,7 @@ const luaV_execute = function(L) { return; /* external invocation: return */ /* invocation via reentry: continue execution */ ci = L.ci; - if (b) { - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } - } + if (b) ldo.adjust_top(L, ci.top); assert(ci.callstatus & lstate.CIST_LUA); assert(ci.l_code[ci.l_savedpc - 1].opcode === OCi.OP_CALL); continue newframe; @@ -628,22 +560,9 @@ const luaV_execute = function(L) { lobject.setobjs2s(L, cb+2, ra+2); lobject.setobjs2s(L, cb+1, ra+1); lobject.setobjs2s(L, cb, ra); - /* func. + 2 args (state and index) */ - if (L.top < cb + 3) { - while (L.top < cb + 3) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > cb + 3) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, cb+3); /* func. + 2 args (state and index) */ ldo.luaD_call(L, cb, i.C); - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, ci.top); /* go straight to OP_TFORLOOP */ i = ci.l_code[ci.l_savedpc++]; ra = RA(L, base, i); @@ -674,15 +593,7 @@ const luaV_execute = function(L) { for (; n > 0; n--) { ltable.luaH_setint(h, last--, L.stack[ra + n]); } - - /* correct top (in case of previous open call) */ - if (L.top < ci.top) { - while (L.top < ci.top) - L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); - } else { - while (L.top > ci.top) - delete L.stack[--L.top]; - } + ldo.adjust_top(L, ci.top); /* correct top (in case of previous open call) */ break; } case OCi.OP_CLOSURE: { @@ -705,16 +616,7 @@ const luaV_execute = function(L) { if (b < 0) { b = n; /* get all var. arguments */ ldo.luaD_checkstack(L, n); - if (L.top >= ra+n) { - while (L.top > ra+n) - delete L.stack[--L.top]; - } else { - while (L.top < ra+n) { - L.stack[L.top] = new lobject.TValue(); - L.top++; - } - } - assert(L.top == ra + n); + ldo.adjust_top(L, ra + n); } for (j = 0; j < b && j < n; j++) -- cgit v1.2.3-70-g09d2