aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-09-05 15:29:15 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-09-05 15:29:15 -0300
commitffbcadfb4197213d55222bca3ecc52606cd980f4 (patch)
treebc80bb66945033f0b2eb88981ef977d809893d52 /ldo.c
parent0b73ed8f083c99b5ff88e0822532db7ad8785881 (diff)
downloadlua-ffbcadfb4197213d55222bca3ecc52606cd980f4.tar.gz
lua-ffbcadfb4197213d55222bca3ecc52606cd980f4.tar.bz2
lua-ffbcadfb4197213d55222bca3ecc52606cd980f4.zip
In C++, 'throw' must go to the correct handler.
In C, we may have several "setjmp" nested, and the "longjmp" will go to the one given by the corresponding "jmp_buf". In C++, a "throw" will always go to the inner "catch". So, the "catch" must check whether it is the recipient of the "throw" and, if not, rethrow the exception to the outer level.
Diffstat (limited to 'ldo.c')
-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;