aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c12
-rw-r--r--lauxlib.c49
-rw-r--r--lauxlib.h6
-rw-r--r--lbaselib.c54
-rw-r--r--ldebug.c45
-rw-r--r--ldebug.h3
-rw-r--r--ldo.c91
-rw-r--r--ldo.h7
-rw-r--r--llex.c4
-rw-r--r--lmem.c4
-rw-r--r--lstate.c10
-rw-r--r--ltests.c37
-rw-r--r--lua.h14
13 files changed, 178 insertions, 158 deletions
diff --git a/lapi.c b/lapi.c
index d2600972..0d27a7e8 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.198 2002/06/13 13:39:55 roberto Exp roberto $ 2** $Id: lapi.c,v 1.199 2002/06/13 13:44:50 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*/
@@ -565,12 +565,10 @@ LUA_API void lua_upcall (lua_State *L, int nargs, int nresults) {
565} 565}
566 566
567 567
568LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf) { 568LUA_API int lua_pcall (lua_State *L, int nargs, int nresults) {
569 int status; 569 int status;
570 const TObject *err;
571 lua_lock(L); 570 lua_lock(L);
572 err = (errf == 0) ? &luaO_nilobject : luaA_index(L, errf); 571 status = luaD_pcall(L, nargs, nresults);
573 status = luaD_pcall(L, nargs, nresults, err);
574 lua_unlock(L); 572 lua_unlock(L);
575 return status; 573 return status;
576} 574}
@@ -631,10 +629,10 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
631*/ 629*/
632 630
633 631
634LUA_API int lua_errorobj (lua_State *L) { 632LUA_API int lua_error (lua_State *L) {
635 lua_lock(L); 633 lua_lock(L);
636 api_checknelems(L, 1); 634 api_checknelems(L, 1);
637 luaD_errorobj(L, L->top - 1, LUA_ERRRUN); 635 luaG_errormsg(L, 0);
638 lua_unlock(L); 636 lua_unlock(L);
639 return 0; /* to avoid warnings */ 637 return 0; /* to avoid warnings */
640} 638}
diff --git a/lauxlib.c b/lauxlib.c
index 51561746..81150cd4 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.73 2002/06/05 16:59:37 roberto Exp roberto $ 2** $Id: lauxlib.c,v 1.74 2002/06/13 13:44:50 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*/
@@ -40,13 +40,13 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
40 if (strcmp(ar.namewhat, "method") == 0) { 40 if (strcmp(ar.namewhat, "method") == 0) {
41 narg--; /* do not count `self' */ 41 narg--; /* do not count `self' */
42 if (narg == 0) /* error is in the self argument itself? */ 42 if (narg == 0) /* error is in the self argument itself? */
43 return luaL_verror(L, 43 return luaL_error(L,
44 "calling %s on bad self (perhaps using `:' instead of `.')", 44 "calling %s on bad self (perhaps using `:' instead of `.')",
45 ar.name); 45 ar.name);
46 } 46 }
47 if (ar.name == NULL) 47 if (ar.name == NULL)
48 ar.name = "?"; 48 ar.name = "?";
49 return luaL_verror(L, "bad argument #%d to `%s' (%s)", 49 return luaL_error(L, "bad argument #%d to `%s' (%s)",
50 narg, ar.name, extramsg); 50 narg, ar.name, extramsg);
51} 51}
52 52
@@ -63,19 +63,12 @@ static void tag_error (lua_State *L, int narg, int tag) {
63} 63}
64 64
65 65
66LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...) { 66LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
67 lua_Debug ar;
68 const char *msg;
69 va_list argp; 67 va_list argp;
70 va_start(argp, fmt); 68 va_start(argp, fmt);
71 msg = lua_pushvfstring(L, fmt, argp); 69 lua_pushvfstring(L, fmt, argp);
72 va_end(argp); 70 va_end(argp);
73 if (lua_getstack(L, 1, &ar)) { /* check calling function */ 71 return lua_error(L);
74 lua_getinfo(L, "Snl", &ar);
75 if (ar.currentline > 0)
76 lua_pushfstring(L, "%s:%d: %s", ar.short_src, ar.currentline, msg);
77 }
78 return lua_errorobj(L);
79} 72}
80 73
81/* }====================================================== */ 74/* }====================================================== */
@@ -92,7 +85,7 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
92 85
93LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) { 86LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) {
94 if (!lua_checkstack(L, space)) 87 if (!lua_checkstack(L, space))
95 luaL_verror(L, "stack overflow (%s)", mes); 88 luaL_error(L, "stack overflow (%s)", mes);
96} 89}
97 90
98 91
@@ -397,35 +390,21 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
397 390
398static void callalert (lua_State *L, int status) { 391static void callalert (lua_State *L, int status) {
399 if (status != 0) { 392 if (status != 0) {
400 int top = lua_gettop(L); 393 int top;
394 if (status == LUA_ERRRUN)
395 lua_concat(L, 2); /* concat error message and traceback */
396 top = lua_gettop(L);
401 lua_getglobal(L, "_ALERT"); 397 lua_getglobal(L, "_ALERT");
402 lua_insert(L, -2); 398 lua_insert(L, -2);
403 lua_pcall(L, 1, 0, 0); 399 lua_pcall(L, 1, 0);
404 lua_settop(L, top-1); 400 lua_settop(L, top-1);
405 } 401 }
406} 402}
407 403
408 404
409LUALIB_API int lua_call (lua_State *L, int nargs, int nresults) {
410 int status;
411 int errpos = lua_gettop(L) - nargs;
412 lua_getglobal(L, "_ERRORMESSAGE");
413 lua_insert(L, errpos); /* put below function and args */
414 status = lua_pcall(L, nargs, nresults, errpos);
415 lua_remove(L, errpos);
416 callalert(L, status);
417 return status;
418}
419
420
421static int aux_do (lua_State *L, int status) { 405static int aux_do (lua_State *L, int status) {
422 if (status == 0) { /* parse OK? */ 406 if (status == 0) /* parse OK? */
423 int err = lua_gettop(L); 407 status = lua_pcall(L, 0, LUA_MULTRET); /* call main */
424 lua_getglobal(L, "_ERRORMESSAGE");
425 lua_insert(L, err);
426 status = lua_pcall(L, 0, LUA_MULTRET, err); /* call main */
427 lua_remove(L, err); /* remove error function */
428 }
429 callalert(L, status); 408 callalert(L, status);
430 return status; 409 return status;
431} 410}
diff --git a/lauxlib.h b/lauxlib.h
index 227e77a6..63db2f94 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.47 2002/05/16 18:39:46 roberto Exp roberto $ 2** $Id: lauxlib.h,v 1.48 2002/06/03 20:11:41 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*/
@@ -44,7 +44,8 @@ LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *msg);
44LUALIB_API void luaL_check_type (lua_State *L, int narg, int t); 44LUALIB_API void luaL_check_type (lua_State *L, int narg, int t);
45LUALIB_API void luaL_check_any (lua_State *L, int narg); 45LUALIB_API void luaL_check_any (lua_State *L, int narg);
46 46
47LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...); 47LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
48
48LUALIB_API int luaL_findstring (const char *name, 49LUALIB_API int luaL_findstring (const char *name,
49 const char *const list[]); 50 const char *const list[]);
50 51
@@ -117,7 +118,6 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B);
117#define luaL_checktype luaL_check_type 118#define luaL_checktype luaL_check_type
118#define luaL_checkany luaL_check_any 119#define luaL_checkany luaL_check_any
119 120
120LUALIB_API int lua_call (lua_State *L, int nargs, int nresults);
121LUALIB_API int lua_dofile (lua_State *L, const char *filename); 121LUALIB_API int lua_dofile (lua_State *L, const char *filename);
122LUALIB_API int lua_dostring (lua_State *L, const char *str); 122LUALIB_API int lua_dostring (lua_State *L, const char *str);
123LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, 123LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
diff --git a/lbaselib.c b/lbaselib.c
index 13739a92..14843ace 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.80 2002/06/13 13:39:55 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.81 2002/06/13 13:44:50 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*/
@@ -37,7 +37,7 @@ static int luaB_print (lua_State *L) {
37 lua_upcall(L, 1, 1); 37 lua_upcall(L, 1, 1);
38 s = lua_tostring(L, -1); /* get result */ 38 s = lua_tostring(L, -1); /* get result */
39 if (s == NULL) 39 if (s == NULL)
40 return luaL_verror(L, "`tostring' must return a string to `print'"); 40 return luaL_error(L, "`tostring' must return a string to `print'");
41 if (i>1) fputs("\t", stdout); 41 if (i>1) fputs("\t", stdout);
42 fputs(s, stdout); 42 fputs(s, stdout);
43 lua_pop(L, 1); /* pop result */ 43 lua_pop(L, 1); /* pop result */
@@ -76,8 +76,8 @@ static int luaB_tonumber (lua_State *L) {
76 76
77 77
78static int luaB_error (lua_State *L) { 78static int luaB_error (lua_State *L) {
79 lua_settop(L, 1); 79 luaL_check_any(L, 1);
80 return lua_errorobj(L); 80 return lua_error(L);
81} 81}
82 82
83 83
@@ -193,9 +193,10 @@ static int luaB_nexti (lua_State *L) {
193static int passresults (lua_State *L, int status) { 193static int passresults (lua_State *L, int status) {
194 if (status == 0) return 1; 194 if (status == 0) return 1;
195 else { 195 else {
196 int numres = (status == LUA_ERRRUN) ? 3 : 2;
196 lua_pushnil(L); 197 lua_pushnil(L);
197 lua_insert(L, -2); 198 lua_insert(L, -numres);
198 return 2; 199 return numres;
199 } 200 }
200} 201}
201 202
@@ -217,7 +218,7 @@ static int luaB_loadfile (lua_State *L) {
217static int luaB_assert (lua_State *L) { 218static int luaB_assert (lua_State *L) {
218 luaL_check_any(L, 1); 219 luaL_check_any(L, 1);
219 if (!lua_toboolean(L, 1)) 220 if (!lua_toboolean(L, 1))
220 return luaL_verror(L, "%s", luaL_opt_string(L, 2, "assertion failed!")); 221 return luaL_error(L, "%s", luaL_opt_string(L, 2, "assertion failed!"));
221 lua_settop(L, 1); 222 lua_settop(L, 1);
222 return 1; 223 return 1;
223} 224}
@@ -234,25 +235,10 @@ static int luaB_unpack (lua_State *L) {
234} 235}
235 236
236 237
237static int luaB_xpcall (lua_State *L) {
238 int status;
239 luaL_check_any(L, 1);
240 luaL_check_any(L, 2);
241 status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET, 1);
242 if (status != 0)
243 return passresults(L, status);
244 else {
245 lua_pushboolean(L, 1);
246 lua_replace(L, 1);
247 return lua_gettop(L); /* return `true' + all results */
248 }
249}
250
251
252static int luaB_pcall (lua_State *L) { 238static int luaB_pcall (lua_State *L) {
253 int status; 239 int status;
254 luaL_check_any(L, 1); 240 luaL_check_any(L, 1);
255 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); 241 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET);
256 if (status != 0) 242 if (status != 0)
257 return passresults(L, status); 243 return passresults(L, status);
258 else { 244 else {
@@ -362,7 +348,7 @@ static int luaB_require (lua_State *L) {
362 lua_pushvalue(L, 1); 348 lua_pushvalue(L, 1);
363 lua_setglobal(L, "_REQUIREDNAME"); 349 lua_setglobal(L, "_REQUIREDNAME");
364 lua_getglobal(L, REQTAB); 350 lua_getglobal(L, REQTAB);
365 if (!lua_istable(L, 2)) return luaL_verror(L, REQTAB " is not a table"); 351 if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table");
366 path = getpath(L); 352 path = getpath(L);
367 lua_pushvalue(L, 1); /* check package's name in book-keeping table */ 353 lua_pushvalue(L, 1); /* check package's name in book-keeping table */
368 lua_gettable(L, 2); 354 lua_gettable(L, 2);
@@ -385,11 +371,11 @@ static int luaB_require (lua_State *L) {
385 return 0; 371 return 0;
386 } 372 }
387 case LUA_ERRFILE: { /* file not found */ 373 case LUA_ERRFILE: { /* file not found */
388 return luaL_verror(L, "could not load package `%s' from path `%s'", 374 return luaL_error(L, "could not load package `%s' from path `%s'",
389 lua_tostring(L, 1), getpath(L)); 375 lua_tostring(L, 1), getpath(L));
390 } 376 }
391 default: { 377 default: {
392 return luaL_verror(L, "error loading package\n%s", lua_tostring(L, -1)); 378 return luaL_error(L, "error loading package\n%s", lua_tostring(L, -1));
393 } 379 }
394 } 380 }
395} 381}
@@ -413,7 +399,6 @@ static const luaL_reg base_funcs[] = {
413 {"rawget", luaB_rawget}, 399 {"rawget", luaB_rawget},
414 {"rawset", luaB_rawset}, 400 {"rawset", luaB_rawset},
415 {"pcall", luaB_pcall}, 401 {"pcall", luaB_pcall},
416 {"xpcall", luaB_xpcall},
417 {"collectgarbage", luaB_collectgarbage}, 402 {"collectgarbage", luaB_collectgarbage},
418 {"gcinfo", luaB_gcinfo}, 403 {"gcinfo", luaB_gcinfo},
419 {"loadfile", luaB_loadfile}, 404 {"loadfile", luaB_loadfile},
@@ -432,9 +417,18 @@ static const luaL_reg base_funcs[] = {
432 417
433static int luaB_resume (lua_State *L) { 418static int luaB_resume (lua_State *L) {
434 lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1)); 419 lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1));
420 int status;
435 lua_settop(L, 0); 421 lua_settop(L, 0);
436 if (lua_resume(L, co) != 0) 422 status = lua_resume(L, co);
437 return lua_errorobj(L); 423 if (status != 0) {
424 if (status == LUA_ERRRUN) {
425 if (lua_isstring(L, -1) && lua_isstring(L, -2))
426 lua_concat(L, 2);
427 else
428 lua_pop(L, 1);
429 }
430 return lua_error(L);
431 }
438 return lua_gettop(L); 432 return lua_gettop(L);
439} 433}
440 434
@@ -455,7 +449,7 @@ static int luaB_coroutine (lua_State *L) {
455 luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, 449 luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
456 "Lua function expected"); 450 "Lua function expected");
457 NL = lua_newthread(L); 451 NL = lua_newthread(L);
458 if (NL == NULL) return luaL_verror(L, "unable to create new thread"); 452 if (NL == NULL) return luaL_error(L, "unable to create new thread");
459 /* move function and arguments from L to NL */ 453 /* move function and arguments from L to NL */
460 for (i=0; i<n; i++) { 454 for (i=0; i<n; i++) {
461 ref = lua_ref(L, 1); 455 ref = lua_ref(L, 1);
diff --git a/ldebug.c b/ldebug.c
index f2de75a1..cd8d481d 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,11 +1,12 @@
1/* 1/*
2** $Id: ldebug.c,v 1.118 2002/06/06 18:17:33 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.119 2002/06/13 13:39:55 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*/
6 6
7 7
8#include <stdlib.h> 8#include <stdlib.h>
9#include <string.h>
9 10
10#include "lua.h" 11#include "lua.h"
11 12
@@ -510,18 +511,42 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
510} 511}
511 512
512 513
514static void addinfo (lua_State *L, int internal) {
515 CallInfo *ci = (internal) ? L->ci : L->ci - 1;
516 const char *msg = svalue(L->top - 1);
517 if (strchr(msg, '\n')) return; /* message already `formatted' */
518 if (!isLmark(ci)) { /* no Lua code? */
519 luaO_pushfstring(L, "%s\n", msg); /* no extra info */
520 }
521 else { /* add file:line information */
522 char buff[LUA_IDSIZE];
523 int line = currentline(L, ci);
524 luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
525 luaO_pushfstring(L, "%s:%d: %s\n", buff, line, msg);
526 }
527}
528
529
530void luaG_errormsg (lua_State *L, int internal) {
531 const TObject *errfunc;
532 if (ttype(L->top - 1) == LUA_TSTRING)
533 addinfo(L, internal);
534 errfunc = luaH_getstr(hvalue(registry(L)), luaS_new(L, LUA_TRACEBACK));
535 if (ttype(errfunc) != LUA_TNIL) { /* is there an error function? */
536 setobj(L->top, errfunc); /* push function */
537 setobj(L->top + 1, L->top - 1); /* push error message */
538 L->top += 2;
539 luaD_call(L, L->top - 2, 1); /* call error function? */
540 }
541 luaD_throw(L, LUA_ERRRUN);
542}
543
544
513void luaG_runerror (lua_State *L, const char *fmt, ...) { 545void luaG_runerror (lua_State *L, const char *fmt, ...) {
514 const char *msg;
515 va_list argp; 546 va_list argp;
516 va_start(argp, fmt); 547 va_start(argp, fmt);
517 msg = luaO_pushvfstring(L, fmt, argp); 548 luaO_pushvfstring(L, fmt, argp);
518 va_end(argp); 549 va_end(argp);
519 if (isLmark(L->ci)) { 550 luaG_errormsg(L, 1);
520 char buff[LUA_IDSIZE];
521 int line = currentline(L, L->ci);
522 luaO_chunkid(buff, getstr(getluaproto(L->ci)->source), LUA_IDSIZE);
523 msg = luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
524 }
525 luaD_error(L, msg, LUA_ERRRUN);
526} 551}
527 552
diff --git a/ldebug.h b/ldebug.h
index ef0a046f..cb168743 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.h,v 1.20 2002/05/02 13:06:20 roberto Exp roberto $ 2** $Id: ldebug.h,v 1.21 2002/05/15 18:57:44 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*/
@@ -21,6 +21,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
21void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); 21void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
22void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); 22void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
23void luaG_runerror (lua_State *L, const char *fmt, ...); 23void luaG_runerror (lua_State *L, const char *fmt, ...);
24void luaG_errormsg (lua_State *L, int internal);
24int luaG_checkcode (const Proto *pt); 25int luaG_checkcode (const Proto *pt);
25 26
26 27
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;
diff --git a/ldo.h b/ldo.h
index 914eddaa..4ff39092 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.44 2002/05/01 20:40:42 roberto Exp roberto $ 2** $Id: ldo.h,v 1.45 2002/05/15 18:57:44 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*/
@@ -35,14 +35,13 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
35void luaD_lineHook (lua_State *L, int line); 35void luaD_lineHook (lua_State *L, int line);
36StkId luaD_precall (lua_State *L, StkId func); 36StkId luaD_precall (lua_State *L, StkId func);
37void luaD_call (lua_State *L, StkId func, int nResults); 37void luaD_call (lua_State *L, StkId func, int nResults);
38int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err); 38int luaD_pcall (lua_State *L, int nargs, int nresults);
39void luaD_poscall (lua_State *L, int wanted, StkId firstResult); 39void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
40void luaD_reallocCI (lua_State *L, int newsize); 40void luaD_reallocCI (lua_State *L, int newsize);
41void luaD_reallocstack (lua_State *L, int newsize); 41void luaD_reallocstack (lua_State *L, int newsize);
42void luaD_growstack (lua_State *L, int n); 42void luaD_growstack (lua_State *L, int n);
43 43
44void luaD_error (lua_State *L, const char *s, int errcode); 44void luaD_throw (lua_State *L, int errcode);
45void luaD_errorobj (lua_State *L, const TObject *s, int errcode);
46int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud); 45int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud);
47 46
48 47
diff --git a/llex.c b/llex.c
index 14dc2902..7f634757 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.103 2002/06/03 14:09:57 roberto Exp roberto $ 2** $Id: llex.c,v 1.104 2002/06/03 20:12:21 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -61,7 +61,7 @@ static void luaX_error (LexState *ls, const char *s, const char *token) {
61 char buff[MAXSRC]; 61 char buff[MAXSRC];
62 luaO_chunkid(buff, getstr(ls->source), MAXSRC); 62 luaO_chunkid(buff, getstr(ls->source), MAXSRC);
63 luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, ls->linenumber, s, token); 63 luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, ls->linenumber, s, token);
64 luaD_errorobj(L, L->top - 1, LUA_ERRSYNTAX); 64 luaD_throw(L, LUA_ERRSYNTAX);
65} 65}
66 66
67 67
diff --git a/lmem.c b/lmem.c
index 00c7253b..369b1812 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.55 2002/05/15 18:57:44 roberto Exp roberto $ 2** $Id: lmem.c,v 1.56 2002/06/11 16:23:47 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -66,7 +66,7 @@ void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
66 block = l_realloc(block, oldsize, size); 66 block = l_realloc(block, oldsize, size);
67 if (block == NULL) { 67 if (block == NULL) {
68 if (L) 68 if (L)
69 luaD_error(L, MEMERRMSG, LUA_ERRMEM); 69 luaD_throw(L, LUA_ERRMEM);
70 else return NULL; /* error before creating state! */ 70 else return NULL; /* error before creating state! */
71 } 71 }
72 } 72 }
diff --git a/lstate.c b/lstate.c
index 45f534ca..2d4bc94c 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.95 2002/06/03 14:09:57 roberto Exp roberto $ 2** $Id: lstate.c,v 1.96 2002/06/06 18:17:33 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*/
@@ -7,6 +7,7 @@
7 7
8#include "lua.h" 8#include "lua.h"
9 9
10#include "ldebug.h"
10#include "ldo.h" 11#include "ldo.h"
11#include "lfunc.h" 12#include "lfunc.h"
12#include "lgc.h" 13#include "lgc.h"
@@ -122,14 +123,13 @@ LUA_API lua_State *lua_newthread (lua_State *OL) {
122 123
123LUA_API lua_State *lua_open (void) { 124LUA_API lua_State *lua_open (void) {
124 lua_State *L; 125 lua_State *L;
125 TObject dummy; 126 TObject dummy[2];
126 setnilvalue(&dummy);
127 L = luaM_new(NULL, lua_State); 127 L = luaM_new(NULL, lua_State);
128 if (L) { /* allocation OK? */ 128 if (L) { /* allocation OK? */
129 preinit_state(L); 129 preinit_state(L);
130 L->l_G = NULL; 130 L->l_G = NULL;
131 L->next = L->previous = L; 131 L->next = L->previous = L;
132 if (luaD_runprotected(L, f_luaopen, &dummy) != 0) { 132 if (luaD_runprotected(L, f_luaopen, dummy) != 0) {
133 /* memory allocation error: free partial state */ 133 /* memory allocation error: free partial state */
134 close_state(L); 134 close_state(L);
135 L = NULL; 135 L = NULL;
@@ -169,8 +169,8 @@ static void close_state (lua_State *L) {
169 169
170 170
171LUA_API void lua_closethread (lua_State *L, lua_State *thread) { 171LUA_API void lua_closethread (lua_State *L, lua_State *thread) {
172 if (L == thread) lua_error(L, "cannot close only thread of a state");
173 lua_lock(L); 172 lua_lock(L);
173 if (L == thread) luaG_runerror(L, "cannot close only thread of a state");
174 luaE_closethread(L, thread); 174 luaE_closethread(L, thread);
175 lua_unlock(L); 175 lua_unlock(L);
176} 176}
diff --git a/ltests.c b/ltests.c
index 2cc66bca..3496a2b1 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.124 2002/06/11 16:23:47 roberto Exp roberto $ 2** $Id: ltests.c,v 1.125 2002/06/13 13:44:50 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*/
@@ -338,6 +338,34 @@ static int string_query (lua_State *L) {
338} 338}
339 339
340 340
341static int xpcall (lua_State *L) {
342 int status;
343 luaL_check_type(L, 1, LUA_TFUNCTION);
344 luaL_check_any(L, 2);
345 lua_pushliteral(L, LUA_TRACEBACK);
346 lua_gettable(L, LUA_REGISTRYINDEX);
347 lua_pushliteral(L, LUA_TRACEBACK);
348 lua_pushvalue(L, 1);
349 lua_settable(L, LUA_REGISTRYINDEX);
350 lua_replace(L, 1);
351 status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET);
352 lua_pushliteral(L, LUA_TRACEBACK);
353 lua_pushvalue(L, 1);
354 lua_settable(L, LUA_REGISTRYINDEX);
355 if (status != 0) {
356 int numres = (status == LUA_ERRRUN) ? 3 : 2;
357 lua_pushnil(L);
358 lua_insert(L, -numres);
359 return numres;
360 }
361 else {
362 lua_pushboolean(L, 1);
363 lua_insert(L, 2);
364 return lua_gettop(L) - 1; /* return `true' + all results */
365 }
366}
367
368
341static int tref (lua_State *L) { 369static int tref (lua_State *L) {
342 int level = lua_gettop(L); 370 int level = lua_gettop(L);
343 int lock = luaL_opt_int(L, 2, 1); 371 int lock = luaL_opt_int(L, 2, 1);
@@ -402,7 +430,7 @@ static int doonnewstack (lua_State *L) {
402 const char *s = luaL_check_lstr(L, 1, &l); 430 const char *s = luaL_check_lstr(L, 1, &l);
403 int status = luaL_loadbuffer(L1, s, l, s); 431 int status = luaL_loadbuffer(L1, s, l, s);
404 if (status == 0) 432 if (status == 0)
405 status = lua_pcall(L1, 0, 0, 0); 433 status = lua_pcall(L1, 0, 0);
406 lua_pushnumber(L, status); 434 lua_pushnumber(L, status);
407 lua_closethread(L, L1); 435 lua_closethread(L, L1);
408 return 1; 436 return 1;
@@ -639,7 +667,7 @@ static int testC (lua_State *L) {
639 else if EQ("call") { 667 else if EQ("call") {
640 int narg = getnum; 668 int narg = getnum;
641 int nres = getnum; 669 int nres = getnum;
642 lua_call(L, narg, nres); 670 lua_pcall(L, narg, nres);
643 } 671 }
644 else if EQ("loadstring") { 672 else if EQ("loadstring") {
645 size_t sl; 673 size_t sl;
@@ -659,7 +687,7 @@ static int testC (lua_State *L) {
659 else if EQ("type") { 687 else if EQ("type") {
660 lua_pushstring(L, lua_typename(L, lua_type(L, getnum))); 688 lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
661 } 689 }
662 else luaL_verror(L, "unknown instruction %s", buff); 690 else luaL_error(L, "unknown instruction %s", buff);
663 } 691 }
664 return 0; 692 return 0;
665} 693}
@@ -677,6 +705,7 @@ static const struct luaL_reg tests_funcs[] = {
677 {"loadlib", loadlib}, 705 {"loadlib", loadlib},
678 {"stacklevel", stacklevel}, 706 {"stacklevel", stacklevel},
679 {"querystr", string_query}, 707 {"querystr", string_query},
708 {"xpcall", xpcall},
680 {"querytab", table_query}, 709 {"querytab", table_query},
681 {"testC", testC}, 710 {"testC", testC},
682 {"ref", tref}, 711 {"ref", tref},
diff --git a/lua.h b/lua.h
index 5c1de5f6..fd2856e8 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.139 2002/06/13 13:39:55 roberto Exp roberto $ 2** $Id: lua.h,v 1.140 2002/06/13 13:44:50 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
@@ -29,6 +29,9 @@
29#define LUA_MULTRET (-1) 29#define LUA_MULTRET (-1)
30 30
31 31
32/* index for a traceback function in the registry */
33#define LUA_TRACEBACK "_TRACEBACK"
34
32/* 35/*
33** pseudo-indices 36** pseudo-indices
34*/ 37*/
@@ -43,6 +46,7 @@
43#define LUA_ERRSYNTAX 3 46#define LUA_ERRSYNTAX 3
44#define LUA_ERRMEM 4 47#define LUA_ERRMEM 4
45#define LUA_ERRERR 5 48#define LUA_ERRERR 5
49#define LUA_ERRTHROW 6
46 50
47 51
48typedef struct lua_State lua_State; 52typedef struct lua_State lua_State;
@@ -180,7 +184,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex);
180** `load' and `call' functions (load and run Lua code) 184** `load' and `call' functions (load and run Lua code)
181*/ 185*/
182LUA_API void lua_upcall (lua_State *L, int nargs, int nresults); 186LUA_API void lua_upcall (lua_State *L, int nargs, int nresults);
183LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf); 187LUA_API int lua_pcall (lua_State *L, int nargs, int nresults);
184LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, 188LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
185 const char *chunkname); 189 const char *chunkname);
186 190
@@ -203,7 +207,7 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
203** miscellaneous functions 207** miscellaneous functions
204*/ 208*/
205 209
206LUA_API int lua_errorobj (lua_State *L); 210LUA_API int lua_error (lua_State *L);
207 211
208LUA_API int lua_next (lua_State *L, int index); 212LUA_API int lua_next (lua_State *L, int index);
209LUA_API int lua_getn (lua_State *L, int index); 213LUA_API int lua_getn (lua_State *L, int index);
@@ -220,8 +224,6 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size);
220** =============================================================== 224** ===============================================================
221*/ 225*/
222 226
223#define lua_error(L,s) (lua_pushstring(L, s), lua_errorobj(L))
224
225#define lua_newpointerbox(L,u) \ 227#define lua_newpointerbox(L,u) \
226 (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) 228 (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
227 229
@@ -275,7 +277,7 @@ LUA_API int lua_pushupvalues (lua_State *L);
275#define LUA_REFNIL (-1) 277#define LUA_REFNIL (-1)
276 278
277#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 279#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
278 (lua_error(L, "unlocked references are obsolete"), 0)) 280 (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
279 281
280#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 282#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
281 283