mirror of
https://github.com/lua/lua
synced 2024-11-25 22:29:39 +03:00
new protocol for error handling
This commit is contained in:
parent
8f080fd683
commit
1dbe708aa8
12
lapi.c
12
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.198 2002/06/13 13:39:55 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 1.199 2002/06/13 13:44:50 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -565,12 +565,10 @@ LUA_API void lua_upcall (lua_State *L, int nargs, int nresults) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf) {
|
||||
LUA_API int lua_pcall (lua_State *L, int nargs, int nresults) {
|
||||
int status;
|
||||
const TObject *err;
|
||||
lua_lock(L);
|
||||
err = (errf == 0) ? &luaO_nilobject : luaA_index(L, errf);
|
||||
status = luaD_pcall(L, nargs, nresults, err);
|
||||
status = luaD_pcall(L, nargs, nresults);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
@ -631,10 +629,10 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
|
||||
*/
|
||||
|
||||
|
||||
LUA_API int lua_errorobj (lua_State *L) {
|
||||
LUA_API int lua_error (lua_State *L) {
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
luaD_errorobj(L, L->top - 1, LUA_ERRRUN);
|
||||
luaG_errormsg(L, 0);
|
||||
lua_unlock(L);
|
||||
return 0; /* to avoid warnings */
|
||||
}
|
||||
|
49
lauxlib.c
49
lauxlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.73 2002/06/05 16:59:37 roberto Exp roberto $
|
||||
** $Id: lauxlib.c,v 1.74 2002/06/13 13:44:50 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -40,13 +40,13 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
|
||||
if (strcmp(ar.namewhat, "method") == 0) {
|
||||
narg--; /* do not count `self' */
|
||||
if (narg == 0) /* error is in the self argument itself? */
|
||||
return luaL_verror(L,
|
||||
return luaL_error(L,
|
||||
"calling %s on bad self (perhaps using `:' instead of `.')",
|
||||
ar.name);
|
||||
}
|
||||
if (ar.name == NULL)
|
||||
ar.name = "?";
|
||||
return luaL_verror(L, "bad argument #%d to `%s' (%s)",
|
||||
return luaL_error(L, "bad argument #%d to `%s' (%s)",
|
||||
narg, ar.name, extramsg);
|
||||
}
|
||||
|
||||
@ -63,19 +63,12 @@ static void tag_error (lua_State *L, int narg, int tag) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...) {
|
||||
lua_Debug ar;
|
||||
const char *msg;
|
||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
msg = lua_pushvfstring(L, fmt, argp);
|
||||
lua_pushvfstring(L, fmt, argp);
|
||||
va_end(argp);
|
||||
if (lua_getstack(L, 1, &ar)) { /* check calling function */
|
||||
lua_getinfo(L, "Snl", &ar);
|
||||
if (ar.currentline > 0)
|
||||
lua_pushfstring(L, "%s:%d: %s", ar.short_src, ar.currentline, msg);
|
||||
}
|
||||
return lua_errorobj(L);
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
@ -92,7 +85,7 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
|
||||
|
||||
LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) {
|
||||
if (!lua_checkstack(L, space))
|
||||
luaL_verror(L, "stack overflow (%s)", mes);
|
||||
luaL_error(L, "stack overflow (%s)", mes);
|
||||
}
|
||||
|
||||
|
||||
@ -397,35 +390,21 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
|
||||
|
||||
static void callalert (lua_State *L, int status) {
|
||||
if (status != 0) {
|
||||
int top = lua_gettop(L);
|
||||
int top;
|
||||
if (status == LUA_ERRRUN)
|
||||
lua_concat(L, 2); /* concat error message and traceback */
|
||||
top = lua_gettop(L);
|
||||
lua_getglobal(L, "_ALERT");
|
||||
lua_insert(L, -2);
|
||||
lua_pcall(L, 1, 0, 0);
|
||||
lua_pcall(L, 1, 0);
|
||||
lua_settop(L, top-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int lua_call (lua_State *L, int nargs, int nresults) {
|
||||
int status;
|
||||
int errpos = lua_gettop(L) - nargs;
|
||||
lua_getglobal(L, "_ERRORMESSAGE");
|
||||
lua_insert(L, errpos); /* put below function and args */
|
||||
status = lua_pcall(L, nargs, nresults, errpos);
|
||||
lua_remove(L, errpos);
|
||||
callalert(L, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int aux_do (lua_State *L, int status) {
|
||||
if (status == 0) { /* parse OK? */
|
||||
int err = lua_gettop(L);
|
||||
lua_getglobal(L, "_ERRORMESSAGE");
|
||||
lua_insert(L, err);
|
||||
status = lua_pcall(L, 0, LUA_MULTRET, err); /* call main */
|
||||
lua_remove(L, err); /* remove error function */
|
||||
}
|
||||
if (status == 0) /* parse OK? */
|
||||
status = lua_pcall(L, 0, LUA_MULTRET); /* call main */
|
||||
callalert(L, status);
|
||||
return status;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.47 2002/05/16 18:39:46 roberto Exp roberto $
|
||||
** $Id: lauxlib.h,v 1.48 2002/06/03 20:11:41 roberto Exp roberto $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -44,7 +44,8 @@ LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *msg);
|
||||
LUALIB_API void luaL_check_type (lua_State *L, int narg, int t);
|
||||
LUALIB_API void luaL_check_any (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...);
|
||||
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
|
||||
|
||||
LUALIB_API int luaL_findstring (const char *name,
|
||||
const char *const list[]);
|
||||
|
||||
@ -117,7 +118,6 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B);
|
||||
#define luaL_checktype luaL_check_type
|
||||
#define luaL_checkany luaL_check_any
|
||||
|
||||
LUALIB_API int lua_call (lua_State *L, int nargs, int nresults);
|
||||
LUALIB_API int lua_dofile (lua_State *L, const char *filename);
|
||||
LUALIB_API int lua_dostring (lua_State *L, const char *str);
|
||||
LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
|
||||
|
54
lbaselib.c
54
lbaselib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.80 2002/06/13 13:39:55 roberto Exp roberto $
|
||||
** $Id: lbaselib.c,v 1.81 2002/06/13 13:44:50 roberto Exp roberto $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -37,7 +37,7 @@ static int luaB_print (lua_State *L) {
|
||||
lua_upcall(L, 1, 1);
|
||||
s = lua_tostring(L, -1); /* get result */
|
||||
if (s == NULL)
|
||||
return luaL_verror(L, "`tostring' must return a string to `print'");
|
||||
return luaL_error(L, "`tostring' must return a string to `print'");
|
||||
if (i>1) fputs("\t", stdout);
|
||||
fputs(s, stdout);
|
||||
lua_pop(L, 1); /* pop result */
|
||||
@ -76,8 +76,8 @@ static int luaB_tonumber (lua_State *L) {
|
||||
|
||||
|
||||
static int luaB_error (lua_State *L) {
|
||||
lua_settop(L, 1);
|
||||
return lua_errorobj(L);
|
||||
luaL_check_any(L, 1);
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
|
||||
@ -193,9 +193,10 @@ static int luaB_nexti (lua_State *L) {
|
||||
static int passresults (lua_State *L, int status) {
|
||||
if (status == 0) return 1;
|
||||
else {
|
||||
int numres = (status == LUA_ERRRUN) ? 3 : 2;
|
||||
lua_pushnil(L);
|
||||
lua_insert(L, -2);
|
||||
return 2;
|
||||
lua_insert(L, -numres);
|
||||
return numres;
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +218,7 @@ static int luaB_loadfile (lua_State *L) {
|
||||
static int luaB_assert (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
if (!lua_toboolean(L, 1))
|
||||
return luaL_verror(L, "%s", luaL_opt_string(L, 2, "assertion failed!"));
|
||||
return luaL_error(L, "%s", luaL_opt_string(L, 2, "assertion failed!"));
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
@ -234,25 +235,10 @@ static int luaB_unpack (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int luaB_xpcall (lua_State *L) {
|
||||
int status;
|
||||
luaL_check_any(L, 1);
|
||||
luaL_check_any(L, 2);
|
||||
status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET, 1);
|
||||
if (status != 0)
|
||||
return passresults(L, status);
|
||||
else {
|
||||
lua_pushboolean(L, 1);
|
||||
lua_replace(L, 1);
|
||||
return lua_gettop(L); /* return `true' + all results */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int luaB_pcall (lua_State *L) {
|
||||
int status;
|
||||
luaL_check_any(L, 1);
|
||||
status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
|
||||
status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET);
|
||||
if (status != 0)
|
||||
return passresults(L, status);
|
||||
else {
|
||||
@ -362,7 +348,7 @@ static int luaB_require (lua_State *L) {
|
||||
lua_pushvalue(L, 1);
|
||||
lua_setglobal(L, "_REQUIREDNAME");
|
||||
lua_getglobal(L, REQTAB);
|
||||
if (!lua_istable(L, 2)) return luaL_verror(L, REQTAB " is not a table");
|
||||
if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table");
|
||||
path = getpath(L);
|
||||
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
|
||||
lua_gettable(L, 2);
|
||||
@ -385,11 +371,11 @@ static int luaB_require (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
case LUA_ERRFILE: { /* file not found */
|
||||
return luaL_verror(L, "could not load package `%s' from path `%s'",
|
||||
return luaL_error(L, "could not load package `%s' from path `%s'",
|
||||
lua_tostring(L, 1), getpath(L));
|
||||
}
|
||||
default: {
|
||||
return luaL_verror(L, "error loading package\n%s", lua_tostring(L, -1));
|
||||
return luaL_error(L, "error loading package\n%s", lua_tostring(L, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -413,7 +399,6 @@ static const luaL_reg base_funcs[] = {
|
||||
{"rawget", luaB_rawget},
|
||||
{"rawset", luaB_rawset},
|
||||
{"pcall", luaB_pcall},
|
||||
{"xpcall", luaB_xpcall},
|
||||
{"collectgarbage", luaB_collectgarbage},
|
||||
{"gcinfo", luaB_gcinfo},
|
||||
{"loadfile", luaB_loadfile},
|
||||
@ -432,9 +417,18 @@ static const luaL_reg base_funcs[] = {
|
||||
|
||||
static int luaB_resume (lua_State *L) {
|
||||
lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1));
|
||||
int status;
|
||||
lua_settop(L, 0);
|
||||
if (lua_resume(L, co) != 0)
|
||||
return lua_errorobj(L);
|
||||
status = lua_resume(L, co);
|
||||
if (status != 0) {
|
||||
if (status == LUA_ERRRUN) {
|
||||
if (lua_isstring(L, -1) && lua_isstring(L, -2))
|
||||
lua_concat(L, 2);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return lua_error(L);
|
||||
}
|
||||
return lua_gettop(L);
|
||||
}
|
||||
|
||||
@ -455,7 +449,7 @@ static int luaB_coroutine (lua_State *L) {
|
||||
luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
|
||||
"Lua function expected");
|
||||
NL = lua_newthread(L);
|
||||
if (NL == NULL) return luaL_verror(L, "unable to create new thread");
|
||||
if (NL == NULL) return luaL_error(L, "unable to create new thread");
|
||||
/* move function and arguments from L to NL */
|
||||
for (i=0; i<n; i++) {
|
||||
ref = lua_ref(L, 1);
|
||||
|
51
ldebug.c
51
ldebug.c
@ -1,11 +1,12 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 1.118 2002/06/06 18:17:33 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 1.119 2002/06/13 13:39:55 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
@ -510,18 +511,42 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
|
||||
}
|
||||
|
||||
|
||||
void luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
const char *msg;
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
msg = luaO_pushvfstring(L, fmt, argp);
|
||||
va_end(argp);
|
||||
if (isLmark(L->ci)) {
|
||||
char buff[LUA_IDSIZE];
|
||||
int line = currentline(L, L->ci);
|
||||
luaO_chunkid(buff, getstr(getluaproto(L->ci)->source), LUA_IDSIZE);
|
||||
msg = luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
|
||||
static void addinfo (lua_State *L, int internal) {
|
||||
CallInfo *ci = (internal) ? L->ci : L->ci - 1;
|
||||
const char *msg = svalue(L->top - 1);
|
||||
if (strchr(msg, '\n')) return; /* message already `formatted' */
|
||||
if (!isLmark(ci)) { /* no Lua code? */
|
||||
luaO_pushfstring(L, "%s\n", msg); /* no extra info */
|
||||
}
|
||||
else { /* add file:line information */
|
||||
char buff[LUA_IDSIZE];
|
||||
int line = currentline(L, ci);
|
||||
luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
|
||||
luaO_pushfstring(L, "%s:%d: %s\n", buff, line, msg);
|
||||
}
|
||||
luaD_error(L, msg, LUA_ERRRUN);
|
||||
}
|
||||
|
||||
|
||||
void luaG_errormsg (lua_State *L, int internal) {
|
||||
const TObject *errfunc;
|
||||
if (ttype(L->top - 1) == LUA_TSTRING)
|
||||
addinfo(L, internal);
|
||||
errfunc = luaH_getstr(hvalue(registry(L)), luaS_new(L, LUA_TRACEBACK));
|
||||
if (ttype(errfunc) != LUA_TNIL) { /* is there an error function? */
|
||||
setobj(L->top, errfunc); /* push function */
|
||||
setobj(L->top + 1, L->top - 1); /* push error message */
|
||||
L->top += 2;
|
||||
luaD_call(L, L->top - 2, 1); /* call error function? */
|
||||
}
|
||||
luaD_throw(L, LUA_ERRRUN);
|
||||
}
|
||||
|
||||
|
||||
void luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
luaO_pushvfstring(L, fmt, argp);
|
||||
va_end(argp);
|
||||
luaG_errormsg(L, 1);
|
||||
}
|
||||
|
||||
|
3
ldebug.h
3
ldebug.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.h,v 1.20 2002/05/02 13:06:20 roberto Exp roberto $
|
||||
** $Id: ldebug.h,v 1.21 2002/05/15 18:57:44 roberto Exp roberto $
|
||||
** Auxiliary functions from Debug Interface module
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -21,6 +21,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
|
||||
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
|
||||
void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
|
||||
void luaG_runerror (lua_State *L, const char *fmt, ...);
|
||||
void luaG_errormsg (lua_State *L, int internal);
|
||||
int luaG_checkcode (const Proto *pt);
|
||||
|
||||
|
||||
|
89
ldo.c
89
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 1.178 2002/06/03 17:46:34 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 1.179 2002/06/03 20:12:50 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -37,10 +37,16 @@ struct lua_longjmp {
|
||||
jmp_buf b;
|
||||
int allowhooks; /* `allowhook' state when protection was set */
|
||||
volatile int status; /* error code */
|
||||
TObject *err; /* error function -> message (start of `ud') */
|
||||
TObject *err; /* error messages (start of `ud') */
|
||||
};
|
||||
|
||||
|
||||
static void pusherrormsg (lua_State *L, int status, TObject *err) {
|
||||
setobj(L->top++, &err[0]);
|
||||
if (status == LUA_ERRRUN)
|
||||
setobj(L->top++, &err[1]);
|
||||
}
|
||||
|
||||
|
||||
static void correctstack (lua_State *L, TObject *oldstack) {
|
||||
struct lua_longjmp *lj;
|
||||
@ -109,7 +115,7 @@ void luaD_growstack (lua_State *L, int n) {
|
||||
static void luaD_growCI (lua_State *L) {
|
||||
L->ci--;
|
||||
if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
|
||||
luaD_error(L, "error in error handling", LUA_ERRERR);
|
||||
luaD_throw(L, LUA_ERRERR);
|
||||
else {
|
||||
luaD_reallocCI(L, 2*L->size_ci);
|
||||
if (L->size_ci > LUA_MAXCALLS)
|
||||
@ -302,7 +308,7 @@ static void move_results (lua_State *L, TObject *from, TObject *to) {
|
||||
|
||||
|
||||
struct ResS {
|
||||
TObject err;
|
||||
TObject err[2];
|
||||
int numres;
|
||||
};
|
||||
|
||||
@ -337,17 +343,11 @@ LUA_API int lua_resume (lua_State *L, lua_State *co) {
|
||||
luaG_runerror(L, "thread is dead - cannot be resumed");
|
||||
if (co->errorJmp != NULL) /* ?? */
|
||||
luaG_runerror(L, "thread is active - cannot be resumed");
|
||||
if (L->errorJmp) {
|
||||
setobj(&ud.err, L->errorJmp->err);
|
||||
}
|
||||
else
|
||||
setnilvalue(&ud.err);
|
||||
status = luaD_runprotected(co, resume, &ud.err);
|
||||
status = luaD_runprotected(co, resume, ud.err);
|
||||
if (status == 0)
|
||||
move_results(L, co->top - ud.numres, co->top);
|
||||
else {
|
||||
setobj(L->top++, &ud.err);
|
||||
}
|
||||
else
|
||||
pusherrormsg(L, status, ud.err);
|
||||
lua_unlock(L);
|
||||
return status;
|
||||
}
|
||||
@ -369,7 +369,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
|
||||
** Execute a protected call.
|
||||
*/
|
||||
struct CallS { /* data to `f_call' */
|
||||
TObject err; /* error field... */
|
||||
TObject err[2];
|
||||
StkId func;
|
||||
int nresults;
|
||||
};
|
||||
@ -381,17 +381,16 @@ static void f_call (lua_State *L, void *ud) {
|
||||
}
|
||||
|
||||
|
||||
int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
|
||||
int luaD_pcall (lua_State *L, int nargs, int nresults) {
|
||||
struct CallS c;
|
||||
int status;
|
||||
c.func = L->top - (nargs+1); /* function to be called */
|
||||
c.nresults = nresults;
|
||||
c.err = *err;
|
||||
status = luaD_runprotected(L, &f_call, &c.err);
|
||||
status = luaD_runprotected(L, &f_call, c.err);
|
||||
if (status != 0) { /* an error occurred? */
|
||||
L->top -= nargs+1; /* remove parameters and func from the stack */
|
||||
luaF_close(L, L->top); /* close eventual pending closures */
|
||||
setobj(L->top++, &c.err);
|
||||
pusherrormsg(L, status, c.err);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -401,7 +400,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err) {
|
||||
** Execute a protected parser.
|
||||
*/
|
||||
struct SParser { /* data to `f_parser' */
|
||||
TObject err; /* error field... */
|
||||
TObject err[2];
|
||||
ZIO *z;
|
||||
int bin;
|
||||
};
|
||||
@ -425,15 +424,14 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||
if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
|
||||
luaC_collectgarbage(L);
|
||||
old_blocks = G(L)->nblocks;
|
||||
setnilvalue(&p.err);
|
||||
status = luaD_runprotected(L, f_parser, &p.err);
|
||||
status = luaD_runprotected(L, f_parser, p.err);
|
||||
if (status == 0) {
|
||||
/* add new memory to threshold (as it probably will stay) */
|
||||
lua_assert(G(L)->nblocks >= old_blocks);
|
||||
G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
|
||||
}
|
||||
else
|
||||
setobj(L->top++, &p.err);
|
||||
pusherrormsg(L, status, p.err);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -445,29 +443,34 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
static void message (lua_State *L, const TObject *msg, int nofunc) {
|
||||
TObject *m = L->errorJmp->err;
|
||||
if (nofunc || ttype(m) != LUA_TFUNCTION) { /* no error function? */
|
||||
setobj(m, msg); /* keep error message */
|
||||
static void seterrorobj (lua_State *L, int errcode, TObject *m) {
|
||||
switch (errcode) {
|
||||
case LUA_ERRMEM: {
|
||||
if (G(L) != NULL && G(L)->GCthreshold > 0) /* state is OK? */
|
||||
setsvalue(&m[0], luaS_new(L, MEMERRMSG));
|
||||
break;
|
||||
}
|
||||
case LUA_ERRERR: {
|
||||
setsvalue(&m[0], luaS_new(L, "error in error handling"));
|
||||
break;
|
||||
}
|
||||
case LUA_ERRSYNTAX: { /* message is on stack top */
|
||||
setobj(&m[0], L->top - 1);
|
||||
break;
|
||||
}
|
||||
case LUA_ERRRUN: { /* traceback is on stack top */
|
||||
setobj(&m[0], L->top - 2);
|
||||
setobj(&m[1], L->top - 1);
|
||||
break;
|
||||
}
|
||||
else { /* call error function */
|
||||
setobj(L->top, m);
|
||||
setobj(L->top + 1, msg);
|
||||
L->top += 2;
|
||||
luaD_call(L, L->top - 2, 1);
|
||||
setobj(m, L->top - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Reports an error, and jumps up to the available recovery label
|
||||
*/
|
||||
void luaD_errorobj (lua_State *L, const TObject *s, int errcode) {
|
||||
void luaD_throw (lua_State *L, int errcode) {
|
||||
seterrorobj(L, errcode, L->errorJmp->err);
|
||||
if (L->errorJmp) {
|
||||
L->errorJmp->status = errcode;
|
||||
message(L, s, (errcode >= LUA_ERRMEM));
|
||||
longjmp(L->errorJmp->b, 1);
|
||||
}
|
||||
else {
|
||||
@ -477,16 +480,6 @@ void luaD_errorobj (lua_State *L, const TObject *s, int errcode) {
|
||||
}
|
||||
|
||||
|
||||
void luaD_error (lua_State *L, const char *s, int errcode) {
|
||||
TObject errobj;
|
||||
if (errcode == LUA_ERRMEM && (G(L) == NULL || G(L)->GCthreshold == 0))
|
||||
setnilvalue(&errobj); /* error bulding state */
|
||||
else
|
||||
setsvalue(&errobj, luaS_new(L, s));
|
||||
luaD_errorobj(L, &errobj, errcode);
|
||||
}
|
||||
|
||||
|
||||
int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud) {
|
||||
struct lua_longjmp lj;
|
||||
lj.ci = L->ci;
|
||||
|
7
ldo.h
7
ldo.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.h,v 1.44 2002/05/01 20:40:42 roberto Exp roberto $
|
||||
** $Id: ldo.h,v 1.45 2002/05/15 18:57:44 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -35,14 +35,13 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
|
||||
void luaD_lineHook (lua_State *L, int line);
|
||||
StkId luaD_precall (lua_State *L, StkId func);
|
||||
void luaD_call (lua_State *L, StkId func, int nResults);
|
||||
int luaD_pcall (lua_State *L, int nargs, int nresults, const TObject *err);
|
||||
int luaD_pcall (lua_State *L, int nargs, int nresults);
|
||||
void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
|
||||
void luaD_reallocCI (lua_State *L, int newsize);
|
||||
void luaD_reallocstack (lua_State *L, int newsize);
|
||||
void luaD_growstack (lua_State *L, int n);
|
||||
|
||||
void luaD_error (lua_State *L, const char *s, int errcode);
|
||||
void luaD_errorobj (lua_State *L, const TObject *s, int errcode);
|
||||
void luaD_throw (lua_State *L, int errcode);
|
||||
int luaD_runprotected (lua_State *L, Pfunc f, TObject *ud);
|
||||
|
||||
|
||||
|
4
llex.c
4
llex.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: llex.c,v 1.103 2002/06/03 14:09:57 roberto Exp roberto $
|
||||
** $Id: llex.c,v 1.104 2002/06/03 20:12:21 roberto Exp roberto $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -61,7 +61,7 @@ static void luaX_error (LexState *ls, const char *s, const char *token) {
|
||||
char buff[MAXSRC];
|
||||
luaO_chunkid(buff, getstr(ls->source), MAXSRC);
|
||||
luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, ls->linenumber, s, token);
|
||||
luaD_errorobj(L, L->top - 1, LUA_ERRSYNTAX);
|
||||
luaD_throw(L, LUA_ERRSYNTAX);
|
||||
}
|
||||
|
||||
|
||||
|
4
lmem.c
4
lmem.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lmem.c,v 1.55 2002/05/15 18:57:44 roberto Exp roberto $
|
||||
** $Id: lmem.c,v 1.56 2002/06/11 16:23:47 roberto Exp roberto $
|
||||
** Interface to Memory Manager
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -66,7 +66,7 @@ void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
|
||||
block = l_realloc(block, oldsize, size);
|
||||
if (block == NULL) {
|
||||
if (L)
|
||||
luaD_error(L, MEMERRMSG, LUA_ERRMEM);
|
||||
luaD_throw(L, LUA_ERRMEM);
|
||||
else return NULL; /* error before creating state! */
|
||||
}
|
||||
}
|
||||
|
10
lstate.c
10
lstate.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 1.95 2002/06/03 14:09:57 roberto Exp roberto $
|
||||
** $Id: lstate.c,v 1.96 2002/06/06 18:17:33 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldebug.h"
|
||||
#include "ldo.h"
|
||||
#include "lfunc.h"
|
||||
#include "lgc.h"
|
||||
@ -122,14 +123,13 @@ LUA_API lua_State *lua_newthread (lua_State *OL) {
|
||||
|
||||
LUA_API lua_State *lua_open (void) {
|
||||
lua_State *L;
|
||||
TObject dummy;
|
||||
setnilvalue(&dummy);
|
||||
TObject dummy[2];
|
||||
L = luaM_new(NULL, lua_State);
|
||||
if (L) { /* allocation OK? */
|
||||
preinit_state(L);
|
||||
L->l_G = NULL;
|
||||
L->next = L->previous = L;
|
||||
if (luaD_runprotected(L, f_luaopen, &dummy) != 0) {
|
||||
if (luaD_runprotected(L, f_luaopen, dummy) != 0) {
|
||||
/* memory allocation error: free partial state */
|
||||
close_state(L);
|
||||
L = NULL;
|
||||
@ -169,8 +169,8 @@ static void close_state (lua_State *L) {
|
||||
|
||||
|
||||
LUA_API void lua_closethread (lua_State *L, lua_State *thread) {
|
||||
if (L == thread) lua_error(L, "cannot close only thread of a state");
|
||||
lua_lock(L);
|
||||
if (L == thread) luaG_runerror(L, "cannot close only thread of a state");
|
||||
luaE_closethread(L, thread);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
37
ltests.c
37
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 1.124 2002/06/11 16:23:47 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 1.125 2002/06/13 13:44:50 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -338,6 +338,34 @@ static int string_query (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static int xpcall (lua_State *L) {
|
||||
int status;
|
||||
luaL_check_type(L, 1, LUA_TFUNCTION);
|
||||
luaL_check_any(L, 2);
|
||||
lua_pushliteral(L, LUA_TRACEBACK);
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
lua_pushliteral(L, LUA_TRACEBACK);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
lua_replace(L, 1);
|
||||
status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET);
|
||||
lua_pushliteral(L, LUA_TRACEBACK);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
if (status != 0) {
|
||||
int numres = (status == LUA_ERRRUN) ? 3 : 2;
|
||||
lua_pushnil(L);
|
||||
lua_insert(L, -numres);
|
||||
return numres;
|
||||
}
|
||||
else {
|
||||
lua_pushboolean(L, 1);
|
||||
lua_insert(L, 2);
|
||||
return lua_gettop(L) - 1; /* return `true' + all results */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int tref (lua_State *L) {
|
||||
int level = lua_gettop(L);
|
||||
int lock = luaL_opt_int(L, 2, 1);
|
||||
@ -402,7 +430,7 @@ static int doonnewstack (lua_State *L) {
|
||||
const char *s = luaL_check_lstr(L, 1, &l);
|
||||
int status = luaL_loadbuffer(L1, s, l, s);
|
||||
if (status == 0)
|
||||
status = lua_pcall(L1, 0, 0, 0);
|
||||
status = lua_pcall(L1, 0, 0);
|
||||
lua_pushnumber(L, status);
|
||||
lua_closethread(L, L1);
|
||||
return 1;
|
||||
@ -639,7 +667,7 @@ static int testC (lua_State *L) {
|
||||
else if EQ("call") {
|
||||
int narg = getnum;
|
||||
int nres = getnum;
|
||||
lua_call(L, narg, nres);
|
||||
lua_pcall(L, narg, nres);
|
||||
}
|
||||
else if EQ("loadstring") {
|
||||
size_t sl;
|
||||
@ -659,7 +687,7 @@ static int testC (lua_State *L) {
|
||||
else if EQ("type") {
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
|
||||
}
|
||||
else luaL_verror(L, "unknown instruction %s", buff);
|
||||
else luaL_error(L, "unknown instruction %s", buff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -677,6 +705,7 @@ static const struct luaL_reg tests_funcs[] = {
|
||||
{"loadlib", loadlib},
|
||||
{"stacklevel", stacklevel},
|
||||
{"querystr", string_query},
|
||||
{"xpcall", xpcall},
|
||||
{"querytab", table_query},
|
||||
{"testC", testC},
|
||||
{"ref", tref},
|
||||
|
14
lua.h
14
lua.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.139 2002/06/13 13:39:55 roberto Exp roberto $
|
||||
** $Id: lua.h,v 1.140 2002/06/13 13:44:50 roberto Exp roberto $
|
||||
** Lua - An Extensible Extension Language
|
||||
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||
** http://www.lua.org mailto:info@lua.org
|
||||
@ -29,6 +29,9 @@
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
|
||||
/* index for a traceback function in the registry */
|
||||
#define LUA_TRACEBACK "_TRACEBACK"
|
||||
|
||||
/*
|
||||
** pseudo-indices
|
||||
*/
|
||||
@ -43,6 +46,7 @@
|
||||
#define LUA_ERRSYNTAX 3
|
||||
#define LUA_ERRMEM 4
|
||||
#define LUA_ERRERR 5
|
||||
#define LUA_ERRTHROW 6
|
||||
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
@ -180,7 +184,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex);
|
||||
** `load' and `call' functions (load and run Lua code)
|
||||
*/
|
||||
LUA_API void lua_upcall (lua_State *L, int nargs, int nresults);
|
||||
LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errf);
|
||||
LUA_API int lua_pcall (lua_State *L, int nargs, int nresults);
|
||||
LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
|
||||
const char *chunkname);
|
||||
|
||||
@ -203,7 +207,7 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
LUA_API int lua_errorobj (lua_State *L);
|
||||
LUA_API int lua_error (lua_State *L);
|
||||
|
||||
LUA_API int lua_next (lua_State *L, int index);
|
||||
LUA_API int lua_getn (lua_State *L, int index);
|
||||
@ -220,8 +224,6 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size);
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define lua_error(L,s) (lua_pushstring(L, s), lua_errorobj(L))
|
||||
|
||||
#define lua_newpointerbox(L,u) \
|
||||
(*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
|
||||
|
||||
@ -275,7 +277,7 @@ LUA_API int lua_pushupvalues (lua_State *L);
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
|
||||
(lua_error(L, "unlocked references are obsolete"), 0))
|
||||
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
|
||||
|
||||
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user