summaryrefslogtreecommitdiff
path: root/ldebug.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-05 11:51:21 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-05 11:51:21 -0300
commit0417a4bb0b3a2a51b251eddbc5860478e316eb53 (patch)
tree38400c59dfdef6e2b3c0f8fb613cdc599d99f8f6 /ldebug.c
parent5037196f6fddb828056578b1c0d352cdef672d6a (diff)
downloadlua-0417a4bb0b3a2a51b251eddbc5860478e316eb53.tar.gz
lua-0417a4bb0b3a2a51b251eddbc5860478e316eb53.tar.bz2
lua-0417a4bb0b3a2a51b251eddbc5860478e316eb53.zip
new implementation for tailcalls and error handling
Diffstat (limited to 'ldebug.c')
-rw-r--r--ldebug.c72
1 files changed, 33 insertions, 39 deletions
diff --git a/ldebug.c b/ldebug.c
index 413bab69..56f6c820 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.124 2002/07/08 18:21:33 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.125 2002/07/16 14:26:56 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -29,14 +29,16 @@
29static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 29static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
30 30
31 31
32static int isLua (CallInfo *ci) {
33 return isLfunction (ci->base - 1);
34}
32 35
33static int currentpc (lua_State *L, CallInfo *ci) { 36static int currentpc (lua_State *L, CallInfo *ci) {
34 if (!isLua(ci)) return -1; /* function is not a Lua function? */ 37 if (!isLua(ci)) return -1; /* function is not a Lua function? */
35 /* next function is not using the same `pc'? (not a Lua->Lua call?) */ 38 if (ci->pc && ci->pc != &luaV_callingmark)
36 if (ci == L->ci || !isLua(ci+1) || ci->u.l.pc != (ci+1)->u.l.pc) 39 ci->u.l.savedpc = *ci->pc; /* `pc' may not be saved; save it */
37 ci->savedpc = *ci->u.l.pc; /* may not be saved; save it */
38 /* function's pc is saved */ 40 /* function's pc is saved */
39 return pcRel(ci->savedpc, ci_func(ci)->l.p); 41 return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
40} 42}
41 43
42 44
@@ -49,8 +51,18 @@ static int currentline (lua_State *L, CallInfo *ci) {
49} 51}
50 52
51 53
52LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) { 54/*
55** save all `pc's from active Lua functions
56*/
57void luaG_saveallpcs (lua_State *L) {
53 CallInfo *ci; 58 CallInfo *ci;
59 /* first save all not saved `pc's */
60 for (ci = L->ci; ci != L->base_ci; ci--)
61 currentpc(L, ci); /* save `pc', if necessary */
62}
63
64
65LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) {
54 int allow; 66 int allow;
55 lua_lock(L); 67 lua_lock(L);
56 allow = allowhook(L); 68 allow = allowhook(L);
@@ -60,8 +72,7 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) {
60 L->hookmask = mask; 72 L->hookmask = mask;
61 setallowhook(L, allow); 73 setallowhook(L, allow);
62 resethookcount(L); 74 resethookcount(L);
63 for (ci = L->base_ci; ci <= L->ci; ci++) 75 luaG_saveallpcs(L);
64 currentpc(L, ci); /* update `savedpc' */
65 lua_unlock(L); 76 lua_unlock(L);
66 return 1; 77 return 1;
67} 78}
@@ -143,7 +154,7 @@ static void infoLproto (lua_Debug *ar, Proto *f) {
143 154
144static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) { 155static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
145 Closure *cl; 156 Closure *cl;
146 if (ttype(func) == LUA_TFUNCTION) 157 if (ttisfunction(func))
147 cl = clvalue(func); 158 cl = clvalue(func);
148 else { 159 else {
149 luaG_runerror(L, "value for `lua_getinfo' is not a function"); 160 luaG_runerror(L, "value for `lua_getinfo' is not a function");
@@ -167,7 +178,7 @@ static const char *travglobals (lua_State *L, const TObject *o) {
167 int i = sizenode(g); 178 int i = sizenode(g);
168 while (i--) { 179 while (i--) {
169 Node *n = node(g, i); 180 Node *n = node(g, i);
170 if (luaO_rawequalObj(o, val(n)) && ttype(key(n)) == LUA_TSTRING) 181 if (luaO_rawequalObj(o, val(n)) && ttisstring(key(n)))
171 return getstr(tsvalue(key(n))); 182 return getstr(tsvalue(key(n)));
172 } 183 }
173 return NULL; 184 return NULL;
@@ -208,7 +219,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
208 break; 219 break;
209 } 220 }
210 case 'u': { 221 case 'u': {
211 ar->nups = (ttype(f) == LUA_TFUNCTION) ? clvalue(f)->c.nupvalues : 0; 222 ar->nups = (ttisfunction(f)) ? clvalue(f)->c.nupvalues : 0;
212 break; 223 break;
213 } 224 }
214 case 'n': { 225 case 'n': {
@@ -222,10 +233,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
222 status = 2; 233 status = 2;
223 break; 234 break;
224 } 235 }
225 case 'c': {
226 ar->isprotected = (ci && luaD_isprotected(L, ci));
227 break;
228 }
229 default: status = 0; /* invalid option */ 236 default: status = 0; /* invalid option */
230 } 237 }
231 } 238 }
@@ -330,7 +337,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
330 } 337 }
331 case OP_GETGLOBAL: 338 case OP_GETGLOBAL:
332 case OP_SETGLOBAL: { 339 case OP_SETGLOBAL: {
333 check(ttype(&pt->k[b]) == LUA_TSTRING); 340 check(ttisstring(&pt->k[b]));
334 break; 341 break;
335 } 342 }
336 case OP_SELF: { 343 case OP_SELF: {
@@ -357,7 +364,8 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
357 pc += b; /* do the jump */ 364 pc += b; /* do the jump */
358 break; 365 break;
359 } 366 }
360 case OP_CALL: { 367 case OP_CALL:
368 case OP_TAILCALL: {
361 if (b != 0) { 369 if (b != 0) {
362 checkreg(pt, a+b-1); 370 checkreg(pt, a+b-1);
363 } 371 }
@@ -370,7 +378,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
370 if (reg >= a) last = pc; /* affect all registers above base */ 378 if (reg >= a) last = pc; /* affect all registers above base */
371 break; 379 break;
372 } 380 }
373 case OP_TAILCALL:
374 case OP_RETURN: { 381 case OP_RETURN: {
375 b--; /* b = num. returns */ 382 b--; /* b = num. returns */
376 if (b > 0) checkreg(pt, a+b-1); 383 if (b > 0) checkreg(pt, a+b-1);
@@ -411,7 +418,7 @@ int luaG_checkcode (const Proto *pt) {
411 418
412static const char *kname (Proto *p, int c) { 419static const char *kname (Proto *p, int c) {
413 c = c - MAXSTACK; 420 c = c - MAXSTACK;
414 if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) 421 if (c >= 0 && ttisstring(&p->k[c]))
415 return svalue(&p->k[c]); 422 return svalue(&p->k[c]);
416 else 423 else
417 return "?"; 424 return "?";
@@ -420,7 +427,7 @@ static const char *kname (Proto *p, int c) {
420 427
421static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, 428static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
422 const char **name) { 429 const char **name) {
423 if (isLua(ci)) { /* an active Lua function? */ 430 if (isLua(ci)) { /* a Lua function? */
424 Proto *p = ci_func(ci)->l.p; 431 Proto *p = ci_func(ci)->l.p;
425 int pc = currentpc(L, ci); 432 int pc = currentpc(L, ci);
426 Instruction i; 433 Instruction i;
@@ -431,7 +438,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
431 lua_assert(pc != -1); 438 lua_assert(pc != -1);
432 switch (GET_OPCODE(i)) { 439 switch (GET_OPCODE(i)) {
433 case OP_GETGLOBAL: { 440 case OP_GETGLOBAL: {
434 lua_assert(ttype(&p->k[GETARG_Bx(i)]) == LUA_TSTRING); 441 lua_assert(ttisstring(&p->k[GETARG_Bx(i)]));
435 *name = svalue(&p->k[GETARG_Bx(i)]); 442 *name = svalue(&p->k[GETARG_Bx(i)]);
436 return "global"; 443 return "global";
437 } 444 }
@@ -458,10 +465,8 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
458 465
459 466
460static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) { 467static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) {
461 if (ci == L->base_ci || !isLua(ci)) 468 return (!isLua(ci)) ? (Instruction)(-1) :
462 return (Instruction)(-1); /* not an active Lua function */ 469 ci_func(ci)->l.p->code[currentpc(L, ci)];
463 else
464 return ci_func(ci)->l.p->code[currentpc(L, ci)];
465} 470}
466 471
467 472
@@ -497,8 +502,8 @@ void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
497 502
498 503
499void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { 504void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
500 if (ttype(p1) == LUA_TSTRING) p1 = p2; 505 if (ttisstring(p1)) p1 = p2;
501 lua_assert(ttype(p1) != LUA_TSTRING); 506 lua_assert(!ttisstring(p1));
502 luaG_typeerror(L, p1, "concat"); 507 luaG_typeerror(L, p1, "concat");
503} 508}
504 509
@@ -540,19 +545,8 @@ static void addinfo (lua_State *L, int internal) {
540 545
541 546
542void luaG_errormsg (lua_State *L, int internal) { 547void luaG_errormsg (lua_State *L, int internal) {
543 const TObject *errfunc; 548 if (ttisstring(L->top - 1))
544 if (ttype(L->top - 1) == LUA_TSTRING)
545 addinfo(L, internal); 549 addinfo(L, internal);
546 errfunc = luaH_getstr(hvalue(registry(L)), luaS_new(L, LUA_TRACEBACK));
547 if (ttype(errfunc) != LUA_TNIL) { /* is there an error function? */
548 setobj(L->top, errfunc); /* push function */
549 setobj(L->top + 1, L->top - 1); /* push error message */
550 L->top += 2;
551 luaD_call(L, L->top - 2, 1); /* call error function? */
552 }
553 else {
554 setnilvalue(L->top++);
555 }
556 luaD_throw(L, LUA_ERRRUN); 550 luaD_throw(L, LUA_ERRRUN);
557} 551}
558 552