diff options
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/Luamm.cc | 9 | ||||
-rw-r--r-- | src/FbTk/Luamm.hh | 14 |
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 | ||
36 | namespace lua { | 37 | namespace 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 |