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