|
@@ -57,10 +57,18 @@
|
|
** =======================================================
|
|
** =======================================================
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+/* chained list of long jump buffers */
|
|
|
|
+typedef struct lua_longjmp {
|
|
|
|
+ struct lua_longjmp *previous;
|
|
|
|
+ jmp_buf b;
|
|
|
|
+ volatile TStatus status; /* error code */
|
|
|
|
+} lua_longjmp;
|
|
|
|
+
|
|
|
|
+
|
|
/*
|
|
/*
|
|
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
|
|
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
|
|
** default, Lua handles errors with exceptions when compiling as
|
|
** default, Lua handles errors with exceptions when compiling as
|
|
-** C++ code, with _longjmp/_setjmp when asked to use them, and with
|
|
|
|
|
|
+** C++ code, with _longjmp/_setjmp when available (POSIX), and with
|
|
** longjmp/setjmp otherwise.
|
|
** longjmp/setjmp otherwise.
|
|
*/
|
|
*/
|
|
#if !defined(LUAI_THROW) /* { */
|
|
#if !defined(LUAI_THROW) /* { */
|
|
@@ -69,38 +77,38 @@
|
|
|
|
|
|
/* C++ exceptions */
|
|
/* C++ exceptions */
|
|
#define LUAI_THROW(L,c) throw(c)
|
|
#define LUAI_THROW(L,c) throw(c)
|
|
-#define LUAI_TRY(L,c,f,ud) \
|
|
|
|
- try { (f)(L, ud); } catch(...) { if ((c)->status == 0) (c)->status = -1; }
|
|
|
|
-#define luai_jmpbuf int /* dummy field */
|
|
|
|
|
|
+
|
|
|
|
+static void LUAI_TRY (lua_State *L, lua_longjmp *c, Pfunc f, void *ud) {
|
|
|
|
+ try {
|
|
|
|
+ f(L, ud); /* call function protected */
|
|
|
|
+ }
|
|
|
|
+ catch (lua_longjmp *c1) { /* Lua error */
|
|
|
|
+ if (c1 != c) /* not the correct level? */
|
|
|
|
+ throw; /* rethrow to upper level */
|
|
|
|
+ }
|
|
|
|
+ catch (...) { /* non-Lua exception */
|
|
|
|
+ c->status = -1; /* create some error code */
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
#elif defined(LUA_USE_POSIX) /* }{ */
|
|
#elif defined(LUA_USE_POSIX) /* }{ */
|
|
|
|
|
|
-/* in POSIX, try _longjmp/_setjmp (more efficient) */
|
|
|
|
|
|
+/* in POSIX, use _longjmp/_setjmp (more efficient) */
|
|
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
|
|
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
|
|
#define LUAI_TRY(L,c,f,ud) if (_setjmp((c)->b) == 0) ((f)(L, ud))
|
|
#define LUAI_TRY(L,c,f,ud) if (_setjmp((c)->b) == 0) ((f)(L, ud))
|
|
-#define luai_jmpbuf jmp_buf
|
|
|
|
|
|
|
|
#else /* }{ */
|
|
#else /* }{ */
|
|
|
|
|
|
/* ISO C handling with long jumps */
|
|
/* ISO C handling with long jumps */
|
|
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
|
|
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
|
|
#define LUAI_TRY(L,c,f,ud) if (setjmp((c)->b) == 0) ((f)(L, ud))
|
|
#define LUAI_TRY(L,c,f,ud) if (setjmp((c)->b) == 0) ((f)(L, ud))
|
|
-#define luai_jmpbuf jmp_buf
|
|
|
|
|
|
|
|
#endif /* } */
|
|
#endif /* } */
|
|
|
|
|
|
#endif /* } */
|
|
#endif /* } */
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
-/* chain list of long jump buffers */
|
|
|
|
-struct lua_longjmp {
|
|
|
|
- struct lua_longjmp *previous;
|
|
|
|
- luai_jmpbuf b;
|
|
|
|
- volatile TStatus status; /* error code */
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-
|
|
|
|
void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
|
|
void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
|
|
if (errcode == LUA_ERRMEM) { /* memory error? */
|
|
if (errcode == LUA_ERRMEM) { /* memory error? */
|
|
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
|
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
|
@@ -151,7 +159,7 @@ l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode) {
|
|
|
|
|
|
TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
|
TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
|
l_uint32 oldnCcalls = L->nCcalls;
|
|
l_uint32 oldnCcalls = L->nCcalls;
|
|
- struct lua_longjmp lj;
|
|
|
|
|
|
+ lua_longjmp lj;
|
|
lj.status = LUA_OK;
|
|
lj.status = LUA_OK;
|
|
lj.previous = L->errorJmp; /* chain new error handler */
|
|
lj.previous = L->errorJmp; /* chain new error handler */
|
|
L->errorJmp = &lj;
|
|
L->errorJmp = &lj;
|