From 4bf190d1b51c8c2d3f5ab0b6355ecd971b735adc Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Sat, 11 Feb 2017 22:22:38 +0100 Subject: TFORCALL, TFORLOOP, luaD_call, tag methods --- src/ldo.js | 81 ++++++++++++++++++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 45 deletions(-) (limited to 'src/ldo.js') diff --git a/src/ldo.js b/src/ldo.js index 488bc86..85bd3d3 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -1,23 +1,21 @@ /*jshint esversion: 6 */ "use strict"; -const OC = require('./lopcodes.js'); const lua = require('./lua.js'); const CT = lua.constant_types; const LUA_MULTRET = lua.LUA_MULTRET; const lobject = require('./lobject.js'); const TValue = lobject.TValue; -const Table = lobject.Table; -const LClosure = lobject.LClosure; -const lfunc = require('./lfunc.js'); -const UpVal = lfunc.UpVal; const lstate = require('./lstate.js'); const CallInfo = lstate.CallInfo; const llimit = require('./llimit.js'); +const ltm = require('./ltm.js'); +const TMS = ltm.TMS; const nil = new TValue(CT.LUA_TNIL, null); -const precall = function(L, off, func, nresults) { +const luaD_precall = function(L, off, nresults) { + let func = L.stack[off]; let ci; switch(func.type) { @@ -56,28 +54,30 @@ const precall = function(L, off, func, nresults) { } ci.nresults = nresults; ci.func = func; + ci.funcOff = off; ci.u.l.base = base; ci.top = base + fsize; L.top = ci.top; ci.u.l.savedpc = p.code; + ci.pcOff = 0; ci.callstatus = lstate.CIST_LUA; return false; break; } default: - // __call - return false; + tryfuncTM(L, off, func); + return luaD_precall(L, off, nresults); } -} +}; -const postcall = function(L, ci, firstResult, nres) { +const luaD_poscall = function(L, ci, firstResult, nres) { let wanted = ci.nresults; let res = ci.funcOff; L.ci = ci.previous; L.ciOff--; return moveresults(L, firstResult, res, nres, wanted); -} +}; const moveresults = function(L, firstResult, res, nres, wanted) { switch (wanted) { @@ -98,7 +98,11 @@ const moveresults = function(L, firstResult, res, nres, wanted) { default: { let i; if (wanted <= nres) { - for (i = 0; i < wanted; i++) + for (i = 0; i < wanted; i++) { + L.stack[res + i] = L.stack[firstResult + i]; + } + } else { + for (i = 0; i < nres; i++) L.stack[res + i] = L.stack[firstResult + i]; for (; i < wanted; i++) L.stack[res + i] = nil; @@ -107,8 +111,9 @@ const moveresults = function(L, firstResult, res, nres, wanted) { } } + L.top = res + wanted; /* top points after the last result */ return true; -} +}; const adjust_varargs = function(L, p, actual) { let nfixargs = p.numparams; @@ -126,38 +131,24 @@ const adjust_varargs = function(L, p, actual) { L.stack[L.top++] = nil; return base; +}; + +const tryfuncTM = function(L, off, func) { + let tm = ltm.luaT_gettmbyobj(L, func, TMS.TM_CALL); + if (!tm.ttisfunction(tm)) + throw new Error("__call metatable member is not a function") // TODO: luaG_typeerror + /* Open a hole inside the stack at 'func' */ + for (p = L.top; p > off; p--) + L.stack[p] = L.stack[p-1]; + L.top++; /* slot ensured by caller */ + L.stack[off] = tm; /* tag method is the new function to be called */ } - -/* -** Check appropriate error for stack overflow ("regular" overflow or -** overflow while handling stack overflow). If 'nCalls' is larger than -** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but -** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to -** allow overflow handling to work) -*/ -const stackerror = function(L) { - if (L.nCcalls === LUAI_MAXCCALLS) - throw new Error("JS stack overflow"); - else if (L.nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) /* error while handing stack error */ - throw new Error("stack overflow") // TODO: luaD_throw(L, LUA_ERRERR); -} - -/* -** Call a function (JS or Lua). The function to be called is at func. -** The arguments are on the stack, right after the function. -** When returns, all the results are on the stack, starting at the original -** function position. -*/ -// const luaD_call = function(L, func, nResults) { -// if (++L->nCcalls >= LUAI_MAXCCALLS) -// stackerror(L); -// if () -// } - module.exports = { - precall: precall, - postcall: postcall, - moveresults: moveresults, - adjust_varargs: adjust_varargs -} \ No newline at end of file + nil: nil, + luaD_precall: luaD_precall, + luaD_poscall: luaD_poscall, + moveresults: moveresults, + adjust_varargs: adjust_varargs, + tryfuncTM: tryfuncTM +}; \ No newline at end of file -- cgit v1.2.3-54-g00ecf