aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/Luamm.cc9
-rw-r--r--src/FbTk/Luamm.hh14
2 files changed, 18 insertions, 5 deletions
diff --git a/src/FbTk/Luamm.cc b/src/FbTk/Luamm.cc
index c4ea2e0..563be9c 100644
--- a/src/FbTk/Luamm.cc
+++ b/src/FbTk/Luamm.cc
@@ -173,7 +173,7 @@ namespace lua {
173 } 173 }
174 174
175 exception::exception(state *l) 175 exception::exception(state *l)
176 : std::runtime_error(get_error_msg(l)), L(l) 176 : std::runtime_error(get_error_msg(l)), L(l), L_valid(l->get_valid())
177 { 177 {
178 L->checkstack(1); 178 L->checkstack(1);
179 179
@@ -184,7 +184,7 @@ namespace lua {
184 } 184 }
185 185
186 exception::exception(const exception &other) 186 exception::exception(const exception &other)
187 : std::runtime_error(other), L(other.L) 187 : std::runtime_error(other), L(other.L), L_valid(other.L_valid)
188 { 188 {
189 L->checkstack(2); 189 L->checkstack(2);
190 190
@@ -196,7 +196,7 @@ namespace lua {
196 196
197 exception::~exception() throw() 197 exception::~exception() throw()
198 { 198 {
199 if(not L) 199 if(not L or not *L_valid)
200 return; 200 return;
201 L->checkstack(1); 201 L->checkstack(1);
202 202
@@ -217,7 +217,7 @@ namespace lua {
217 } 217 }
218 218
219 state::state() 219 state::state()
220 : cobj(luaL_newstate()) 220 : cobj(luaL_newstate()), valid(new bool(true))
221 { 221 {
222 if(cobj == NULL) { 222 if(cobj == NULL) {
223 // docs say this can happen only in case of a memory allocation error 223 // docs say this can happen only in case of a memory allocation error
@@ -249,6 +249,7 @@ namespace lua {
249 luaL_openlibs(cobj); 249 luaL_openlibs(cobj);
250 } 250 }
251 catch(...) { 251 catch(...) {
252 *valid = false;
252 lua_close(cobj); 253 lua_close(cobj);
253 throw; 254 throw;
254 } 255 }
diff --git a/src/FbTk/Luamm.hh b/src/FbTk/Luamm.hh
index f2084e7..1ba9cbe 100644
--- a/src/FbTk/Luamm.hh
+++ b/src/FbTk/Luamm.hh
@@ -31,6 +31,7 @@
31#include <lua.h> 31#include <lua.h>
32#include <lualib.h> 32#include <lualib.h>
33 33
34#include "RefCount.hh"
34#include "Slot.hh" 35#include "Slot.hh"
35 36
36namespace lua { 37namespace lua {
@@ -84,6 +85,7 @@ namespace lua {
84 */ 85 */
85 class exception: public std::runtime_error { 86 class exception: public std::runtime_error {
86 state *L; 87 state *L;
88 FbTk::RefCount<const bool> L_valid;
87 int key; 89 int key;
88 90
89 static std::string get_error_msg(state *L); 91 static std::string get_error_msg(state *L);
@@ -152,9 +154,19 @@ namespace lua {
152 bool safe_compare(lua_CFunction trampoline, int index1, int index2); 154 bool safe_compare(lua_CFunction trampoline, int index1, int index2);
153 void do_pushclosure(int n); 155 void do_pushclosure(int n);
154 156
157 /**
158 * The pointed-to value is true if this object still exists. We need this because the
159 * exceptions have to know if they may reference it to remove the saved lua exception. If
160 * this object is destroyed then the exception was already collected by the garbage
161 * colletor and referencing this would generate a segfault.
162 */
163 FbTk::RefCount<bool> valid;
164
155 public: 165 public:
156 state(); 166 state();
157 ~state() { lua_close(cobj); } 167 ~state() { *valid = false; lua_close(cobj); }
168
169 FbTk::RefCount<const bool> get_valid() const { return valid; }
158 170
159 /* 171 /*
160 * Lua functions come in three flavours 172 * Lua functions come in three flavours