1*0a6a1f1dSLionel Sambuc /* $NetBSD: ldebug.c,v 1.5 2015/10/08 13:21:00 mbalmer Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: ldebug.c,v 2.115 2015/05/22 17:45:56 roberto Exp
511be35a1SLionel Sambuc ** Debug Interface
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc
911be35a1SLionel Sambuc #define ldebug_c
1011be35a1SLionel Sambuc #define LUA_CORE
1111be35a1SLionel Sambuc
12*0a6a1f1dSLionel Sambuc #include "lprefix.h"
13*0a6a1f1dSLionel Sambuc
14*0a6a1f1dSLionel Sambuc
15*0a6a1f1dSLionel Sambuc #include <stdarg.h>
16*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
17*0a6a1f1dSLionel Sambuc #include <stddef.h>
18*0a6a1f1dSLionel Sambuc #include <string.h>
19*0a6a1f1dSLionel Sambuc #endif
20*0a6a1f1dSLionel Sambuc
2111be35a1SLionel Sambuc #include "lua.h"
2211be35a1SLionel Sambuc
2311be35a1SLionel Sambuc #include "lapi.h"
2411be35a1SLionel Sambuc #include "lcode.h"
2511be35a1SLionel Sambuc #include "ldebug.h"
2611be35a1SLionel Sambuc #include "ldo.h"
2711be35a1SLionel Sambuc #include "lfunc.h"
2811be35a1SLionel Sambuc #include "lobject.h"
2911be35a1SLionel Sambuc #include "lopcodes.h"
3011be35a1SLionel Sambuc #include "lstate.h"
3111be35a1SLionel Sambuc #include "lstring.h"
3211be35a1SLionel Sambuc #include "ltable.h"
3311be35a1SLionel Sambuc #include "ltm.h"
3411be35a1SLionel Sambuc #include "lvm.h"
3511be35a1SLionel Sambuc
3611be35a1SLionel Sambuc
3711be35a1SLionel Sambuc
38*0a6a1f1dSLionel Sambuc #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
39*0a6a1f1dSLionel Sambuc
40*0a6a1f1dSLionel Sambuc
41*0a6a1f1dSLionel Sambuc /* Active Lua function (given call info) */
42*0a6a1f1dSLionel Sambuc #define ci_func(ci) (clLvalue((ci)->func))
43*0a6a1f1dSLionel Sambuc
44*0a6a1f1dSLionel Sambuc
4511be35a1SLionel Sambuc static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
4611be35a1SLionel Sambuc
4711be35a1SLionel Sambuc
currentpc(CallInfo * ci)48*0a6a1f1dSLionel Sambuc static int currentpc (CallInfo *ci) {
49*0a6a1f1dSLionel Sambuc lua_assert(isLua(ci));
50*0a6a1f1dSLionel Sambuc return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
5111be35a1SLionel Sambuc }
5211be35a1SLionel Sambuc
5311be35a1SLionel Sambuc
currentline(CallInfo * ci)54*0a6a1f1dSLionel Sambuc static int currentline (CallInfo *ci) {
55*0a6a1f1dSLionel Sambuc return getfuncline(ci_func(ci)->p, currentpc(ci));
56*0a6a1f1dSLionel Sambuc }
57*0a6a1f1dSLionel Sambuc
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc /*
60*0a6a1f1dSLionel Sambuc ** If function yielded, its 'func' can be in the 'extra' field. The
61*0a6a1f1dSLionel Sambuc ** next function restores 'func' to its correct value for debugging
62*0a6a1f1dSLionel Sambuc ** purposes. (It exchanges 'func' and 'extra'; so, when called again,
63*0a6a1f1dSLionel Sambuc ** after debugging, it also "re-restores" ** 'func' to its altered value.
64*0a6a1f1dSLionel Sambuc */
swapextra(lua_State * L)65*0a6a1f1dSLionel Sambuc static void swapextra (lua_State *L) {
66*0a6a1f1dSLionel Sambuc if (L->status == LUA_YIELD) {
67*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci; /* get function that yielded */
68*0a6a1f1dSLionel Sambuc StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
69*0a6a1f1dSLionel Sambuc ci->func = restorestack(L, ci->extra);
70*0a6a1f1dSLionel Sambuc ci->extra = savestack(L, temp);
71*0a6a1f1dSLionel Sambuc }
7211be35a1SLionel Sambuc }
7311be35a1SLionel Sambuc
7411be35a1SLionel Sambuc
7511be35a1SLionel Sambuc /*
7611be35a1SLionel Sambuc ** this function can be called asynchronous (e.g. during a signal)
7711be35a1SLionel Sambuc */
lua_sethook(lua_State * L,lua_Hook func,int mask,int count)78*0a6a1f1dSLionel Sambuc LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
7911be35a1SLionel Sambuc if (func == NULL || mask == 0) { /* turn off hooks? */
8011be35a1SLionel Sambuc mask = 0;
8111be35a1SLionel Sambuc func = NULL;
8211be35a1SLionel Sambuc }
83*0a6a1f1dSLionel Sambuc if (isLua(L->ci))
84*0a6a1f1dSLionel Sambuc L->oldpc = L->ci->u.l.savedpc;
8511be35a1SLionel Sambuc L->hook = func;
8611be35a1SLionel Sambuc L->basehookcount = count;
8711be35a1SLionel Sambuc resethookcount(L);
8811be35a1SLionel Sambuc L->hookmask = cast_byte(mask);
8911be35a1SLionel Sambuc }
9011be35a1SLionel Sambuc
9111be35a1SLionel Sambuc
lua_gethook(lua_State * L)9211be35a1SLionel Sambuc LUA_API lua_Hook lua_gethook (lua_State *L) {
9311be35a1SLionel Sambuc return L->hook;
9411be35a1SLionel Sambuc }
9511be35a1SLionel Sambuc
9611be35a1SLionel Sambuc
lua_gethookmask(lua_State * L)9711be35a1SLionel Sambuc LUA_API int lua_gethookmask (lua_State *L) {
9811be35a1SLionel Sambuc return L->hookmask;
9911be35a1SLionel Sambuc }
10011be35a1SLionel Sambuc
10111be35a1SLionel Sambuc
lua_gethookcount(lua_State * L)10211be35a1SLionel Sambuc LUA_API int lua_gethookcount (lua_State *L) {
10311be35a1SLionel Sambuc return L->basehookcount;
10411be35a1SLionel Sambuc }
10511be35a1SLionel Sambuc
10611be35a1SLionel Sambuc
lua_getstack(lua_State * L,int level,lua_Debug * ar)10711be35a1SLionel Sambuc LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
10811be35a1SLionel Sambuc int status;
10911be35a1SLionel Sambuc CallInfo *ci;
110*0a6a1f1dSLionel Sambuc if (level < 0) return 0; /* invalid (negative) level */
11111be35a1SLionel Sambuc lua_lock(L);
112*0a6a1f1dSLionel Sambuc for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
11311be35a1SLionel Sambuc level--;
114*0a6a1f1dSLionel Sambuc if (level == 0 && ci != &L->base_ci) { /* level found? */
11511be35a1SLionel Sambuc status = 1;
116*0a6a1f1dSLionel Sambuc ar->i_ci = ci;
11711be35a1SLionel Sambuc }
11811be35a1SLionel Sambuc else status = 0; /* no such level */
11911be35a1SLionel Sambuc lua_unlock(L);
12011be35a1SLionel Sambuc return status;
12111be35a1SLionel Sambuc }
12211be35a1SLionel Sambuc
12311be35a1SLionel Sambuc
upvalname(Proto * p,int uv)124*0a6a1f1dSLionel Sambuc static const char *upvalname (Proto *p, int uv) {
125*0a6a1f1dSLionel Sambuc TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
126*0a6a1f1dSLionel Sambuc if (s == NULL) return "?";
127*0a6a1f1dSLionel Sambuc else return getstr(s);
12811be35a1SLionel Sambuc }
12911be35a1SLionel Sambuc
13011be35a1SLionel Sambuc
findvararg(CallInfo * ci,int n,StkId * pos)131*0a6a1f1dSLionel Sambuc static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
132*0a6a1f1dSLionel Sambuc int nparams = clLvalue(ci->func)->p->numparams;
133*0a6a1f1dSLionel Sambuc if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
134*0a6a1f1dSLionel Sambuc return NULL; /* no such vararg */
13511be35a1SLionel Sambuc else {
136*0a6a1f1dSLionel Sambuc *pos = ci->func + nparams + n;
137*0a6a1f1dSLionel Sambuc return "(*vararg)"; /* generic name for any vararg */
13811be35a1SLionel Sambuc }
13911be35a1SLionel Sambuc }
14011be35a1SLionel Sambuc
14111be35a1SLionel Sambuc
findlocal(lua_State * L,CallInfo * ci,int n,StkId * pos)142*0a6a1f1dSLionel Sambuc static const char *findlocal (lua_State *L, CallInfo *ci, int n,
143*0a6a1f1dSLionel Sambuc StkId *pos) {
144*0a6a1f1dSLionel Sambuc const char *name = NULL;
145*0a6a1f1dSLionel Sambuc StkId base;
146*0a6a1f1dSLionel Sambuc if (isLua(ci)) {
147*0a6a1f1dSLionel Sambuc if (n < 0) /* access to vararg values? */
148*0a6a1f1dSLionel Sambuc return findvararg(ci, -n, pos);
149*0a6a1f1dSLionel Sambuc else {
150*0a6a1f1dSLionel Sambuc base = ci->u.l.base;
151*0a6a1f1dSLionel Sambuc name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
152*0a6a1f1dSLionel Sambuc }
153*0a6a1f1dSLionel Sambuc }
154*0a6a1f1dSLionel Sambuc else
155*0a6a1f1dSLionel Sambuc base = ci->func + 1;
156*0a6a1f1dSLionel Sambuc if (name == NULL) { /* no 'standard' name? */
157*0a6a1f1dSLionel Sambuc StkId limit = (ci == L->ci) ? L->top : ci->next->func;
158*0a6a1f1dSLionel Sambuc if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
159*0a6a1f1dSLionel Sambuc name = "(*temporary)"; /* generic name for any valid slot */
160*0a6a1f1dSLionel Sambuc else
161*0a6a1f1dSLionel Sambuc return NULL; /* no name */
162*0a6a1f1dSLionel Sambuc }
163*0a6a1f1dSLionel Sambuc *pos = base + (n - 1);
164*0a6a1f1dSLionel Sambuc return name;
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc
167*0a6a1f1dSLionel Sambuc
lua_getlocal(lua_State * L,const lua_Debug * ar,int n)16811be35a1SLionel Sambuc LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
169*0a6a1f1dSLionel Sambuc const char *name;
17011be35a1SLionel Sambuc lua_lock(L);
171*0a6a1f1dSLionel Sambuc swapextra(L);
172*0a6a1f1dSLionel Sambuc if (ar == NULL) { /* information about non-active function? */
173*0a6a1f1dSLionel Sambuc if (!isLfunction(L->top - 1)) /* not a Lua function? */
174*0a6a1f1dSLionel Sambuc name = NULL;
175*0a6a1f1dSLionel Sambuc else /* consider live variables at function start (parameters) */
176*0a6a1f1dSLionel Sambuc name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
177*0a6a1f1dSLionel Sambuc }
178*0a6a1f1dSLionel Sambuc else { /* active function; get information through 'ar' */
179*0a6a1f1dSLionel Sambuc StkId pos = NULL; /* to avoid warnings */
180*0a6a1f1dSLionel Sambuc name = findlocal(L, ar->i_ci, n, &pos);
181*0a6a1f1dSLionel Sambuc if (name) {
182*0a6a1f1dSLionel Sambuc setobj2s(L, L->top, pos);
183*0a6a1f1dSLionel Sambuc api_incr_top(L);
184*0a6a1f1dSLionel Sambuc }
185*0a6a1f1dSLionel Sambuc }
186*0a6a1f1dSLionel Sambuc swapextra(L);
18711be35a1SLionel Sambuc lua_unlock(L);
18811be35a1SLionel Sambuc return name;
18911be35a1SLionel Sambuc }
19011be35a1SLionel Sambuc
19111be35a1SLionel Sambuc
lua_setlocal(lua_State * L,const lua_Debug * ar,int n)19211be35a1SLionel Sambuc LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
193*0a6a1f1dSLionel Sambuc StkId pos = NULL; /* to avoid warnings */
194*0a6a1f1dSLionel Sambuc const char *name;
19511be35a1SLionel Sambuc lua_lock(L);
196*0a6a1f1dSLionel Sambuc swapextra(L);
197*0a6a1f1dSLionel Sambuc name = findlocal(L, ar->i_ci, n, &pos);
198*0a6a1f1dSLionel Sambuc if (name) {
199*0a6a1f1dSLionel Sambuc setobjs2s(L, pos, L->top - 1);
20011be35a1SLionel Sambuc L->top--; /* pop value */
201*0a6a1f1dSLionel Sambuc }
202*0a6a1f1dSLionel Sambuc swapextra(L);
20311be35a1SLionel Sambuc lua_unlock(L);
20411be35a1SLionel Sambuc return name;
20511be35a1SLionel Sambuc }
20611be35a1SLionel Sambuc
20711be35a1SLionel Sambuc
funcinfo(lua_Debug * ar,Closure * cl)20811be35a1SLionel Sambuc static void funcinfo (lua_Debug *ar, Closure *cl) {
209*0a6a1f1dSLionel Sambuc if (noLuaClosure(cl)) {
21011be35a1SLionel Sambuc ar->source = "=[C]";
21111be35a1SLionel Sambuc ar->linedefined = -1;
21211be35a1SLionel Sambuc ar->lastlinedefined = -1;
21311be35a1SLionel Sambuc ar->what = "C";
21411be35a1SLionel Sambuc }
21511be35a1SLionel Sambuc else {
216*0a6a1f1dSLionel Sambuc Proto *p = cl->l.p;
217*0a6a1f1dSLionel Sambuc ar->source = p->source ? getstr(p->source) : "=?";
218*0a6a1f1dSLionel Sambuc ar->linedefined = p->linedefined;
219*0a6a1f1dSLionel Sambuc ar->lastlinedefined = p->lastlinedefined;
22011be35a1SLionel Sambuc ar->what = (ar->linedefined == 0) ? "main" : "Lua";
22111be35a1SLionel Sambuc }
22211be35a1SLionel Sambuc luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
22311be35a1SLionel Sambuc }
22411be35a1SLionel Sambuc
22511be35a1SLionel Sambuc
collectvalidlines(lua_State * L,Closure * f)22611be35a1SLionel Sambuc static void collectvalidlines (lua_State *L, Closure *f) {
227*0a6a1f1dSLionel Sambuc if (noLuaClosure(f)) {
22811be35a1SLionel Sambuc setnilvalue(L->top);
229*0a6a1f1dSLionel Sambuc api_incr_top(L);
23011be35a1SLionel Sambuc }
23111be35a1SLionel Sambuc else {
23211be35a1SLionel Sambuc int i;
233*0a6a1f1dSLionel Sambuc TValue v;
234*0a6a1f1dSLionel Sambuc int *lineinfo = f->l.p->lineinfo;
235*0a6a1f1dSLionel Sambuc Table *t = luaH_new(L); /* new table to store active lines */
236*0a6a1f1dSLionel Sambuc sethvalue(L, L->top, t); /* push it on stack */
237*0a6a1f1dSLionel Sambuc api_incr_top(L);
238*0a6a1f1dSLionel Sambuc setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
239*0a6a1f1dSLionel Sambuc for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
240*0a6a1f1dSLionel Sambuc luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
24111be35a1SLionel Sambuc }
24211be35a1SLionel Sambuc }
24311be35a1SLionel Sambuc
24411be35a1SLionel Sambuc
auxgetinfo(lua_State * L,const char * what,lua_Debug * ar,Closure * f,CallInfo * ci)24511be35a1SLionel Sambuc static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
24611be35a1SLionel Sambuc Closure *f, CallInfo *ci) {
24711be35a1SLionel Sambuc int status = 1;
24811be35a1SLionel Sambuc for (; *what; what++) {
24911be35a1SLionel Sambuc switch (*what) {
25011be35a1SLionel Sambuc case 'S': {
25111be35a1SLionel Sambuc funcinfo(ar, f);
25211be35a1SLionel Sambuc break;
25311be35a1SLionel Sambuc }
25411be35a1SLionel Sambuc case 'l': {
255*0a6a1f1dSLionel Sambuc ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
25611be35a1SLionel Sambuc break;
25711be35a1SLionel Sambuc }
25811be35a1SLionel Sambuc case 'u': {
259*0a6a1f1dSLionel Sambuc ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
260*0a6a1f1dSLionel Sambuc if (noLuaClosure(f)) {
261*0a6a1f1dSLionel Sambuc ar->isvararg = 1;
262*0a6a1f1dSLionel Sambuc ar->nparams = 0;
263*0a6a1f1dSLionel Sambuc }
264*0a6a1f1dSLionel Sambuc else {
265*0a6a1f1dSLionel Sambuc ar->isvararg = f->l.p->is_vararg;
266*0a6a1f1dSLionel Sambuc ar->nparams = f->l.p->numparams;
267*0a6a1f1dSLionel Sambuc }
268*0a6a1f1dSLionel Sambuc break;
269*0a6a1f1dSLionel Sambuc }
270*0a6a1f1dSLionel Sambuc case 't': {
271*0a6a1f1dSLionel Sambuc ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
27211be35a1SLionel Sambuc break;
27311be35a1SLionel Sambuc }
27411be35a1SLionel Sambuc case 'n': {
275*0a6a1f1dSLionel Sambuc /* calling function is a known Lua function? */
276*0a6a1f1dSLionel Sambuc if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
277*0a6a1f1dSLionel Sambuc ar->namewhat = getfuncname(L, ci->previous, &ar->name);
278*0a6a1f1dSLionel Sambuc else
279*0a6a1f1dSLionel Sambuc ar->namewhat = NULL;
28011be35a1SLionel Sambuc if (ar->namewhat == NULL) {
28111be35a1SLionel Sambuc ar->namewhat = ""; /* not found */
28211be35a1SLionel Sambuc ar->name = NULL;
28311be35a1SLionel Sambuc }
28411be35a1SLionel Sambuc break;
28511be35a1SLionel Sambuc }
28611be35a1SLionel Sambuc case 'L':
28711be35a1SLionel Sambuc case 'f': /* handled by lua_getinfo */
28811be35a1SLionel Sambuc break;
28911be35a1SLionel Sambuc default: status = 0; /* invalid option */
29011be35a1SLionel Sambuc }
29111be35a1SLionel Sambuc }
29211be35a1SLionel Sambuc return status;
29311be35a1SLionel Sambuc }
29411be35a1SLionel Sambuc
29511be35a1SLionel Sambuc
lua_getinfo(lua_State * L,const char * what,lua_Debug * ar)29611be35a1SLionel Sambuc LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
29711be35a1SLionel Sambuc int status;
298*0a6a1f1dSLionel Sambuc Closure *cl;
299*0a6a1f1dSLionel Sambuc CallInfo *ci;
300*0a6a1f1dSLionel Sambuc StkId func;
30111be35a1SLionel Sambuc lua_lock(L);
302*0a6a1f1dSLionel Sambuc swapextra(L);
30311be35a1SLionel Sambuc if (*what == '>') {
304*0a6a1f1dSLionel Sambuc ci = NULL;
305*0a6a1f1dSLionel Sambuc func = L->top - 1;
306*0a6a1f1dSLionel Sambuc api_check(L, ttisfunction(func), "function expected");
30711be35a1SLionel Sambuc what++; /* skip the '>' */
30811be35a1SLionel Sambuc L->top--; /* pop function */
30911be35a1SLionel Sambuc }
310*0a6a1f1dSLionel Sambuc else {
311*0a6a1f1dSLionel Sambuc ci = ar->i_ci;
312*0a6a1f1dSLionel Sambuc func = ci->func;
31311be35a1SLionel Sambuc lua_assert(ttisfunction(ci->func));
31411be35a1SLionel Sambuc }
315*0a6a1f1dSLionel Sambuc cl = ttisclosure(func) ? clvalue(func) : NULL;
316*0a6a1f1dSLionel Sambuc status = auxgetinfo(L, what, ar, cl, ci);
31711be35a1SLionel Sambuc if (strchr(what, 'f')) {
318*0a6a1f1dSLionel Sambuc setobjs2s(L, L->top, func);
319*0a6a1f1dSLionel Sambuc api_incr_top(L);
32011be35a1SLionel Sambuc }
321*0a6a1f1dSLionel Sambuc swapextra(L); /* correct before option 'L', which can raise a mem. error */
32211be35a1SLionel Sambuc if (strchr(what, 'L'))
323*0a6a1f1dSLionel Sambuc collectvalidlines(L, cl);
32411be35a1SLionel Sambuc lua_unlock(L);
32511be35a1SLionel Sambuc return status;
32611be35a1SLionel Sambuc }
32711be35a1SLionel Sambuc
32811be35a1SLionel Sambuc
32911be35a1SLionel Sambuc /*
33011be35a1SLionel Sambuc ** {======================================================
331*0a6a1f1dSLionel Sambuc ** Symbolic Execution
33211be35a1SLionel Sambuc ** =======================================================
33311be35a1SLionel Sambuc */
33411be35a1SLionel Sambuc
335*0a6a1f1dSLionel Sambuc static const char *getobjname (Proto *p, int lastpc, int reg,
336*0a6a1f1dSLionel Sambuc const char **name);
33711be35a1SLionel Sambuc
33811be35a1SLionel Sambuc
339*0a6a1f1dSLionel Sambuc /*
340*0a6a1f1dSLionel Sambuc ** find a "name" for the RK value 'c'
341*0a6a1f1dSLionel Sambuc */
kname(Proto * p,int pc,int c,const char ** name)342*0a6a1f1dSLionel Sambuc static void kname (Proto *p, int pc, int c, const char **name) {
343*0a6a1f1dSLionel Sambuc if (ISK(c)) { /* is 'c' a constant? */
344*0a6a1f1dSLionel Sambuc TValue *kvalue = &p->k[INDEXK(c)];
345*0a6a1f1dSLionel Sambuc if (ttisstring(kvalue)) { /* literal constant? */
346*0a6a1f1dSLionel Sambuc *name = svalue(kvalue); /* it is its own name */
347*0a6a1f1dSLionel Sambuc return;
348*0a6a1f1dSLionel Sambuc }
349*0a6a1f1dSLionel Sambuc /* else no reasonable name found */
350*0a6a1f1dSLionel Sambuc }
351*0a6a1f1dSLionel Sambuc else { /* 'c' is a register */
352*0a6a1f1dSLionel Sambuc const char *what = getobjname(p, pc, c, name); /* search for 'c' */
353*0a6a1f1dSLionel Sambuc if (what && *what == 'c') { /* found a constant name? */
354*0a6a1f1dSLionel Sambuc return; /* 'name' already filled */
355*0a6a1f1dSLionel Sambuc }
356*0a6a1f1dSLionel Sambuc /* else no reasonable name found */
357*0a6a1f1dSLionel Sambuc }
358*0a6a1f1dSLionel Sambuc *name = "?"; /* no reasonable name found */
35911be35a1SLionel Sambuc }
36011be35a1SLionel Sambuc
36111be35a1SLionel Sambuc
filterpc(int pc,int jmptarget)362*0a6a1f1dSLionel Sambuc static int filterpc (int pc, int jmptarget) {
363*0a6a1f1dSLionel Sambuc if (pc < jmptarget) /* is code conditional (inside a jump)? */
364*0a6a1f1dSLionel Sambuc return -1; /* cannot know who sets that register */
365*0a6a1f1dSLionel Sambuc else return pc; /* current position sets that register */
36611be35a1SLionel Sambuc }
36711be35a1SLionel Sambuc
36811be35a1SLionel Sambuc
369*0a6a1f1dSLionel Sambuc /*
370*0a6a1f1dSLionel Sambuc ** try to find last instruction before 'lastpc' that modified register 'reg'
371*0a6a1f1dSLionel Sambuc */
findsetreg(Proto * p,int lastpc,int reg)372*0a6a1f1dSLionel Sambuc static int findsetreg (Proto *p, int lastpc, int reg) {
37311be35a1SLionel Sambuc int pc;
374*0a6a1f1dSLionel Sambuc int setreg = -1; /* keep last instruction that changed 'reg' */
375*0a6a1f1dSLionel Sambuc int jmptarget = 0; /* any code before this address is conditional */
37611be35a1SLionel Sambuc for (pc = 0; pc < lastpc; pc++) {
377*0a6a1f1dSLionel Sambuc Instruction i = p->code[pc];
37811be35a1SLionel Sambuc OpCode op = GET_OPCODE(i);
37911be35a1SLionel Sambuc int a = GETARG_A(i);
38011be35a1SLionel Sambuc switch (op) {
38111be35a1SLionel Sambuc case OP_LOADNIL: {
382*0a6a1f1dSLionel Sambuc int b = GETARG_B(i);
383*0a6a1f1dSLionel Sambuc if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
384*0a6a1f1dSLionel Sambuc setreg = filterpc(pc, jmptarget);
38511be35a1SLionel Sambuc break;
38611be35a1SLionel Sambuc }
387*0a6a1f1dSLionel Sambuc case OP_TFORCALL: {
388*0a6a1f1dSLionel Sambuc if (reg >= a + 2) /* affect all regs above its base */
389*0a6a1f1dSLionel Sambuc setreg = filterpc(pc, jmptarget);
39011be35a1SLionel Sambuc break;
39111be35a1SLionel Sambuc }
39211be35a1SLionel Sambuc case OP_CALL:
39311be35a1SLionel Sambuc case OP_TAILCALL: {
394*0a6a1f1dSLionel Sambuc if (reg >= a) /* affect all registers above base */
395*0a6a1f1dSLionel Sambuc setreg = filterpc(pc, jmptarget);
39611be35a1SLionel Sambuc break;
39711be35a1SLionel Sambuc }
398*0a6a1f1dSLionel Sambuc case OP_JMP: {
399*0a6a1f1dSLionel Sambuc int b = GETARG_sBx(i);
400*0a6a1f1dSLionel Sambuc int dest = pc + 1 + b;
401*0a6a1f1dSLionel Sambuc /* jump is forward and do not skip 'lastpc'? */
402*0a6a1f1dSLionel Sambuc if (pc < dest && dest <= lastpc) {
403*0a6a1f1dSLionel Sambuc if (dest > jmptarget)
404*0a6a1f1dSLionel Sambuc jmptarget = dest; /* update 'jmptarget' */
40511be35a1SLionel Sambuc }
40611be35a1SLionel Sambuc break;
40711be35a1SLionel Sambuc }
408*0a6a1f1dSLionel Sambuc default:
409*0a6a1f1dSLionel Sambuc if (testAMode(op) && reg == a) /* any instruction that set A */
410*0a6a1f1dSLionel Sambuc setreg = filterpc(pc, jmptarget);
41111be35a1SLionel Sambuc break;
41211be35a1SLionel Sambuc }
41311be35a1SLionel Sambuc }
414*0a6a1f1dSLionel Sambuc return setreg;
41511be35a1SLionel Sambuc }
41611be35a1SLionel Sambuc
41711be35a1SLionel Sambuc
getobjname(Proto * p,int lastpc,int reg,const char ** name)418*0a6a1f1dSLionel Sambuc static const char *getobjname (Proto *p, int lastpc, int reg,
41911be35a1SLionel Sambuc const char **name) {
420*0a6a1f1dSLionel Sambuc int pc;
421*0a6a1f1dSLionel Sambuc *name = luaF_getlocalname(p, reg + 1, lastpc);
42211be35a1SLionel Sambuc if (*name) /* is a local? */
42311be35a1SLionel Sambuc return "local";
424*0a6a1f1dSLionel Sambuc /* else try symbolic execution */
425*0a6a1f1dSLionel Sambuc pc = findsetreg(p, lastpc, reg);
426*0a6a1f1dSLionel Sambuc if (pc != -1) { /* could find instruction? */
427*0a6a1f1dSLionel Sambuc Instruction i = p->code[pc];
428*0a6a1f1dSLionel Sambuc OpCode op = GET_OPCODE(i);
429*0a6a1f1dSLionel Sambuc switch (op) {
43011be35a1SLionel Sambuc case OP_MOVE: {
431*0a6a1f1dSLionel Sambuc int b = GETARG_B(i); /* move from 'b' to 'a' */
432*0a6a1f1dSLionel Sambuc if (b < GETARG_A(i))
433*0a6a1f1dSLionel Sambuc return getobjname(p, pc, b, name); /* get name for 'b' */
43411be35a1SLionel Sambuc break;
43511be35a1SLionel Sambuc }
436*0a6a1f1dSLionel Sambuc case OP_GETTABUP:
43711be35a1SLionel Sambuc case OP_GETTABLE: {
43811be35a1SLionel Sambuc int k = GETARG_C(i); /* key index */
439*0a6a1f1dSLionel Sambuc int t = GETARG_B(i); /* table index */
440*0a6a1f1dSLionel Sambuc const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
441*0a6a1f1dSLionel Sambuc ? luaF_getlocalname(p, t + 1, pc)
442*0a6a1f1dSLionel Sambuc : upvalname(p, t);
443*0a6a1f1dSLionel Sambuc kname(p, pc, k, name);
444*0a6a1f1dSLionel Sambuc return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
44511be35a1SLionel Sambuc }
44611be35a1SLionel Sambuc case OP_GETUPVAL: {
447*0a6a1f1dSLionel Sambuc *name = upvalname(p, GETARG_B(i));
44811be35a1SLionel Sambuc return "upvalue";
44911be35a1SLionel Sambuc }
450*0a6a1f1dSLionel Sambuc case OP_LOADK:
451*0a6a1f1dSLionel Sambuc case OP_LOADKX: {
452*0a6a1f1dSLionel Sambuc int b = (op == OP_LOADK) ? GETARG_Bx(i)
453*0a6a1f1dSLionel Sambuc : GETARG_Ax(p->code[pc + 1]);
454*0a6a1f1dSLionel Sambuc if (ttisstring(&p->k[b])) {
455*0a6a1f1dSLionel Sambuc *name = svalue(&p->k[b]);
456*0a6a1f1dSLionel Sambuc return "constant";
457*0a6a1f1dSLionel Sambuc }
458*0a6a1f1dSLionel Sambuc break;
459*0a6a1f1dSLionel Sambuc }
46011be35a1SLionel Sambuc case OP_SELF: {
46111be35a1SLionel Sambuc int k = GETARG_C(i); /* key index */
462*0a6a1f1dSLionel Sambuc kname(p, pc, k, name);
46311be35a1SLionel Sambuc return "method";
46411be35a1SLionel Sambuc }
465*0a6a1f1dSLionel Sambuc default: break; /* go through to return NULL */
46611be35a1SLionel Sambuc }
46711be35a1SLionel Sambuc }
468*0a6a1f1dSLionel Sambuc return NULL; /* could not find reasonable name */
46911be35a1SLionel Sambuc }
47011be35a1SLionel Sambuc
47111be35a1SLionel Sambuc
getfuncname(lua_State * L,CallInfo * ci,const char ** name)47211be35a1SLionel Sambuc static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
473*0a6a1f1dSLionel Sambuc TMS tm = (TMS)0; /* to avoid warnings */
474*0a6a1f1dSLionel Sambuc Proto *p = ci_func(ci)->p; /* calling function */
475*0a6a1f1dSLionel Sambuc int pc = currentpc(ci); /* calling instruction index */
476*0a6a1f1dSLionel Sambuc Instruction i = p->code[pc]; /* calling instruction */
477*0a6a1f1dSLionel Sambuc if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
478*0a6a1f1dSLionel Sambuc *name = "?";
479*0a6a1f1dSLionel Sambuc return "hook";
480*0a6a1f1dSLionel Sambuc }
481*0a6a1f1dSLionel Sambuc switch (GET_OPCODE(i)) {
482*0a6a1f1dSLionel Sambuc case OP_CALL:
483*0a6a1f1dSLionel Sambuc case OP_TAILCALL: /* get function name */
484*0a6a1f1dSLionel Sambuc return getobjname(p, pc, GETARG_A(i), name);
485*0a6a1f1dSLionel Sambuc case OP_TFORCALL: { /* for iterator */
486*0a6a1f1dSLionel Sambuc *name = "for iterator";
487*0a6a1f1dSLionel Sambuc return "for iterator";
488*0a6a1f1dSLionel Sambuc }
489*0a6a1f1dSLionel Sambuc /* all other instructions can call only through metamethods */
490*0a6a1f1dSLionel Sambuc case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
491*0a6a1f1dSLionel Sambuc tm = TM_INDEX;
492*0a6a1f1dSLionel Sambuc break;
493*0a6a1f1dSLionel Sambuc case OP_SETTABUP: case OP_SETTABLE:
494*0a6a1f1dSLionel Sambuc tm = TM_NEWINDEX;
495*0a6a1f1dSLionel Sambuc break;
496*0a6a1f1dSLionel Sambuc case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
497*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
498*0a6a1f1dSLionel Sambuc case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
499*0a6a1f1dSLionel Sambuc #else /* _KERNEL */
500*0a6a1f1dSLionel Sambuc case OP_IDIV: case OP_BAND:
501*0a6a1f1dSLionel Sambuc #endif
502*0a6a1f1dSLionel Sambuc case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
503*0a6a1f1dSLionel Sambuc int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */
504*0a6a1f1dSLionel Sambuc tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */
505*0a6a1f1dSLionel Sambuc break;
506*0a6a1f1dSLionel Sambuc }
507*0a6a1f1dSLionel Sambuc case OP_UNM: tm = TM_UNM; break;
508*0a6a1f1dSLionel Sambuc case OP_BNOT: tm = TM_BNOT; break;
509*0a6a1f1dSLionel Sambuc case OP_LEN: tm = TM_LEN; break;
510*0a6a1f1dSLionel Sambuc case OP_CONCAT: tm = TM_CONCAT; break;
511*0a6a1f1dSLionel Sambuc case OP_EQ: tm = TM_EQ; break;
512*0a6a1f1dSLionel Sambuc case OP_LT: tm = TM_LT; break;
513*0a6a1f1dSLionel Sambuc case OP_LE: tm = TM_LE; break;
514*0a6a1f1dSLionel Sambuc default: lua_assert(0); /* other instructions cannot call a function */
515*0a6a1f1dSLionel Sambuc }
516*0a6a1f1dSLionel Sambuc *name = getstr(G(L)->tmname[tm]);
517*0a6a1f1dSLionel Sambuc return "metamethod";
51811be35a1SLionel Sambuc }
51911be35a1SLionel Sambuc
520*0a6a1f1dSLionel Sambuc /* }====================================================== */
52111be35a1SLionel Sambuc
522*0a6a1f1dSLionel Sambuc
523*0a6a1f1dSLionel Sambuc
524*0a6a1f1dSLionel Sambuc /*
525*0a6a1f1dSLionel Sambuc ** The subtraction of two potentially unrelated pointers is
526*0a6a1f1dSLionel Sambuc ** not ISO C, but it should not crash a program; the subsequent
527*0a6a1f1dSLionel Sambuc ** checks are ISO C and ensure a correct result.
528*0a6a1f1dSLionel Sambuc */
isinstack(CallInfo * ci,const TValue * o)52911be35a1SLionel Sambuc static int isinstack (CallInfo *ci, const TValue *o) {
530*0a6a1f1dSLionel Sambuc ptrdiff_t i = o - ci->u.l.base;
531*0a6a1f1dSLionel Sambuc return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
53211be35a1SLionel Sambuc }
53311be35a1SLionel Sambuc
53411be35a1SLionel Sambuc
535*0a6a1f1dSLionel Sambuc /*
536*0a6a1f1dSLionel Sambuc ** Checks whether value 'o' came from an upvalue. (That can only happen
537*0a6a1f1dSLionel Sambuc ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
538*0a6a1f1dSLionel Sambuc ** upvalues.)
539*0a6a1f1dSLionel Sambuc */
getupvalname(CallInfo * ci,const TValue * o,const char ** name)540*0a6a1f1dSLionel Sambuc static const char *getupvalname (CallInfo *ci, const TValue *o,
541*0a6a1f1dSLionel Sambuc const char **name) {
542*0a6a1f1dSLionel Sambuc LClosure *c = ci_func(ci);
543*0a6a1f1dSLionel Sambuc int i;
544*0a6a1f1dSLionel Sambuc for (i = 0; i < c->nupvalues; i++) {
545*0a6a1f1dSLionel Sambuc if (c->upvals[i]->v == o) {
546*0a6a1f1dSLionel Sambuc *name = upvalname(c->p, i);
547*0a6a1f1dSLionel Sambuc return "upvalue";
548*0a6a1f1dSLionel Sambuc }
549*0a6a1f1dSLionel Sambuc }
550*0a6a1f1dSLionel Sambuc return NULL;
55111be35a1SLionel Sambuc }
55211be35a1SLionel Sambuc
55311be35a1SLionel Sambuc
varinfo(lua_State * L,const TValue * o)554*0a6a1f1dSLionel Sambuc static const char *varinfo (lua_State *L, const TValue *o) {
555*0a6a1f1dSLionel Sambuc const char *name = NULL; /* to avoid warnings */
556*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
557*0a6a1f1dSLionel Sambuc const char *kind = NULL;
558*0a6a1f1dSLionel Sambuc if (isLua(ci)) {
559*0a6a1f1dSLionel Sambuc kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
560*0a6a1f1dSLionel Sambuc if (!kind && isinstack(ci, o)) /* no? try a register */
561*0a6a1f1dSLionel Sambuc kind = getobjname(ci_func(ci)->p, currentpc(ci),
562*0a6a1f1dSLionel Sambuc cast_int(o - ci->u.l.base), &name);
563*0a6a1f1dSLionel Sambuc }
564*0a6a1f1dSLionel Sambuc return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
565*0a6a1f1dSLionel Sambuc }
566*0a6a1f1dSLionel Sambuc
567*0a6a1f1dSLionel Sambuc
luaG_typeerror(lua_State * L,const TValue * o,const char * op)568*0a6a1f1dSLionel Sambuc l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
569*0a6a1f1dSLionel Sambuc const char *t = objtypename(o);
570*0a6a1f1dSLionel Sambuc luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
571*0a6a1f1dSLionel Sambuc }
572*0a6a1f1dSLionel Sambuc
573*0a6a1f1dSLionel Sambuc
luaG_concaterror(lua_State * L,const TValue * p1,const TValue * p2)574*0a6a1f1dSLionel Sambuc l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
575*0a6a1f1dSLionel Sambuc if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
57611be35a1SLionel Sambuc luaG_typeerror(L, p1, "concatenate");
57711be35a1SLionel Sambuc }
57811be35a1SLionel Sambuc
57911be35a1SLionel Sambuc
luaG_opinterror(lua_State * L,const TValue * p1,const TValue * p2,const char * msg)580*0a6a1f1dSLionel Sambuc l_noret luaG_opinterror (lua_State *L, const TValue *p1,
581*0a6a1f1dSLionel Sambuc const TValue *p2, const char *msg) {
582*0a6a1f1dSLionel Sambuc lua_Number temp;
583*0a6a1f1dSLionel Sambuc if (!tonumber(p1, &temp)) /* first operand is wrong? */
584*0a6a1f1dSLionel Sambuc p2 = p1; /* now second is wrong */
585*0a6a1f1dSLionel Sambuc luaG_typeerror(L, p2, msg);
58611be35a1SLionel Sambuc }
58711be35a1SLionel Sambuc
58811be35a1SLionel Sambuc
589*0a6a1f1dSLionel Sambuc /*
590*0a6a1f1dSLionel Sambuc ** Error when both values are convertible to numbers, but not to integers
591*0a6a1f1dSLionel Sambuc */
luaG_tointerror(lua_State * L,const TValue * p1,const TValue * p2)592*0a6a1f1dSLionel Sambuc l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
593*0a6a1f1dSLionel Sambuc lua_Integer temp;
594*0a6a1f1dSLionel Sambuc if (!tointeger(p1, &temp))
595*0a6a1f1dSLionel Sambuc p2 = p1;
596*0a6a1f1dSLionel Sambuc luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
597*0a6a1f1dSLionel Sambuc }
598*0a6a1f1dSLionel Sambuc
599*0a6a1f1dSLionel Sambuc
luaG_ordererror(lua_State * L,const TValue * p1,const TValue * p2)600*0a6a1f1dSLionel Sambuc l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
601*0a6a1f1dSLionel Sambuc const char *t1 = objtypename(p1);
602*0a6a1f1dSLionel Sambuc const char *t2 = objtypename(p2);
603*0a6a1f1dSLionel Sambuc if (t1 == t2)
60411be35a1SLionel Sambuc luaG_runerror(L, "attempt to compare two %s values", t1);
60511be35a1SLionel Sambuc else
60611be35a1SLionel Sambuc luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
60711be35a1SLionel Sambuc }
60811be35a1SLionel Sambuc
60911be35a1SLionel Sambuc
610*0a6a1f1dSLionel Sambuc /* add src:line information to 'msg' */
luaG_addinfo(lua_State * L,const char * msg,TString * src,int line)611*0a6a1f1dSLionel Sambuc const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
612*0a6a1f1dSLionel Sambuc int line) {
613*0a6a1f1dSLionel Sambuc char buff[LUA_IDSIZE];
614*0a6a1f1dSLionel Sambuc if (src)
615*0a6a1f1dSLionel Sambuc luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
616*0a6a1f1dSLionel Sambuc else { /* no source available; use "?" instead */
617*0a6a1f1dSLionel Sambuc buff[0] = '?'; buff[1] = '\0';
61811be35a1SLionel Sambuc }
619*0a6a1f1dSLionel Sambuc return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
62011be35a1SLionel Sambuc }
62111be35a1SLionel Sambuc
62211be35a1SLionel Sambuc
luaG_errormsg(lua_State * L)623*0a6a1f1dSLionel Sambuc l_noret luaG_errormsg (lua_State *L) {
62411be35a1SLionel Sambuc if (L->errfunc != 0) { /* is there an error handling function? */
62511be35a1SLionel Sambuc StkId errfunc = restorestack(L, L->errfunc);
62611be35a1SLionel Sambuc setobjs2s(L, L->top, L->top - 1); /* move argument */
62711be35a1SLionel Sambuc setobjs2s(L, L->top - 1, errfunc); /* push function */
628*0a6a1f1dSLionel Sambuc L->top++; /* assume EXTRA_STACK */
629*0a6a1f1dSLionel Sambuc luaD_call(L, L->top - 2, 1, 0); /* call it */
63011be35a1SLionel Sambuc }
63111be35a1SLionel Sambuc luaD_throw(L, LUA_ERRRUN);
63211be35a1SLionel Sambuc }
63311be35a1SLionel Sambuc
63411be35a1SLionel Sambuc
luaG_runerror(lua_State * L,const char * fmt,...)635*0a6a1f1dSLionel Sambuc l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
636*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
637*0a6a1f1dSLionel Sambuc const char *msg;
63811be35a1SLionel Sambuc va_list argp;
63911be35a1SLionel Sambuc va_start(argp, fmt);
640*0a6a1f1dSLionel Sambuc msg = luaO_pushvfstring(L, fmt, argp); /* format message */
64111be35a1SLionel Sambuc va_end(argp);
642*0a6a1f1dSLionel Sambuc if (isLua(ci)) /* if Lua function, add source:line information */
643*0a6a1f1dSLionel Sambuc luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
64411be35a1SLionel Sambuc luaG_errormsg(L);
64511be35a1SLionel Sambuc }
64611be35a1SLionel Sambuc
647*0a6a1f1dSLionel Sambuc
luaG_traceexec(lua_State * L)648*0a6a1f1dSLionel Sambuc void luaG_traceexec (lua_State *L) {
649*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
650*0a6a1f1dSLionel Sambuc lu_byte mask = L->hookmask;
651*0a6a1f1dSLionel Sambuc int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
652*0a6a1f1dSLionel Sambuc if (counthook)
653*0a6a1f1dSLionel Sambuc resethookcount(L); /* reset count */
654*0a6a1f1dSLionel Sambuc if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
655*0a6a1f1dSLionel Sambuc ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
656*0a6a1f1dSLionel Sambuc return; /* do not call hook again (VM yielded, so it did not move) */
657*0a6a1f1dSLionel Sambuc }
658*0a6a1f1dSLionel Sambuc if (counthook)
659*0a6a1f1dSLionel Sambuc luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
660*0a6a1f1dSLionel Sambuc if (mask & LUA_MASKLINE) {
661*0a6a1f1dSLionel Sambuc Proto *p = ci_func(ci)->p;
662*0a6a1f1dSLionel Sambuc int npc = pcRel(ci->u.l.savedpc, p);
663*0a6a1f1dSLionel Sambuc int newline = getfuncline(p, npc);
664*0a6a1f1dSLionel Sambuc if (npc == 0 || /* call linehook when enter a new function, */
665*0a6a1f1dSLionel Sambuc ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
666*0a6a1f1dSLionel Sambuc newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
667*0a6a1f1dSLionel Sambuc luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
668*0a6a1f1dSLionel Sambuc }
669*0a6a1f1dSLionel Sambuc L->oldpc = ci->u.l.savedpc;
670*0a6a1f1dSLionel Sambuc if (L->status == LUA_YIELD) { /* did hook yield? */
671*0a6a1f1dSLionel Sambuc if (counthook)
672*0a6a1f1dSLionel Sambuc L->hookcount = 1; /* undo decrement to zero */
673*0a6a1f1dSLionel Sambuc ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
674*0a6a1f1dSLionel Sambuc ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
675*0a6a1f1dSLionel Sambuc ci->func = L->top - 1; /* protect stack below results */
676*0a6a1f1dSLionel Sambuc luaD_throw(L, LUA_YIELD);
677*0a6a1f1dSLionel Sambuc }
678*0a6a1f1dSLionel Sambuc }
679*0a6a1f1dSLionel Sambuc
680