diff options
author | Benoit Giannangeli <giann008@gmail.com> | 2017-04-14 08:59:00 +0200 |
---|---|---|
committer | Benoit Giannangeli <giann008@gmail.com> | 2017-04-14 11:06:19 +0200 |
commit | 43c97cbc2904d2bac87c61515bbc16c38a091548 (patch) | |
tree | 31dee0450518dc6a6aebd913e450bcd8ed4131b2 /src/ldo.js | |
parent | fd613ef1da5e3eeb10d13351ccf217e33b30b1dd (diff) | |
download | fengari-43c97cbc2904d2bac87c61515bbc16c38a091548.tar.gz fengari-43c97cbc2904d2bac87c61515bbc16c38a091548.tar.bz2 fengari-43c97cbc2904d2bac87c61515bbc16c38a091548.zip |
hooks
Diffstat (limited to 'src/ldo.js')
-rw-r--r-- | src/ldo.js | 38 |
1 files changed, 37 insertions, 1 deletions
@@ -73,7 +73,8 @@ const luaD_precall = function(L, off, nresults) { ci.funcOff = off; ci.top = L.top + lua.LUA_MINSTACK; ci.callstatus = 0; - // TODO: hook + if (L.hookmask & lua.LUA_MASKCALL) + luaD_hook(L, lua.LUA_HOOKCALL, -1); let n = f(L); /* do the actual call */ assert(n < L.top - L.ci.funcOff, "not enough elements in the stack"); @@ -129,6 +130,13 @@ const luaD_precall = function(L, off, nresults) { const luaD_poscall = function(L, ci, firstResult, nres) { let wanted = ci.nresults; + + if (L.hookmask & (lua.LUA_MASKRET | lua.LUA_MASKLINE)) { + if (L.hookmask & lua.LUA_MASKRET) + luaD_hook(L, lua.LUA_HOOKRET, -1); + L.oldpc = ci.previous.pcOff; /* 'oldpc' for caller function */ + } + let res = ci.funcOff; L.ci = ci.previous; L.ciOff--; @@ -171,6 +179,33 @@ const moveresults = function(L, firstResult, res, nres, wanted) { return true; }; +/* +** Call a hook for the given event. Make sure there is a hook to be +** called. (Both 'L->hook' and 'L->hookmask', which triggers this +** function, can be changed asynchronously by signals.) +*/ +const luaD_hook = function(L, event, line) { + let hook = L.hook; + if (hook && L.allowhook) { /* make sure there is a hook */ + let ci = L.ci; + let top = L.top; + let ci_top = ci.top; + let ar = new lua.lua_Debug(); + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + ci.top = L.top + lua.LUA_MINSTACK; + L.allowhook = 0; /* cannot call hooks inside a hook */ + ci.callstatus |= lstate.CIST_HOOKED; + hook(L, ar); + assert(!L.allowhook); + L.allowhook = 1; + ci.top = ci_top; + L.top = top; + ci.callstatus &= ~lstate.CIST_HOOKED; + } +}; + const adjust_varargs = function(L, p, actual) { let nfixargs = p.numparams; /* move fixed parameters to final position */ @@ -566,6 +601,7 @@ module.exports.SParser = SParser; module.exports.adjust_varargs = adjust_varargs; module.exports.luaD_call = luaD_call; module.exports.luaD_callnoyield = luaD_callnoyield; +module.exports.luaD_hook = luaD_hook; module.exports.luaD_pcall = luaD_pcall; module.exports.luaD_poscall = luaD_poscall; module.exports.luaD_precall = luaD_precall; |