There are several hard limits built in to GameLisp.
There cannot be more than 16,777,216 (
2^24) distinct symbols. Running out of symbols is treated
as an unrecoverable error, similar to an out-of-memory condition: attempting to allocate additional
symbols will trigger a panic.
There can't be more than 256 simultaneous GameLisp function calls on the callstack. Attempting to call the 257th function will trigger an error instead. This is because:
- GameLisp implements recursion using Rust's callstack.
- A Rust stack overflow would abort the process.
- GameLisp function calls use up quite a lot of stack space.
- The default stack size for
*-pc-windows-msvctargets is only one megabyte.
Rust currently seems to use up a very large amount of stack space in debug builds. If you try to
glsp crate at
opt-level = 0, you may still encounter stack overflows, even when there
are only a few dozen GameLisp function calls on the callstack.
Each "frame" (
fn body or single toplevel form) may only contain 256 "registers" (parameters,
local variables, scratch registers or literals). Exceeding this limit will trigger an error.
This will usually only happen if you use macros to code-generate an extremely long function.
In that case, you can break up the function into multiple frames by wrapping each part of
its body in a separate
class form may not contain more than 31
state* forms, including nested
states and states defined by mixins.
When a function call has more than 32 arguments, the 33rd and later arguments can't be splayed.
No more than 256
Runtimes may simultaneously exist within a single thread.
Runtime may not contain more than 8,388,606 (
2^23 - 2) rooted objects. (This is the
combined total of objects which have been strongly rooted, with
Root, and those which have been
weakly rooted, with
Gc). There's also a soft limit on strongly-rooted objects, because they each
consume a few nanoseconds of time whenever the garbage collector is invoked. If you're likely to
require more than 100,000 strongly-rooted objects, consider storing that data in Rust rather than
There are a small number of ways that a
Gc may outlive its parent
Runtime, or be
assigned to a different
Runtime. In either scenario, the only way that GameLisp can uphold
memory safety is by immediately aborting the process! The most likely way you might do this
accidentally is by either leaking a
Root (using a function like
or storing a
Root in a