summaryrefslogtreecommitdiff
path: root/src/ldo.js
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-04-14 08:59:00 +0200
committerBenoit Giannangeli <giann008@gmail.com>2017-04-14 11:06:19 +0200
commit43c97cbc2904d2bac87c61515bbc16c38a091548 (patch)
tree31dee0450518dc6a6aebd913e450bcd8ed4131b2 /src/ldo.js
parentfd613ef1da5e3eeb10d13351ccf217e33b30b1dd (diff)
downloadfengari-43c97cbc2904d2bac87c61515bbc16c38a091548.tar.gz
fengari-43c97cbc2904d2bac87c61515bbc16c38a091548.tar.bz2
fengari-43c97cbc2904d2bac87c61515bbc16c38a091548.zip
hooks
Diffstat (limited to 'src/ldo.js')
-rw-r--r--src/ldo.js38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/ldo.js b/src/ldo.js
index 6a74cad..0fcbf0e 100644
--- a/src/ldo.js
+++ b/src/ldo.js
@@ -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;