add all safety and feature test macros, and improve feature safety definitions and configuration defines

This commit is contained in:
ThePhD 2017-12-07 21:46:43 -05:00
parent ec020048fb
commit 399300fa6e
19 changed files with 182 additions and 119 deletions

View File

@ -287,4 +287,3 @@ matrix:
allow_failures:
- os: osx
osx_image: xcode8.3

View File

@ -59,9 +59,9 @@ author = 'ThePhD'
# built documents.
#
# The short X.Y version.
version = '2.18'
version = '2.19'
# The full version, including alpha/beta/rc tags.
release = '2.18.7'
release = '2.19.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -10,8 +10,65 @@ config
Note that you can obtain safety with regards to functions you bind by using the :doc:`protect<api/protect>` wrapper around function/variable bindings you set into Lua. Additionally, you can have basic boolean checks when using the API by just converting to a :doc:`sol::optional\<T><api/optional>` when necessary for getting things out of Lua and for function arguments.
.. _config-safety:
Safety Config
+++++++++++++
``SOL_SAFE_USERTYPE`` triggers the following change:
* If the userdata to a usertype function is nil, will trigger an error instead of letting things go through and letting the system segfault/crash
* Turned on by default with clang++, g++ and VC++ if a basic check for building in debug mode is detected (lack of ``_NDEBUG`` or similar compiler-specific checks)
``SOL_SAFE_REFERENCES`` triggers the following changes:
* Checks the Lua type to ensure it matches what you expect it to be upon using :doc:`sol::reference<api/reference>` derived types, such as ``sol::thread``, ``sol::function``, etc...
* Turned on by default with clang++, g++ and VC++ if a basic check for building in debug mode is detected (lack of ``_NDEBUG`` or similar compiler-specific checks)
``SOL_SAFE_FUNCTION_CALLS`` triggers the following changes:
* ``sol::stack::call`` and its variants will, if no templated boolean is specified, check all of the arguments for a function call
* All calls from Lua will have their arguments checked
* Turned on by default with clang++, g++ and VC++ if a basic check for building in debug mode is detected (lack of ``_NDEBUG`` or similar compiler-specific checks)
``SOL_SAFE_FUNCTION`` triggers the following change:
* All uses of ``sol::function`` and ``sol::stack_function`` will default to ``sol::protected_function`` and ``sol::stack_protected_function``, respectively, rather than ``sol::unsafe_function`` and ``sol::stack_unsafe_function``
* Will make any ``sol::state_view::script`` calls default to their safe variants if there is no supplied environment or error handler function
* **Not** turned on by default under any detectible compiler settings: *this MUST be turned on manually*
``SOL_SAFE_NUMERICS`` triggers the following changes:
* Numbers will also be checked to see if they fit within a ``lua_Number`` if there is no ``lua_Integer`` type available that can fit your signed or unsigned number
* You can opt-out of this behavior with ``SOL_NO_CHECK_NUMBER_PRECISION``
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_SAFE_GETTER`` triggers the following changes:
* ``sol::stack::get`` (used everywhere) defaults to using ``sol::stack::check_get`` and dereferencing the argument. It uses ``sol::type_panic`` as the handler if something goes wrong
* Affects nearly the entire library for safety (with some blind spots covered by the other definitions)
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_CHECK_ARGUMENTS`` triggers the following changes:
* If ``SOL_SAFE_USERTYPE``, ``SOL_SAFE_REFERENCES``, ``SOL_SAFE_FUNCTION``, ``SOL_SAFE_NUMERICS``, ``SOL_SAFE_GETTER``, and ``SOL_SAFE_FUNCTION_CALLS`` are not defined, they get defined and the effects described above kick in
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_NO_CHECK_NUMBER_PRECISION`` triggers the following changes:
* If ``SOL_SAFE_NUMERICS`` is defined, turns off number precision and integer precision fitting when pushing numbers into sol2
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_STRINGS_ARE_NUMBERS`` triggers the following changes:
* Allows automatic to-string conversions for numbers
- ``lua_tolstring`` conversions are not permitted on numbers through sol2 by default: only actual strings are allowed
- This is necessary to allow :doc:`sol::overload<api/overload>` to work properly
* ``sol::stack::get`` and ``sol::stack::check_get`` will allow anything that Lua thinks is number-worthy to be number-worthy
* This includes: integers, floating-point numbers, and strings
* This **does not** include: booleans, types with ``__tostring`` enabled, and everything else
* Overrides safety and always applies if it is turned on
* **Not** turned on by default under any settings: *this MUST be turned on manually*
.. _config-feature:
Feature Config
++++++++++++++
``SOL_USE_BOOST`` triggers the following change:
* Attempts to use ``boost::optional`` instead of sol's own ``optional``
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_ENABLE_INTEROP`` triggers the following change:
* Allows the use of ``extensible<T>`` to be used with ``userdata_checker`` and ``userdata_getter`` to retrieve non-sol usertypes
@ -20,42 +77,22 @@ Note that you can obtain safety with regards to functions you bind by using the
* May come with a slight performance penalty: only recommended for those stuck with non-sol libraries that still need to leverage some of sol's power
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_SAFE_USERTYPE`` triggers the following change:
* If the userdata to a usertype function is nil, will trigger an error instead of letting things go through and letting the system segfault/crash
* Turned on by default with clang++, g++ and VC++ if a basic check for building in debug mode is detected (lack of ``_NDEBUG`` or similar compiler-specific checks)
``SOL_SAFE_FUNCTION`` triggers the following change:
* All uses of ``sol::function`` and ``sol::stack_function`` will default to ``sol::protected_function`` and ``sol::stack_protected_function``, respectively, rather than ``sol::unsafe_function`` and ``sol::stack_unsafe_function``.
* Will make any ``sol::state_view::script`` calls default to their safe variants if there is no supplied environment or error handler function
* **Not** turned on by default under any detectible compiler settings: *this MUST be turned on manually*
``SOL_STRINGS_ARE_NUMBERS`` triggers the following changes:
* ``sol::stack::get`` and ``sol::stack::check_get`` will allow anything that Lua thinks is number-worthy to be number-worthy
* This includes: integers, numbers, and strings
* Does **not** include: booleans, types with ``__tostring`` enabled, and everything else
* Overrides ``SOL_CHECK_ARGUMENTS`` and always applies if it is turned on
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_NO_CHECK_NUMBER_PRECISION`` triggers the following changes:
* If ``SOL_CHECK_ARGUMENTS`` is defined, turns off number precision and integer precision fitting when pushing numbers into sol2
* **Not** turned on by default under any settings: *this MUST be turned on manually*
``SOL_CHECK_ARGUMENTS`` triggers the following changes:
* ``sol::stack::get`` (used everywhere) defaults to using ``sol::stack::check_get`` and dereferencing the argument. It uses ``sol::type_panic`` as the handler if something goes wrong
* ``lua_tolstring`` conversions are not permitted on numbers: through the API: only actual strings are allowed. This is necessary to allow :doc:`sol::overload<api/overload>` to work properly
* ``sol::stack::call`` and its variants will, if no templated boolean is specified, check all of the arguments for a function call
* If ``SOL_SAFE_USERTYPE`` is not defined, it gets defined to turn being on and the effects described above kick in
* Numbers will also be checked to see if they fit within a ``lua_Number`` if there is no ``lua_Integer`` type available that can fit your signed or unsigned number. You can opt-out of this behavior with ``SOL_NO_CHECK_NUMBER_PRECISION``
* **Not** turned on by default under any settings: *this MUST be turned on manually*
.. _config-memory:
Memory Config
+++++++++++++
``SOL_NO_MEMORY_ALIGNMENT`` triggers the following changes:
* Memory is no longer aligned and is instead directly sized and allocated
* If you need to access underlying userdata memory from sol, please see the :doc:`usertype memory documentation<api/usertype_memory>`
* **Not** turned on by default under any settings: *this MUST be turned on manually*
.. _config-linker:
Linker Config
+++++++++++++
``SOL_USING_CXX_LUA`` triggers the following changes:
* Lua includes are no longer wrapped in ``extern "C" {}`` blocks
* Turns on ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` automatically for you
@ -64,7 +101,8 @@ Note that you can obtain safety with regards to functions you bind by using the
``SOL_USING_CXX_LUA_JIT`` triggers the following changes:
* LuaJIT includes are no longer wrapped in ``extern "C" {}`` blocks
* Turns on ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` automatically for you
* Only use this if you know you've built your LuaJIT with the C++-specific invocations of your compiler (LuaJIT by default builds as C code)
* Only use this if you know you've built your LuaJIT with the C++-specific invocations of your compiler
* LuaJIT by default builds as C code, but includes hook to handle C++ code unwinding: this should almost never be necessary for regular builds
``SOL_EXCEPTIONS_ALWAYS_UNSAFE`` triggers the following changes:
* If any of the ``SOL_USING_CXX_*`` defines are in play, it **does NOT** automatically turn on ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` automatically
@ -84,6 +122,8 @@ Memory safety can be tricky. Lua is handled by a garbage-collected runtime, mean
The usertype memory layout for all Lua-instantiated userdata and for all objects pushed/set into the Lua Runtime is also described :doc:`here<api/usertype_memory>`. Things before or after that specified memory slot is implementation-defined and no assumptions are to be made about it.
Please be wary of alignment issues. sol2 **aligns memory** by default. If you need to access underlying userdata memory from sol, please see the :doc:`usertype memory documentation<api/usertype_memory>`
functions
---------

View File

@ -353,7 +353,7 @@ namespace sol {
}
};
template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, bool clean_stack = true, typename = void>
template <typename T, typename F, bool is_index, bool is_variable, bool checked = detail::default_safe_function_calls, int boost = 0, bool clean_stack = true, typename = void>
struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost, clean_stack> {};
template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack>
@ -715,12 +715,12 @@ namespace sol {
}
};
template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = stack::stack_detail::default_check_arguments, bool clean_stack = true, typename Fx, typename... Args>
template <typename T, bool is_index, bool is_variable, int boost = 0, bool checked = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... Args>
inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, checked, boost, clean_stack>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
}
template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = stack::stack_detail::default_check_arguments, bool clean_stack = true>
template <typename T, bool is_index, bool is_variable, typename F, int start = 1, bool checked = detail::default_safe_function_calls, bool clean_stack = true>
inline int call_user(lua_State* L) {
auto& fx = stack::get<user<F>>(L, upvalue_index(start));
return call_wrapped<T, is_index, is_variable, 0, checked, clean_stack>(L, fx);

View File

@ -89,7 +89,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(lua_State* L, T&& r)
: base_t(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_coroutine>(lua_state(), -1, handler);
@ -97,14 +97,14 @@ namespace sol {
}
basic_coroutine(lua_State* L, int index = -1)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_coroutine>(lua_state(), index, handler);
#endif // Safety
}
basic_coroutine(lua_State* L, ref_index index)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_coroutine>(lua_state(), -1, handler);

View File

@ -60,7 +60,7 @@ namespace sol {
basic_environment(env_t, const stack_reference& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<env_t>(this->lua_state(), -1, handler);
#endif // Safety
@ -69,7 +69,7 @@ namespace sol {
template <bool b>
basic_environment(env_t, const basic_reference<b>& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<env_t>(this->lua_state(), -1, handler);
#endif // Safety
@ -77,14 +77,14 @@ namespace sol {
}
basic_environment(lua_State* L, int index = -1)
: base_t(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_environment>(L, index, handler);
#endif // Safety
}
basic_environment(lua_State* L, ref_index index)
: base_t(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_environment>(L, -1, handler);
@ -93,7 +93,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(T&& r) noexcept
: base_t(detail::no_safety, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};
@ -104,7 +104,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(lua_State* L, T&& r) noexcept
: base_t(detail::no_safety, L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};

View File

@ -52,14 +52,8 @@
#ifdef _MSC_VER
#if defined(_DEBUG) && !defined(NDEBUG)
#if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction
#define SOL_SAFE_REFERENCES 1
#endif
#if !defined(SOL_SAFE_USERTYPE)
// Usertypes should be safe no matter what
#define SOL_SAFE_USERTYPE 1
#ifndef SOL_IN_DEBUG_DETECTED
#define SOL_IN_DEBUG_DETECTED 1
#endif
#endif // VC++ Debug macros
@ -79,15 +73,9 @@
#if !defined(NDEBUG) && !defined(__OPTIMIZE__)
#if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction
#define SOL_SAFE_REFERENCES 1
#endif
#if !defined(SOL_SAFE_USERTYPE)
// Usertypes should be safe no matter what
#define SOL_SAFE_USERTYPE 1
#endif
#ifndef SOL_IN_DEBUG_DETECTED
#define SOL_IN_DEBUG_DETECTED 1
#endif SOL_IN_DEBUG_DETECTED
#endif // Not Debug && g++ optimizer flag
@ -129,6 +117,12 @@
#define SOL_SAFE_REFERENCES 1
#endif
// Changes all typedefs of sol::function to point to the
// protected_function version, instead of unsafe_function
#if !defined(SOL_SAFE_FUNCTION)
#define SOL_SAFE_FUNCTION 1
#endif
// Checks function parameters and
// returns upon call into/from Lua
// local a = 1
@ -145,12 +139,49 @@
#define SOL_SAFE_PROXIES 1
#endif
// Check overflowing number conversions
// for things like 64 bit integers that don't fit in a typical lua_Number
// for Lua 5.1 and 5.2
#if !defined(SOL_SAFE_NUMERICS)
#define SOL_SAFE_NUMERICS 1
#endif
#endif // Turn on Safety for all if top-level macro is defined
#ifdef SOL_IN_DEBUG_DETECTED
#if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction
#define SOL_SAFE_REFERENCES 1
#endif
#if !defined(SOL_SAFE_USERTYPE)
// Usertypes should be safe no matter what
#define SOL_SAFE_USERTYPE 1
#endif
#if !defined(SOL_SAFE_FUNCTION_CALLS)
// Function calls from Lua should be automatically safe in debug mode
#define SOL_SAFE_FUNCTION_CALLS 1
#endif
#endif // Turn on all debug safety features for VC++ / g++ / clang++ and similar
#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
#ifndef SOL_NO_NIL
#if !defined(SOL_NO_NIL)
#define SOL_NO_NIL 1
#endif
#endif // avoiding nil defines / keywords
namespace sol {
namespace detail {
const bool default_safe_function_calls =
#ifdef SOL_SAFE_FUNCTION_CALLS
true;
#else
false;
#endif
}
} // namespace sol::detail
#endif // SOL_FEATURE_TEST_HPP

View File

@ -388,7 +388,7 @@ namespace sol {
template <typename T, typename... Lists>
struct pusher<detail::tagged<T, constructor_list<Lists...>>> {
static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
lua_CFunction cf = call_detail::construct<T, stack_detail::default_check_arguments, true, Lists...>;
lua_CFunction cf = call_detail::construct<T, detail::default_safe_function_calls, true, Lists...>;
return stack::push(L, cf);
}
};

View File

@ -46,9 +46,9 @@ namespace sol {
template <typename T>
decltype(auto) tagged_get(types<T>) const {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_PROXIES
if (!valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none, "");
type_panic_c_str(L, index, type_of(L, index), type::none);
}
#endif // Check Argument Safety
return stack::get<T>(L, index);
@ -62,9 +62,9 @@ namespace sol {
}
error tagged_get(types<error>) const {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_PROXIES
if (valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none);
type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
}
#endif // Check Argument Safety
return error(detail::direct_error, stack::get<std::string>(L, index));

View File

@ -203,7 +203,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept
: base_t(std::forward<T>(r)), error_handler(get_default_handler(r.lua_state())) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};
@ -260,7 +260,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L, T&& r, handler_t eh)
: base_t(L, std::forward<T>(r)), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -272,7 +272,7 @@ namespace sol {
}
basic_protected_function(lua_State* L, int index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
@ -282,7 +282,7 @@ namespace sol {
}
basic_protected_function(lua_State* L, absolute_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
@ -292,7 +292,7 @@ namespace sol {
}
basic_protected_function(lua_State* L, raw_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_protected_function>(L, index, handler);
#endif // Safety
@ -302,7 +302,7 @@ namespace sol {
}
basic_protected_function(lua_State* L, ref_index index, handler_t eh)
: base_t(L, index), error_handler(std::move(eh)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_protected_function>(lua_state(), -1, handler);

View File

@ -51,7 +51,7 @@ namespace sol {
template <typename T>
decltype(auto) tagged_get(types<T>, int index_offset) const {
int target = index + index_offset;
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_PROXIES
if (!valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
@ -70,7 +70,7 @@ namespace sol {
error tagged_get(types<error>, int index_offset) const {
int target = index + index_offset;
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_PROXIES
if (valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");

View File

@ -110,7 +110,7 @@ namespace sol {
}
};
template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
template <bool checkargs = detail::default_safe_function_calls , std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value >>
inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
#ifndef _MSC_VER
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
@ -121,7 +121,7 @@ namespace sol {
return evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
#ifndef _MSC_VER
static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
@ -139,41 +139,41 @@ namespace sol {
return luaL_ref(L, tableindex);
}
template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
typedef std::make_index_sequence<sizeof...(Args)> args_indices;
return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
template <bool check_args = detail::default_safe_function_calls, typename... Args, typename Fx, typename... FxArgs>
inline void call(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
typedef std::make_index_sequence<sizeof...(Args)> args_indices;
stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
template <bool check_args = detail::default_safe_function_calls, typename... Args, typename Fx, typename... FxArgs>
inline void call(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
typedef meta::count_for_pack<lua_size, Args...> expected_count;
return call<check_args>(tr, ta, L, (std::max)(static_cast<int>(lua_gettop(L) - expected_count::value), static_cast<int>(0)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
template <bool check_args = detail::default_safe_function_calls, typename... Args, typename Fx, typename... FxArgs>
inline void call_from_top(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
typedef meta::count_for_pack<lua_size, Args...> expected_count;
call<check_args>(tr, ta, L, (std::max)(static_cast<int>(lua_gettop(L) - expected_count::value), static_cast<int>(0)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename... Args, typename Fx, typename... FxArgs>
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename... Args, typename Fx, typename... FxArgs>
inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
if (clean_stack) {
@ -182,7 +182,7 @@ namespace sol {
return 0;
}
template <bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
typedef meta::unqualified_t<decltype(r)> R;
@ -197,7 +197,7 @@ namespace sol {
return push_reference(L, std::forward<decltype(r)>(r));
}
template <bool check_args = stack_detail::default_check_arguments, bool clean_stack = true, typename Fx, typename... FxArgs>
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
typedef typename traits_type::args_list args_list;

View File

@ -66,7 +66,7 @@ namespace stack {
int isnum = 0;
const lua_Number value = lua_tonumberx(L, index, &isnum);
if (isnum != 0) {
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
#if defined(SOL_SAFE_NUMERICS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
const auto integer_value = llround(value);
if (static_cast<lua_Number>(integer_value) == value) {
tracking.use(1);

View File

@ -522,13 +522,6 @@ namespace sol {
template <typename T>
using strip_extensible_t = typename strip_extensible<T>::type;
const bool default_check_arguments =
#ifdef SOL_CHECK_ARGUMENTS
true;
#else
false;
#endif
template <typename C>
static int get_size_hint(const C& c) {
return static_cast<int>(c.size());
@ -678,7 +671,7 @@ namespace sol {
namespace stack_detail {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_GETTER
template <typename T>
inline auto tagged_get(types<T>, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
auto op = check_get<T>(L, index, type_panic_c_str, tracking);

View File

@ -214,7 +214,7 @@ namespace stack {
return 1;
}
#endif
#if defined(SOL_CHECK_ARGUMENTS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
#if defined(SOL_SAFE_NUMERICS) && !defined(SOL_NO_CHECK_NUMBER_PRECISION)
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
#ifdef SOL_NO_EXCEPTIONS
// Is this really worth it?

View File

@ -213,7 +213,7 @@ namespace sol {
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(lua_State* L, T&& r)
: base_t(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_table_core>(lua_state(), -1, handler);
@ -227,14 +227,14 @@ namespace sol {
}
basic_table_core(lua_State* L, int index = -1)
: basic_table_core(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_table_core>(L, index, handler);
#endif // Safety
}
basic_table_core(lua_State* L, ref_index index)
: basic_table_core(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_table_core>(lua_state(), -1, handler);
@ -243,7 +243,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_type, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(T&& r) noexcept
: basic_table_core(detail::no_safety, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};

View File

@ -102,7 +102,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_thread(T&& r)
: base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_thread>(lua_state(), -1, handler);
@ -117,7 +117,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_thread(lua_State* L, T&& r)
: base_t(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_thread>(lua_state(), -1, handler);
@ -125,14 +125,14 @@ namespace sol {
}
basic_thread(lua_State* L, int index = -1)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_thread>(L, index, handler);
#endif // Safety
}
basic_thread(lua_State* L, ref_index index)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_thread>(lua_state(), -1, handler);
@ -146,7 +146,7 @@ namespace sol {
}
basic_thread(lua_State* L, lua_thread_state actualthread)
: base_t(L, -stack::push(L, actualthread)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_thread>(lua_state(), -1, handler);
#endif // Safety

View File

@ -69,7 +69,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_function(T&& r) noexcept
: base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler{};
@ -90,7 +90,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_function(lua_State* L, T&& r)
: base_t(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_function>(lua_state(), -1, handler);
@ -98,14 +98,14 @@ namespace sol {
}
basic_function(lua_State* L, int index = -1)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_function>(L, index, handler);
#endif // Safety
}
basic_function(lua_State* L, ref_index index)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_function>(lua_state(), -1, handler);

View File

@ -37,7 +37,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_userdata(T&& r) noexcept
: base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_userdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(lua_state(), -1, type::userdata);
@ -57,7 +57,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_userdata(lua_State* L, T&& r)
: base_t(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_userdata>(L, -1, handler);
@ -65,14 +65,14 @@ namespace sol {
}
basic_userdata(lua_State* L, int index = -1)
: base_t(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_userdata>(L, index, handler);
#endif // Safety
}
basic_userdata(lua_State* L, ref_index index)
: base_t(detail::no_safety, L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_userdata>(L, -1, handler);
@ -91,7 +91,7 @@ namespace sol {
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lightuserdata(T&& r) noexcept
: base_t(std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
if (!is_lightuserdata<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
type_assert(lua_state(), -1, type::lightuserdata);
@ -111,7 +111,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lightuserdata(lua_State* L, T&& r)
: basic_lightuserdata(L, std::forward<T>(r)) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_lightuserdata>(lua_state(), -1, handler);
@ -119,14 +119,14 @@ namespace sol {
}
basic_lightuserdata(lua_State* L, int index = -1)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
constructor_handler handler{};
stack::check<basic_lightuserdata>(L, index, handler);
#endif // Safety
}
basic_lightuserdata(lua_State* L, ref_index index)
: base_t(L, index) {
#ifdef SOL_CHECK_ARGUMENTS
#ifdef SOL_SAFE_REFERENCES
auto pp = stack::push_pop(*this);
constructor_handler handler{};
stack::check<basic_lightuserdata>(lua_state(), index, handler);