1*088332b5SXin Li /*
2*088332b5SXin Li ** $Id: ldebug.c $
3*088332b5SXin Li ** Debug Interface
4*088332b5SXin Li ** See Copyright Notice in lua.h
5*088332b5SXin Li */
6*088332b5SXin Li
7*088332b5SXin Li #define ldebug_c
8*088332b5SXin Li #define LUA_CORE
9*088332b5SXin Li
10*088332b5SXin Li #include "lprefix.h"
11*088332b5SXin Li
12*088332b5SXin Li
13*088332b5SXin Li #include <stdarg.h>
14*088332b5SXin Li #include <stddef.h>
15*088332b5SXin Li #include <string.h>
16*088332b5SXin Li
17*088332b5SXin Li #include "lua.h"
18*088332b5SXin Li
19*088332b5SXin Li #include "lapi.h"
20*088332b5SXin Li #include "lcode.h"
21*088332b5SXin Li #include "ldebug.h"
22*088332b5SXin Li #include "ldo.h"
23*088332b5SXin Li #include "lfunc.h"
24*088332b5SXin Li #include "lobject.h"
25*088332b5SXin Li #include "lopcodes.h"
26*088332b5SXin Li #include "lstate.h"
27*088332b5SXin Li #include "lstring.h"
28*088332b5SXin Li #include "ltable.h"
29*088332b5SXin Li #include "ltm.h"
30*088332b5SXin Li #include "lvm.h"
31*088332b5SXin Li
32*088332b5SXin Li
33*088332b5SXin Li
34*088332b5SXin Li #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
35*088332b5SXin Li
36*088332b5SXin Li /* inverse of 'pcRel' */
37*088332b5SXin Li #define invpcRel(pc, p) ((p)->code + (pc) + 1)
38*088332b5SXin Li
39*088332b5SXin Li static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
40*088332b5SXin Li const char **name);
41*088332b5SXin Li
42*088332b5SXin Li
currentpc(CallInfo * ci)43*088332b5SXin Li static int currentpc (CallInfo *ci) {
44*088332b5SXin Li lua_assert(isLua(ci));
45*088332b5SXin Li return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
46*088332b5SXin Li }
47*088332b5SXin Li
48*088332b5SXin Li
49*088332b5SXin Li /*
50*088332b5SXin Li ** Get a "base line" to find the line corresponding to an instruction.
51*088332b5SXin Li ** For that, search the array of absolute line info for the largest saved
52*088332b5SXin Li ** instruction smaller or equal to the wanted instruction. A special
53*088332b5SXin Li ** case is when there is no absolute info or the instruction is before
54*088332b5SXin Li ** the first absolute one.
55*088332b5SXin Li */
getbaseline(const Proto * f,int pc,int * basepc)56*088332b5SXin Li static int getbaseline (const Proto *f, int pc, int *basepc) {
57*088332b5SXin Li if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) {
58*088332b5SXin Li *basepc = -1; /* start from the beginning */
59*088332b5SXin Li return f->linedefined;
60*088332b5SXin Li }
61*088332b5SXin Li else {
62*088332b5SXin Li unsigned int i;
63*088332b5SXin Li if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc)
64*088332b5SXin Li i = f->sizeabslineinfo - 1; /* instruction is after last saved one */
65*088332b5SXin Li else { /* binary search */
66*088332b5SXin Li unsigned int j = f->sizeabslineinfo - 1; /* pc < anchorlines[j] */
67*088332b5SXin Li i = 0; /* abslineinfo[i] <= pc */
68*088332b5SXin Li while (i < j - 1) {
69*088332b5SXin Li unsigned int m = (j + i) / 2;
70*088332b5SXin Li if (pc >= f->abslineinfo[m].pc)
71*088332b5SXin Li i = m;
72*088332b5SXin Li else
73*088332b5SXin Li j = m;
74*088332b5SXin Li }
75*088332b5SXin Li }
76*088332b5SXin Li *basepc = f->abslineinfo[i].pc;
77*088332b5SXin Li return f->abslineinfo[i].line;
78*088332b5SXin Li }
79*088332b5SXin Li }
80*088332b5SXin Li
81*088332b5SXin Li
82*088332b5SXin Li /*
83*088332b5SXin Li ** Get the line corresponding to instruction 'pc' in function 'f';
84*088332b5SXin Li ** first gets a base line and from there does the increments until
85*088332b5SXin Li ** the desired instruction.
86*088332b5SXin Li */
luaG_getfuncline(const Proto * f,int pc)87*088332b5SXin Li int luaG_getfuncline (const Proto *f, int pc) {
88*088332b5SXin Li if (f->lineinfo == NULL) /* no debug information? */
89*088332b5SXin Li return -1;
90*088332b5SXin Li else {
91*088332b5SXin Li int basepc;
92*088332b5SXin Li int baseline = getbaseline(f, pc, &basepc);
93*088332b5SXin Li while (basepc++ < pc) { /* walk until given instruction */
94*088332b5SXin Li lua_assert(f->lineinfo[basepc] != ABSLINEINFO);
95*088332b5SXin Li baseline += f->lineinfo[basepc]; /* correct line */
96*088332b5SXin Li }
97*088332b5SXin Li return baseline;
98*088332b5SXin Li }
99*088332b5SXin Li }
100*088332b5SXin Li
101*088332b5SXin Li
getcurrentline(CallInfo * ci)102*088332b5SXin Li static int getcurrentline (CallInfo *ci) {
103*088332b5SXin Li return luaG_getfuncline(ci_func(ci)->p, currentpc(ci));
104*088332b5SXin Li }
105*088332b5SXin Li
106*088332b5SXin Li
107*088332b5SXin Li /*
108*088332b5SXin Li ** Set 'trap' for all active Lua frames.
109*088332b5SXin Li ** This function can be called during a signal, under "reasonable"
110*088332b5SXin Li ** assumptions. A new 'ci' is completely linked in the list before it
111*088332b5SXin Li ** becomes part of the "active" list, and we assume that pointers are
112*088332b5SXin Li ** atomic; see comment in next function.
113*088332b5SXin Li ** (A compiler doing interprocedural optimizations could, theoretically,
114*088332b5SXin Li ** reorder memory writes in such a way that the list could be
115*088332b5SXin Li ** temporarily broken while inserting a new element. We simply assume it
116*088332b5SXin Li ** has no good reasons to do that.)
117*088332b5SXin Li */
settraps(CallInfo * ci)118*088332b5SXin Li static void settraps (CallInfo *ci) {
119*088332b5SXin Li for (; ci != NULL; ci = ci->previous)
120*088332b5SXin Li if (isLua(ci))
121*088332b5SXin Li ci->u.l.trap = 1;
122*088332b5SXin Li }
123*088332b5SXin Li
124*088332b5SXin Li
125*088332b5SXin Li /*
126*088332b5SXin Li ** This function can be called during a signal, under "reasonable"
127*088332b5SXin Li ** assumptions.
128*088332b5SXin Li ** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount')
129*088332b5SXin Li ** are for debug only, and it is no problem if they get arbitrary
130*088332b5SXin Li ** values (causes at most one wrong hook call). 'hookmask' is an atomic
131*088332b5SXin Li ** value. We assume that pointers are atomic too (e.g., gcc ensures that
132*088332b5SXin Li ** for all platforms where it runs). Moreover, 'hook' is always checked
133*088332b5SXin Li ** before being called (see 'luaD_hook').
134*088332b5SXin Li */
lua_sethook(lua_State * L,lua_Hook func,int mask,int count)135*088332b5SXin Li LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
136*088332b5SXin Li if (func == NULL || mask == 0) { /* turn off hooks? */
137*088332b5SXin Li mask = 0;
138*088332b5SXin Li func = NULL;
139*088332b5SXin Li }
140*088332b5SXin Li L->hook = func;
141*088332b5SXin Li L->basehookcount = count;
142*088332b5SXin Li resethookcount(L);
143*088332b5SXin Li L->hookmask = cast_byte(mask);
144*088332b5SXin Li if (mask)
145*088332b5SXin Li settraps(L->ci); /* to trace inside 'luaV_execute' */
146*088332b5SXin Li }
147*088332b5SXin Li
148*088332b5SXin Li
lua_gethook(lua_State * L)149*088332b5SXin Li LUA_API lua_Hook lua_gethook (lua_State *L) {
150*088332b5SXin Li return L->hook;
151*088332b5SXin Li }
152*088332b5SXin Li
153*088332b5SXin Li
lua_gethookmask(lua_State * L)154*088332b5SXin Li LUA_API int lua_gethookmask (lua_State *L) {
155*088332b5SXin Li return L->hookmask;
156*088332b5SXin Li }
157*088332b5SXin Li
158*088332b5SXin Li
lua_gethookcount(lua_State * L)159*088332b5SXin Li LUA_API int lua_gethookcount (lua_State *L) {
160*088332b5SXin Li return L->basehookcount;
161*088332b5SXin Li }
162*088332b5SXin Li
163*088332b5SXin Li
lua_getstack(lua_State * L,int level,lua_Debug * ar)164*088332b5SXin Li LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
165*088332b5SXin Li int status;
166*088332b5SXin Li CallInfo *ci;
167*088332b5SXin Li if (level < 0) return 0; /* invalid (negative) level */
168*088332b5SXin Li lua_lock(L);
169*088332b5SXin Li for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
170*088332b5SXin Li level--;
171*088332b5SXin Li if (level == 0 && ci != &L->base_ci) { /* level found? */
172*088332b5SXin Li status = 1;
173*088332b5SXin Li ar->i_ci = ci;
174*088332b5SXin Li }
175*088332b5SXin Li else status = 0; /* no such level */
176*088332b5SXin Li lua_unlock(L);
177*088332b5SXin Li return status;
178*088332b5SXin Li }
179*088332b5SXin Li
180*088332b5SXin Li
upvalname(const Proto * p,int uv)181*088332b5SXin Li static const char *upvalname (const Proto *p, int uv) {
182*088332b5SXin Li TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
183*088332b5SXin Li if (s == NULL) return "?";
184*088332b5SXin Li else return getstr(s);
185*088332b5SXin Li }
186*088332b5SXin Li
187*088332b5SXin Li
findvararg(CallInfo * ci,int n,StkId * pos)188*088332b5SXin Li static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
189*088332b5SXin Li if (clLvalue(s2v(ci->func))->p->is_vararg) {
190*088332b5SXin Li int nextra = ci->u.l.nextraargs;
191*088332b5SXin Li if (n >= -nextra) { /* 'n' is negative */
192*088332b5SXin Li *pos = ci->func - nextra - (n + 1);
193*088332b5SXin Li return "(vararg)"; /* generic name for any vararg */
194*088332b5SXin Li }
195*088332b5SXin Li }
196*088332b5SXin Li return NULL; /* no such vararg */
197*088332b5SXin Li }
198*088332b5SXin Li
199*088332b5SXin Li
luaG_findlocal(lua_State * L,CallInfo * ci,int n,StkId * pos)200*088332b5SXin Li const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
201*088332b5SXin Li StkId base = ci->func + 1;
202*088332b5SXin Li const char *name = NULL;
203*088332b5SXin Li if (isLua(ci)) {
204*088332b5SXin Li if (n < 0) /* access to vararg values? */
205*088332b5SXin Li return findvararg(ci, n, pos);
206*088332b5SXin Li else
207*088332b5SXin Li name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
208*088332b5SXin Li }
209*088332b5SXin Li if (name == NULL) { /* no 'standard' name? */
210*088332b5SXin Li StkId limit = (ci == L->ci) ? L->top : ci->next->func;
211*088332b5SXin Li if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */
212*088332b5SXin Li /* generic name for any valid slot */
213*088332b5SXin Li name = isLua(ci) ? "(temporary)" : "(C temporary)";
214*088332b5SXin Li }
215*088332b5SXin Li else
216*088332b5SXin Li return NULL; /* no name */
217*088332b5SXin Li }
218*088332b5SXin Li if (pos)
219*088332b5SXin Li *pos = base + (n - 1);
220*088332b5SXin Li return name;
221*088332b5SXin Li }
222*088332b5SXin Li
223*088332b5SXin Li
lua_getlocal(lua_State * L,const lua_Debug * ar,int n)224*088332b5SXin Li LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
225*088332b5SXin Li const char *name;
226*088332b5SXin Li lua_lock(L);
227*088332b5SXin Li if (ar == NULL) { /* information about non-active function? */
228*088332b5SXin Li if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */
229*088332b5SXin Li name = NULL;
230*088332b5SXin Li else /* consider live variables at function start (parameters) */
231*088332b5SXin Li name = luaF_getlocalname(clLvalue(s2v(L->top - 1))->p, n, 0);
232*088332b5SXin Li }
233*088332b5SXin Li else { /* active function; get information through 'ar' */
234*088332b5SXin Li StkId pos = NULL; /* to avoid warnings */
235*088332b5SXin Li name = luaG_findlocal(L, ar->i_ci, n, &pos);
236*088332b5SXin Li if (name) {
237*088332b5SXin Li setobjs2s(L, L->top, pos);
238*088332b5SXin Li api_incr_top(L);
239*088332b5SXin Li }
240*088332b5SXin Li }
241*088332b5SXin Li lua_unlock(L);
242*088332b5SXin Li return name;
243*088332b5SXin Li }
244*088332b5SXin Li
245*088332b5SXin Li
lua_setlocal(lua_State * L,const lua_Debug * ar,int n)246*088332b5SXin Li LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
247*088332b5SXin Li StkId pos = NULL; /* to avoid warnings */
248*088332b5SXin Li const char *name;
249*088332b5SXin Li lua_lock(L);
250*088332b5SXin Li name = luaG_findlocal(L, ar->i_ci, n, &pos);
251*088332b5SXin Li if (name) {
252*088332b5SXin Li setobjs2s(L, pos, L->top - 1);
253*088332b5SXin Li L->top--; /* pop value */
254*088332b5SXin Li }
255*088332b5SXin Li lua_unlock(L);
256*088332b5SXin Li return name;
257*088332b5SXin Li }
258*088332b5SXin Li
259*088332b5SXin Li
funcinfo(lua_Debug * ar,Closure * cl)260*088332b5SXin Li static void funcinfo (lua_Debug *ar, Closure *cl) {
261*088332b5SXin Li if (noLuaClosure(cl)) {
262*088332b5SXin Li ar->source = "=[C]";
263*088332b5SXin Li ar->srclen = LL("=[C]");
264*088332b5SXin Li ar->linedefined = -1;
265*088332b5SXin Li ar->lastlinedefined = -1;
266*088332b5SXin Li ar->what = "C";
267*088332b5SXin Li }
268*088332b5SXin Li else {
269*088332b5SXin Li const Proto *p = cl->l.p;
270*088332b5SXin Li if (p->source) {
271*088332b5SXin Li ar->source = getstr(p->source);
272*088332b5SXin Li ar->srclen = tsslen(p->source);
273*088332b5SXin Li }
274*088332b5SXin Li else {
275*088332b5SXin Li ar->source = "=?";
276*088332b5SXin Li ar->srclen = LL("=?");
277*088332b5SXin Li }
278*088332b5SXin Li ar->linedefined = p->linedefined;
279*088332b5SXin Li ar->lastlinedefined = p->lastlinedefined;
280*088332b5SXin Li ar->what = (ar->linedefined == 0) ? "main" : "Lua";
281*088332b5SXin Li }
282*088332b5SXin Li luaO_chunkid(ar->short_src, ar->source, ar->srclen);
283*088332b5SXin Li }
284*088332b5SXin Li
285*088332b5SXin Li
nextline(const Proto * p,int currentline,int pc)286*088332b5SXin Li static int nextline (const Proto *p, int currentline, int pc) {
287*088332b5SXin Li if (p->lineinfo[pc] != ABSLINEINFO)
288*088332b5SXin Li return currentline + p->lineinfo[pc];
289*088332b5SXin Li else
290*088332b5SXin Li return luaG_getfuncline(p, pc);
291*088332b5SXin Li }
292*088332b5SXin Li
293*088332b5SXin Li
collectvalidlines(lua_State * L,Closure * f)294*088332b5SXin Li static void collectvalidlines (lua_State *L, Closure *f) {
295*088332b5SXin Li if (noLuaClosure(f)) {
296*088332b5SXin Li setnilvalue(s2v(L->top));
297*088332b5SXin Li api_incr_top(L);
298*088332b5SXin Li }
299*088332b5SXin Li else {
300*088332b5SXin Li int i;
301*088332b5SXin Li TValue v;
302*088332b5SXin Li const Proto *p = f->l.p;
303*088332b5SXin Li int currentline = p->linedefined;
304*088332b5SXin Li Table *t = luaH_new(L); /* new table to store active lines */
305*088332b5SXin Li sethvalue2s(L, L->top, t); /* push it on stack */
306*088332b5SXin Li api_incr_top(L);
307*088332b5SXin Li setbtvalue(&v); /* boolean 'true' to be the value of all indices */
308*088332b5SXin Li for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */
309*088332b5SXin Li currentline = nextline(p, currentline, i);
310*088332b5SXin Li luaH_setint(L, t, currentline, &v); /* table[line] = true */
311*088332b5SXin Li }
312*088332b5SXin Li }
313*088332b5SXin Li }
314*088332b5SXin Li
315*088332b5SXin Li
getfuncname(lua_State * L,CallInfo * ci,const char ** name)316*088332b5SXin Li static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
317*088332b5SXin Li if (ci == NULL) /* no 'ci'? */
318*088332b5SXin Li return NULL; /* no info */
319*088332b5SXin Li else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
320*088332b5SXin Li *name = "__gc";
321*088332b5SXin Li return "metamethod"; /* report it as such */
322*088332b5SXin Li }
323*088332b5SXin Li /* calling function is a known Lua function? */
324*088332b5SXin Li else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
325*088332b5SXin Li return funcnamefromcode(L, ci->previous, name);
326*088332b5SXin Li else return NULL; /* no way to find a name */
327*088332b5SXin Li }
328*088332b5SXin Li
329*088332b5SXin Li
auxgetinfo(lua_State * L,const char * what,lua_Debug * ar,Closure * f,CallInfo * ci)330*088332b5SXin Li static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
331*088332b5SXin Li Closure *f, CallInfo *ci) {
332*088332b5SXin Li int status = 1;
333*088332b5SXin Li for (; *what; what++) {
334*088332b5SXin Li switch (*what) {
335*088332b5SXin Li case 'S': {
336*088332b5SXin Li funcinfo(ar, f);
337*088332b5SXin Li break;
338*088332b5SXin Li }
339*088332b5SXin Li case 'l': {
340*088332b5SXin Li ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1;
341*088332b5SXin Li break;
342*088332b5SXin Li }
343*088332b5SXin Li case 'u': {
344*088332b5SXin Li ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
345*088332b5SXin Li if (noLuaClosure(f)) {
346*088332b5SXin Li ar->isvararg = 1;
347*088332b5SXin Li ar->nparams = 0;
348*088332b5SXin Li }
349*088332b5SXin Li else {
350*088332b5SXin Li ar->isvararg = f->l.p->is_vararg;
351*088332b5SXin Li ar->nparams = f->l.p->numparams;
352*088332b5SXin Li }
353*088332b5SXin Li break;
354*088332b5SXin Li }
355*088332b5SXin Li case 't': {
356*088332b5SXin Li ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
357*088332b5SXin Li break;
358*088332b5SXin Li }
359*088332b5SXin Li case 'n': {
360*088332b5SXin Li ar->namewhat = getfuncname(L, ci, &ar->name);
361*088332b5SXin Li if (ar->namewhat == NULL) {
362*088332b5SXin Li ar->namewhat = ""; /* not found */
363*088332b5SXin Li ar->name = NULL;
364*088332b5SXin Li }
365*088332b5SXin Li break;
366*088332b5SXin Li }
367*088332b5SXin Li case 'r': {
368*088332b5SXin Li if (ci == NULL || !(ci->callstatus & CIST_TRAN))
369*088332b5SXin Li ar->ftransfer = ar->ntransfer = 0;
370*088332b5SXin Li else {
371*088332b5SXin Li ar->ftransfer = ci->u2.transferinfo.ftransfer;
372*088332b5SXin Li ar->ntransfer = ci->u2.transferinfo.ntransfer;
373*088332b5SXin Li }
374*088332b5SXin Li break;
375*088332b5SXin Li }
376*088332b5SXin Li case 'L':
377*088332b5SXin Li case 'f': /* handled by lua_getinfo */
378*088332b5SXin Li break;
379*088332b5SXin Li default: status = 0; /* invalid option */
380*088332b5SXin Li }
381*088332b5SXin Li }
382*088332b5SXin Li return status;
383*088332b5SXin Li }
384*088332b5SXin Li
385*088332b5SXin Li
lua_getinfo(lua_State * L,const char * what,lua_Debug * ar)386*088332b5SXin Li LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
387*088332b5SXin Li int status;
388*088332b5SXin Li Closure *cl;
389*088332b5SXin Li CallInfo *ci;
390*088332b5SXin Li TValue *func;
391*088332b5SXin Li lua_lock(L);
392*088332b5SXin Li if (*what == '>') {
393*088332b5SXin Li ci = NULL;
394*088332b5SXin Li func = s2v(L->top - 1);
395*088332b5SXin Li api_check(L, ttisfunction(func), "function expected");
396*088332b5SXin Li what++; /* skip the '>' */
397*088332b5SXin Li L->top--; /* pop function */
398*088332b5SXin Li }
399*088332b5SXin Li else {
400*088332b5SXin Li ci = ar->i_ci;
401*088332b5SXin Li func = s2v(ci->func);
402*088332b5SXin Li lua_assert(ttisfunction(func));
403*088332b5SXin Li }
404*088332b5SXin Li cl = ttisclosure(func) ? clvalue(func) : NULL;
405*088332b5SXin Li status = auxgetinfo(L, what, ar, cl, ci);
406*088332b5SXin Li if (strchr(what, 'f')) {
407*088332b5SXin Li setobj2s(L, L->top, func);
408*088332b5SXin Li api_incr_top(L);
409*088332b5SXin Li }
410*088332b5SXin Li if (strchr(what, 'L'))
411*088332b5SXin Li collectvalidlines(L, cl);
412*088332b5SXin Li lua_unlock(L);
413*088332b5SXin Li return status;
414*088332b5SXin Li }
415*088332b5SXin Li
416*088332b5SXin Li
417*088332b5SXin Li /*
418*088332b5SXin Li ** {======================================================
419*088332b5SXin Li ** Symbolic Execution
420*088332b5SXin Li ** =======================================================
421*088332b5SXin Li */
422*088332b5SXin Li
423*088332b5SXin Li static const char *getobjname (const Proto *p, int lastpc, int reg,
424*088332b5SXin Li const char **name);
425*088332b5SXin Li
426*088332b5SXin Li
427*088332b5SXin Li /*
428*088332b5SXin Li ** Find a "name" for the constant 'c'.
429*088332b5SXin Li */
kname(const Proto * p,int c,const char ** name)430*088332b5SXin Li static void kname (const Proto *p, int c, const char **name) {
431*088332b5SXin Li TValue *kvalue = &p->k[c];
432*088332b5SXin Li *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?";
433*088332b5SXin Li }
434*088332b5SXin Li
435*088332b5SXin Li
436*088332b5SXin Li /*
437*088332b5SXin Li ** Find a "name" for the register 'c'.
438*088332b5SXin Li */
rname(const Proto * p,int pc,int c,const char ** name)439*088332b5SXin Li static void rname (const Proto *p, int pc, int c, const char **name) {
440*088332b5SXin Li const char *what = getobjname(p, pc, c, name); /* search for 'c' */
441*088332b5SXin Li if (!(what && *what == 'c')) /* did not find a constant name? */
442*088332b5SXin Li *name = "?";
443*088332b5SXin Li }
444*088332b5SXin Li
445*088332b5SXin Li
446*088332b5SXin Li /*
447*088332b5SXin Li ** Find a "name" for a 'C' value in an RK instruction.
448*088332b5SXin Li */
rkname(const Proto * p,int pc,Instruction i,const char ** name)449*088332b5SXin Li static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
450*088332b5SXin Li int c = GETARG_C(i); /* key index */
451*088332b5SXin Li if (GETARG_k(i)) /* is 'c' a constant? */
452*088332b5SXin Li kname(p, c, name);
453*088332b5SXin Li else /* 'c' is a register */
454*088332b5SXin Li rname(p, pc, c, name);
455*088332b5SXin Li }
456*088332b5SXin Li
457*088332b5SXin Li
filterpc(int pc,int jmptarget)458*088332b5SXin Li static int filterpc (int pc, int jmptarget) {
459*088332b5SXin Li if (pc < jmptarget) /* is code conditional (inside a jump)? */
460*088332b5SXin Li return -1; /* cannot know who sets that register */
461*088332b5SXin Li else return pc; /* current position sets that register */
462*088332b5SXin Li }
463*088332b5SXin Li
464*088332b5SXin Li
465*088332b5SXin Li /*
466*088332b5SXin Li ** Try to find last instruction before 'lastpc' that modified register 'reg'.
467*088332b5SXin Li */
findsetreg(const Proto * p,int lastpc,int reg)468*088332b5SXin Li static int findsetreg (const Proto *p, int lastpc, int reg) {
469*088332b5SXin Li int pc;
470*088332b5SXin Li int setreg = -1; /* keep last instruction that changed 'reg' */
471*088332b5SXin Li int jmptarget = 0; /* any code before this address is conditional */
472*088332b5SXin Li if (testMMMode(GET_OPCODE(p->code[lastpc])))
473*088332b5SXin Li lastpc--; /* previous instruction was not actually executed */
474*088332b5SXin Li for (pc = 0; pc < lastpc; pc++) {
475*088332b5SXin Li Instruction i = p->code[pc];
476*088332b5SXin Li OpCode op = GET_OPCODE(i);
477*088332b5SXin Li int a = GETARG_A(i);
478*088332b5SXin Li int change; /* true if current instruction changed 'reg' */
479*088332b5SXin Li switch (op) {
480*088332b5SXin Li case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */
481*088332b5SXin Li int b = GETARG_B(i);
482*088332b5SXin Li change = (a <= reg && reg <= a + b);
483*088332b5SXin Li break;
484*088332b5SXin Li }
485*088332b5SXin Li case OP_TFORCALL: { /* affect all regs above its base */
486*088332b5SXin Li change = (reg >= a + 2);
487*088332b5SXin Li break;
488*088332b5SXin Li }
489*088332b5SXin Li case OP_CALL:
490*088332b5SXin Li case OP_TAILCALL: { /* affect all registers above base */
491*088332b5SXin Li change = (reg >= a);
492*088332b5SXin Li break;
493*088332b5SXin Li }
494*088332b5SXin Li case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */
495*088332b5SXin Li int b = GETARG_sJ(i);
496*088332b5SXin Li int dest = pc + 1 + b;
497*088332b5SXin Li /* jump does not skip 'lastpc' and is larger than current one? */
498*088332b5SXin Li if (dest <= lastpc && dest > jmptarget)
499*088332b5SXin Li jmptarget = dest; /* update 'jmptarget' */
500*088332b5SXin Li change = 0;
501*088332b5SXin Li break;
502*088332b5SXin Li }
503*088332b5SXin Li default: /* any instruction that sets A */
504*088332b5SXin Li change = (testAMode(op) && reg == a);
505*088332b5SXin Li break;
506*088332b5SXin Li }
507*088332b5SXin Li if (change)
508*088332b5SXin Li setreg = filterpc(pc, jmptarget);
509*088332b5SXin Li }
510*088332b5SXin Li return setreg;
511*088332b5SXin Li }
512*088332b5SXin Li
513*088332b5SXin Li
514*088332b5SXin Li /*
515*088332b5SXin Li ** Check whether table being indexed by instruction 'i' is the
516*088332b5SXin Li ** environment '_ENV'
517*088332b5SXin Li */
gxf(const Proto * p,int pc,Instruction i,int isup)518*088332b5SXin Li static const char *gxf (const Proto *p, int pc, Instruction i, int isup) {
519*088332b5SXin Li int t = GETARG_B(i); /* table index */
520*088332b5SXin Li const char *name; /* name of indexed variable */
521*088332b5SXin Li if (isup) /* is an upvalue? */
522*088332b5SXin Li name = upvalname(p, t);
523*088332b5SXin Li else
524*088332b5SXin Li getobjname(p, pc, t, &name);
525*088332b5SXin Li return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
526*088332b5SXin Li }
527*088332b5SXin Li
528*088332b5SXin Li
getobjname(const Proto * p,int lastpc,int reg,const char ** name)529*088332b5SXin Li static const char *getobjname (const Proto *p, int lastpc, int reg,
530*088332b5SXin Li const char **name) {
531*088332b5SXin Li int pc;
532*088332b5SXin Li *name = luaF_getlocalname(p, reg + 1, lastpc);
533*088332b5SXin Li if (*name) /* is a local? */
534*088332b5SXin Li return "local";
535*088332b5SXin Li /* else try symbolic execution */
536*088332b5SXin Li pc = findsetreg(p, lastpc, reg);
537*088332b5SXin Li if (pc != -1) { /* could find instruction? */
538*088332b5SXin Li Instruction i = p->code[pc];
539*088332b5SXin Li OpCode op = GET_OPCODE(i);
540*088332b5SXin Li switch (op) {
541*088332b5SXin Li case OP_MOVE: {
542*088332b5SXin Li int b = GETARG_B(i); /* move from 'b' to 'a' */
543*088332b5SXin Li if (b < GETARG_A(i))
544*088332b5SXin Li return getobjname(p, pc, b, name); /* get name for 'b' */
545*088332b5SXin Li break;
546*088332b5SXin Li }
547*088332b5SXin Li case OP_GETTABUP: {
548*088332b5SXin Li int k = GETARG_C(i); /* key index */
549*088332b5SXin Li kname(p, k, name);
550*088332b5SXin Li return gxf(p, pc, i, 1);
551*088332b5SXin Li }
552*088332b5SXin Li case OP_GETTABLE: {
553*088332b5SXin Li int k = GETARG_C(i); /* key index */
554*088332b5SXin Li rname(p, pc, k, name);
555*088332b5SXin Li return gxf(p, pc, i, 0);
556*088332b5SXin Li }
557*088332b5SXin Li case OP_GETI: {
558*088332b5SXin Li *name = "integer index";
559*088332b5SXin Li return "field";
560*088332b5SXin Li }
561*088332b5SXin Li case OP_GETFIELD: {
562*088332b5SXin Li int k = GETARG_C(i); /* key index */
563*088332b5SXin Li kname(p, k, name);
564*088332b5SXin Li return gxf(p, pc, i, 0);
565*088332b5SXin Li }
566*088332b5SXin Li case OP_GETUPVAL: {
567*088332b5SXin Li *name = upvalname(p, GETARG_B(i));
568*088332b5SXin Li return "upvalue";
569*088332b5SXin Li }
570*088332b5SXin Li case OP_LOADK:
571*088332b5SXin Li case OP_LOADKX: {
572*088332b5SXin Li int b = (op == OP_LOADK) ? GETARG_Bx(i)
573*088332b5SXin Li : GETARG_Ax(p->code[pc + 1]);
574*088332b5SXin Li if (ttisstring(&p->k[b])) {
575*088332b5SXin Li *name = svalue(&p->k[b]);
576*088332b5SXin Li return "constant";
577*088332b5SXin Li }
578*088332b5SXin Li break;
579*088332b5SXin Li }
580*088332b5SXin Li case OP_SELF: {
581*088332b5SXin Li rkname(p, pc, i, name);
582*088332b5SXin Li return "method";
583*088332b5SXin Li }
584*088332b5SXin Li default: break; /* go through to return NULL */
585*088332b5SXin Li }
586*088332b5SXin Li }
587*088332b5SXin Li return NULL; /* could not find reasonable name */
588*088332b5SXin Li }
589*088332b5SXin Li
590*088332b5SXin Li
591*088332b5SXin Li /*
592*088332b5SXin Li ** Try to find a name for a function based on the code that called it.
593*088332b5SXin Li ** (Only works when function was called by a Lua function.)
594*088332b5SXin Li ** Returns what the name is (e.g., "for iterator", "method",
595*088332b5SXin Li ** "metamethod") and sets '*name' to point to the name.
596*088332b5SXin Li */
funcnamefromcode(lua_State * L,CallInfo * ci,const char ** name)597*088332b5SXin Li static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
598*088332b5SXin Li const char **name) {
599*088332b5SXin Li TMS tm = (TMS)0; /* (initial value avoids warnings) */
600*088332b5SXin Li const Proto *p = ci_func(ci)->p; /* calling function */
601*088332b5SXin Li int pc = currentpc(ci); /* calling instruction index */
602*088332b5SXin Li Instruction i = p->code[pc]; /* calling instruction */
603*088332b5SXin Li if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
604*088332b5SXin Li *name = "?";
605*088332b5SXin Li return "hook";
606*088332b5SXin Li }
607*088332b5SXin Li switch (GET_OPCODE(i)) {
608*088332b5SXin Li case OP_CALL:
609*088332b5SXin Li case OP_TAILCALL:
610*088332b5SXin Li return getobjname(p, pc, GETARG_A(i), name); /* get function name */
611*088332b5SXin Li case OP_TFORCALL: { /* for iterator */
612*088332b5SXin Li *name = "for iterator";
613*088332b5SXin Li return "for iterator";
614*088332b5SXin Li }
615*088332b5SXin Li /* other instructions can do calls through metamethods */
616*088332b5SXin Li case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
617*088332b5SXin Li case OP_GETI: case OP_GETFIELD:
618*088332b5SXin Li tm = TM_INDEX;
619*088332b5SXin Li break;
620*088332b5SXin Li case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD:
621*088332b5SXin Li tm = TM_NEWINDEX;
622*088332b5SXin Li break;
623*088332b5SXin Li case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
624*088332b5SXin Li tm = cast(TMS, GETARG_C(i));
625*088332b5SXin Li break;
626*088332b5SXin Li }
627*088332b5SXin Li case OP_UNM: tm = TM_UNM; break;
628*088332b5SXin Li case OP_BNOT: tm = TM_BNOT; break;
629*088332b5SXin Li case OP_LEN: tm = TM_LEN; break;
630*088332b5SXin Li case OP_CONCAT: tm = TM_CONCAT; break;
631*088332b5SXin Li case OP_EQ: tm = TM_EQ; break;
632*088332b5SXin Li case OP_LT: case OP_LE: case OP_LTI: case OP_LEI:
633*088332b5SXin Li *name = "order"; /* '<=' can call '__lt', etc. */
634*088332b5SXin Li return "metamethod";
635*088332b5SXin Li case OP_CLOSE: case OP_RETURN:
636*088332b5SXin Li *name = "close";
637*088332b5SXin Li return "metamethod";
638*088332b5SXin Li default:
639*088332b5SXin Li return NULL; /* cannot find a reasonable name */
640*088332b5SXin Li }
641*088332b5SXin Li *name = getstr(G(L)->tmname[tm]) + 2;
642*088332b5SXin Li return "metamethod";
643*088332b5SXin Li }
644*088332b5SXin Li
645*088332b5SXin Li /* }====================================================== */
646*088332b5SXin Li
647*088332b5SXin Li
648*088332b5SXin Li
649*088332b5SXin Li /*
650*088332b5SXin Li ** The subtraction of two potentially unrelated pointers is
651*088332b5SXin Li ** not ISO C, but it should not crash a program; the subsequent
652*088332b5SXin Li ** checks are ISO C and ensure a correct result.
653*088332b5SXin Li */
isinstack(CallInfo * ci,const TValue * o)654*088332b5SXin Li static int isinstack (CallInfo *ci, const TValue *o) {
655*088332b5SXin Li StkId base = ci->func + 1;
656*088332b5SXin Li ptrdiff_t i = cast(StkId, o) - base;
657*088332b5SXin Li return (0 <= i && i < (ci->top - base) && s2v(base + i) == o);
658*088332b5SXin Li }
659*088332b5SXin Li
660*088332b5SXin Li
661*088332b5SXin Li /*
662*088332b5SXin Li ** Checks whether value 'o' came from an upvalue. (That can only happen
663*088332b5SXin Li ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
664*088332b5SXin Li ** upvalues.)
665*088332b5SXin Li */
getupvalname(CallInfo * ci,const TValue * o,const char ** name)666*088332b5SXin Li static const char *getupvalname (CallInfo *ci, const TValue *o,
667*088332b5SXin Li const char **name) {
668*088332b5SXin Li LClosure *c = ci_func(ci);
669*088332b5SXin Li int i;
670*088332b5SXin Li for (i = 0; i < c->nupvalues; i++) {
671*088332b5SXin Li if (c->upvals[i]->v == o) {
672*088332b5SXin Li *name = upvalname(c->p, i);
673*088332b5SXin Li return "upvalue";
674*088332b5SXin Li }
675*088332b5SXin Li }
676*088332b5SXin Li return NULL;
677*088332b5SXin Li }
678*088332b5SXin Li
679*088332b5SXin Li
varinfo(lua_State * L,const TValue * o)680*088332b5SXin Li static const char *varinfo (lua_State *L, const TValue *o) {
681*088332b5SXin Li const char *name = NULL; /* to avoid warnings */
682*088332b5SXin Li CallInfo *ci = L->ci;
683*088332b5SXin Li const char *kind = NULL;
684*088332b5SXin Li if (isLua(ci)) {
685*088332b5SXin Li kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
686*088332b5SXin Li if (!kind && isinstack(ci, o)) /* no? try a register */
687*088332b5SXin Li kind = getobjname(ci_func(ci)->p, currentpc(ci),
688*088332b5SXin Li cast_int(cast(StkId, o) - (ci->func + 1)), &name);
689*088332b5SXin Li }
690*088332b5SXin Li return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
691*088332b5SXin Li }
692*088332b5SXin Li
693*088332b5SXin Li
luaG_typeerror(lua_State * L,const TValue * o,const char * op)694*088332b5SXin Li l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
695*088332b5SXin Li const char *t = luaT_objtypename(L, o);
696*088332b5SXin Li luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
697*088332b5SXin Li }
698*088332b5SXin Li
699*088332b5SXin Li
luaG_forerror(lua_State * L,const TValue * o,const char * what)700*088332b5SXin Li l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) {
701*088332b5SXin Li luaG_runerror(L, "bad 'for' %s (number expected, got %s)",
702*088332b5SXin Li what, luaT_objtypename(L, o));
703*088332b5SXin Li }
704*088332b5SXin Li
705*088332b5SXin Li
luaG_concaterror(lua_State * L,const TValue * p1,const TValue * p2)706*088332b5SXin Li l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
707*088332b5SXin Li if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
708*088332b5SXin Li luaG_typeerror(L, p1, "concatenate");
709*088332b5SXin Li }
710*088332b5SXin Li
711*088332b5SXin Li
luaG_opinterror(lua_State * L,const TValue * p1,const TValue * p2,const char * msg)712*088332b5SXin Li l_noret luaG_opinterror (lua_State *L, const TValue *p1,
713*088332b5SXin Li const TValue *p2, const char *msg) {
714*088332b5SXin Li if (!ttisnumber(p1)) /* first operand is wrong? */
715*088332b5SXin Li p2 = p1; /* now second is wrong */
716*088332b5SXin Li luaG_typeerror(L, p2, msg);
717*088332b5SXin Li }
718*088332b5SXin Li
719*088332b5SXin Li
720*088332b5SXin Li /*
721*088332b5SXin Li ** Error when both values are convertible to numbers, but not to integers
722*088332b5SXin Li */
luaG_tointerror(lua_State * L,const TValue * p1,const TValue * p2)723*088332b5SXin Li l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
724*088332b5SXin Li lua_Integer temp;
725*088332b5SXin Li if (!tointegerns(p1, &temp))
726*088332b5SXin Li p2 = p1;
727*088332b5SXin Li luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
728*088332b5SXin Li }
729*088332b5SXin Li
730*088332b5SXin Li
luaG_ordererror(lua_State * L,const TValue * p1,const TValue * p2)731*088332b5SXin Li l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
732*088332b5SXin Li const char *t1 = luaT_objtypename(L, p1);
733*088332b5SXin Li const char *t2 = luaT_objtypename(L, p2);
734*088332b5SXin Li if (strcmp(t1, t2) == 0)
735*088332b5SXin Li luaG_runerror(L, "attempt to compare two %s values", t1);
736*088332b5SXin Li else
737*088332b5SXin Li luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
738*088332b5SXin Li }
739*088332b5SXin Li
740*088332b5SXin Li
741*088332b5SXin Li /* add src:line information to 'msg' */
luaG_addinfo(lua_State * L,const char * msg,TString * src,int line)742*088332b5SXin Li const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
743*088332b5SXin Li int line) {
744*088332b5SXin Li char buff[LUA_IDSIZE];
745*088332b5SXin Li if (src)
746*088332b5SXin Li luaO_chunkid(buff, getstr(src), tsslen(src));
747*088332b5SXin Li else { /* no source available; use "?" instead */
748*088332b5SXin Li buff[0] = '?'; buff[1] = '\0';
749*088332b5SXin Li }
750*088332b5SXin Li return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
751*088332b5SXin Li }
752*088332b5SXin Li
753*088332b5SXin Li
luaG_errormsg(lua_State * L)754*088332b5SXin Li l_noret luaG_errormsg (lua_State *L) {
755*088332b5SXin Li if (L->errfunc != 0) { /* is there an error handling function? */
756*088332b5SXin Li StkId errfunc = restorestack(L, L->errfunc);
757*088332b5SXin Li lua_assert(ttisfunction(s2v(errfunc)));
758*088332b5SXin Li setobjs2s(L, L->top, L->top - 1); /* move argument */
759*088332b5SXin Li setobjs2s(L, L->top - 1, errfunc); /* push function */
760*088332b5SXin Li L->top++; /* assume EXTRA_STACK */
761*088332b5SXin Li luaD_callnoyield(L, L->top - 2, 1); /* call it */
762*088332b5SXin Li }
763*088332b5SXin Li luaD_throw(L, LUA_ERRRUN);
764*088332b5SXin Li }
765*088332b5SXin Li
766*088332b5SXin Li
luaG_runerror(lua_State * L,const char * fmt,...)767*088332b5SXin Li l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
768*088332b5SXin Li CallInfo *ci = L->ci;
769*088332b5SXin Li const char *msg;
770*088332b5SXin Li va_list argp;
771*088332b5SXin Li luaC_checkGC(L); /* error message uses memory */
772*088332b5SXin Li va_start(argp, fmt);
773*088332b5SXin Li msg = luaO_pushvfstring(L, fmt, argp); /* format message */
774*088332b5SXin Li va_end(argp);
775*088332b5SXin Li if (isLua(ci)) /* if Lua function, add source:line information */
776*088332b5SXin Li luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
777*088332b5SXin Li luaG_errormsg(L);
778*088332b5SXin Li }
779*088332b5SXin Li
780*088332b5SXin Li
781*088332b5SXin Li /*
782*088332b5SXin Li ** Check whether new instruction 'newpc' is in a different line from
783*088332b5SXin Li ** previous instruction 'oldpc'.
784*088332b5SXin Li */
changedline(const Proto * p,int oldpc,int newpc)785*088332b5SXin Li static int changedline (const Proto *p, int oldpc, int newpc) {
786*088332b5SXin Li if (p->lineinfo == NULL) /* no debug information? */
787*088332b5SXin Li return 0;
788*088332b5SXin Li while (oldpc++ < newpc) {
789*088332b5SXin Li if (p->lineinfo[oldpc] != 0)
790*088332b5SXin Li return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc));
791*088332b5SXin Li }
792*088332b5SXin Li return 0; /* no line changes between positions */
793*088332b5SXin Li }
794*088332b5SXin Li
795*088332b5SXin Li
796*088332b5SXin Li /*
797*088332b5SXin Li ** Traces the execution of a Lua function. Called before the execution
798*088332b5SXin Li ** of each opcode, when debug is on. 'L->oldpc' stores the last
799*088332b5SXin Li ** instruction traced, to detect line changes. When entering a new
800*088332b5SXin Li ** function, 'npci' will be zero and will test as a new line without
801*088332b5SXin Li ** the need for 'oldpc'; so, 'oldpc' does not need to be initialized
802*088332b5SXin Li ** before. Some exceptional conditions may return to a function without
803*088332b5SXin Li ** updating 'oldpc'. In that case, 'oldpc' may be invalid; if so, it is
804*088332b5SXin Li ** reset to zero. (A wrong but valid 'oldpc' at most causes an extra
805*088332b5SXin Li ** call to a line hook.)
806*088332b5SXin Li */
luaG_traceexec(lua_State * L,const Instruction * pc)807*088332b5SXin Li int luaG_traceexec (lua_State *L, const Instruction *pc) {
808*088332b5SXin Li CallInfo *ci = L->ci;
809*088332b5SXin Li lu_byte mask = L->hookmask;
810*088332b5SXin Li const Proto *p = ci_func(ci)->p;
811*088332b5SXin Li int counthook;
812*088332b5SXin Li /* 'L->oldpc' may be invalid; reset it in this case */
813*088332b5SXin Li int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0;
814*088332b5SXin Li if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */
815*088332b5SXin Li ci->u.l.trap = 0; /* don't need to stop again */
816*088332b5SXin Li return 0; /* turn off 'trap' */
817*088332b5SXin Li }
818*088332b5SXin Li pc++; /* reference is always next instruction */
819*088332b5SXin Li ci->u.l.savedpc = pc; /* save 'pc' */
820*088332b5SXin Li counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
821*088332b5SXin Li if (counthook)
822*088332b5SXin Li resethookcount(L); /* reset count */
823*088332b5SXin Li else if (!(mask & LUA_MASKLINE))
824*088332b5SXin Li return 1; /* no line hook and count != 0; nothing to be done now */
825*088332b5SXin Li if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
826*088332b5SXin Li ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
827*088332b5SXin Li return 1; /* do not call hook again (VM yielded, so it did not move) */
828*088332b5SXin Li }
829*088332b5SXin Li if (!isIT(*(ci->u.l.savedpc - 1)))
830*088332b5SXin Li L->top = ci->top; /* prepare top */
831*088332b5SXin Li if (counthook)
832*088332b5SXin Li luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */
833*088332b5SXin Li if (mask & LUA_MASKLINE) {
834*088332b5SXin Li int npci = pcRel(pc, p);
835*088332b5SXin Li if (npci == 0 || /* call linehook when enter a new function, */
836*088332b5SXin Li pc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */
837*088332b5SXin Li changedline(p, oldpc, npci)) { /* enter new line */
838*088332b5SXin Li int newline = luaG_getfuncline(p, npci);
839*088332b5SXin Li luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */
840*088332b5SXin Li }
841*088332b5SXin Li L->oldpc = npci; /* 'pc' of last call to line hook */
842*088332b5SXin Li }
843*088332b5SXin Li if (L->status == LUA_YIELD) { /* did hook yield? */
844*088332b5SXin Li if (counthook)
845*088332b5SXin Li L->hookcount = 1; /* undo decrement to zero */
846*088332b5SXin Li ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
847*088332b5SXin Li ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
848*088332b5SXin Li luaD_throw(L, LUA_YIELD);
849*088332b5SXin Li }
850*088332b5SXin Li return 1; /* keep 'trap' on */
851*088332b5SXin Li }
852*088332b5SXin Li
853