summaryrefslogtreecommitdiff
path: root/src/ldo.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldo.js')
-rw-r--r--src/ldo.js81
1 files changed, 36 insertions, 45 deletions
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