diff options
-rw-r--r-- | include/BLua.h | 8 | ||||
-rw-r--r-- | lib/BLua.cc | 66 |
2 files changed, 57 insertions, 17 deletions
diff --git a/include/BLua.h b/include/BLua.h index d5e4f2b..0a7b7a6 100644 --- a/include/BLua.h +++ b/include/BLua.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.h,v 1.22 2004-12-17 11:46:41 pixel Exp $ */ +/* $Id: BLua.h,v 1.23 2004-12-27 18:50:55 pixel Exp $ */ #ifndef __BLUA_H__ #define __BLUA_H__ @@ -55,7 +55,7 @@ class Lua : public Base { void open_dir(); void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX); void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0); - void call(int = 0, int = 0); + void call(int = 0, int = 0) throw (GeneralException); void push(); void push(lua_Number); void push(const String &); @@ -70,6 +70,7 @@ class Lua : public Base { void gettable(int = -2, bool raw = false); void setvar(); int gettop(); + void push_lua_context(); void error(const String &); int type(int = -1); bool isnil(int = -1); @@ -103,10 +104,13 @@ class Lua : public Base { virtual void lock() {} virtual void unlock() {} + + bool is_protected(); private: Lua(lua_State *); lua_State * L; static std::map<lua_State *, Lua *> lualist; + bool _protected; }; class LuaObject : public Base { diff --git a/lib/BLua.cc b/lib/BLua.cc index 5ec58e1..335da3d 100644 --- a/lib/BLua.cc +++ b/lib/BLua.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: BLua.cc,v 1.25 2004-12-22 00:08:01 pixel Exp $ */ +/* $Id: BLua.cc,v 1.26 2004-12-27 18:50:55 pixel Exp $ */ #include "BLua.h" #include <lualib.h> @@ -26,8 +26,6 @@ #define BUFFERSIZE 2048 #endif - - extern "C" { void do_lua_lock(lua_State * _L) { Lua * L; @@ -56,6 +54,7 @@ class LuaStatics : public Base { static int putF(lua_State *, const void *, size_t, void *); static int luapanic(lua_State *); static int trueluapanic(lua_State *) throw(GeneralException); + static int luaerror(lua_State *); static int collector(lua_State *); static int destructor(lua_State *); @@ -70,13 +69,24 @@ class LuaStatics : public Base { std::map<lua_State *, Lua *> Lua::lualist; +int LuaStatics::luaerror(lua_State * _L) throw (GeneralException) { + Lua * L = Lua::find(_L); + L->push_lua_context(); + L->showerror(); + return 0; +} + int LuaStatics::luapanic(lua_State * L) { return trueluapanic(L); } -int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) { - Lua::find(L)->showerror(); - throw LuaException("Error running Lua code, bailing out."); +int LuaStatics::trueluapanic(lua_State * _L) throw (GeneralException) { + Lua * L = Lua::find(_L); + if (L->is_protected()) + return 0; // luaerror will get it for us... + L->push_lua_context(); + L->showerror(); + throw LuaException("Unprotected error running Lua code, bailing out; except unstable lua environment."); } int LuaStatics::andB(lua_State * _L) { @@ -218,7 +228,7 @@ Lua::Lua() : L(lua_open()) { declarefunc("hex", LuaStatics::hex); } -Lua::Lua(lua_State * _L) : L(_L) { +Lua::Lua(lua_State * _L) : L(_L), _protected(false) { lua_atpanic(L, LuaStatics::luapanic); lualist[L] = this; } @@ -228,6 +238,10 @@ Lua::~Lua() { lua_close(L); } +bool Lua::is_protected() { + return _protected; +} + Lua::Lua(const Lua & l) throw (GeneralException) { throw GeneralException("Error: can't duplicate a Lua object."); } @@ -277,11 +291,31 @@ void Lua::call(const String & f, int i, int nargs, int nresults) { lua_pushstring(L, f.to_charp()); lua_gettable(L, i); lua_insert(L, -1 - nargs - nresults); - lua_call(L, nargs, nresults); -} - -void Lua::call(int nargs, int nresults) { - lua_call(L, nargs, nresults); + call(nargs, nresults); +} + +void Lua::call(int nargs, int nresults) throw(GeneralException) { + int r; + + lua_pushcfunction(L, LuaStatics::luaerror); + lua_insert(L, 1); + _protected = true; + r = lua_pcall(L, nargs, nresults, 1); + _protected = false; + lua_remove(L, 1); + + switch(r) { + case 0: + return; + case LUA_ERRRUN: + throw LuaException("Runtime error while running LUA code."); + case LUA_ERRMEM: + throw LuaException("Memory allocation error while running LUA code."); + case LUA_ERRERR: + throw LuaException("Error in Error function."); + default: + throw LuaException("Unknow error while running LUA code."); + } } void Lua::push() { @@ -352,7 +386,7 @@ int Lua::gettop() { return lua_gettop(L); } -void Lua::error(const String & msg) { +void Lua::push_lua_context() { String whole_msg; struct lua_Debug ar; bool got_error = false; @@ -370,7 +404,9 @@ void Lua::error(const String & msg) { } level++; } while (!got_error); +} +void Lua::error(const String & msg) { push(msg); lua_error(L); @@ -488,6 +524,7 @@ void Lua::load(Handle * h, bool docall) throw (GeneralException) { status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp()); if (status) { + push_lua_context(); showerror(); throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'"); } @@ -533,8 +570,7 @@ void Lua::showerror() { int i; String t; - printm(M_ERROR, "Lua object: Got an LUA error\n"); - printm(M_ERROR, "Inspecting LUA stack\n"); + printm(M_ERROR, "Lua object: Got an LUA error, inspecting stack.\n"); if (n == 0) { printm(M_ERROR, "Stack empty\n"); |