summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/BLua.cc66
1 files changed, 51 insertions, 15 deletions
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");