Quote from the Lua 5.0 implementation
Part of the array tries to store values corresponding to integers from 1 to a certain limit n. Values corresponding to non-integer keys or integer keys outside the range of the array are stored in the hash part.
The index of the array part starts at 1, so t[0] = 0 will go to the hash part.
The calculated size of the part of the array is the largest, since at least half of the slots between 1 and n are used (to avoid loss of space with sparse arrays), and there is at least one interval used between n / 2 + 1 and n (to avoid size n when n / 2 will do).
According to this rule, in the table of examples:
local t = {100, 200, 300, x = 9.3}
The part of the array that contains 3 elements can be 3, 4, or 5. (EDIT: size must be 4, see @dualed comment.)
Suppose the array has size 4, when writing t[5] = 500 part of the array can no longer hold the element t[5] , what if the size of the array changes to 8? At size 8, part of the array contains 4 elements that are equal (so, at least) to half the size of the array. And the index from n / 2 + 1 to n, which in this case is 5-8, has one element: t[5] . Thus, the size of array 8 can fulfill this requirement. In this case, t[5] goes to the part of the array.
source share