From 14c3273ed8f66fd62976c945770cbfd2c3e1cb82 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 19 May 2011 14:58:31 +0200 Subject: Remove the possibility to transport exceptions through lua code It's impossible to do this without C++0x features (we need std::exception_ptr). --- src/FbTk/Luamm.cc | 61 ++++++++----------------------------------------------- src/FbTk/Luamm.hh | 2 +- 2 files changed, 9 insertions(+), 54 deletions(-) diff --git a/src/FbTk/Luamm.cc b/src/FbTk/Luamm.cc index ff3669f..3de86db 100644 --- a/src/FbTk/Luamm.cc +++ b/src/FbTk/Luamm.cc @@ -27,27 +27,11 @@ namespace lua { namespace { // keys for storing values in lua registry - const char cpp_exception_metatable[] = "lua::cpp_exception_metatable"; const char cpp_function_metatable [] = "lua::cpp_function_metatable"; const char lua_exception_namespace[] = "lua::lua_exception_namespace"; const char this_cpp_object [] = "lua::this_cpp_object"; - // converts C++ exceptions to strings, so lua can do something with them - int exception_to_string(lua_State *l) - { - std::exception_ptr *ptr = static_cast(lua_touserdata(l, -1)); - assert(ptr); - try { - std::rethrow_exception(*ptr); - } - catch(std::exception &e) { - lua_pushstring(l, e.what()); - } - catch(...) { - lua_pushstring(l, ptr->__cxa_exception_type()->name()); - } - return 1; - } + typedef FbTk::Slot Slot; int absindex(lua_State *l, int index) throw() { return index<0 && -index<=lua_gettop(l) ? lua_gettop(l)+1+index : index; } @@ -84,7 +68,7 @@ namespace lua { lua_pop(l, 1); try { - cpp_function *fn = static_cast( L->touserdata(lua_upvalueindex(1)) ); + Slot *fn = static_cast( L->touserdata(lua_upvalueindex(1)) ); assert(fn); return (*fn)(L); } @@ -92,12 +76,11 @@ namespace lua { // rethrow lua errors as such e.push_lua_error(L); } + catch(std::exception &e) { + L->pushstring(e.what()); + } catch(...) { - // C++ exceptions (pointers to them, actually) are stored as lua userdata and - // then thrown - L->createuserdata(std::current_exception()); - L->rawgetfield(REGISTRYINDEX, cpp_exception_metatable); - L->setmetatable(-2); + L->pushstring("Unknown exception"); } // lua_error does longjmp(), so destructors for objects in this function will not be @@ -238,21 +221,11 @@ namespace lua { pushlightuserdata(this); rawsetfield(REGISTRYINDEX, this_cpp_object); - // a metatable for C++ exceptions travelling through lua code - newmetatable(cpp_exception_metatable); - lua_pushcfunction(cobj, &exception_to_string); - rawsetfield(-2, "__tostring"); - pushboolean(false); - rawsetfield(-2, "__metatable"); - pushdestructor(); - rawsetfield(-2, "__gc"); - pop(); - // a metatable for C++ functions callable from lua code newmetatable(cpp_function_metatable); pushboolean(false); rawsetfield(-2, "__metatable"); - pushdestructor >(); + pushdestructor(); rawsetfield(-2, "__gc"); pop(); @@ -279,25 +252,7 @@ namespace lua { throw std::bad_alloc(); } - checkstack(3); - rawgetfield(REGISTRYINDEX, cpp_exception_metatable); - if(getmetatable(-2)) { - if(rawequal(-1, -2)) { - // it's a C++ exception, rethrow it - std::exception_ptr *ptr = static_cast(touserdata(-3)); - assert(ptr); - - /* - * we create a copy, so we can pop the object without fearing the exception will - * be collected by lua's GC - */ - std::exception_ptr t(*ptr); ptr = NULL; - pop(3); - std::rethrow_exception(t); - } - pop(2); - } - // it's a lua exception, wrap it + // wrap the lua exception and throw it if(r == LUA_ERRERR) throw lua::errfunc_error(this); else diff --git a/src/FbTk/Luamm.hh b/src/FbTk/Luamm.hh index f39f3de..ca012c3 100644 --- a/src/FbTk/Luamm.hh +++ b/src/FbTk/Luamm.hh @@ -238,7 +238,7 @@ namespace lua { const char* tocstring(int index, size_t *len = NULL) { return lua_tolstring(cobj, index, len); } // Don't use pushclosure() to create a __gc function. The problem is that lua calls them // in an unspecified order, and we may end up destroying the object holding the - // std::function before we get a chance to call it. This pushes a function that simply + // FbTk::Slot before we get a chance to call it. This pushes a function that simply // calls ~T when the time comes. Only set it as __gc on userdata of type T. template void pushdestructor() { lua_pushcfunction(cobj, &destroy_cpp_object); } -- cgit v0.11.2