If Lua raises an error we won't ever link the new_script into the list
and won't find it to remove it and free its components later. The
components do ultimately get freed by the destruction of the heap, and
there's no way to access them after, but we'd rather it be empty and
know nothing is dangling.
This should be replaced by storing the components as Lua objects and
letting Lua's GC take care of them. That way the code could be made much
less fragile.
Also removes a chance of a leak in run_next_script.
Nominally cannot be called as we do not call error-raising Lua functions
outside of protected mode. In the event a panic happens somehow anyway,
Lua calls `lua_abort` which we already handle safely.
Lua calls our registered panic function if a Lua error is raised outside
of any protected mode set up by `lua_pcall` and friends. As scripts
themselves are run in protected mode, such an error will only originate
from our engine code.
The current code handles panics, but does so incorrectly by neglecting
to free the error message buffer during a panic exit. As the underlying
heap is eventually destroyed and recreated, that static buffer pointer
is to a heap that no longer exists. If the new state raises an error it
will try to free that pointer, causing heap corruption and sadness.
Fix this issue and avoid similar ones by refactoring to run the main
part of the scripting engine in Lua protected mode. This creates exactly
one exit path from the scripting engine and avoids the need for fragile
panic handling infrastructure that duplicates what is built into Lua.
Quoth the Lua manual, "The panic function, as its name implies, is a
mechanism of last resort. Programs should avoid it."
This is unlikely to be triggerable in flight as the main engine loop
does not appear to use the Lua API in a way which can trigger errors.
But the possibility can't be fully excluded. It is, however, possible to
trigger beforehand using a perfectly wrong heap size that causes a
memory error during initialization.
Note that due to the error message buffer being freed properly now, an
error message originating from the engine will not cause a pre-arm
failure. This could be improved in the future.
Referencing the original function to run is of questionable value and
the only user uses it to grab the script environent from the upvalues.
Instead, use a reference to the script environment table directly.
Some bits of the code in the require machinery use the `lua_ref` to
access the script environment. However, this can change after the script
is rescheduled and it returns an arbitrary function to run next.
Resolve this by introducing `run_ref` which is specifically a reference
to the function to run next. `lua_ref` is preserved for the script
lifetime.