diff --git a/src/main/java/org/squiddev/cobalt/LuaTable.java b/src/main/java/org/squiddev/cobalt/LuaTable.java index a27d918d..0bfdf091 100644 --- a/src/main/java/org/squiddev/cobalt/LuaTable.java +++ b/src/main/java/org/squiddev/cobalt/LuaTable.java @@ -116,7 +116,7 @@ public LuaTable checkTable() { */ public void presize(int nArray) { if (nArray > array.length) { - resize(1 << log2(nArray), nodes.length, false); + resize(nArray, nodes.length, false); } } diff --git a/src/main/java/org/squiddev/cobalt/function/LuaInterpreter.java b/src/main/java/org/squiddev/cobalt/function/LuaInterpreter.java index 5a435d28..ecc1b74b 100644 --- a/src/main/java/org/squiddev/cobalt/function/LuaInterpreter.java +++ b/src/main/java/org/squiddev/cobalt/function/LuaInterpreter.java @@ -554,6 +554,8 @@ static Varargs execute(final LuaState state, DebugFrame di, LuaInterpretedFuncti if (b == 0) { b = di.top - a - 1; int m = b - di.extras.count(); + tbl.presize(offset + b); + int j = 1; for (; j <= m; j++) tbl.rawset(offset + j, stack[a + j]); for (; j <= b; j++) tbl.rawset(offset + j, di.extras.arg(j - m)); diff --git a/src/test/resources/spec/table_spec.lua b/src/test/resources/spec/table_spec.lua index 6c670ccb..293f7825 100644 --- a/src/test/resources/spec/table_spec.lua +++ b/src/test/resources/spec/table_spec.lua @@ -56,6 +56,31 @@ describe("Lua tables", function() expect(#{ 1, 2, 3, nil, 5, nil, 7, 8, 9 }):eq(9) expect(#{ 1, nil, [2] = 2, 3 }):eq(3) end) + + it("behaves identically to PUC Lua after resizing", function() + local n = 8 + + -- We grow the array part to be of length N. + local tbl = {} + for i = 1, n do tbl[i] = true end + expect(#tbl):eq(n) + + -- Then clear out all but the last value. This does not shrink the array part, so we + -- still have a length N. + for i = 1, n - 1 do tbl[i] = nil end + expect(#tbl):eq(n) + end) + end) + + describe("can be constructed from varargs", function() + it("presizes the array", function() + local function create(...) return { ... } end + + -- If we'd constructed this table normally, it'd have a length of 5. However, + -- SETLIST will presize the table to ensure the array part is of length 5. As + -- the last slot is full, the array is considered saturated. + expect(#create(nil, nil, nil, nil, 1)):eq(5) + end) end) describe("weak tables", function()