summaryrefslogtreecommitdiff
path: root/library/LuaTypes.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-03-28 15:28:42 +0800
committerPetr Mrázek2012-03-28 17:00:07 +0800
commit929657bed4e1300537a88401de9e3b14f2e1dc72 (patch)
treec9f6f8fe6a6a316eb61ca0ff5c74c04a92463611 /library/LuaTypes.cpp
parentfe091de0b23791a7a76382e66b2c923edeea19cb (diff)
downloaddfhack-929657bed4e1300537a88401de9e3b14f2e1dc72.tar.gz
dfhack-929657bed4e1300537a88401de9e3b14f2e1dc72.tar.bz2
dfhack-929657bed4e1300537a88401de9e3b14f2e1dc72.tar.xz
Disable pointer auto-vivification unless new is specified.
Since it is essentially allocating non-gc managed objects, it can lead to memory leaks and shouldn't happen invisibly. Also support using the 'assign' key to request assign() from another object before processing the current map.
Diffstat (limited to 'library/LuaTypes.cpp')
-rw-r--r--library/LuaTypes.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp
index 1e33ed71..79f515d4 100644
--- a/library/LuaTypes.cpp
+++ b/library/LuaTypes.cpp
@@ -168,10 +168,16 @@ static void autovivify_ptr(lua_State *state, int fname_idx, void **pptr,
{
lua_getfield(state, val_index, "new");
- if (!lua_isnil(state, -1))
+ // false or nil => bail out
+ if (!lua_toboolean(state, -1))
+ field_error(state, fname_idx, "null and autovivify not requested", "write");
+
+ // not 'true' => call df.new()
+ if (!lua_isboolean(state, -1))
{
int top = lua_gettop(state);
+ // Verify new points to a reasonable type of object
type_identity *suggested = get_object_identity(state, top, "autovivify", true, true);
if (!is_type_compatible(state, target, 0, suggested, top+1, false))
@@ -179,17 +185,22 @@ static void autovivify_ptr(lua_State *state, int fname_idx, void **pptr,
lua_pop(state, 1);
+ // Invoke df.new()
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME);
lua_swap(state);
lua_call(state, 1, 1);
+ // Retrieve the pointer
void *nval = get_object_internal(state, target, top, false);
+ // shouldn't happen: this means suggested type is compatible,
+ // but its new() result isn't for some reason.
if (!nval)
field_error(state, fname_idx, "inconsistent autovivify type", "write");
*pptr = nval;
}
+ // otherwise use the target type
else
{
if (!target)