aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c15
-rw-r--r--lauxlib.c6
-rw-r--r--lbaselib.c22
-rw-r--r--ldebug.c27
-rw-r--r--ldebug.h3
-rw-r--r--ldo.c63
-rw-r--r--ldo.h4
-rw-r--r--lstate.c8
-rw-r--r--lstate.h15
-rw-r--r--ltests.c12
-rw-r--r--lua.c74
-rw-r--r--lua.h5
12 files changed, 94 insertions, 160 deletions
diff --git a/lapi.c b/lapi.c
index 7d1831c8..d7b8c376 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
613LUA_API int lua_pcall (lua_State *L, int nargs, int nresults) { 613LUA_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
622LUA_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
629LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, 624LUA_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;
diff --git a/lauxlib.c b/lauxlib.c
index 01bcf9a1..f4e21d60 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
405static int aux_do (lua_State *L, int status) { 405static 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;
diff --git a/lbaselib.c b/lbaselib.c
index 8ff09683..b05a1b15 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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) {
276static int luaB_pcall (lua_State *L) { 276static 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
288static int luaB_xpcall (lua_State *L) { 286static 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
diff --git a/ldebug.c b/ldebug.c
index 56f6c820..0108b47e 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
36static int currentpc (lua_State *L, CallInfo *ci) { 36static 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*/
57void 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
65LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask) { 54LUA_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) {
547void luaG_errormsg (lua_State *L, int internal) { 538void 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
diff --git a/ldebug.h b/ldebug.h
index 204592db..c6cccd8c 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -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
26void luaG_saveallpcs (lua_State *L);
27void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); 26void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
28void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 27void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
29void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); 28void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
diff --git a/ldo.c b/ldo.c
index e6307b0c..85561e06 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
66void luaD_throw (lua_State *L, int errcode) { 66void 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
103void 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*/
120static 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
170static void luaD_growCI (lua_State *L) { 143static 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
413static void f_call (lua_State *L, void *ud) { 384static 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
421int luaD_pcall (lua_State *L, int nargs, int nresults) { 390int 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
diff --git a/ldo.h b/ldo.h
index fdd889ed..0d6047cc 100644
--- a/ldo.h
+++ b/ldo.h
@@ -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);
39void luaD_callhook (lua_State *L, lua_Hookevent event, int line); 39void luaD_callhook (lua_State *L, lua_Hookevent event, int line);
40StkId luaD_precall (lua_State *L, StkId func); 40StkId luaD_precall (lua_State *L, StkId func);
41void luaD_call (lua_State *L, StkId func, int nResults); 41void luaD_call (lua_State *L, StkId func, int nResults);
42int luaD_pcall (lua_State *L, int nargs, int nresults); 42int luaD_pcall (lua_State *L, int nargs, int nresults, int errfunc);
43void luaD_poscall (lua_State *L, int wanted, StkId firstResult); 43void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
44void luaD_reallocCI (lua_State *L, int newsize); 44void luaD_reallocCI (lua_State *L, int newsize);
45void luaD_reallocstack (lua_State *L, int newsize); 45void luaD_reallocstack (lua_State *L, int newsize);
diff --git a/lstate.c b/lstate.c
index 1f1c73fe..4e281977 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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}
diff --git a/lstate.h b/lstate.h
index a334921a..2cbebc23 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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*/
107typedef 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. */
diff --git a/ltests.c b/ltests.c
index 0f889531..dcef65c3 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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;
diff --git a/lua.c b/lua.c
index 3d86743d..19713f40 100644
--- a/lua.c
+++ b/lua.c
@@ -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
82static void l_message (const char *pname, const char *msg) { 82static 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
88static void report (int status, int traceback) { 91static 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) {
108static int lcall (int clear) { 102static 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
120static int l_panic (lua_State *l) { 117static 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
127static void print_version (void) { 124static 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
147static int docall (int status) { 144static 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
178static int readline (const char *prompt) { 183static 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) {
219static int load_string (void) { 221static 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);
diff --git a/lua.h b/lua.h
index 8407a6ed..2bc32fa6 100644
--- a/lua.h
+++ b/lua.h
@@ -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*/
185LUA_API void lua_call (lua_State *L, int nargs, int nresults); 185LUA_API void lua_call (lua_State *L, int nargs, int nresults);
186LUA_API int lua_pcall (lua_State *L, int nargs, int nresults); 186LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
187LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, 187LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
188 const char *chunkname); 188 const char *chunkname);
189LUA_API void lua_pcallreset (lua_State *L);
190 189
191 190
192/* 191/*