1*dfc11533SChris Williamson /*
2*dfc11533SChris Williamson ** $Id: ldebug.c,v 2.90.1.4 2015/02/19 17:05:13 roberto Exp $
3*dfc11533SChris Williamson ** Debug Interface
4*dfc11533SChris Williamson ** See Copyright Notice in lua.h
5*dfc11533SChris Williamson */
6*dfc11533SChris Williamson
7*dfc11533SChris Williamson
8*dfc11533SChris Williamson #include <sys/zfs_context.h>
9*dfc11533SChris Williamson
10*dfc11533SChris Williamson #define ldebug_c
11*dfc11533SChris Williamson #define LUA_CORE
12*dfc11533SChris Williamson
13*dfc11533SChris Williamson #include "lua.h"
14*dfc11533SChris Williamson
15*dfc11533SChris Williamson #include "lapi.h"
16*dfc11533SChris Williamson #include "lcode.h"
17*dfc11533SChris Williamson #include "ldebug.h"
18*dfc11533SChris Williamson #include "ldo.h"
19*dfc11533SChris Williamson #include "lfunc.h"
20*dfc11533SChris Williamson #include "lobject.h"
21*dfc11533SChris Williamson #include "lopcodes.h"
22*dfc11533SChris Williamson #include "lstate.h"
23*dfc11533SChris Williamson #include "lstring.h"
24*dfc11533SChris Williamson #include "ltable.h"
25*dfc11533SChris Williamson #include "ltm.h"
26*dfc11533SChris Williamson #include "lvm.h"
27*dfc11533SChris Williamson
28*dfc11533SChris Williamson
29*dfc11533SChris Williamson
30*dfc11533SChris Williamson #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
31*dfc11533SChris Williamson
32*dfc11533SChris Williamson
33*dfc11533SChris Williamson static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
34*dfc11533SChris Williamson
35*dfc11533SChris Williamson
currentpc(CallInfo * ci)36*dfc11533SChris Williamson static int currentpc (CallInfo *ci) {
37*dfc11533SChris Williamson lua_assert(isLua(ci));
38*dfc11533SChris Williamson return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
39*dfc11533SChris Williamson }
40*dfc11533SChris Williamson
41*dfc11533SChris Williamson
currentline(CallInfo * ci)42*dfc11533SChris Williamson static int currentline (CallInfo *ci) {
43*dfc11533SChris Williamson return getfuncline(ci_func(ci)->p, currentpc(ci));
44*dfc11533SChris Williamson }
45*dfc11533SChris Williamson
46*dfc11533SChris Williamson
swapextra(lua_State * L)47*dfc11533SChris Williamson static void swapextra (lua_State *L) {
48*dfc11533SChris Williamson if (L->status == LUA_YIELD) {
49*dfc11533SChris Williamson CallInfo *ci = L->ci; /* get function that yielded */
50*dfc11533SChris Williamson StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
51*dfc11533SChris Williamson ci->func = restorestack(L, ci->extra);
52*dfc11533SChris Williamson ci->extra = savestack(L, temp);
53*dfc11533SChris Williamson }
54*dfc11533SChris Williamson }
55*dfc11533SChris Williamson
56*dfc11533SChris Williamson
57*dfc11533SChris Williamson /*
58*dfc11533SChris Williamson ** this function can be called asynchronous (e.g. during a signal)
59*dfc11533SChris Williamson */
lua_sethook(lua_State * L,lua_Hook func,int mask,int count)60*dfc11533SChris Williamson LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
61*dfc11533SChris Williamson if (func == NULL || mask == 0) { /* turn off hooks? */
62*dfc11533SChris Williamson mask = 0;
63*dfc11533SChris Williamson func = NULL;
64*dfc11533SChris Williamson }
65*dfc11533SChris Williamson if (isLua(L->ci))
66*dfc11533SChris Williamson L->oldpc = L->ci->u.l.savedpc;
67*dfc11533SChris Williamson L->hook = func;
68*dfc11533SChris Williamson L->basehookcount = count;
69*dfc11533SChris Williamson resethookcount(L);
70*dfc11533SChris Williamson L->hookmask = cast_byte(mask);
71*dfc11533SChris Williamson return 1;
72*dfc11533SChris Williamson }
73*dfc11533SChris Williamson
74*dfc11533SChris Williamson
lua_gethook(lua_State * L)75*dfc11533SChris Williamson LUA_API lua_Hook lua_gethook (lua_State *L) {
76*dfc11533SChris Williamson return L->hook;
77*dfc11533SChris Williamson }
78*dfc11533SChris Williamson
79*dfc11533SChris Williamson
lua_gethookmask(lua_State * L)80*dfc11533SChris Williamson LUA_API int lua_gethookmask (lua_State *L) {
81*dfc11533SChris Williamson return L->hookmask;
82*dfc11533SChris Williamson }
83*dfc11533SChris Williamson
84*dfc11533SChris Williamson
lua_gethookcount(lua_State * L)85*dfc11533SChris Williamson LUA_API int lua_gethookcount (lua_State *L) {
86*dfc11533SChris Williamson return L->basehookcount;
87*dfc11533SChris Williamson }
88*dfc11533SChris Williamson
89*dfc11533SChris Williamson
lua_getstack(lua_State * L,int level,lua_Debug * ar)90*dfc11533SChris Williamson LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
91*dfc11533SChris Williamson int status;
92*dfc11533SChris Williamson CallInfo *ci;
93*dfc11533SChris Williamson if (level < 0) return 0; /* invalid (negative) level */
94*dfc11533SChris Williamson lua_lock(L);
95*dfc11533SChris Williamson for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
96*dfc11533SChris Williamson level--;
97*dfc11533SChris Williamson if (level == 0 && ci != &L->base_ci) { /* level found? */
98*dfc11533SChris Williamson status = 1;
99*dfc11533SChris Williamson ar->i_ci = ci;
100*dfc11533SChris Williamson }
101*dfc11533SChris Williamson else status = 0; /* no such level */
102*dfc11533SChris Williamson lua_unlock(L);
103*dfc11533SChris Williamson return status;
104*dfc11533SChris Williamson }
105*dfc11533SChris Williamson
106*dfc11533SChris Williamson
upvalname(Proto * p,int uv)107*dfc11533SChris Williamson static const char *upvalname (Proto *p, int uv) {
108*dfc11533SChris Williamson TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
109*dfc11533SChris Williamson if (s == NULL) return "?";
110*dfc11533SChris Williamson else return getstr(s);
111*dfc11533SChris Williamson }
112*dfc11533SChris Williamson
113*dfc11533SChris Williamson
findvararg(CallInfo * ci,int n,StkId * pos)114*dfc11533SChris Williamson static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
115*dfc11533SChris Williamson int nparams = clLvalue(ci->func)->p->numparams;
116*dfc11533SChris Williamson if (n >= ci->u.l.base - ci->func - nparams)
117*dfc11533SChris Williamson return NULL; /* no such vararg */
118*dfc11533SChris Williamson else {
119*dfc11533SChris Williamson *pos = ci->func + nparams + n;
120*dfc11533SChris Williamson return "(*vararg)"; /* generic name for any vararg */
121*dfc11533SChris Williamson }
122*dfc11533SChris Williamson }
123*dfc11533SChris Williamson
124*dfc11533SChris Williamson
findlocal(lua_State * L,CallInfo * ci,int n,StkId * pos)125*dfc11533SChris Williamson static const char *findlocal (lua_State *L, CallInfo *ci, int n,
126*dfc11533SChris Williamson StkId *pos) {
127*dfc11533SChris Williamson const char *name = NULL;
128*dfc11533SChris Williamson StkId base;
129*dfc11533SChris Williamson if (isLua(ci)) {
130*dfc11533SChris Williamson if (n < 0) /* access to vararg values? */
131*dfc11533SChris Williamson return findvararg(ci, -n, pos);
132*dfc11533SChris Williamson else {
133*dfc11533SChris Williamson base = ci->u.l.base;
134*dfc11533SChris Williamson name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
135*dfc11533SChris Williamson }
136*dfc11533SChris Williamson }
137*dfc11533SChris Williamson else
138*dfc11533SChris Williamson base = ci->func + 1;
139*dfc11533SChris Williamson if (name == NULL) { /* no 'standard' name? */
140*dfc11533SChris Williamson StkId limit = (ci == L->ci) ? L->top : ci->next->func;
141*dfc11533SChris Williamson if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
142*dfc11533SChris Williamson name = "(*temporary)"; /* generic name for any valid slot */
143*dfc11533SChris Williamson else
144*dfc11533SChris Williamson return NULL; /* no name */
145*dfc11533SChris Williamson }
146*dfc11533SChris Williamson *pos = base + (n - 1);
147*dfc11533SChris Williamson return name;
148*dfc11533SChris Williamson }
149*dfc11533SChris Williamson
150*dfc11533SChris Williamson
lua_getlocal(lua_State * L,const lua_Debug * ar,int n)151*dfc11533SChris Williamson LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
152*dfc11533SChris Williamson const char *name;
153*dfc11533SChris Williamson lua_lock(L);
154*dfc11533SChris Williamson swapextra(L);
155*dfc11533SChris Williamson if (ar == NULL) { /* information about non-active function? */
156*dfc11533SChris Williamson if (!isLfunction(L->top - 1)) /* not a Lua function? */
157*dfc11533SChris Williamson name = NULL;
158*dfc11533SChris Williamson else /* consider live variables at function start (parameters) */
159*dfc11533SChris Williamson name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
160*dfc11533SChris Williamson }
161*dfc11533SChris Williamson else { /* active function; get information through 'ar' */
162*dfc11533SChris Williamson StkId pos = 0; /* to avoid warnings */
163*dfc11533SChris Williamson name = findlocal(L, ar->i_ci, n, &pos);
164*dfc11533SChris Williamson if (name) {
165*dfc11533SChris Williamson setobj2s(L, L->top, pos);
166*dfc11533SChris Williamson api_incr_top(L);
167*dfc11533SChris Williamson }
168*dfc11533SChris Williamson }
169*dfc11533SChris Williamson swapextra(L);
170*dfc11533SChris Williamson lua_unlock(L);
171*dfc11533SChris Williamson return name;
172*dfc11533SChris Williamson }
173*dfc11533SChris Williamson
174*dfc11533SChris Williamson
lua_setlocal(lua_State * L,const lua_Debug * ar,int n)175*dfc11533SChris Williamson LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
176*dfc11533SChris Williamson StkId pos = 0; /* to avoid warnings */
177*dfc11533SChris Williamson const char *name;
178*dfc11533SChris Williamson lua_lock(L);
179*dfc11533SChris Williamson swapextra(L);
180*dfc11533SChris Williamson name = findlocal(L, ar->i_ci, n, &pos);
181*dfc11533SChris Williamson if (name)
182*dfc11533SChris Williamson setobjs2s(L, pos, L->top - 1);
183*dfc11533SChris Williamson L->top--; /* pop value */
184*dfc11533SChris Williamson swapextra(L);
185*dfc11533SChris Williamson lua_unlock(L);
186*dfc11533SChris Williamson return name;
187*dfc11533SChris Williamson }
188*dfc11533SChris Williamson
189*dfc11533SChris Williamson
funcinfo(lua_Debug * ar,Closure * cl)190*dfc11533SChris Williamson static void funcinfo (lua_Debug *ar, Closure *cl) {
191*dfc11533SChris Williamson if (noLuaClosure(cl)) {
192*dfc11533SChris Williamson ar->source = "=[C]";
193*dfc11533SChris Williamson ar->linedefined = -1;
194*dfc11533SChris Williamson ar->lastlinedefined = -1;
195*dfc11533SChris Williamson ar->what = "C";
196*dfc11533SChris Williamson }
197*dfc11533SChris Williamson else {
198*dfc11533SChris Williamson Proto *p = cl->l.p;
199*dfc11533SChris Williamson ar->source = p->source ? getstr(p->source) : "=?";
200*dfc11533SChris Williamson ar->linedefined = p->linedefined;
201*dfc11533SChris Williamson ar->lastlinedefined = p->lastlinedefined;
202*dfc11533SChris Williamson ar->what = (ar->linedefined == 0) ? "main" : "Lua";
203*dfc11533SChris Williamson }
204*dfc11533SChris Williamson luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
205*dfc11533SChris Williamson }
206*dfc11533SChris Williamson
207*dfc11533SChris Williamson
collectvalidlines(lua_State * L,Closure * f)208*dfc11533SChris Williamson static void collectvalidlines (lua_State *L, Closure *f) {
209*dfc11533SChris Williamson if (noLuaClosure(f)) {
210*dfc11533SChris Williamson setnilvalue(L->top);
211*dfc11533SChris Williamson api_incr_top(L);
212*dfc11533SChris Williamson }
213*dfc11533SChris Williamson else {
214*dfc11533SChris Williamson int i;
215*dfc11533SChris Williamson TValue v;
216*dfc11533SChris Williamson int *lineinfo = f->l.p->lineinfo;
217*dfc11533SChris Williamson Table *t = luaH_new(L); /* new table to store active lines */
218*dfc11533SChris Williamson sethvalue(L, L->top, t); /* push it on stack */
219*dfc11533SChris Williamson api_incr_top(L);
220*dfc11533SChris Williamson setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
221*dfc11533SChris Williamson for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
222*dfc11533SChris Williamson luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
223*dfc11533SChris Williamson }
224*dfc11533SChris Williamson }
225*dfc11533SChris Williamson
226*dfc11533SChris Williamson
auxgetinfo(lua_State * L,const char * what,lua_Debug * ar,Closure * f,CallInfo * ci)227*dfc11533SChris Williamson static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
228*dfc11533SChris Williamson Closure *f, CallInfo *ci) {
229*dfc11533SChris Williamson int status = 1;
230*dfc11533SChris Williamson for (; *what; what++) {
231*dfc11533SChris Williamson switch (*what) {
232*dfc11533SChris Williamson case 'S': {
233*dfc11533SChris Williamson funcinfo(ar, f);
234*dfc11533SChris Williamson break;
235*dfc11533SChris Williamson }
236*dfc11533SChris Williamson case 'l': {
237*dfc11533SChris Williamson ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
238*dfc11533SChris Williamson break;
239*dfc11533SChris Williamson }
240*dfc11533SChris Williamson case 'u': {
241*dfc11533SChris Williamson ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
242*dfc11533SChris Williamson if (noLuaClosure(f)) {
243*dfc11533SChris Williamson ar->isvararg = 1;
244*dfc11533SChris Williamson ar->nparams = 0;
245*dfc11533SChris Williamson }
246*dfc11533SChris Williamson else {
247*dfc11533SChris Williamson ar->isvararg = f->l.p->is_vararg;
248*dfc11533SChris Williamson ar->nparams = f->l.p->numparams;
249*dfc11533SChris Williamson }
250*dfc11533SChris Williamson break;
251*dfc11533SChris Williamson }
252*dfc11533SChris Williamson case 't': {
253*dfc11533SChris Williamson ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
254*dfc11533SChris Williamson break;
255*dfc11533SChris Williamson }
256*dfc11533SChris Williamson case 'n': {
257*dfc11533SChris Williamson /* calling function is a known Lua function? */
258*dfc11533SChris Williamson if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
259*dfc11533SChris Williamson ar->namewhat = getfuncname(L, ci->previous, &ar->name);
260*dfc11533SChris Williamson else
261*dfc11533SChris Williamson ar->namewhat = NULL;
262*dfc11533SChris Williamson if (ar->namewhat == NULL) {
263*dfc11533SChris Williamson ar->namewhat = ""; /* not found */
264*dfc11533SChris Williamson ar->name = NULL;
265*dfc11533SChris Williamson }
266*dfc11533SChris Williamson break;
267*dfc11533SChris Williamson }
268*dfc11533SChris Williamson case 'L':
269*dfc11533SChris Williamson case 'f': /* handled by lua_getinfo */
270*dfc11533SChris Williamson break;
271*dfc11533SChris Williamson default: status = 0; /* invalid option */
272*dfc11533SChris Williamson }
273*dfc11533SChris Williamson }
274*dfc11533SChris Williamson return status;
275*dfc11533SChris Williamson }
276*dfc11533SChris Williamson
277*dfc11533SChris Williamson
lua_getinfo(lua_State * L,const char * what,lua_Debug * ar)278*dfc11533SChris Williamson LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
279*dfc11533SChris Williamson int status;
280*dfc11533SChris Williamson Closure *cl;
281*dfc11533SChris Williamson CallInfo *ci;
282*dfc11533SChris Williamson StkId func;
283*dfc11533SChris Williamson lua_lock(L);
284*dfc11533SChris Williamson swapextra(L);
285*dfc11533SChris Williamson if (*what == '>') {
286*dfc11533SChris Williamson ci = NULL;
287*dfc11533SChris Williamson func = L->top - 1;
288*dfc11533SChris Williamson api_check(L, ttisfunction(func), "function expected");
289*dfc11533SChris Williamson what++; /* skip the '>' */
290*dfc11533SChris Williamson L->top--; /* pop function */
291*dfc11533SChris Williamson }
292*dfc11533SChris Williamson else {
293*dfc11533SChris Williamson ci = ar->i_ci;
294*dfc11533SChris Williamson func = ci->func;
295*dfc11533SChris Williamson lua_assert(ttisfunction(ci->func));
296*dfc11533SChris Williamson }
297*dfc11533SChris Williamson cl = ttisclosure(func) ? clvalue(func) : NULL;
298*dfc11533SChris Williamson status = auxgetinfo(L, what, ar, cl, ci);
299*dfc11533SChris Williamson if (strchr(what, 'f')) {
300*dfc11533SChris Williamson setobjs2s(L, L->top, func);
301*dfc11533SChris Williamson api_incr_top(L);
302*dfc11533SChris Williamson }
303*dfc11533SChris Williamson swapextra(L);
304*dfc11533SChris Williamson if (strchr(what, 'L'))
305*dfc11533SChris Williamson collectvalidlines(L, cl);
306*dfc11533SChris Williamson lua_unlock(L);
307*dfc11533SChris Williamson return status;
308*dfc11533SChris Williamson }
309*dfc11533SChris Williamson
310*dfc11533SChris Williamson
311*dfc11533SChris Williamson /*
312*dfc11533SChris Williamson ** {======================================================
313*dfc11533SChris Williamson ** Symbolic Execution
314*dfc11533SChris Williamson ** =======================================================
315*dfc11533SChris Williamson */
316*dfc11533SChris Williamson
317*dfc11533SChris Williamson static const char *getobjname (Proto *p, int lastpc, int reg,
318*dfc11533SChris Williamson const char **name);
319*dfc11533SChris Williamson
320*dfc11533SChris Williamson
321*dfc11533SChris Williamson /*
322*dfc11533SChris Williamson ** find a "name" for the RK value 'c'
323*dfc11533SChris Williamson */
kname(Proto * p,int pc,int c,const char ** name)324*dfc11533SChris Williamson static void kname (Proto *p, int pc, int c, const char **name) {
325*dfc11533SChris Williamson if (ISK(c)) { /* is 'c' a constant? */
326*dfc11533SChris Williamson TValue *kvalue = &p->k[INDEXK(c)];
327*dfc11533SChris Williamson if (ttisstring(kvalue)) { /* literal constant? */
328*dfc11533SChris Williamson *name = svalue(kvalue); /* it is its own name */
329*dfc11533SChris Williamson return;
330*dfc11533SChris Williamson }
331*dfc11533SChris Williamson /* else no reasonable name found */
332*dfc11533SChris Williamson }
333*dfc11533SChris Williamson else { /* 'c' is a register */
334*dfc11533SChris Williamson const char *what = getobjname(p, pc, c, name); /* search for 'c' */
335*dfc11533SChris Williamson if (what && *what == 'c') { /* found a constant name? */
336*dfc11533SChris Williamson return; /* 'name' already filled */
337*dfc11533SChris Williamson }
338*dfc11533SChris Williamson /* else no reasonable name found */
339*dfc11533SChris Williamson }
340*dfc11533SChris Williamson *name = "?"; /* no reasonable name found */
341*dfc11533SChris Williamson }
342*dfc11533SChris Williamson
343*dfc11533SChris Williamson
filterpc(int pc,int jmptarget)344*dfc11533SChris Williamson static int filterpc (int pc, int jmptarget) {
345*dfc11533SChris Williamson if (pc < jmptarget) /* is code conditional (inside a jump)? */
346*dfc11533SChris Williamson return -1; /* cannot know who sets that register */
347*dfc11533SChris Williamson else return pc; /* current position sets that register */
348*dfc11533SChris Williamson }
349*dfc11533SChris Williamson
350*dfc11533SChris Williamson
351*dfc11533SChris Williamson /*
352*dfc11533SChris Williamson ** try to find last instruction before 'lastpc' that modified register 'reg'
353*dfc11533SChris Williamson */
findsetreg(Proto * p,int lastpc,int reg)354*dfc11533SChris Williamson static int findsetreg (Proto *p, int lastpc, int reg) {
355*dfc11533SChris Williamson int pc;
356*dfc11533SChris Williamson int setreg = -1; /* keep last instruction that changed 'reg' */
357*dfc11533SChris Williamson int jmptarget = 0; /* any code before this address is conditional */
358*dfc11533SChris Williamson for (pc = 0; pc < lastpc; pc++) {
359*dfc11533SChris Williamson Instruction i = p->code[pc];
360*dfc11533SChris Williamson OpCode op = GET_OPCODE(i);
361*dfc11533SChris Williamson int a = GETARG_A(i);
362*dfc11533SChris Williamson switch (op) {
363*dfc11533SChris Williamson case OP_LOADNIL: {
364*dfc11533SChris Williamson int b = GETARG_B(i);
365*dfc11533SChris Williamson if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
366*dfc11533SChris Williamson setreg = filterpc(pc, jmptarget);
367*dfc11533SChris Williamson break;
368*dfc11533SChris Williamson }
369*dfc11533SChris Williamson case OP_TFORCALL: {
370*dfc11533SChris Williamson if (reg >= a + 2) /* affect all regs above its base */
371*dfc11533SChris Williamson setreg = filterpc(pc, jmptarget);
372*dfc11533SChris Williamson break;
373*dfc11533SChris Williamson }
374*dfc11533SChris Williamson case OP_CALL:
375*dfc11533SChris Williamson case OP_TAILCALL: {
376*dfc11533SChris Williamson if (reg >= a) /* affect all registers above base */
377*dfc11533SChris Williamson setreg = filterpc(pc, jmptarget);
378*dfc11533SChris Williamson break;
379*dfc11533SChris Williamson }
380*dfc11533SChris Williamson case OP_JMP: {
381*dfc11533SChris Williamson int b = GETARG_sBx(i);
382*dfc11533SChris Williamson int dest = pc + 1 + b;
383*dfc11533SChris Williamson /* jump is forward and do not skip `lastpc'? */
384*dfc11533SChris Williamson if (pc < dest && dest <= lastpc) {
385*dfc11533SChris Williamson if (dest > jmptarget)
386*dfc11533SChris Williamson jmptarget = dest; /* update 'jmptarget' */
387*dfc11533SChris Williamson }
388*dfc11533SChris Williamson break;
389*dfc11533SChris Williamson }
390*dfc11533SChris Williamson case OP_TEST: {
391*dfc11533SChris Williamson if (reg == a) /* jumped code can change 'a' */
392*dfc11533SChris Williamson setreg = filterpc(pc, jmptarget);
393*dfc11533SChris Williamson break;
394*dfc11533SChris Williamson }
395*dfc11533SChris Williamson default:
396*dfc11533SChris Williamson if (testAMode(op) && reg == a) /* any instruction that set A */
397*dfc11533SChris Williamson setreg = filterpc(pc, jmptarget);
398*dfc11533SChris Williamson break;
399*dfc11533SChris Williamson }
400*dfc11533SChris Williamson }
401*dfc11533SChris Williamson return setreg;
402*dfc11533SChris Williamson }
403*dfc11533SChris Williamson
404*dfc11533SChris Williamson
getobjname(Proto * p,int lastpc,int reg,const char ** name)405*dfc11533SChris Williamson static const char *getobjname (Proto *p, int lastpc, int reg,
406*dfc11533SChris Williamson const char **name) {
407*dfc11533SChris Williamson int pc;
408*dfc11533SChris Williamson *name = luaF_getlocalname(p, reg + 1, lastpc);
409*dfc11533SChris Williamson if (*name) /* is a local? */
410*dfc11533SChris Williamson return "local";
411*dfc11533SChris Williamson /* else try symbolic execution */
412*dfc11533SChris Williamson pc = findsetreg(p, lastpc, reg);
413*dfc11533SChris Williamson if (pc != -1) { /* could find instruction? */
414*dfc11533SChris Williamson Instruction i = p->code[pc];
415*dfc11533SChris Williamson OpCode op = GET_OPCODE(i);
416*dfc11533SChris Williamson switch (op) {
417*dfc11533SChris Williamson case OP_MOVE: {
418*dfc11533SChris Williamson int b = GETARG_B(i); /* move from 'b' to 'a' */
419*dfc11533SChris Williamson if (b < GETARG_A(i))
420*dfc11533SChris Williamson return getobjname(p, pc, b, name); /* get name for 'b' */
421*dfc11533SChris Williamson break;
422*dfc11533SChris Williamson }
423*dfc11533SChris Williamson case OP_GETTABUP:
424*dfc11533SChris Williamson case OP_GETTABLE: {
425*dfc11533SChris Williamson int k = GETARG_C(i); /* key index */
426*dfc11533SChris Williamson int t = GETARG_B(i); /* table index */
427*dfc11533SChris Williamson const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
428*dfc11533SChris Williamson ? luaF_getlocalname(p, t + 1, pc)
429*dfc11533SChris Williamson : upvalname(p, t);
430*dfc11533SChris Williamson kname(p, pc, k, name);
431*dfc11533SChris Williamson return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
432*dfc11533SChris Williamson }
433*dfc11533SChris Williamson case OP_GETUPVAL: {
434*dfc11533SChris Williamson *name = upvalname(p, GETARG_B(i));
435*dfc11533SChris Williamson return "upvalue";
436*dfc11533SChris Williamson }
437*dfc11533SChris Williamson case OP_LOADK:
438*dfc11533SChris Williamson case OP_LOADKX: {
439*dfc11533SChris Williamson int b = (op == OP_LOADK) ? GETARG_Bx(i)
440*dfc11533SChris Williamson : GETARG_Ax(p->code[pc + 1]);
441*dfc11533SChris Williamson if (ttisstring(&p->k[b])) {
442*dfc11533SChris Williamson *name = svalue(&p->k[b]);
443*dfc11533SChris Williamson return "constant";
444*dfc11533SChris Williamson }
445*dfc11533SChris Williamson break;
446*dfc11533SChris Williamson }
447*dfc11533SChris Williamson case OP_SELF: {
448*dfc11533SChris Williamson int k = GETARG_C(i); /* key index */
449*dfc11533SChris Williamson kname(p, pc, k, name);
450*dfc11533SChris Williamson return "method";
451*dfc11533SChris Williamson }
452*dfc11533SChris Williamson default: break; /* go through to return NULL */
453*dfc11533SChris Williamson }
454*dfc11533SChris Williamson }
455*dfc11533SChris Williamson return NULL; /* could not find reasonable name */
456*dfc11533SChris Williamson }
457*dfc11533SChris Williamson
458*dfc11533SChris Williamson
getfuncname(lua_State * L,CallInfo * ci,const char ** name)459*dfc11533SChris Williamson static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
460*dfc11533SChris Williamson TMS tm;
461*dfc11533SChris Williamson Proto *p = ci_func(ci)->p; /* calling function */
462*dfc11533SChris Williamson int pc = currentpc(ci); /* calling instruction index */
463*dfc11533SChris Williamson Instruction i = p->code[pc]; /* calling instruction */
464*dfc11533SChris Williamson switch (GET_OPCODE(i)) {
465*dfc11533SChris Williamson case OP_CALL:
466*dfc11533SChris Williamson case OP_TAILCALL: /* get function name */
467*dfc11533SChris Williamson return getobjname(p, pc, GETARG_A(i), name);
468*dfc11533SChris Williamson case OP_TFORCALL: { /* for iterator */
469*dfc11533SChris Williamson *name = "for iterator";
470*dfc11533SChris Williamson return "for iterator";
471*dfc11533SChris Williamson }
472*dfc11533SChris Williamson /* all other instructions can call only through metamethods */
473*dfc11533SChris Williamson case OP_SELF:
474*dfc11533SChris Williamson case OP_GETTABUP:
475*dfc11533SChris Williamson case OP_GETTABLE: tm = TM_INDEX; break;
476*dfc11533SChris Williamson case OP_SETTABUP:
477*dfc11533SChris Williamson case OP_SETTABLE: tm = TM_NEWINDEX; break;
478*dfc11533SChris Williamson case OP_EQ: tm = TM_EQ; break;
479*dfc11533SChris Williamson case OP_ADD: tm = TM_ADD; break;
480*dfc11533SChris Williamson case OP_SUB: tm = TM_SUB; break;
481*dfc11533SChris Williamson case OP_MUL: tm = TM_MUL; break;
482*dfc11533SChris Williamson case OP_DIV: tm = TM_DIV; break;
483*dfc11533SChris Williamson case OP_MOD: tm = TM_MOD; break;
484*dfc11533SChris Williamson case OP_POW: tm = TM_POW; break;
485*dfc11533SChris Williamson case OP_UNM: tm = TM_UNM; break;
486*dfc11533SChris Williamson case OP_LEN: tm = TM_LEN; break;
487*dfc11533SChris Williamson case OP_LT: tm = TM_LT; break;
488*dfc11533SChris Williamson case OP_LE: tm = TM_LE; break;
489*dfc11533SChris Williamson case OP_CONCAT: tm = TM_CONCAT; break;
490*dfc11533SChris Williamson default:
491*dfc11533SChris Williamson return NULL; /* else no useful name can be found */
492*dfc11533SChris Williamson }
493*dfc11533SChris Williamson *name = getstr(G(L)->tmname[tm]);
494*dfc11533SChris Williamson return "metamethod";
495*dfc11533SChris Williamson }
496*dfc11533SChris Williamson
497*dfc11533SChris Williamson /* }====================================================== */
498*dfc11533SChris Williamson
499*dfc11533SChris Williamson
500*dfc11533SChris Williamson
501*dfc11533SChris Williamson /*
502*dfc11533SChris Williamson ** only ANSI way to check whether a pointer points to an array
503*dfc11533SChris Williamson ** (used only for error messages, so efficiency is not a big concern)
504*dfc11533SChris Williamson */
isinstack(CallInfo * ci,const TValue * o)505*dfc11533SChris Williamson static int isinstack (CallInfo *ci, const TValue *o) {
506*dfc11533SChris Williamson StkId p;
507*dfc11533SChris Williamson for (p = ci->u.l.base; p < ci->top; p++)
508*dfc11533SChris Williamson if (o == p) return 1;
509*dfc11533SChris Williamson return 0;
510*dfc11533SChris Williamson }
511*dfc11533SChris Williamson
512*dfc11533SChris Williamson
getupvalname(CallInfo * ci,const TValue * o,const char ** name)513*dfc11533SChris Williamson static const char *getupvalname (CallInfo *ci, const TValue *o,
514*dfc11533SChris Williamson const char **name) {
515*dfc11533SChris Williamson LClosure *c = ci_func(ci);
516*dfc11533SChris Williamson int i;
517*dfc11533SChris Williamson for (i = 0; i < c->nupvalues; i++) {
518*dfc11533SChris Williamson if (c->upvals[i]->v == o) {
519*dfc11533SChris Williamson *name = upvalname(c->p, i);
520*dfc11533SChris Williamson return "upvalue";
521*dfc11533SChris Williamson }
522*dfc11533SChris Williamson }
523*dfc11533SChris Williamson return NULL;
524*dfc11533SChris Williamson }
525*dfc11533SChris Williamson
526*dfc11533SChris Williamson
luaG_typeerror(lua_State * L,const TValue * o,const char * op)527*dfc11533SChris Williamson l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
528*dfc11533SChris Williamson CallInfo *ci = L->ci;
529*dfc11533SChris Williamson const char *name = NULL;
530*dfc11533SChris Williamson const char *t = objtypename(o);
531*dfc11533SChris Williamson const char *kind = NULL;
532*dfc11533SChris Williamson if (isLua(ci)) {
533*dfc11533SChris Williamson kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
534*dfc11533SChris Williamson if (!kind && isinstack(ci, o)) /* no? try a register */
535*dfc11533SChris Williamson kind = getobjname(ci_func(ci)->p, currentpc(ci),
536*dfc11533SChris Williamson cast_int(o - ci->u.l.base), &name);
537*dfc11533SChris Williamson }
538*dfc11533SChris Williamson if (kind)
539*dfc11533SChris Williamson luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
540*dfc11533SChris Williamson op, kind, name, t);
541*dfc11533SChris Williamson else
542*dfc11533SChris Williamson luaG_runerror(L, "attempt to %s a %s value", op, t);
543*dfc11533SChris Williamson }
544*dfc11533SChris Williamson
545*dfc11533SChris Williamson
luaG_concaterror(lua_State * L,StkId p1,StkId p2)546*dfc11533SChris Williamson l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
547*dfc11533SChris Williamson if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
548*dfc11533SChris Williamson lua_assert(!ttisstring(p1) && !ttisnumber(p1));
549*dfc11533SChris Williamson luaG_typeerror(L, p1, "concatenate");
550*dfc11533SChris Williamson }
551*dfc11533SChris Williamson
552*dfc11533SChris Williamson
luaG_aritherror(lua_State * L,const TValue * p1,const TValue * p2)553*dfc11533SChris Williamson l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
554*dfc11533SChris Williamson TValue temp;
555*dfc11533SChris Williamson if (luaV_tonumber(p1, &temp) == NULL)
556*dfc11533SChris Williamson p2 = p1; /* first operand is wrong */
557*dfc11533SChris Williamson luaG_typeerror(L, p2, "perform arithmetic on");
558*dfc11533SChris Williamson }
559*dfc11533SChris Williamson
560*dfc11533SChris Williamson
luaG_ordererror(lua_State * L,const TValue * p1,const TValue * p2)561*dfc11533SChris Williamson l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
562*dfc11533SChris Williamson const char *t1 = objtypename(p1);
563*dfc11533SChris Williamson const char *t2 = objtypename(p2);
564*dfc11533SChris Williamson if (t1 == t2)
565*dfc11533SChris Williamson luaG_runerror(L, "attempt to compare two %s values", t1);
566*dfc11533SChris Williamson else
567*dfc11533SChris Williamson luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
568*dfc11533SChris Williamson }
569*dfc11533SChris Williamson
570*dfc11533SChris Williamson
addinfo(lua_State * L,const char * msg)571*dfc11533SChris Williamson static void addinfo (lua_State *L, const char *msg) {
572*dfc11533SChris Williamson CallInfo *ci = L->ci;
573*dfc11533SChris Williamson if (isLua(ci)) { /* is Lua code? */
574*dfc11533SChris Williamson char buff[LUA_IDSIZE]; /* add file:line information */
575*dfc11533SChris Williamson int line = currentline(ci);
576*dfc11533SChris Williamson TString *src = ci_func(ci)->p->source;
577*dfc11533SChris Williamson if (src)
578*dfc11533SChris Williamson luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
579*dfc11533SChris Williamson else { /* no source available; use "?" instead */
580*dfc11533SChris Williamson buff[0] = '?'; buff[1] = '\0';
581*dfc11533SChris Williamson }
582*dfc11533SChris Williamson luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
583*dfc11533SChris Williamson }
584*dfc11533SChris Williamson }
585*dfc11533SChris Williamson
586*dfc11533SChris Williamson
luaG_errormsg(lua_State * L)587*dfc11533SChris Williamson l_noret luaG_errormsg (lua_State *L) {
588*dfc11533SChris Williamson if (L->errfunc != 0) { /* is there an error handling function? */
589*dfc11533SChris Williamson StkId errfunc = restorestack(L, L->errfunc);
590*dfc11533SChris Williamson if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
591*dfc11533SChris Williamson setobjs2s(L, L->top, L->top - 1); /* move argument */
592*dfc11533SChris Williamson setobjs2s(L, L->top - 1, errfunc); /* push function */
593*dfc11533SChris Williamson L->top++;
594*dfc11533SChris Williamson luaD_call(L, L->top - 2, 1, 0); /* call it */
595*dfc11533SChris Williamson }
596*dfc11533SChris Williamson luaD_throw(L, LUA_ERRRUN);
597*dfc11533SChris Williamson }
598*dfc11533SChris Williamson
599*dfc11533SChris Williamson
luaG_runerror(lua_State * L,const char * fmt,...)600*dfc11533SChris Williamson l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
601*dfc11533SChris Williamson va_list argp;
602*dfc11533SChris Williamson va_start(argp, fmt);
603*dfc11533SChris Williamson addinfo(L, luaO_pushvfstring(L, fmt, argp));
604*dfc11533SChris Williamson va_end(argp);
605*dfc11533SChris Williamson luaG_errormsg(L);
606*dfc11533SChris Williamson }
607*dfc11533SChris Williamson
608