aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-18 12:19:27 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-18 12:19:27 -0300
commit1dbe708aa84f3a1e51daf8d7e2f714e2b02f554b (patch)
treee845de9ee24b94362146e38410ae0670df18526b /ldo.c
parent8f080fd683d63b0cd4b38380f6a5bdae5d6e2584 (diff)
downloadlua-1dbe708aa84f3a1e51daf8d7e2f714e2b02f554b.tar.gz
lua-1dbe708aa84f3a1e51daf8d7e2f714e2b02f554b.tar.bz2
lua-1dbe708aa84f3a1e51daf8d7e2f714e2b02f554b.zip
new protocol for error handling
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c91
1 files changed, 42 insertions, 49 deletions
diff --git a/ldo.c b/ldo.c
index e6eba7d1..c47fdac2 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.178 2002/06/03 17:46:34 roberto Exp roberto $ 2** $Id: ldo.c,v 1.179 2002/06/03 20:12:50 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -37,10 +37,16 @@ struct lua_longjmp {
37 jmp_buf b; 37 jmp_buf b;
38 int allowhooks; /* `allowhook' state when protection was set */ 38 int allowhooks; /* `allowhook' state when protection was set */
39 volatile int status; /* error code */ 39 volatile int status; /* error code */
40 TObject *err; /* error function -> message (start of `ud') */ 40 TObject *err; /* error messages (start of `ud') */
41}; 41};
42 42
43 43
44static void pusherrormsg (lua_State *L, int status, TObject *err) {
45 setobj(L->top++, &err[0]);
46 if (status == LUA_ERRRUN)
47 setobj(L->top++, &err[1]);
48}
49
44 50
45static void correctstack (lua_State *L, TObject *oldstack) { 51static void correctstack (lua_State *L, TObject *oldstack) {
46 struct lua_longjmp *lj; 52 struct lua_longjmp *lj;
@@ -109,7 +115,7 @@ void luaD_growstack (lua_State *L, int n) {
109static void luaD_growCI (lua_State *L) { 115static void luaD_growCI (lua_State *L) {
110 L->ci--; 116 L->ci--;
111 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ 117 if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
112 luaD_error(L, "error in error handling", LUA_ERRERR); 118 luaD_throw(L, LUA_ERRERR);
113 else { 119 else {
114 luaD_reallocCI(L, 2*L->size_ci); 120 luaD_reallocCI(L, 2*L->size_ci);
115 if (L->size_ci > LUA_MAXCALLS) 121 if (L->size_ci > LUA_MAXCALLS)
@@ -302,7 +308,7 @@ static void move_results (lua_State *L, TObject *from, TObject *to) {
302 308
303 309
304struct ResS { 310struct ResS {
305 TObject err; 311 TObject err[2];
306 int numres; 312 int numres;
307}; 313};
308 314
@@ -337,17 +343,11 @@ LUA_API int lua_resume (lua_State *L, lua_State *co) {
337 luaG_runerror(L, "thread is dead - cannot be resumed"); 343 luaG_runerror(L, "thread is dead - cannot be resumed");
338 if (co->errorJmp != NULL) /* ?? */ 344 if (co->errorJmp != NULL) /* ?? */
339 luaG_runerror(L, "thread is active - cannot be resumed"); 345 luaG_runerror(L, "thread is active - cannot be resumed");
340 if (L->errorJmp) { 346 status = luaD_runprotected(co, resume, ud.err);
341 setobj(&ud.err, L->errorJmp->err);
342 }
343 else
344 setnilvalue(&ud.err);
345 status = luaD_runprotected(co, resume, &ud.err);
346 if (status == 0) 347 if (status == 0)
347 move_results(L, co->top - ud.numres, co->top); 348 move_results(L, co->top - ud.numres, co->top);
348 else { 349 else
349 setobj(L->top++, &ud.err); 350 pusherrormsg(L, status, ud.err);
350}
351 lua_unlock(L); 351 lua_unlock(L);
352 return status; 352 return status;
353} 353}
@@ -369,7 +369,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
369** Execute a protected call. 369** Execute a protected call.
370*/ 370*/
371struct CallS { /* data to `f_call' */ 371struct CallS { /* data to `f_call' */
372 TObject err; /* error field... */ 372 TObject err[2];
373 StkId func; 373 StkId func;
374 int nresults; 374 int nresults;
375}; 375};
@@ -381,17 +381,16 @@ static void f_call (lua_State *L, void *ud) {
381} 381}
382 382
383 383
384int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) { 384int luaD_pcall (lua_State *L, int nargs, int nresults) {
385 struct CallS c; 385 struct CallS c;
386 int status; 386 int status;
387 c.func = L->top - (nargs+1); /* function to be called */ 387 c.func = L->top - (nargs+1); /* function to be called */
388 c.nresults = nresults; 388 c.nresults = nresults;
389 c.err = *err; 389 status = luaD_runprotected(L, &f_call, c.err);
390 status = luaD_runprotected(L, &f_call, &c.err);
391 if (status != 0) { /* an error occurred? */ 390 if (status != 0) { /* an error occurred? */
392 L->top -= nargs+1; /* remove parameters and func from the stack */ 391 L->top -= nargs+1; /* remove parameters and func from the stack */
393 luaF_close(L, L->top); /* close eventual pending closures */ 392 luaF_close(L, L->top); /* close eventual pending closures */
394 setobj(L->top++, &c.err); 393 pusherrormsg(L, status, c.err);
395 } 394 }
396 return status; 395 return status;
397} 396}
@@ -401,7 +400,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
401** Execute a protected parser. 400** Execute a protected parser.
402*/ 401*/
403struct SParser { /* data to `f_parser' */ 402struct SParser { /* data to `f_parser' */
404 TObject err; /* error field... */ 403 TObject err[2];
405 ZIO *z; 404 ZIO *z;
406 int bin; 405 int bin;
407}; 406};
@@ -425,15 +424,14 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
425 if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold) 424 if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
426 luaC_collectgarbage(L); 425 luaC_collectgarbage(L);
427 old_blocks = G(L)->nblocks; 426 old_blocks = G(L)->nblocks;
428 setnilvalue(&p.err); 427 status = luaD_runprotected(L, f_parser, p.err);
429 status = luaD_runprotected(L, f_parser, &p.err);
430 if (status == 0) { 428 if (status == 0) {
431 /* add new memory to threshold (as it probably will stay) */ 429 /* add new memory to threshold (as it probably will stay) */
432 lua_assert(G(L)->nblocks >= old_blocks); 430 lua_assert(G(L)->nblocks >= old_blocks);
433 G(L)->GCthreshold += (G(L)->nblocks - old_blocks); 431 G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
434 } 432 }
435 else 433 else
436 setobj(L->top++, &p.err); 434 pusherrormsg(L, status, p.err);
437 return status; 435 return status;
438} 436}
439 437
@@ -445,29 +443,34 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
445** ======================================================= 443** =======================================================
446*/ 444*/
447 445
448 446static void seterrorobj (lua_State *L, int errcode, TObject *m) {
449static void message (lua_State *L, const TObject *msg, int nofunc) { 447 switch (errcode) {
450 TObject *m = L->errorJmp->err; 448 case LUA_ERRMEM: {
451 if (nofunc || ttype(m) != LUA_TFUNCTION) { /* no error function? */ 449 if (G(L) != NULL && G(L)->GCthreshold > 0) /* state is OK? */
452 setobj(m, msg); /* keep error message */ 450 setsvalue(&m[0], luaS_new(L, MEMERRMSG));
453 } 451 break;
454 else { /* call error function */ 452 }
455 setobj(L->top, m); 453 case LUA_ERRERR: {
456 setobj(L->top + 1, msg); 454 setsvalue(&m[0], luaS_new(L, "error in error handling"));
457 L->top += 2; 455 break;
458 luaD_call(L, L->top - 2, 1); 456 }
459 setobj(m, L->top - 1); 457 case LUA_ERRSYNTAX: { /* message is on stack top */
458 setobj(&m[0], L->top - 1);
459 break;
460 }
461 case LUA_ERRRUN: { /* traceback is on stack top */
462 setobj(&m[0], L->top - 2);
463 setobj(&m[1], L->top - 1);
464 break;
465 }
460 } 466 }
461} 467}
462 468
463 469
464/* 470void luaD_throw (lua_State *L, int errcode) {
465** Reports an error, and jumps up to the available recovery label 471 seterrorobj(L, errcode, L->errorJmp->err);
466*/
467void luaD_errorobj (lua_State *L, const TObject *s, int errcode) {
468 if (L->errorJmp) { 472 if (L->errorJmp) {
469 L->errorJmp->status = errcode; 473 L->errorJmp->status = errcode;
470 message(L, s, (errcode >= LUA_ERRMEM));
471 longjmp(L->errorJmp->b, 1); 474 longjmp(L->errorJmp->b, 1);
472 } 475 }
473 else { 476 else {
@@ -477,16 +480,6 @@ void luaD_errorobj (lua_State *L, const TObject *s, int errcode) {
477} 480}
478 481
479 482
480void luaD_error (lua_State *L, const char *s, int errcode) {
481 TObject errobj;
482 if (errcode == LUA_ERRMEM && (G(L) == NULL || G(L)->GCthreshold == 0))
483 setnilvalue(&errobj); /* error bulding state */
484 else
485 setsvalue(&errobj, luaS_new(L, s));
486 luaD_errorobj(L, &errobj, errcode);
487}
488
489
490int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) { 483int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
491 struct lua_longjmp lj; 484 struct lua_longjmp lj;
492 lj.ci = L->ci; 485 lj.ci = L->ci;