lua-users home
lua-l archive

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


On Mon, Mar 30, 2020 at 6:10 PM Jonathan Goble <jcgoble3@gmail.com> wrote:

> is there a way to "catch" a longjmp, perform operations (like calling destructors), and "re-throw"?

The answer would be platform-specific and possibly arcane in some cases, pretty much like the answer to the question whether using C++ exceptions would propagate through C-mode code. If that is within the scope of your project, this could be interesting per se.

But if your code is to be as portable as possible, you should assume that long jumps cannot be mixed with stack-allocated objects with destructors. If you want to have such objects in your C++ code callable from Lua, you will have to use local scopes to segregate them from code that might raise Lua errors, and within those scopes, only use the Lua API that is documented not to raise errors. Most of lua_pushX() functions are error-free, with the notable exception of strings and closures. So you can convert most of your objects into "simple" Lua values easily, but to convert them intro Lua strings or Lua functions, you would need some trickery. Here is a helper function to push a string that does not raise Lua errors (externally):

bool safe_pushstring(lua_State* L, char const* str)
{
    auto push = [](auto L)
    {
        auto ptr = lua_touserdata(L, 1);
        if (ptr)
        {
            auto str = *reinterpret_cast<char**>(ptr);
            lua_pushstring(L, str);
            return 1;
        }

        return 0; // or raise an error
    };

    // these never raise Lua errors
    lua_pushcfunction(L, push);
    lua_pushlightuserdata(L, &str);
    auto ret = lua_pcall(L, 1, 1, 0);
    return ret == 0;
}

Cheers,
V.