lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 10/24/07, Colin <share-lua@think42.com> wrote:
Your patch would be highly welcome, yes! I am curious how you manage "fly
through" of exceptions without some half-serious changes...

I don't have my notes with me right now, so I'm going from memory. Apologies in advance if any of this is wrong.

As of Lua 5.1, in luaconf.h, you're able to redefine the LUAI_THROW/LUAI_TRY macros that Lua uses for errors. Previously, error handling was done entirely with setjmp/longjmp, which is not ideal for C++ (longjmps ignore destructors of stack objects, causing possible memory leaks).

If compiled as C++, Lua will use throw/catch, throwing a lua_longjmp, and catching all exceptions. The lua_longjmp that is thrown isn't actually used, but the LUAI_TRY macro takes a lua_longjmp parameter that IS used. There's three problems with this approach: 1) if you haven't used lua_pcall somewhere up the stack, lua_State::errorJmp is null, and Lua will panic and exit(). 2) In a pcall, Lua treats all exceptions as internal exceptions (which behave differently from lua_error, namely in the lua_longjmp::status). 3) If Lua catches an external exception, it can't provide any information about it, since it's not aware of std::exception.

The changes I've made allow a user of the Lua API to use lua_call if they want exceptions to bubble up (including lua_exceptions with the error message stored inside) and lua_pcall if they want exceptions to be caught. The latter is necessary since pcall is the only thing Lua has for exception handling (that I know of).

All this does have the unfortunate side effect of 2 additional string copies per lua_exception thrown and subsequently caught by lua_pcall, but there isn't really a better way without rewriting large portions of the Lua API.

- James