Replace a call to abort() with a VTableMissing exception

This makes some scripts crash less when the viewscreen vtable is unavailable,
for example.
develop
lethosor 2017-12-25 20:13:15 -05:00
parent e6651171bf
commit 0332a5c25a
4 changed files with 23 additions and 1 deletions

@ -36,6 +36,7 @@ distribution.
#include "DataDefs.h" #include "DataDefs.h"
#include "DataIdentity.h" #include "DataIdentity.h"
#include "VTableInterpose.h" #include "VTableInterpose.h"
#include "Error.h"
#include "MiscUtils.h" #include "MiscUtils.h"
@ -310,7 +311,7 @@ void virtual_identity::adjust_vtable(virtual_ptr obj, virtual_identity *main)
return; return;
std::cerr << "Attempt to create class '" << getName() << "' without known vtable." << std::endl; std::cerr << "Attempt to create class '" << getName() << "' without known vtable." << std::endl;
abort(); throw DFHack::Error::VTableMissing(getName());
} }
virtual_ptr virtual_identity::clone(virtual_ptr obj) virtual_ptr virtual_identity::clone(virtual_ptr obj)

@ -1086,6 +1086,11 @@ int LuaWrapper::method_wrapper_core(lua_State *state, function_identity_base *id
std::string tmp = stl_sprintf("Invalid argument; expected: %s", vn ? vn : "?"); std::string tmp = stl_sprintf("Invalid argument; expected: %s", vn ? vn : "?");
field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke"); field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke");
} }
catch (Error::VTableMissing &e) {
const char *cn = e.name();
std::string tmp = stl_sprintf("Missing vtable address: %s", cn ? cn : "?");
field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke");
}
catch (std::exception &e) { catch (std::exception &e) {
std::string tmp = stl_sprintf("C++ exception: %s", e.what()); std::string tmp = stl_sprintf("C++ exception: %s", e.what());
field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke"); field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke");
@ -1110,6 +1115,10 @@ int Lua::CallWithCatch(lua_State *state, int (*fn)(lua_State*), const char *cont
const char *vn = e.expr(); const char *vn = e.expr();
return luaL_error(state, "%s: Invalid argument; expected: %s", context, vn ? vn : "?"); return luaL_error(state, "%s: Invalid argument; expected: %s", context, vn ? vn : "?");
} }
catch (Error::VTableMissing &e) {
const char *cn = e.name();
return luaL_error(state, "%s: Missing vtable address: %s", context, cn ? cn : "?");
}
catch (std::exception &e) { catch (std::exception &e) {
return luaL_error(state, "%s: C++ exception: %s", context, e.what()); return luaL_error(state, "%s: C++ exception: %s", context, e.what());
} }

@ -49,6 +49,10 @@ const char *DFHack::Error::InvalidArgument::what() const throw() {
return "DFHack::Error::InvalidArgument"; return "DFHack::Error::InvalidArgument";
} }
const char *DFHack::Error::VTableMissing::what() const throw() {
return "DFHack::Error::VTableMissing";
}
std::string stl_sprintf(const char *fmt, ...) { std::string stl_sprintf(const char *fmt, ...) {
va_list lst; va_list lst;
va_start(lst, fmt); va_start(lst, fmt);

@ -75,6 +75,14 @@ namespace DFHack
#define CHECK_INVALID_ARGUMENT(expr) \ #define CHECK_INVALID_ARGUMENT(expr) \
{ if (!(expr)) throw DFHack::Error::InvalidArgument(#expr); } { if (!(expr)) throw DFHack::Error::InvalidArgument(#expr); }
class DFHACK_EXPORT VTableMissing : public All {
const char *name_;
public:
VTableMissing(const char *name_ = NULL) : name_(name_) {}
const char *name() const { return name_; }
virtual const char *what() const throw();
};
class DFHACK_EXPORT AllSymbols : public All{}; class DFHACK_EXPORT AllSymbols : public All{};
// Syntax errors and whatnot, the xml can't be read // Syntax errors and whatnot, the xml can't be read