diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 12:32:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 12:32:22 -0300 |
commit | a2fa48a570b01b2a2cd37f01799f08f693fc5892 (patch) | |
tree | b41fc7e88f7f941ae1589921f8d7c0ff57146f4d | |
parent | 8b2b8790b5c419282f4fa0c7faa168379647b3b9 (diff) | |
download | lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.tar.gz lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.tar.bz2 lua-a2fa48a570b01b2a2cd37f01799f08f693fc5892.zip |
new (old?) error handling scheme
-rw-r--r-- | lapi.c | 15 | ||||
-rw-r--r-- | lauxlib.c | 6 | ||||
-rw-r--r-- | lbaselib.c | 22 | ||||
-rw-r--r-- | ldebug.c | 27 | ||||
-rw-r--r-- | ldebug.h | 3 | ||||
-rw-r--r-- | ldo.c | 63 | ||||
-rw-r--r-- | ldo.h | 4 | ||||
-rw-r--r-- | lstate.c | 8 | ||||
-rw-r--r-- | lstate.h | 15 | ||||
-rw-r--r-- | ltests.c | 12 | ||||
-rw-r--r-- | lua.c | 74 | ||||
-rw-r--r-- | lua.h | 5 |
12 files changed, 94 insertions, 160 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.205 2002/07/17 16:25:13 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.206 2002/08/05 14:43:38 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -610,22 +610,17 @@ LUA_API void lua_call (lua_State *L, int nargs, int nresults) { | |||
610 | } | 610 | } |
611 | 611 | ||
612 | 612 | ||
613 | LUA_API int lua_pcall (lua_State *L, int nargs, int nresults) { | 613 | LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { |
614 | int status; | 614 | int status; |
615 | ptrdiff_t func; | ||
615 | lua_lock(L); | 616 | lua_lock(L); |
616 | status = luaD_pcall(L, nargs, nresults); | 617 | func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc)); |
618 | status = luaD_pcall(L, nargs, nresults, func); | ||
617 | lua_unlock(L); | 619 | lua_unlock(L); |
618 | return status; | 620 | return status; |
619 | } | 621 | } |
620 | 622 | ||
621 | 623 | ||
622 | LUA_API void lua_pcallreset (lua_State *L) { | ||
623 | lua_lock(L); | ||
624 | luaD_resetprotection(L); /* reset error handler */ | ||
625 | lua_unlock(L); | ||
626 | } | ||
627 | |||
628 | |||
629 | LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, | 624 | LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, |
630 | const char *chunkname) { | 625 | const char *chunkname) { |
631 | ZIO z; | 626 | ZIO z; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.78 2002/07/01 19:23:58 roberto Exp $ | 2 | ** $Id: lauxlib.c,v 1.79 2002/08/05 17:36:24 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -404,9 +404,7 @@ static void callalert (lua_State *L, int status) { | |||
404 | 404 | ||
405 | static int aux_do (lua_State *L, int status) { | 405 | static int aux_do (lua_State *L, int status) { |
406 | if (status == 0) { /* parse OK? */ | 406 | if (status == 0) { /* parse OK? */ |
407 | status = lua_pcall(L, 0, LUA_MULTRET); /* call main */ | 407 | status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */ |
408 | if (status != 0) | ||
409 | lua_pcallreset(L); | ||
410 | } | 408 | } |
411 | callalert(L, status); | 409 | callalert(L, status); |
412 | return status; | 410 | return status; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.91 2002/07/17 16:25:13 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.92 2002/08/05 14:46:02 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -276,9 +276,7 @@ static int luaB_unpack (lua_State *L) { | |||
276 | static int luaB_pcall (lua_State *L) { | 276 | static int luaB_pcall (lua_State *L) { |
277 | int status; | 277 | int status; |
278 | luaL_check_any(L, 1); | 278 | luaL_check_any(L, 1); |
279 | status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET); | 279 | status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); |
280 | if (status) /* error? */ | ||
281 | lua_pcallreset(L); /* reset error handler */ | ||
282 | lua_pushboolean(L, (status == 0)); | 280 | lua_pushboolean(L, (status == 0)); |
283 | lua_insert(L, 1); | 281 | lua_insert(L, 1); |
284 | return lua_gettop(L); /* return status + all results */ | 282 | return lua_gettop(L); /* return status + all results */ |
@@ -287,22 +285,12 @@ static int luaB_pcall (lua_State *L) { | |||
287 | 285 | ||
288 | static int luaB_xpcall (lua_State *L) { | 286 | static int luaB_xpcall (lua_State *L) { |
289 | int status; | 287 | int status; |
290 | int ref; | ||
291 | luaL_check_any(L, 2); | 288 | luaL_check_any(L, 2); |
292 | lua_settop(L, 2); | 289 | lua_settop(L, 2); |
293 | ref = lua_ref(L, 1); /* save error function */ | 290 | lua_insert(L, 1); /* put error function under function to be called */ |
294 | status = lua_pcall(L, 0, LUA_MULTRET); | 291 | status = lua_pcall(L, 0, LUA_MULTRET, 1); |
295 | if (status) { /* error? */ | ||
296 | if (status == LUA_ERRRUN) { /* run-time error? */ | ||
297 | lua_getref(L, ref); /* get error function */ | ||
298 | lua_pushvalue(L, -2); /* error message */ | ||
299 | lua_call(L, 1, 1); /* call error function */ | ||
300 | } | ||
301 | lua_pcallreset(L); /* reset error handler */ | ||
302 | } | ||
303 | lua_unref(L, ref); /* free reference */ | ||
304 | lua_pushboolean(L, (status == 0)); | 292 | lua_pushboolean(L, (status == 0)); |
305 | lua_insert(L, 1); | 293 | lua_replace(L, 1); |
306 | return lua_gettop(L); /* return status + all results */ | 294 | return lua_gettop(L); /* return status + all results */ |
307 | } | 295 | } |
308 | 296 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.125 2002/07/16 14:26:56 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.126 2002/08/05 14:51:21 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 | */ |
@@ -35,7 +35,7 @@ static int isLua (CallInfo *ci) { | |||
35 | 35 | ||
36 | static int currentpc (lua_State *L, CallInfo *ci) { | 36 | static int currentpc (lua_State *L, CallInfo *ci) { |
37 | if (!isLua(ci)) return -1; /* function is not a Lua function? */ | 37 | if (!isLua(ci)) return -1; /* function is not a Lua function? */ |
38 | if (ci->pc && ci->pc != &luaV_callingmark) | 38 | if (ci->pc != &luaV_callingmark) /* is not calling another Lua function? */ |
39 | ci->u.l.savedpc = *ci->pc; /* `pc' may not be saved; save it */ | 39 | ci->u.l.savedpc = *ci->pc; /* `pc' may not be saved; save it */ |
40 | /* function's pc is saved */ | 40 | /* function's pc is saved */ |
41 | return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); | 41 | return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); |
@@ -51,19 +51,9 @@ static int currentline (lua_State *L, CallInfo *ci) { | |||
51 | } | 51 | } |
52 | 52 | ||
53 | 53 | ||
54 | /* | ||
55 | ** save all `pc's from active Lua functions | ||
56 | */ | ||
57 | void luaG_saveallpcs (lua_State *L) { | ||
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 | |||
65 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) { | 54 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) { |
66 | int allow; | 55 | int allow; |
56 | CallInfo *ci; | ||
67 | lua_lock(L); | 57 | lua_lock(L); |
68 | allow = allowhook(L); | 58 | allow = allowhook(L); |
69 | if (func == NULL) mask = 0; | 59 | if (func == NULL) mask = 0; |
@@ -72,7 +62,8 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) { | |||
72 | L->hookmask = mask; | 62 | L->hookmask = mask; |
73 | setallowhook(L, allow); | 63 | setallowhook(L, allow); |
74 | resethookcount(L); | 64 | resethookcount(L); |
75 | luaG_saveallpcs(L); | 65 | for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ |
66 | currentpc(L, ci); | ||
76 | lua_unlock(L); | 67 | lua_unlock(L); |
77 | return 1; | 68 | return 1; |
78 | } | 69 | } |
@@ -547,6 +538,14 @@ static void addinfo (lua_State *L, int internal) { | |||
547 | void luaG_errormsg (lua_State *L, int internal) { | 538 | void luaG_errormsg (lua_State *L, int internal) { |
548 | if (ttisstring(L->top - 1)) | 539 | if (ttisstring(L->top - 1)) |
549 | addinfo(L, internal); | 540 | addinfo(L, internal); |
541 | if (L->errfunc != 0) { /* is there an error handling function? */ | ||
542 | StkId errfunc = restorestack(L, L->errfunc); | ||
543 | if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); | ||
544 | setobj(L->top, L->top - 1); /* move argument */ | ||
545 | setobj(L->top - 1, errfunc); /* push function */ | ||
546 | incr_top(L); | ||
547 | luaD_call(L, L->top - 2, 1); /* call it */ | ||
548 | } | ||
550 | luaD_throw(L, LUA_ERRRUN); | 549 | luaD_throw(L, LUA_ERRRUN); |
551 | } | 550 | } |
552 | 551 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.h,v 1.25 2002/07/08 20:22:08 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.26 2002/08/05 14:51:21 roberto Exp roberto $ |
3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -23,7 +23,6 @@ | |||
23 | #define allowhook(L) ((L->hookmask) & 1) | 23 | #define allowhook(L) ((L->hookmask) & 1) |
24 | 24 | ||
25 | 25 | ||
26 | void luaG_saveallpcs (lua_State *L); | ||
27 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); | 26 | void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); |
28 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); | 27 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2); |
29 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); | 28 | void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.188 2002/07/16 14:26:56 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.189 2002/08/05 17:36:24 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 | */ |
@@ -64,9 +64,6 @@ static void seterrorobj (lua_State *L, int errcode) { | |||
64 | 64 | ||
65 | 65 | ||
66 | void luaD_throw (lua_State *L, int errcode) { | 66 | void luaD_throw (lua_State *L, int errcode) { |
67 | if (errcode == LUA_ERRRUN) | ||
68 | luaD_checkstack(L, LUA_MINSTACK); /* ensure stack space to handle error */ | ||
69 | luaG_saveallpcs(L); /* C stack will disapear */ | ||
70 | if (L->errorJmp) { | 67 | if (L->errorJmp) { |
71 | L->errorJmp->status = errcode; | 68 | L->errorJmp->status = errcode; |
72 | longjmp(L->errorJmp->b, 1); | 69 | longjmp(L->errorJmp->b, 1); |
@@ -99,30 +96,6 @@ static void restore_stack_limit (lua_State *L) { | |||
99 | } | 96 | } |
100 | } | 97 | } |
101 | 98 | ||
102 | |||
103 | void luaD_resetprotection (lua_State *L) { | ||
104 | Protection *p; | ||
105 | StkId err = L->top - 1; /* error msg. position (if there is one) */ | ||
106 | lua_assert(L->number_toreset > 0); | ||
107 | p = &L->toreset[--L->number_toreset]; | ||
108 | L->ci = restoreci(L, p->ci); | ||
109 | L->top = restorestack(L, p->top); | ||
110 | L->ci->top = L->top + LUA_MINSTACK; | ||
111 | setallowhook(L, p->allowhooks); | ||
112 | restore_stack_limit(L); | ||
113 | setobj(L->top++, err); /* copy error message to corrected top */ | ||
114 | } | ||
115 | |||
116 | |||
117 | /* | ||
118 | ** invalidate all pc pointers from stack part that becomes inactive | ||
119 | */ | ||
120 | static void deactivateinfo (lua_State *L, CallInfo *p_ci) { | ||
121 | CallInfo *ci; | ||
122 | for (ci = L->ci; ci > p_ci; ci--) | ||
123 | ci->pc = NULL; | ||
124 | } | ||
125 | |||
126 | /* }====================================================== */ | 99 | /* }====================================================== */ |
127 | 100 | ||
128 | 101 | ||
@@ -168,7 +141,6 @@ void luaD_growstack (lua_State *L, int n) { | |||
168 | 141 | ||
169 | 142 | ||
170 | static void luaD_growCI (lua_State *L) { | 143 | static void luaD_growCI (lua_State *L) { |
171 | L->ci--; | ||
172 | if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ | 144 | if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ |
173 | luaD_throw(L, LUA_ERRERR); | 145 | luaD_throw(L, LUA_ERRERR); |
174 | else { | 146 | else { |
@@ -176,7 +148,6 @@ static void luaD_growCI (lua_State *L) { | |||
176 | if (L->size_ci > LUA_MAXCALLS) | 148 | if (L->size_ci > LUA_MAXCALLS) |
177 | luaG_runerror(L, "stack overflow"); | 149 | luaG_runerror(L, "stack overflow"); |
178 | } | 150 | } |
179 | L->ci++; | ||
180 | } | 151 | } |
181 | 152 | ||
182 | 153 | ||
@@ -412,34 +383,34 @@ struct CallS { /* data to `f_call' */ | |||
412 | 383 | ||
413 | static void f_call (lua_State *L, void *ud) { | 384 | static void f_call (lua_State *L, void *ud) { |
414 | struct CallS *c = cast(struct CallS *, ud); | 385 | struct CallS *c = cast(struct CallS *, ud); |
415 | luaM_growvector(L, L->toreset, L->number_toreset, L->size_toreset, | ||
416 | Protection, MAX_INT, ""); | ||
417 | luaD_call(L, c->func, c->nresults); | 386 | luaD_call(L, c->func, c->nresults); |
418 | } | 387 | } |
419 | 388 | ||
420 | 389 | ||
421 | int luaD_pcall (lua_State *L, int nargs, int nresults) { | 390 | int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) { |
422 | struct CallS c; | 391 | struct CallS c; |
423 | int status; | 392 | int status; |
424 | int protectionlevel = L->number_toreset; | 393 | ptrdiff_t old_top = savestack(L, L->top); |
425 | Protection protection; | 394 | ptrdiff_t old_ci = saveci(L, L->ci); |
426 | protection.top = savestack(L, L->top); | 395 | int old_allowhooks = allowhook(L); |
427 | protection.ci = saveci(L, L->ci); | 396 | ptrdiff_t old_errfunc = L->errfunc; |
428 | protection.allowhooks = allowhook(L); | 397 | L->errfunc = errfunc; |
429 | c.func = L->top - (nargs+1); /* function to be called */ | 398 | c.func = L->top - (nargs+1); /* function to be called */ |
430 | c.nresults = nresults; | 399 | c.nresults = nresults; |
431 | status = luaD_rawrunprotected(L, &f_call, &c); | 400 | status = luaD_rawrunprotected(L, &f_call, &c); |
432 | if (status != 0) { /* an error occurred? */ | 401 | if (status != 0) { /* an error occurred? */ |
433 | /* remove parameters and func from the stack */ | 402 | StkId err; /* error msg. position */ |
434 | protection.top = savestack(L, restorestack(L, protection.top) - (nargs+1)); | ||
435 | /* close eventual pending closures */ | ||
436 | luaF_close(L, restorestack(L, protection.top)); | ||
437 | L->ci->top = L->top + LUA_MINSTACK; /* extra space to handle error */ | ||
438 | seterrorobj(L, status); | 403 | seterrorobj(L, status); |
439 | deactivateinfo(L, restoreci(L, protection.ci)); | 404 | err = L->top - 1; |
440 | L->number_toreset = protectionlevel + 1; | 405 | /* remove parameters and func from the stack */ |
441 | L->toreset[L->number_toreset - 1] = protection; | 406 | L->top = restorestack(L, old_top) - (nargs+1); |
407 | setobj(L->top++, err); /* copy error message to corrected top */ | ||
408 | luaF_close(L, L->top); /* close eventual pending closures */ | ||
409 | L->ci = restoreci(L, old_ci); | ||
410 | setallowhook(L, old_allowhooks); | ||
411 | restore_stack_limit(L); | ||
442 | } | 412 | } |
413 | L->errfunc = old_errfunc; | ||
443 | return status; | 414 | return status; |
444 | } | 415 | } |
445 | 416 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 1.48 2002/07/08 18:21:33 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 1.49 2002/08/05 17:36:24 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 | */ |
@@ -39,7 +39,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin); | |||
39 | void luaD_callhook (lua_State *L, lua_Hookevent event, int line); | 39 | void luaD_callhook (lua_State *L, lua_Hookevent event, int line); |
40 | StkId luaD_precall (lua_State *L, StkId func); | 40 | StkId luaD_precall (lua_State *L, StkId func); |
41 | void luaD_call (lua_State *L, StkId func, int nResults); | 41 | void luaD_call (lua_State *L, StkId func, int nResults); |
42 | int luaD_pcall (lua_State *L, int nargs, int nresults); | 42 | int luaD_pcall (lua_State *L, int nargs, int nresults, int errfunc); |
43 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult); | 43 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult); |
44 | void luaD_reallocCI (lua_State *L, int newsize); | 44 | void luaD_reallocCI (lua_State *L, int newsize); |
45 | void luaD_reallocstack (lua_State *L, int newsize); | 45 | void luaD_reallocstack (lua_State *L, int newsize); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 1.100 2002/08/05 17:36:24 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.101 2002/08/05 18:45:45 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -47,8 +47,6 @@ static void stack_init (lua_State *L, lua_State *OL) { | |||
47 | L->ci->top = L->top + LUA_MINSTACK; | 47 | L->ci->top = L->top + LUA_MINSTACK; |
48 | L->size_ci = BASIC_CI_SIZE; | 48 | L->size_ci = BASIC_CI_SIZE; |
49 | L->end_ci = L->base_ci + L->size_ci; | 49 | L->end_ci = L->base_ci + L->size_ci; |
50 | L->toreset = luaM_newvector(OL, 2, Protection); | ||
51 | L->size_toreset = 2; | ||
52 | } | 50 | } |
53 | 51 | ||
54 | 52 | ||
@@ -102,8 +100,7 @@ static void preinit_state (lua_State *L) { | |||
102 | L->openupval = NULL; | 100 | L->openupval = NULL; |
103 | L->size_ci = 0; | 101 | L->size_ci = 0; |
104 | L->base_ci = L->ci = NULL; | 102 | L->base_ci = L->ci = NULL; |
105 | L->toreset = NULL; | 103 | L->errfunc = 0; |
106 | L->size_toreset = L->number_toreset = 0; | ||
107 | setnilvalue(defaultmeta(L)); | 104 | setnilvalue(defaultmeta(L)); |
108 | setnilvalue(gt(L)); | 105 | setnilvalue(gt(L)); |
109 | setnilvalue(registry(L)); | 106 | setnilvalue(registry(L)); |
@@ -154,7 +151,6 @@ void luaE_closethread (lua_State *OL, lua_State *L) { | |||
154 | L->previous->next = L->next; | 151 | L->previous->next = L->next; |
155 | L->next->previous = L->previous; | 152 | L->next->previous = L->previous; |
156 | luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo); | 153 | luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo); |
157 | luaM_freearray(OL, L->toreset, L->size_toreset, Protection); | ||
158 | luaM_freearray(OL, L->stack, L->stacksize, TObject); | 154 | luaM_freearray(OL, L->stack, L->stacksize, TObject); |
159 | luaM_freelem(OL, L); | 155 | luaM_freelem(OL, L); |
160 | } | 156 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.89 2002/07/16 14:26:56 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.90 2002/08/05 17:36:24 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -101,15 +101,6 @@ typedef struct CallInfo { | |||
101 | } CallInfo; | 101 | } CallInfo; |
102 | 102 | ||
103 | 103 | ||
104 | /* | ||
105 | ** informations about a `protection' (error recovery points) | ||
106 | */ | ||
107 | typedef struct Protection { | ||
108 | ptrdiff_t ci; | ||
109 | ptrdiff_t top; | ||
110 | int allowhooks; | ||
111 | } Protection; | ||
112 | |||
113 | 104 | ||
114 | #define ci_func(ci) (clvalue((ci)->base - 1)) | 105 | #define ci_func(ci) (clvalue((ci)->base - 1)) |
115 | 106 | ||
@@ -154,9 +145,7 @@ struct lua_State { | |||
154 | lua_Hook hook; | 145 | lua_Hook hook; |
155 | UpVal *openupval; /* list of open upvalues in this stack */ | 146 | UpVal *openupval; /* list of open upvalues in this stack */ |
156 | struct lua_longjmp *errorJmp; /* current error recover point */ | 147 | struct lua_longjmp *errorJmp; /* current error recover point */ |
157 | Protection *toreset; /* array of pending pcall resets */ | 148 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
158 | int number_toreset; | ||
159 | int size_toreset; | ||
160 | lua_State *next; /* circular double linked list of states */ | 149 | lua_State *next; /* circular double linked list of states */ |
161 | lua_State *previous; | 150 | lua_State *previous; |
162 | TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */ | 151 | TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.130 2002/07/17 16:25:13 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.131 2002/08/05 14:10:10 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -402,7 +402,7 @@ static int doonnewstack (lua_State *L) { | |||
402 | const char *s = luaL_check_lstr(L, 1, &l); | 402 | const char *s = luaL_check_lstr(L, 1, &l); |
403 | int status = luaL_loadbuffer(L1, s, l, s); | 403 | int status = luaL_loadbuffer(L1, s, l, s); |
404 | if (status == 0) | 404 | if (status == 0) |
405 | status = lua_pcall(L1, 0, 0); | 405 | status = lua_pcall(L1, 0, 0, 0); |
406 | lua_pushnumber(L, status); | 406 | lua_pushnumber(L, status); |
407 | lua_closethread(L, L1); | 407 | lua_closethread(L, L1); |
408 | return 1; | 408 | return 1; |
@@ -456,10 +456,8 @@ static int doremote (lua_State *L) { | |||
456 | int status; | 456 | int status; |
457 | lua_settop(L1, 0); | 457 | lua_settop(L1, 0); |
458 | status = luaL_loadbuffer(L1, code, lcode, code); | 458 | status = luaL_loadbuffer(L1, code, lcode, code); |
459 | if (status == 0) { | 459 | if (status == 0) |
460 | status = lua_pcall(L1, 0, LUA_MULTRET); | 460 | status = lua_pcall(L1, 0, LUA_MULTRET, 0); |
461 | if (status != 0) lua_pcallreset(L1); | ||
462 | } | ||
463 | if (status != 0) { | 461 | if (status != 0) { |
464 | lua_pushnil(L); | 462 | lua_pushnil(L); |
465 | lua_pushnumber(L, status); | 463 | lua_pushnumber(L, status); |
@@ -647,7 +645,7 @@ static int testC (lua_State *L) { | |||
647 | else if EQ("call") { | 645 | else if EQ("call") { |
648 | int narg = getnum; | 646 | int narg = getnum; |
649 | int nres = getnum; | 647 | int nres = getnum; |
650 | lua_pcall(L, narg, nres); | 648 | lua_pcall(L, narg, nres, 0); |
651 | } | 649 | } |
652 | else if EQ("loadstring") { | 650 | else if EQ("loadstring") { |
653 | size_t sl; | 651 | size_t sl; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.c,v 1.96 2002/07/10 20:44:34 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.97 2002/07/10 20:49:01 roberto Exp roberto $ |
3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,8 +35,8 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */ | |||
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | 37 | ||
38 | #ifndef LUA_USERINIT | 38 | #ifndef lua_userinit |
39 | #define LUA_USERINIT(L) openstdlibs(L) | 39 | #define lua_userinit(L) openstdlibs(L) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | 42 | ||
@@ -80,23 +80,17 @@ static void print_usage (void) { | |||
80 | 80 | ||
81 | 81 | ||
82 | static void l_message (const char *pname, const char *msg) { | 82 | static void l_message (const char *pname, const char *msg) { |
83 | size_t l = strlen(msg); | ||
83 | if (pname) fprintf(stderr, "%s: ", pname); | 84 | if (pname) fprintf(stderr, "%s: ", pname); |
84 | fprintf(stderr, "%s", msg); | 85 | fprintf(stderr, "%s", msg); |
86 | if (l > 0 && msg[l-1] != '\n') /* does not end with newline? */ | ||
87 | fprintf(stderr, "\n"); /* add a newline */ | ||
85 | } | 88 | } |
86 | 89 | ||
87 | 90 | ||
88 | static void report (int status, int traceback) { | 91 | static void report (int status) { |
89 | const char *msg; | 92 | const char *msg; |
90 | if (status) { | 93 | if (status) { |
91 | if (status == LUA_ERRRUN) { | ||
92 | if (!traceback) lua_pop(L, 1); /* remove traceback */ | ||
93 | else { | ||
94 | if (lua_isstring(L, -2) && lua_isstring(L, -1)) | ||
95 | lua_concat(L, 2); /* concat error message and traceback */ | ||
96 | else | ||
97 | lua_remove(L, -2); /* leave only traceback on stack */ | ||
98 | } | ||
99 | } | ||
100 | msg = lua_tostring(L, -1); | 94 | msg = lua_tostring(L, -1); |
101 | if (msg == NULL) msg = "(no message)"; | 95 | if (msg == NULL) msg = "(no message)"; |
102 | l_message(progname, msg); | 96 | l_message(progname, msg); |
@@ -108,9 +102,12 @@ static void report (int status, int traceback) { | |||
108 | static int lcall (int clear) { | 102 | static int lcall (int clear) { |
109 | int status; | 103 | int status; |
110 | int top = lua_gettop(L); | 104 | int top = lua_gettop(L); |
105 | lua_getglobal(L, "_TRACEBACK"); /* get traceback function */ | ||
106 | lua_insert(L, top); /* put it under chunk */ | ||
111 | signal(SIGINT, laction); | 107 | signal(SIGINT, laction); |
112 | status = lua_pcall(L, 0, LUA_MULTRET); | 108 | status = lua_pcall(L, 0, LUA_MULTRET, -2); |
113 | signal(SIGINT, SIG_DFL); | 109 | signal(SIGINT, SIG_DFL); |
110 | lua_remove(L, top); /* remove traceback function */ | ||
114 | if (status == 0 && clear) | 111 | if (status == 0 && clear) |
115 | lua_settop(L, top); /* remove eventual results */ | 112 | lua_settop(L, top); /* remove eventual results */ |
116 | return status; | 113 | return status; |
@@ -119,13 +116,13 @@ static int lcall (int clear) { | |||
119 | 116 | ||
120 | static int l_panic (lua_State *l) { | 117 | static int l_panic (lua_State *l) { |
121 | (void)l; | 118 | (void)l; |
122 | l_message(progname, "unable to recover; exiting\n"); | 119 | l_message(progname, "unable to recover; exiting"); |
123 | return 0; | 120 | return 0; |
124 | } | 121 | } |
125 | 122 | ||
126 | 123 | ||
127 | static void print_version (void) { | 124 | static void print_version (void) { |
128 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT "\n"); | 125 | l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT); |
129 | } | 126 | } |
130 | 127 | ||
131 | 128 | ||
@@ -146,7 +143,7 @@ static void getargs (char *argv[], int n) { | |||
146 | 143 | ||
147 | static int docall (int status) { | 144 | static int docall (int status) { |
148 | if (status == 0) status = lcall(1); | 145 | if (status == 0) status = lcall(1); |
149 | report(status, 1); | 146 | report(status); |
150 | return status; | 147 | return status; |
151 | } | 148 | } |
152 | 149 | ||
@@ -161,13 +158,21 @@ static int dostring (const char *s, const char *name) { | |||
161 | } | 158 | } |
162 | 159 | ||
163 | 160 | ||
164 | #ifndef save_line | 161 | /* |
165 | #define save_line(b) /* empty */ | 162 | ** this macro can be used by some `history' system to save lines |
163 | ** read in manual input | ||
164 | */ | ||
165 | #ifndef lua_saveline | ||
166 | #define lua_saveline(L,line) /* empty */ | ||
166 | #endif | 167 | #endif |
167 | 168 | ||
168 | 169 | ||
169 | #ifndef read_line | 170 | /* |
170 | #define read_line(p) readline(p) | 171 | ** this macro defines a function to show the prompt and reads the |
172 | ** next line for manual input | ||
173 | */ | ||
174 | #ifndef lua_readline | ||
175 | #define lua_readline(L,prompt) readline(L,prompt) | ||
171 | 176 | ||
172 | /* maximum length of an input line */ | 177 | /* maximum length of an input line */ |
173 | #ifndef MAXINPUT | 178 | #ifndef MAXINPUT |
@@ -175,7 +180,7 @@ static int dostring (const char *s, const char *name) { | |||
175 | #endif | 180 | #endif |
176 | 181 | ||
177 | 182 | ||
178 | static int readline (const char *prompt) { | 183 | static int readline (lua_State *l, const char *prompt) { |
179 | static char buffer[MAXINPUT]; | 184 | static char buffer[MAXINPUT]; |
180 | if (prompt) { | 185 | if (prompt) { |
181 | fputs(prompt, stdout); | 186 | fputs(prompt, stdout); |
@@ -184,10 +189,7 @@ static int readline (const char *prompt) { | |||
184 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) | 189 | if (fgets(buffer, sizeof(buffer), stdin) == NULL) |
185 | return 0; /* read fails */ | 190 | return 0; /* read fails */ |
186 | else { | 191 | else { |
187 | size_t l = strlen(buffer); | 192 | lua_pushstring(l, buffer); |
188 | if (l > 0 && buffer[l-1] == '\n') | ||
189 | buffer[l-1] = '\0'; /* remove eventual `\n' */ | ||
190 | lua_pushstring(L, buffer); | ||
191 | return 1; | 193 | return 1; |
192 | } | 194 | } |
193 | } | 195 | } |
@@ -219,7 +221,7 @@ static int incomplete (int status) { | |||
219 | static int load_string (void) { | 221 | static int load_string (void) { |
220 | int status; | 222 | int status; |
221 | lua_settop(L, 0); | 223 | lua_settop(L, 0); |
222 | if (read_line(get_prompt(1)) == 0) /* no input? */ | 224 | if (lua_readline(L, get_prompt(1)) == 0) /* no input? */ |
223 | return -1; | 225 | return -1; |
224 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ | 226 | if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ |
225 | lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ | 227 | lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ |
@@ -228,12 +230,11 @@ static int load_string (void) { | |||
228 | for (;;) { /* repeat until gets a complete line */ | 230 | for (;;) { /* repeat until gets a complete line */ |
229 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); | 231 | status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); |
230 | if (!incomplete(status)) break; /* cannot try to add lines? */ | 232 | if (!incomplete(status)) break; /* cannot try to add lines? */ |
231 | lua_pushliteral(L, "\n"); /* no; add line separator */ | 233 | if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */ |
232 | if (read_line(get_prompt(0)) == 0) /* no more input? */ | ||
233 | return -1; | 234 | return -1; |
234 | lua_concat(L, lua_gettop(L)); /* join lines and line separator */ | 235 | lua_concat(L, lua_gettop(L)); /* join lines */ |
235 | } | 236 | } |
236 | save_line(lua_tostring(L, 1)); | 237 | lua_saveline(L, lua_tostring(L, 1)); |
237 | lua_remove(L, 1); /* remove line */ | 238 | lua_remove(L, 1); /* remove line */ |
238 | return status; | 239 | return status; |
239 | } | 240 | } |
@@ -245,11 +246,12 @@ static void manual_input (void) { | |||
245 | progname = NULL; | 246 | progname = NULL; |
246 | while ((status = load_string()) != -1) { | 247 | while ((status = load_string()) != -1) { |
247 | if (status == 0) status = lcall(0); | 248 | if (status == 0) status = lcall(0); |
248 | report(status, 0); | 249 | report(status); |
249 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ | 250 | if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ |
250 | lua_getglobal(L, "print"); | 251 | lua_getglobal(L, "print"); |
251 | lua_insert(L, 1); | 252 | lua_insert(L, 1); |
252 | lua_pcall(L, lua_gettop(L)-1, 0); | 253 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) |
254 | l_message(progname, "error calling `print'"); | ||
253 | } | 255 | } |
254 | } | 256 | } |
255 | lua_settop(L, 0); /* clear stack */ | 257 | lua_settop(L, 0); /* clear stack */ |
@@ -311,11 +313,11 @@ static int handle_argv (char *argv[], int *interactive) { | |||
311 | break; | 313 | break; |
312 | } | 314 | } |
313 | case 'c': { | 315 | case 'c': { |
314 | l_message(progname, "option `-c' is deprecated\n"); | 316 | l_message(progname, "option `-c' is deprecated"); |
315 | break; | 317 | break; |
316 | } | 318 | } |
317 | case 's': { | 319 | case 's': { |
318 | l_message(progname, "option `-s' is deprecated\n"); | 320 | l_message(progname, "option `-s' is deprecated"); |
319 | break; | 321 | break; |
320 | } | 322 | } |
321 | default: { | 323 | default: { |
@@ -364,7 +366,7 @@ int main (int argc, char *argv[]) { | |||
364 | progname = argv[0]; | 366 | progname = argv[0]; |
365 | L = lua_open(); /* create state */ | 367 | L = lua_open(); /* create state */ |
366 | lua_atpanic(L, l_panic); | 368 | lua_atpanic(L, l_panic); |
367 | lua_pop(L, LUA_USERINIT(L)); /* open libraries, discard any results */ | 369 | lua_pop(L, lua_userinit(L)); /* open libraries, discard any results */ |
368 | status = handle_luainit(); | 370 | status = handle_luainit(); |
369 | if (status != 0) return status; | 371 | if (status != 0) return status; |
370 | status = handle_argv(argv, &interactive); | 372 | status = handle_argv(argv, &interactive); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.147 2002/07/17 16:25:13 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.148 2002/08/05 14:51:47 roberto Exp roberto $ |
3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** http://www.lua.org mailto:info@lua.org |
@@ -183,10 +183,9 @@ LUA_API int lua_setglobals (lua_State *L, int level); | |||
183 | ** `load' and `call' functions (load and run Lua code) | 183 | ** `load' and `call' functions (load and run Lua code) |
184 | */ | 184 | */ |
185 | LUA_API void lua_call (lua_State *L, int nargs, int nresults); | 185 | LUA_API void lua_call (lua_State *L, int nargs, int nresults); |
186 | LUA_API int lua_pcall (lua_State *L, int nargs, int nresults); | 186 | LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc); |
187 | LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, | 187 | LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, |
188 | const char *chunkname); | 188 | const char *chunkname); |
189 | LUA_API void lua_pcallreset (lua_State *L); | ||
190 | 189 | ||
191 | 190 | ||
192 | /* | 191 | /* |