All-weak tables are not being revisited after being visited during
propagation; if it gets a new metatable after that, the new metatable
may not be marked.
No thread started with pcall (instead of resume) can be closed,
because coroutine.close would not respect the expected number of
results from the protected call.
In a constructor, each field generates at least one opcode, and the
number of opcodes is limited by INT_MAX. Therefore, the counters for
number of fields cannot exceed this limit. (The current limit for
items in the hash part of a table has a limit smaller than INT_MAX.
However, as long as there are no overflows, the logic for table
resizing will handle that limit.)
A goto cannot jump into the scope of any variable declaration,
including 'global *'. To report the error, it needs a "name" for
the scope it is entering.
The parser uses "break" as fake label to compile "break" as "goto
break". To avoid producing this string at each use, it keeps it
available in its state.
In generational collection, objects marked as touched1 stay in gray
lists between collections. This commit fixes a bug introduced in
commit 808976bb59.
It can be a little slower, but only for quite large stacks and moreover
stack reallocation is not a common operation. With no strong contrary
reason, it is better to follow the standard.
When computing the Mersenne number, instead of spreading 1's a fixed
number of times (with shifts of 1, 2, 4, 8, 16, and 32), spread only
until the number becomes a Mersenne number.
To avoid complains from some tools, the addition when computing
math.random(n,m), which is computed as n + random(0, m - n), should
use unsigned integers.
New function 'resetCI' resets the CallInfo list of a thread, ensuring
a proper state when creating a new thread, closing a thread, or
closing a state, so that we can run code after that. (When closing a
thread, we need to run its __close metamethods; when closing a
state, we need to run its __close metamethods and its finalizers.)
If a metatable is a weak table, its __newindex field could be collected
by an emergency collection while being used in 'luaV_finishset'. (This
bug has similarities with bug 5.3.2-1, fixed in commit a272fa66.)
This function can be called unprotected, so it should not raise any
kind of errors. (It could raise a memory-allocation error when creating
a message).
Tests for memory-allocation errors moved from 'api.lua' to this new
file, as 'api.lua' was already too big. (Besides, these tests have
nothing to do with the API.)
After a weak table is traversed in the atomic phase, if it does not
have white values ('hasclears') it does not need to be retraversed
again. (Comments were correct, but code did not agree with them.)
Lua can easily overflow an unsigned short counting nested calls.
(The limit to this value is the maximum stack size, LUAI_MAXSTACK,
which is currently 1e6.)
Since commit f407b3c4a, it was being used for two distinct (and
incompatible) meanings:
A: Function has TBC variables (now bit CIST_TBC)
B: Interpreter is closing TBC variables (original bit CIST_CLSRET)
B implies A, but A does not imply B.
Added comments so that all braces pair correctly. (The parser has
several instances of unmatched braces as characters ('{' or '}'), which
hinders matching regular braces in the code.)
The compilation of a goto or a label just create an entry and generate
boilerplate code for the gotos. As we don't know yet whether it needs a
CLOSE, we code a jump followed by a CLOSE, which is then dead code.
When a block ends (and then we know for sure whether there are variables
that need to be closed), we check the goto's against the labels of that
block. When closing a goto against a label, if it needs a CLOSE, the
compiler swaps the order of the jump and the CLOSE, making the CLOSE
active.
Do not optimize only for table updates (key already present).
Creation of new short keys in new tables can be quite common in
programs that create lots of small tables, for instance with
constructors like {x=e1,y=e2}.
Protect stack top before possible stack reallocation. (In the current
implementation, a stack reallocation cannot call an emergency
collection, so there is no bug, but it is safer not to depend on that.)
Moreover, each function being parsed has its own table.
The code is cleaner when each table is used for one specific purpose:
The scanner uses its table to anchor and unify strings, mapping strings
to themselves; the parser uses it to reuse constants in the code,
mapping constants to their indices in the constant table. A different
table for each task avoids false collisions.
The extra check in checknoTM (versus only checking whether there is a
metatable) is cheap, and it is not that uncommon for a table to have a
metatable without a __newindex metafield.
Optimize this opcode for the common case. For long names or method
calls after too many constants, operation can be coded as a move
followed by 'gettable'.
When reinserting elements into a table during a rehash, the code does
not need to invoke all the complexity of a full 'luaH_set':
- The table has space for all keys.
- The key cannot exist in the new hash.
- The keys are valid (not NaN nor nil).
- The keys are normalized (1.0 -> 1).
- The values cannot be nil.
- No barrier needed (the table already pointed to the key and value).
The array at the end of a Lua closure has pointers to upvalues, not
to tagged values. This bug cannot cause any issue: The ISO C standard
requires that all pointers to structures have the same representation,
so sizeof(TValue*) must be equal to sizeof(UpVal*).
Instead of using 'alimit' for keeping the size of the array and at
the same time being a hint for '#t', a table now keeps these two
values separate. The Table structure has a field 'asize' with the
size of the array, while the length hint is kept in the array itself.
That way, tables with no array part waste no space with that field.
Moreover, the space for the hint may have zero cost for small arrays,
if the array of tags plus the hint still fits in a single word.
'debug.getinfo' can return number of extra arguments added to a call by
a chain of __call metavalues. That information is being used to improve
error messages about errors in these extra arguments.
Without this extra space, sequences of insertions/deletions (and
some other uses) can have unpexpected low performances. See the
added tests for an example, and *Mathematical Models to Analyze Lua
Hybrid Tables and Why They Need a Fix* (Martínez, Nicaud, Rotondo;
arXiv:2208.13602v2) for detais.
Array part needs 1/3 of its elements filled, instead of 1/2.
Array entries use ~1/3 the memory of hash entries, so this new rule
still ensures that array parts do not use more memory than keeping
the values in the hash, while allowing more uses of the array part,
which is more efficient than the hash.
If there are no integer keys outside the array part, there is no
reason to resize it, saving the time to count its elements. Moreover,
assignments to non-integer keys will not collapse a table created with
'table.create'.