summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Noble <nnoble@blizzard.com>2013-07-24 14:23:25 -0700
committerNicolas Noble <nnoble@blizzard.com>2013-07-24 14:23:25 -0700
commit712b4bed9973c60b5c139f98e51ed804ce8a628d (patch)
tree5a634d54a49d71e1dc6091092d8a8f763403446b
parente37ef65aaa42e790a741c15dbae9b83e9c04cd3a (diff)
Better exception handling support for Lua.
-rw-r--r--includes/LuaTask.h6
-rw-r--r--src/BLua.cc21
-rw-r--r--src/LuaTask.cc17
3 files changed, 38 insertions, 6 deletions
diff --git a/includes/LuaTask.h b/includes/LuaTask.h
index 50226cd..1f7a0b5 100644
--- a/includes/LuaTask.h
+++ b/includes/LuaTask.h
@@ -12,10 +12,11 @@ class LuaMainTask;
class LuaExecCell {
public:
LuaExecCell();
- virtual ~LuaExecCell() { }
+ virtual ~LuaExecCell() { if (m_exception) delete m_exception; }
void detach() { m_detached = true; }
void exec(LuaMainTask * mainTask);
- bool gotError() { return m_gotError; }
+ bool gotError() { return m_gotError || m_exception; }
+ void throwError() throw (GeneralException);
protected:
virtual void run(Lua &) = 0;
void setError() { m_gotError = true; }
@@ -23,6 +24,7 @@ class LuaExecCell {
Events::Async m_event;
bool m_detached = false;
bool m_gotError = false;
+ GeneralException * m_exception = NULL;
friend class LuaTask;
LuaExecCell(const LuaExecCell &) = delete;
diff --git a/src/BLua.cc b/src/BLua.cc
index 21a7452..29b68c2 100644
--- a/src/BLua.cc
+++ b/src/BLua.cc
@@ -474,12 +474,19 @@ Balau::String Balau::Lua::tostring(int i) {
struct LoadF {
Balau::IO<Balau::Handle> f;
char buff[BUFFERSIZE];
+ Balau::GeneralException * exception = NULL;
};
const char * Balau::LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
LoadF * lf = (LoadF *)ud;
- *size = lf->f->read(lf->buff, BUFFERSIZE);
+ try {
+ *size = lf->f->read(lf->buff, BUFFERSIZE);
+ }
+ catch (GeneralException e) {
+ lf->exception = new GeneralException(e);
+ AssertHelper("LuaJIT is lame.");
+ }
return (*size > 0) ? lf->buff : NULL;
}
@@ -522,9 +529,15 @@ void Balau::Lua::load(IO<Handle> h, bool docall) throw (GeneralException) {
status = lua_load(L, LuaStatics::getF, &lf, name.to_charp());
if (status) {
- pushLuaContext();
- showerror();
- throw LuaException(String("Error loading lua chunk from Handle `") + h->getName() + "'");
+ if (lf.exception) {
+ GeneralException copy(*lf.exception);
+ delete lf.exception;
+ throw copy;
+ } else {
+ pushLuaContext();
+ showerror();
+ throw LuaException(String("Error loading lua chunk from Handle `") + h->getName() + "'");
+ }
}
if (docall)
diff --git a/src/LuaTask.cc b/src/LuaTask.cc
index 12d4435..fc92cdf 100644
--- a/src/LuaTask.cc
+++ b/src/LuaTask.cc
@@ -60,6 +60,9 @@ void Balau::LuaTask::Do() {
try {
m_cell->run(L);
}
+ catch (GeneralException e) {
+ m_cell->m_exception = new GeneralException(e);
+ }
catch (...) {
m_cell->setError();
}
@@ -77,6 +80,20 @@ void Balau::LuaExecCell::exec(LuaMainTask * mainTask) {
Task::operationYield(&m_event);
}
+void Balau::LuaExecCell::throwError() throw (GeneralException) {
+ if (!gotError())
+ return;
+
+ if (m_exception) {
+ GeneralException copy(*m_exception);
+ delete m_exception;
+ m_exception = NULL;
+ throw copy;
+ } else {
+ throw GeneralException("Unknown error");
+ }
+}
+
void Balau::LuaExecString::run(Lua & L) {
L.load(m_str);
}