diff options
-rw-r--r-- | ldebug.c | 22 | ||||
-rw-r--r-- | ldebug.h | 1 | ||||
-rw-r--r-- | lstate.h | 2 | ||||
-rw-r--r-- | lvm.c | 13 |
4 files changed, 27 insertions, 11 deletions
@@ -866,6 +866,28 @@ static int changedline (const Proto *p, int oldpc, int newpc) { | |||
866 | 866 | ||
867 | 867 | ||
868 | /* | 868 | /* |
869 | ** Traces Lua calls. If code is running the first instruction of a function, | ||
870 | ** and function is not vararg, and it is not coming from an yield, | ||
871 | ** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall' | ||
872 | ** after adjusting its variable arguments; otherwise, they could call | ||
873 | ** a line/count hook before the call hook. Functions coming from | ||
874 | ** an yield already called 'luaD_hookcall' before yielding.) | ||
875 | */ | ||
876 | int luaG_tracecall (lua_State *L) { | ||
877 | CallInfo *ci = L->ci; | ||
878 | Proto *p = ci_func(ci)->p; | ||
879 | ci->u.l.trap = 1; /* ensure hooks will be checked */ | ||
880 | if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */ | ||
881 | if (p->is_vararg) | ||
882 | return 0; /* hooks will start at VARARGPREP instruction */ | ||
883 | else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */ | ||
884 | luaD_hookcall(L, ci); /* check 'call' hook */ | ||
885 | } | ||
886 | return 1; /* keep 'trap' on */ | ||
887 | } | ||
888 | |||
889 | |||
890 | /* | ||
869 | ** Traces the execution of a Lua function. Called before the execution | 891 | ** Traces the execution of a Lua function. Called before the execution |
870 | ** of each opcode, when debug is on. 'L->oldpc' stores the last | 892 | ** of each opcode, when debug is on. 'L->oldpc' stores the last |
871 | ** instruction traced, to detect line changes. When entering a new | 893 | ** instruction traced, to detect line changes. When entering a new |
@@ -58,6 +58,7 @@ LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, | |||
58 | TString *src, int line); | 58 | TString *src, int line); |
59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); | 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); |
60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); | 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); |
61 | LUAI_FUNC int luaG_tracecall (lua_State *L); | ||
61 | 62 | ||
62 | 63 | ||
63 | #endif | 64 | #endif |
@@ -181,7 +181,7 @@ struct CallInfo { | |||
181 | union { | 181 | union { |
182 | struct { /* only for Lua functions */ | 182 | struct { /* only for Lua functions */ |
183 | const Instruction *savedpc; | 183 | const Instruction *savedpc; |
184 | volatile l_signalT trap; | 184 | volatile l_signalT trap; /* function is tracing lines/counts */ |
185 | int nextraargs; /* # of extra arguments in vararg functions */ | 185 | int nextraargs; /* # of extra arguments in vararg functions */ |
186 | } l; | 186 | } l; |
187 | struct { /* only for C functions */ | 187 | struct { /* only for C functions */ |
@@ -1157,18 +1157,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1157 | startfunc: | 1157 | startfunc: |
1158 | trap = L->hookmask; | 1158 | trap = L->hookmask; |
1159 | returning: /* trap already set */ | 1159 | returning: /* trap already set */ |
1160 | cl = clLvalue(s2v(ci->func.p)); | 1160 | cl = ci_func(ci); |
1161 | k = cl->p->k; | 1161 | k = cl->p->k; |
1162 | pc = ci->u.l.savedpc; | 1162 | pc = ci->u.l.savedpc; |
1163 | if (l_unlikely(trap)) { | 1163 | if (l_unlikely(trap)) |
1164 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ | 1164 | trap = luaG_tracecall(L); |
1165 | if (cl->p->is_vararg) | ||
1166 | trap = 0; /* hooks will start after VARARGPREP instruction */ | ||
1167 | else /* check 'call' hook */ | ||
1168 | luaD_hookcall(L, ci); | ||
1169 | } | ||
1170 | ci->u.l.trap = 1; /* assume trap is on, for now */ | ||
1171 | } | ||
1172 | base = ci->func.p + 1; | 1165 | base = ci->func.p + 1; |
1173 | /* main loop of interpreter */ | 1166 | /* main loop of interpreter */ |
1174 | for (;;) { | 1167 | for (;;) { |