diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-07-11 11:00:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-07-11 11:00:31 -0300 |
commit | 575637319e7f7328253268b6705d961ff62784ca (patch) | |
tree | dd84024ed0bc7e14ec4f39391f402e3008e2df3c /ldo.c | |
parent | 87be01598bd06ada6acb9389947f427ca80231a5 (diff) | |
download | lua-575637319e7f7328253268b6705d961ff62784ca.tar.gz lua-575637319e7f7328253268b6705d961ff62784ca.tar.bz2 lua-575637319e7f7328253268b6705d961ff62784ca.zip |
better recovery at panic
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 47 |
1 files changed, 32 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.26 2005/06/13 14:15:54 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.27 2005/06/13 21:17:59 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 | */ |
@@ -68,14 +68,41 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | 70 | ||
71 | static void restore_stack_limit (lua_State *L) { | ||
72 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | ||
73 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ | ||
74 | int inuse = cast(int, L->ci - L->base_ci); | ||
75 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ | ||
76 | luaD_reallocCI(L, LUAI_MAXCALLS); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | |||
81 | static void resetstack (lua_State *L, int status) { | ||
82 | L->ci = L->base_ci; | ||
83 | L->base = L->ci->base; | ||
84 | luaF_close(L, L->base); /* close eventual pending closures */ | ||
85 | seterrorobj(L, status, L->base); | ||
86 | L->nCcalls = 0; | ||
87 | L->allowhook = 1; | ||
88 | restore_stack_limit(L); | ||
89 | L->errfunc = 0; | ||
90 | L->errorJmp = NULL; | ||
91 | } | ||
92 | |||
93 | |||
71 | void luaD_throw (lua_State *L, int errcode) { | 94 | void luaD_throw (lua_State *L, int errcode) { |
72 | if (L->errorJmp) { | 95 | if (L->errorJmp) { |
73 | L->errorJmp->status = errcode; | 96 | L->errorJmp->status = errcode; |
74 | LUAI_THROW(L, L->errorJmp); | 97 | LUAI_THROW(L, L->errorJmp); |
75 | } | 98 | } |
76 | else { | 99 | else { |
77 | L->status = errcode; | 100 | L->status = cast(lu_byte, errcode); |
78 | if (G(L)->panic) G(L)->panic(L); | 101 | if (G(L)->panic) { |
102 | resetstack(L, errcode); | ||
103 | lua_unlock(L); | ||
104 | G(L)->panic(L); | ||
105 | } | ||
79 | exit(EXIT_FAILURE); | 106 | exit(EXIT_FAILURE); |
80 | } | 107 | } |
81 | } | 108 | } |
@@ -93,16 +120,6 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
93 | return lj.status; | 120 | return lj.status; |
94 | } | 121 | } |
95 | 122 | ||
96 | |||
97 | static void restore_stack_limit (lua_State *L) { | ||
98 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | ||
99 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ | ||
100 | int inuse = cast(int, L->ci - L->base_ci); | ||
101 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ | ||
102 | luaD_reallocCI(L, LUAI_MAXCALLS); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* }====================================================== */ | 123 | /* }====================================================== */ |
107 | 124 | ||
108 | 125 | ||
@@ -408,7 +425,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
408 | } | 425 | } |
409 | status = luaD_rawrunprotected(L, resume, &nargs); | 426 | status = luaD_rawrunprotected(L, resume, &nargs); |
410 | if (status != 0) { /* error? */ | 427 | if (status != 0) { /* error? */ |
411 | L->status = status; /* mark thread as `dead' */ | 428 | L->status = cast(lu_byte, status); /* mark thread as `dead' */ |
412 | seterrorobj(L, status, L->top); | 429 | seterrorobj(L, status, L->top); |
413 | } | 430 | } |
414 | else | 431 | else |
@@ -441,7 +458,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
441 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 458 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
442 | ptrdiff_t old_top, ptrdiff_t ef) { | 459 | ptrdiff_t old_top, ptrdiff_t ef) { |
443 | int status; | 460 | int status; |
444 | int oldnCcalls = L->nCcalls; | 461 | unsigned short oldnCcalls = L->nCcalls; |
445 | ptrdiff_t old_ci = saveci(L, L->ci); | 462 | ptrdiff_t old_ci = saveci(L, L->ci); |
446 | lu_byte old_allowhooks = L->allowhook; | 463 | lu_byte old_allowhooks = L->allowhook; |
447 | ptrdiff_t old_errfunc = L->errfunc; | 464 | ptrdiff_t old_errfunc = L->errfunc; |