summaryrefslogtreecommitdiff
path: root/library/LuaTypes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/LuaTypes.cpp')
-rw-r--r--library/LuaTypes.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp
index 8548c5d0..9f2689fa 100644
--- a/library/LuaTypes.cpp
+++ b/library/LuaTypes.cpp
@@ -37,6 +37,7 @@ distribution.
#include "DataDefs.h"
#include "DataIdentity.h"
#include "LuaWrapper.h"
+#include "LuaTools.h"
#include "DataFuncs.h"
#include "MiscUtils.h"
@@ -285,6 +286,9 @@ void container_identity::lua_item_read(lua_State *state, int fname_idx, void *pt
void container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
{
+ if (is_readonly())
+ field_error(state, fname_idx, "container is read-only", "write");
+
auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
void *pitem = item_pointer(id, ptr, idx);
id->lua_write(state, fname_idx, pitem, val_index);
@@ -890,7 +894,7 @@ static int meta_bitfield_len(lua_State *state)
static void read_bitfield(lua_State *state, uint8_t *ptr, bitfield_identity *id, int idx)
{
- int size = id->getBits()[idx].size;
+ int size = std::max(1, id->getBits()[idx].size);
int value = getBitfieldField(ptr, idx, size);
if (size <= 1)
@@ -947,7 +951,7 @@ static int meta_bitfield_newindex(lua_State *state)
}
int idx = check_container_index(state, id->getNumBits(), 2, iidx, "write");
- int size = id->getBits()[idx].size;
+ int size = std::max(1, id->getBits()[idx].size);
if (lua_isboolean(state, 3) || lua_isnil(state, 3))
setBitfieldField(ptr, idx, size, lua_toboolean(state, 3));
@@ -1064,6 +1068,27 @@ int LuaWrapper::method_wrapper_core(lua_State *state, function_identity_base *id
return 1;
}
+int Lua::CallWithCatch(lua_State *state, int (*fn)(lua_State*), const char *context)
+{
+ if (!context)
+ context = "native code";
+
+ try {
+ return fn(state);
+ }
+ catch (Error::NullPointer &e) {
+ const char *vn = e.varname();
+ return luaL_error(state, "%s: NULL pointer: %s", context, vn ? vn : "?");
+ }
+ catch (Error::InvalidArgument &e) {
+ const char *vn = e.expr();
+ return luaL_error(state, "%s: Invalid argument; expected: %s", context, vn ? vn : "?");
+ }
+ catch (std::exception &e) {
+ return luaL_error(state, "%s: C++ exception: %s", context, e.what());
+ }
+}
+
/**
* Push a closure invoking the given function.
*/