aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/ldo.c b/ldo.c
index dff9488e..44937068 100644
--- a/ldo.c
+++ b/ldo.c
@@ -57,10 +57,18 @@
57** ======================================================= 57** =======================================================
58*/ 58*/
59 59
60/* chained list of long jump buffers */
61typedef struct lua_longjmp {
62 struct lua_longjmp *previous;
63 jmp_buf b;
64 volatile TStatus status; /* error code */
65} lua_longjmp;
66
67
60/* 68/*
61** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By 69** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
62** default, Lua handles errors with exceptions when compiling as 70** default, Lua handles errors with exceptions when compiling as
63** C++ code, with _longjmp/_setjmp when asked to use them, and with 71** C++ code, with _longjmp/_setjmp when available (POSIX), and with
64** longjmp/setjmp otherwise. 72** longjmp/setjmp otherwise.
65*/ 73*/
66#if !defined(LUAI_THROW) /* { */ 74#if !defined(LUAI_THROW) /* { */
@@ -69,38 +77,38 @@
69 77
70/* C++ exceptions */ 78/* C++ exceptions */
71#define LUAI_THROW(L,c) throw(c) 79#define LUAI_THROW(L,c) throw(c)
72#define LUAI_TRY(L,c,f,ud) \ 80
73 try { (f)(L, ud); } catch(...) { if ((c)->status == 0) (c)->status = -1; } 81static void LUAI_TRY (lua_State *L, lua_longjmp *c, Pfunc f, void *ud) {
74#define luai_jmpbuf int /* dummy field */ 82 try {
83 f(L, ud); /* call function protected */
84 }
85 catch (lua_longjmp *c1) { /* Lua error */
86 if (c1 != c) /* not the correct level? */
87 throw; /* rethrow to upper level */
88 }
89 catch (...) { /* non-Lua exception */
90 c->status = -1; /* create some error code */
91 }
92}
93
75 94
76#elif defined(LUA_USE_POSIX) /* }{ */ 95#elif defined(LUA_USE_POSIX) /* }{ */
77 96
78/* in POSIX, try _longjmp/_setjmp (more efficient) */ 97/* in POSIX, use _longjmp/_setjmp (more efficient) */
79#define LUAI_THROW(L,c) _longjmp((c)->b, 1) 98#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
80#define LUAI_TRY(L,c,f,ud) if (_setjmp((c)->b) == 0) ((f)(L, ud)) 99#define LUAI_TRY(L,c,f,ud) if (_setjmp((c)->b) == 0) ((f)(L, ud))
81#define luai_jmpbuf jmp_buf
82 100
83#else /* }{ */ 101#else /* }{ */
84 102
85/* ISO C handling with long jumps */ 103/* ISO C handling with long jumps */
86#define LUAI_THROW(L,c) longjmp((c)->b, 1) 104#define LUAI_THROW(L,c) longjmp((c)->b, 1)
87#define LUAI_TRY(L,c,f,ud) if (setjmp((c)->b) == 0) ((f)(L, ud)) 105#define LUAI_TRY(L,c,f,ud) if (setjmp((c)->b) == 0) ((f)(L, ud))
88#define luai_jmpbuf jmp_buf
89 106
90#endif /* } */ 107#endif /* } */
91 108
92#endif /* } */ 109#endif /* } */
93 110
94 111
95
96/* chain list of long jump buffers */
97struct lua_longjmp {
98 struct lua_longjmp *previous;
99 luai_jmpbuf b;
100 volatile TStatus status; /* error code */
101};
102
103
104void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) { 112void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
105 if (errcode == LUA_ERRMEM) { /* memory error? */ 113 if (errcode == LUA_ERRMEM) { /* memory error? */
106 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ 114 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
@@ -151,7 +159,7 @@ l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode) {
151 159
152TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 160TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
153 l_uint32 oldnCcalls = L->nCcalls; 161 l_uint32 oldnCcalls = L->nCcalls;
154 struct lua_longjmp lj; 162 lua_longjmp lj;
155 lj.status = LUA_OK; 163 lj.status = LUA_OK;
156 lj.previous = L->errorJmp; /* chain new error handler */ 164 lj.previous = L->errorJmp; /* chain new error handler */
157 L->errorJmp = &lj; 165 L->errorJmp = &lj;