diff options
| author | Alexander Gavrilov | 2012-03-28 15:28:42 +0800 |
|---|---|---|
| committer | Petr Mrázek | 2012-03-28 17:00:07 +0800 |
| commit | 929657bed4e1300537a88401de9e3b14f2e1dc72 (patch) | |
| tree | c9f6f8fe6a6a316eb61ca0ff5c74c04a92463611 /library/LuaTypes.cpp | |
| parent | fe091de0b23791a7a76382e66b2c923edeea19cb (diff) | |
| download | dfhack-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.cpp | 13 |
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) |
