Get rid of MSVC problems and improve state API.

- Just let MSVC have crap codegen. The compiler sucks anyways. Fixes
- Add incremental GC power. Fixes #997.
- Add non-null offset manipulation. Did I mention I hate VC++ and how it implemented _Aligned? Fixes #1017.
This commit is contained in:
ThePhD 2020-09-05 17:25:15 -04:00
parent de87bec171
commit 63df43e061
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
7 changed files with 627 additions and 348 deletions

View File

@ -28,14 +28,19 @@
#include <sol/call.hpp> #include <sol/call.hpp>
#include <sol/bind_traits.hpp> #include <sol/bind_traits.hpp>
namespace sol { namespace sol { namespace function_detail {
namespace function_detail {
template <typename Function, bool is_yielding> template <typename Function, bool is_yielding>
struct upvalue_free_function { struct upvalue_free_function {
using function_type = std::remove_pointer_t<std::decay_t<Function>>; using function_type = std::remove_pointer_t<std::decay_t<Function>>;
using traits_type = meta::bind_traits<function_type>; using traits_type = meta::bind_traits<function_type>;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L); auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
function_type* fx = udata.first; function_type* fx = udata.first;
return call_detail::call_wrapped<void, true, false>(L, fx); return call_detail::call_wrapped<void, true, false>(L, fx);
@ -61,7 +66,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member function pointer // idx 1...n: verbatim data of member function pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -72,7 +83,13 @@ namespace function_detail {
return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item); return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
} }
static int call(lua_State* L) noexcept(traits_type::is_noexcept) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -92,7 +109,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -112,7 +135,13 @@ namespace function_detail {
} }
} }
static int call(lua_State* L) noexcept(traits_type::is_noexcept) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -132,7 +161,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -150,7 +185,13 @@ namespace function_detail {
} }
} }
static int call(lua_State* L) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -170,14 +211,26 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2)); function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
return call_detail::call_wrapped<T, false, false>(L, memfx); return call_detail::call_wrapped<T, false, false>(L, memfx);
} }
static int call(lua_State* L) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -258,7 +311,6 @@ namespace function_detail {
return call(L); return call(L);
} }
}; };
} }} // namespace sol::function_detail
} // namespace sol::function_detail
#endif // SOL_FUNCTION_TYPES_STATELESS_HPP #endif // SOL_FUNCTION_TYPES_STATELESS_HPP

View File

@ -92,7 +92,9 @@ namespace sol {
template <typename... Args> template <typename... Args>
std::size_t aligned_space_for(void* alignment = nullptr) { std::size_t aligned_space_for(void* alignment = nullptr) {
char* start = static_cast<char*>(alignment); // use temporary storage to prevent strict UB shenanigans
char alignment_shim[(std::max)({ sizeof(Args)... }) + (std::max)({ alignof(Args)... })] {};
char* start = alignment == nullptr ? static_cast<char*>(alignment) : alignment_shim;
(void)detail::swallow { int {}, (align_one(std::alignment_of_v<Args>, sizeof(Args), alignment), int {})... }; (void)detail::swallow { int {}, (align_one(std::alignment_of_v<Args>, sizeof(Args), alignment), int {})... };
return static_cast<char*>(alignment) - start; return static_cast<char*>(alignment) - start;
} }

View File

@ -637,10 +637,88 @@ namespace sol {
return s; return s;
} }
bool supports_gc_mode(gc_mode mode) const noexcept {
#if SOL_LUA_VERSION >= 504
// supports all modes
(void)mode;
return true;
#endif
return mode == gc_mode::default;
}
bool is_gc_on() const {
return lua_gc(lua_state(), LUA_GCISRUNNING, 0) == 1;
}
void collect_garbage() { void collect_garbage() {
lua_gc(lua_state(), LUA_GCCOLLECT, 0); lua_gc(lua_state(), LUA_GCCOLLECT, 0);
} }
void collect_gc() {
collect_garbage();
}
bool step_gc(int step_size_kilobytes) {
// THOUGHT: std::chrono-alikes to map "kilobyte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VERSION >= 504
// The manual implies that this function is almost always successful...
// is it?? It could depend on the GC mode...
return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) != 0;
#else
return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) == 1;
#endif
}
void restart_gc() {
lua_gc(lua_state(), LUA_GCRESTART, 0);
}
void stop_gc() {
lua_gc(lua_state(), LUA_GCSTOP, 0);
}
// Returns the old GC mode. Check support using the supports_gc_mode function.
gc_mode change_gc_mode_incremental(int pause, int step_multiplier, int step_byte_size) {
// "What the fuck does any of this mean??"
// http://www.lua.org/manual/5.4/manual.html#2.5.1
// THOUGHT: std::chrono-alikes to map "byte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VERSION >= 504
int old_mode = lua_gc(lua_state(), LUA_GCINC, pause, step_multiplier, step_byte_size);
if (old_mode == LUA_GCGEN) {
return gc_mode::generational;
}
else if (old_mode == LUA_GCINC) {
return gc_mode::incremental;
}
#else
lua_gc(lua_state(), LUA_GCSETPAUSE, pause);
lua_gc(lua_state(), LUA_GCSETSTEPMUL, step_multiplier);
(void)step_byte_size; // means nothing in older versions
#endif
return gc_mode::default;
}
// Returns the old GC mode. Check support using the supports_gc_mode function.
gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier) {
#if SOL_LUA_VERSION >= 504
// "What does this shit mean?"
// http://www.lua.org/manual/5.4/manual.html#2.5.2
int old_mode = lua_gc(lua_state(), LUA_GCGEN, minor_multiplier, major_multiplier);
if (old_mode == LUA_GCGEN) {
return gc_mode::generational;
}
else if (old_mode == LUA_GCINC) {
return gc_mode::incremental;
}
#endif
return gc_mode::default;
}
operator lua_State*() const { operator lua_State*() const {
return lua_state(); return lua_state();
} }

