Skip to content

Commit 2177a92

Browse files
committed
Make table.append() behave as table.insert() with nil
Fixes #72
1 parent fed1a35 commit 2177a92

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

VM/src/ltablib.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,20 +237,18 @@ static int tmove(lua_State* L)
237237
}
238238

239239
// ServerLua: table.append(t, ...) - appends varargs to end of table
240-
// Largely a replacement for consecutive `table.insert()` calls.
240+
// Semantically equivalent to consecutive `table.insert()` calls.
241241
static int tappend(lua_State* L)
242242
{
243-
// Need some extra slots for actually appending
244243
lua_checkstack(L, 2);
245244

246245
luaL_checktype(L, 1, LUA_TTABLE);
247-
int orig_len = lua_objlen(L, 1);
248246
int top = lua_gettop(L);
249247

250248
for (int i = 2; i <= top; i++)
251249
{
252250
lua_pushvalue(L, i);
253-
lua_rawseti(L, 1, orig_len + (i - 1));
251+
lua_rawseti(L, 1, lua_objlen(L, 1) + 1);
254252
}
255253

256254
return 0;

tests/conformance/tables.luau

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,20 @@ do
825825

826826
-- returns nil
827827
assert(table.append({1}, 2) == nil)
828+
829+
-- Is semantically equivalent to repeated `table.insert()`
830+
-- (i.e. it implicitly skips `nil` and respects existing holes
831+
t5 = table.create(3)
832+
t5[5] = 5
833+
t5[1] = 1
834+
t5[2] = 2
835+
assert(#t5 == 2)
836+
-- `nil`s are basically no-ops, as they would be in `table.insert()`
837+
table.append(t5, 3, 4, nil, nil, nil, 6)
838+
assert(#t5 == 6)
839+
840+
-- Eesh, wish there was lljson here.
841+
assert(t5[3] == 3 and t5[4] == 4 and t5[5] == 5 and t5[6] == 6 and t5[7] == nil)
828842
end
829843

830844
-- ServerLua: table.extend

0 commit comments

Comments
 (0)