diff options
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 91 |
1 files changed, 42 insertions, 49 deletions
| @@ -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 | ||
| 44 | static 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 | ||
| 45 | static void correctstack (lua_State *L, TObject *oldstack) { | 51 | static 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) { | |||
| 109 | static void luaD_growCI (lua_State *L) { | 115 | static 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 | ||
| 304 | struct ResS { | 310 | struct 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 | */ |
| 371 | struct CallS { /* data to `f_call' */ | 371 | struct 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 | ||
| 384 | int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) { | 384 | int 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 | */ |
| 403 | struct SParser { /* data to `f_parser' */ | 402 | struct 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 | 446 | static void seterrorobj (lua_State *L, int errcode, TObject *m) { | |
| 449 | static 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 | /* | 470 | void 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 | */ | ||
| 467 | void 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 | ||
| 480 | void 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 | |||
| 490 | int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) { | 483 | int 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; |
