diff options
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 42 |
1 files changed, 25 insertions, 17 deletions
| @@ -57,10 +57,18 @@ | |||
| 57 | ** ======================================================= | 57 | ** ======================================================= |
| 58 | */ | 58 | */ |
| 59 | 59 | ||
| 60 | /* chained list of long jump buffers */ | ||
| 61 | typedef 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; } | 81 | static 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 */ | ||
| 97 | struct lua_longjmp { | ||
| 98 | struct lua_longjmp *previous; | ||
| 99 | luai_jmpbuf b; | ||
| 100 | volatile TStatus status; /* error code */ | ||
| 101 | }; | ||
| 102 | |||
| 103 | |||
| 104 | void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) { | 112 | void 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 | ||
| 152 | TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | 160 | TStatus 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; |