View File

@ -646,6 +646,12 @@ namespace sol {
file = LUA_ERRFILE, file = LUA_ERRFILE,
}; };
enum class gc_mode : int {
incremental = 0,
generational = 1,
default = incremental,
};
enum class type : int { enum class type : int {
none = LUA_TNONE, none = LUA_TNONE,
lua_nil = LUA_TNIL, lua_nil = LUA_TNIL,

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-08-12 23:04:25.864654 UTC // Generated 2020-09-05 21:23:26.771012 UTC
// This header was generated with sol v3.2.1 (revision 5bbc095) // This header was generated with sol v3.2.1 (revision de87bec)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_CONFIG_HPP #ifndef SOL_SINGLE_CONFIG_HPP

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-08-12 23:04:25.839654 UTC // Generated 2020-09-05 21:23:26.767014 UTC
// This header was generated with sol v3.2.1 (revision 5bbc095) // This header was generated with sol v3.2.1 (revision de87bec)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-08-12 23:04:25.317593 UTC // Generated 2020-09-05 21:23:26.587015 UTC
// This header was generated with sol v3.2.1 (revision 5bbc095) // This header was generated with sol v3.2.1 (revision de87bec)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -7079,6 +7079,12 @@ namespace sol {
file = LUA_ERRFILE, file = LUA_ERRFILE,
}; };
enum class gc_mode : int {
incremental = 0,
generational = 1,
default = incremental,
};
enum class type : int { enum class type : int {
none = LUA_TNONE, none = LUA_TNONE,
lua_nil = LUA_TNIL, lua_nil = LUA_TNIL,
@ -9722,7 +9728,11 @@ namespace sol {
template <typename... Args> template <typename... Args>
std::size_t aligned_space_for(void* alignment = nullptr) { std::size_t aligned_space_for(void* alignment = nullptr) {
char* start = static_cast<char*>(alignment); // use temporary storage to prevent strict UB shenanigans
using union_type = std::aligned_union<1, Args...>;
using union_type_t = typename union_type::type;
char alignment_shim[(std::max)({ sizeof(Args)... }) + (std::max)({ alignof(Args)... })] {};
char* start = alignment == nullptr ? static_cast<char*>(alignment) : alignment_shim;
(void)detail::swallow { int {}, (align_one(std::alignment_of_v<Args>, sizeof(Args), alignment), int {})... }; (void)detail::swallow { int {}, (align_one(std::alignment_of_v<Args>, sizeof(Args), alignment), int {})... };
return static_cast<char*>(alignment) - start; return static_cast<char*>(alignment) - start;
} }
@ -17455,14 +17465,19 @@ namespace sol {
// beginning of sol/function_types_stateless.hpp // beginning of sol/function_types_stateless.hpp
namespace sol { namespace sol { namespace function_detail {
namespace function_detail {
template <typename Function, bool is_yielding> template <typename Function, bool is_yielding>
struct upvalue_free_function { struct upvalue_free_function {
using function_type = std::remove_pointer_t<std::decay_t<Function>>; using function_type = std::remove_pointer_t<std::decay_t<Function>>;
using traits_type = meta::bind_traits<function_type>; using traits_type = meta::bind_traits<function_type>;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L); auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
function_type* fx = udata.first; function_type* fx = udata.first;
return call_detail::call_wrapped<void, true, false>(L, fx); return call_detail::call_wrapped<void, true, false>(L, fx);
@ -17488,7 +17503,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member function pointer // idx 1...n: verbatim data of member function pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -17499,7 +17520,13 @@ namespace function_detail {
return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item); return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
} }
static int call(lua_State* L) noexcept(traits_type::is_noexcept) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -17519,7 +17546,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -17539,7 +17572,13 @@ namespace function_detail {
} }
} }
static int call(lua_State* L) noexcept(traits_type::is_noexcept) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -17559,7 +17598,13 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
// idx n + 1: is the object's void pointer // idx n + 1: is the object's void pointer
@ -17577,7 +17622,13 @@ namespace function_detail {
} }
} }
static int call(lua_State* L) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -17597,14 +17648,26 @@ namespace function_detail {
typedef std::remove_pointer_t<std::decay_t<Function>> function_type; typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) noexcept(traits_type::is_noexcept) { static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
// Layout: // Layout:
// idx 1...n: verbatim data of member variable pointer // idx 1...n: verbatim data of member variable pointer
function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2)); function_type& memfx = stack::get<user<function_type>>(L, upvalue_index(2));
return call_detail::call_wrapped<T, false, false>(L, memfx); return call_detail::call_wrapped<T, false, false>(L, memfx);
} }
static int call(lua_State* L) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
#endif
{
int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L); int nr = detail::typed_static_trampoline<decltype(&real_call), (&real_call)>(L);
if (is_yielding) { if (is_yielding) {
return lua_yield(L, nr); return lua_yield(L, nr);
@ -17685,8 +17748,7 @@ namespace function_detail {
return call(L); return call(L);
} }
}; };
} }} // namespace sol::function_detail
} // namespace sol::function_detail
// end of sol/function_types_stateless.hpp // end of sol/function_types_stateless.hpp
@ -25366,10 +25428,88 @@ namespace sol {
return s; return s;
} }
bool supports_gc_mode(gc_mode mode) const noexcept {
#if SOL_LUA_VERSION >= 504
// supports all modes
(void)mode;
return true;
#endif
return mode == gc_mode::default;
}
bool is_gc_on() const {
return lua_gc(lua_state(), LUA_GCISRUNNING, 0) == 1;
}
void collect_garbage() { void collect_garbage() {
lua_gc(lua_state(), LUA_GCCOLLECT, 0); lua_gc(lua_state(), LUA_GCCOLLECT, 0);
} }
void collect_gc() {
collect_garbage();
}
bool step_gc(int step_size_kilobytes) {
// THOUGHT: std::chrono-alikes to map "kilobyte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VERSION >= 504
// The manual implies that this function is almost always successful...
// is it?? It could depend on the GC mode...
return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) != 0;
#else
return lua_gc(lua_state(), LUA_GCSTEP, step_size_kilobytes) == 1;
#endif
}
void restart_gc() {
lua_gc(lua_state(), LUA_GCRESTART, 0);
}
void stop_gc() {
lua_gc(lua_state(), LUA_GCSTOP, 0);
}
// Returns the old GC mode. Check support using the supports_gc_mode function.
gc_mode change_gc_mode_incremental(int pause, int step_multiplier, int step_byte_size) {
// "What the fuck does any of this mean??"
// http://www.lua.org/manual/5.4/manual.html#2.5.1
// THOUGHT: std::chrono-alikes to map "byte size" here...?
// Make it harder to give MB or KB to a B parameter...?
// Probably overkill for now.
#if SOL_LUA_VERSION >= 504
int old_mode = lua_gc(lua_state(), LUA_GCINC, pause, step_multiplier, step_byte_size);
if (old_mode == LUA_GCGEN) {
return gc_mode::generational;
}
else if (old_mode == LUA_GCINC) {
return gc_mode::incremental;
}
#else
lua_gc(lua_state(), LUA_GCSETPAUSE, pause);
lua_gc(lua_state(), LUA_GCSETSTEPMUL, step_multiplier);
(void)step_byte_size; // means nothing in older versions
#endif
return gc_mode::default;
}
// Returns the old GC mode. Check support using the supports_gc_mode function.
gc_mode change_gc_mode_generational(int minor_multiplier, int major_multiplier) {
#if SOL_LUA_VERSION >= 504
// "What does this shit mean?"
// http://www.lua.org/manual/5.4/manual.html#2.5.2
int old_mode = lua_gc(lua_state(), LUA_GCGEN, minor_multiplier, major_multiplier);
if (old_mode == LUA_GCGEN) {
return gc_mode::generational;
}
else if (old_mode == LUA_GCINC) {
return gc_mode::incremental;
}
#endif
return gc_mode::default;
}
operator lua_State*() const { operator lua_State*() const {
return lua_state(); return lua_state();
} }
@ -26275,7 +26415,8 @@ namespace sol {
using base_t = std::vector<object, Al>; using base_t = std::vector<object, Al>;
public: public:
basic_variadic_results() : base_t() {} basic_variadic_results() : base_t() {
}
basic_variadic_results(unsafe_function_result fr) : base_t() { basic_variadic_results(unsafe_function_result fr) : base_t() {
this->reserve(fr.return_count()); this->reserve(fr.return_count());