Mitigates issue caused by moving around deleted effect objects, otherwise the push_weak_ref function would've been called on a garbage lua state pointer
No longer manage a Group's lifetime explicitly in native code, but instead leverage Lua's garbage collector to handle it's lifetime.
In this change, Groups will be stored internally in the core inside a weak table, so that they will still be reference-able when needed, but if no reference were to exist in Lua code, they will be subject to garbage collection.
Whenever a Group is used by native code, its wrapped by a owned_lua template class, this is akin to std::shared_ptr--It reference counts the usages of that group internally in the core, including managing it in the Lua registry index when in use, so that it won't be collected.
With this approach, the exponential memory usage growth caused by long running procedures due to the creation hundredths of thousands of groups per iteration, is mitigated, since the temporary groups will be reaped more frequently, as opposed to the old approach of them being cleared only after the topmost Lua function had finished executing.
For now a single GC step is triggered whenever the total number of groups is more than 2048--an arbitrary value that seems to work well enough, but which can be changed/optimized after proper profiling.
A major upgrade with this approach is the removal of the concept of Groups "kept alive" and having to "explicitly delete" them to make them outlive a Lua function execution, since they will now follow Lua's variables lifetime properly.
In lua 5.4 and later, it's now possible to specify the number of userdata value slots, including 0, unlike in earlier versions where the slots were always fixed at 1.
Since they're unused in our case, use the full function to have 0 slots available and save some space for each userdata object
Rather than calculate the stacktrace after the pcall, register an error handler in lua that will print it the moment the error is raised, thus leading to more accurate and meaningful traces
Functions from the auxiliary library, assume the stack has always at least 5 empty slots, add macro ensure_luaL_stack to wrap every such call so that the stack is checked for enough free space beforehand. This will make mandatory to use the latest version of visual studio 2017 as minimum for windows (it was already being required for c++17 support regardless), as it needs the conformant c++ preprocessor option to be used.
Also only copy exactly the size of the pointer rather than data equal to LUA_EXTRASPACE, as that could be more than a pointer, thus leaving to an out of bounds read
Due to the way each card object is designed, the __tostring method has to be put in each cXXXXXX table, and cannot be put in the Card table as lua will do a rawget on the metatable to get the metamethods. Use a "wrapper" function as default tostring method to handle when that method is called directly from the metatable itself and not from a card object, that will load a defined Debug.CardToString function if present, otherwise emulates the same tostring behaviour lua uses
The given lua stack to a c function has enough room to push few return values without issues, so all the functions that return a fixed amount of values (usually 1 or 2) weren't touched, all the others that return an unknown amount are now properly calling checkstack to make the lua api allocate the space needed for all the return values.
Remove the need to manually need to call those 2 functions to manage the call depth and no action counters, now in places where this is needed (so where lua_pcall is used) call_lua will be called, that handles everything. Also remove the redoundant calls to flatten/deepen that were called in functions that ended up calling other functions that did the pcall (and woudl also call those functions as well).
Fixes also another issue where deepen was not called immediately before the actual lua_pcall call but had some other lua functions inbetween that could have raised an error and made it skip the corresponding flatten call
It's now being used by the scripting library and in any case it doesn't really make anything safer, if someone could write a malicious eval call, that same person could write the malicious code in the script directly
Semantically the proper operator to use for oneline increments is the preincrement one, the postincrement is the one to be used only in teh cases where the previous value is required.
Make it a templated function taking the parameter type at compile time, this allows performing more sanity checks, and fixes the situations with ambiguity of 0 with nullptr, also fixing some isntances where such behaviour was present.
Removes ambiguity when the core needs a full unsigned 32 bit integer that could be altered when returned as signed integer since lua_Integer is an int64.
Fixes an issue where the core would keep using a yielded state to call functions on, thing that is forbidden by the lua api and caused assertions with lua built with LUA_APICHECK