Before calling a finalizer, Lua not only checks stack limits, but
actually ensures that a minimum number of slots are already allocated
for the call. (If it cannot ensure that, it postpones the finalizer.)
That avoids finalizers not running due to memory errors that the
programmer cannot control.
If the stack does not have some minimum available space, the GC defers
calling a finalizer until the next cycle. That avoids errors while
running a finalizer that the programmer cannot control.
In C, we may have several "setjmp" nested, and the "longjmp" will go
to the one given by the corresponding "jmp_buf". In C++, a "throw"
will always go to the inner "catch". So, the "catch" must check
whether it is the recipient of the "throw" and, if not, rethrow
the exception to the outer level.
LUAI_MAXSTACK is limited to INT_MAX/2, so can use INT_MAX/2 to define
pseudo-indices (LUA_REGISTRYINDEX) in 'lua.h'. A change in the maximum
stack size does not need to change the Lua-C ABI.
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.
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).
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.
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.)
The use of a pointer (not access, only for computations) after its
deallocation is forbiden in ISO C, but seems to work fine in all
platforms we are aware of. So, using that to correct stack pointers
after a stack reallocation seems safe and is much simpler than the
current implementation (first change all pointers to offsets and
then changing the offsets back to pointers). Anyway, for now that
option is disabled.
That reduces the size of "CallInfo". Moreover, bit CIST_HOOKED from
call status is not needed. When in a hook, 'transferinfo' is always
valid, being zero when the hook is not call/return.
Therefore, fields ftransfer/ntransfer in lua_Debug must have type
'int'. (Maximum stack size must fit in an 'int'.) Also, this commit
adds check that maximum stack size respects size_t for size in bytes.
Several definitions that don't need to be "global" (that is, that
concerns only specific parts of the code) moved out of llimits.h,
to more appropriate places.
Yielding in a hook must decrease the program counter, because it already
counted an instruction that, in the end, was not executed. However,
that decrement should be done only when about to restart the thread.
Otherwise, inspecting the thread with the debug library shows it one
instruction behind of where it really is.
To avoid the need of both the old and the new stack addresses valid
at the same time, to correct the pointers to the stack, these pointers
are changed to offsets before the reallocation and then changed back
to pointers after the reallocation.
'luaD_growstack' already checks that. This commit also fixes an
internal bug in 'luaD_growstack': a large 'n' could cause an arithmetic
overflow when computing 'needed'.
The pointer to the metamethod can be invalidated by a finalizer that
can run during a GC in 'checkstackGCp'. (This commit also fixes a
detail in the manual.) Bug introduced in commit 91673a8ec.
'luaD_pretailcall' mimics 'luaD_precall', handling call metamethods
and calling C functions directly. That makes the code in the
interpreter loop simpler.
This commit also goes back to emulating the tail call in 'luaD_precall'
with a goto, as C compilers may not do proper tail calls and the C
stack can overflow much sooner than the Lua stack (which grows as the
metamethod is added to it).