diff options
Diffstat (limited to 'src/ltm.js')
-rw-r--r-- | src/ltm.js | 97 |
1 files changed, 96 insertions, 1 deletions
@@ -4,7 +4,102 @@ const lobject = require('./lobject.js'); const TValue = lobject.TValue; const Table = lobject.Table; +const ldo = require('./ldo.js'); +const lstate = require('./lstate.js'); +const lua = require('./lua.js'); +const CT = lua.constant_types; +const TMS = { + TM_INDEX: "__index", + TM_NEWINDEX: "__newindex", + TM_GC: "__gc", + TM_MODE: "__mode", + TM_LEN: "__len", + TM_EQ: "__eq", /* last tag method with fast access */ + TM_ADD: "__add", + TM_SUB: "__sub", + TM_MUL: "__mul", + TM_MOD: "__mod", + TM_POW: "__pow", + TM_DIV: "__div", + TM_IDIV: "__idiv", + TM_BAND: "__band", + TM_BOR: "__bor", + TM_BXOR: "__bxor", + TM_SHL: "__shl", + TM_SHR: "__shr", + TM_UNM: "__unm", + TM_BNOT: "__bnot", + TM_LT: "__lt", + TM_LE: "__le", + TM_CONCAT: "__concat", + TM_CALL: "__call", + TM_N: 26 +}; -module.exports = {}
\ No newline at end of file +const luaT_callTM = function(L, f, p1, p2, p3, hasres) { + let result = p3; + let func = L.top; + + L.stack[L.top] = f; /* push function (assume EXTRA_STACK) */ + L.stack[L.top + 1] = p1; /* 1st argument */ + L.stack[L.top + 2] = p2; /* 2nd argument */ + L.top += 3; + + if (!hasres) /* no result? 'p3' is third argument */ + L.stack[L.top++] = p3; /* 3rd argument */ + + if (ci.callstatus & lstate.CIST_LUA) + ldo.luaD_call(L, func, hasres); + else + ldo.luaD_callnoyield(L, func, hasres); + + if (hasres) { + L.stack[result] = L.stack[--L.top]; + } +}; + +const luaT_callbinTM = function(L, p1, p2, res, event) { + let tm = luaT_gettmbyobj(L, p1, event); + if (tm.ttisnil()) + tm = luaT_gettmbyobj(L, p2, event); + if (tm.ttisnil()) return false; + luaT_callTM(L, tm, p1, p2, res, 1); + return true; +} + +const luaT_trybinTM = function(L, p1, p2, res, event) { + if (!luaT_gettmbyobj(L, p1, p2, res, event)) { + throw new Error("TM error"); // TODO: luaG_error + } +} + +const luaT_callorderTM = function(L, p1, p2, event) { + if (!luaT_callbinTM(L, p2, p2, L.top, event)) + return -1; + else + return !l_isfalse(L.stack[L.top]) ? 1 : 0; +} + +const luaT_gettmbyobj = function(L, o, event) { + let mt; + switch(o.ttnov()) { + case CT.LUA_TTABLE: + case CT.LUA_TTUSERDATA: + mt = o.value.metatable; + default: + // TODO: mt = G(L)->mt[ttnov(o)]; + } + + return mt ? mt.__index(mt, event) : ldo.nil; +} + +module.exports = { + TMS: TMS, + luaT_callTM: luaT_callTM, + luaT_callbinTM: luaT_callbinTM, + luaT_trybinTM: luaT_trybinTM, + luaT_callorderTM: luaT_callorderTM, + luaT_gettmbyobj: luaT_gettmbyobj +}
\ No newline at end of file |