Break all the behaviors. _All_ of them.

This commit is contained in:
ThePhD 2019-11-29 13:08:41 -05:00
parent 21c030933f
commit 83a656ae61
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
15 changed files with 242 additions and 157 deletions

View File

@ -95,6 +95,9 @@ else()
set(IS_X64 TRUE) set(IS_X64 TRUE)
endif() endif()
if (PROJECT_SOURCE_DIR MATCHES ${CMAKE_SOURCE_DIR})
set(SOL2_IS_TOP_LEVEL TRUE)
endif()
# # # sol2 Source Groups # # # sol2 Source Groups
# # Sources everyone is going to need # # Sources everyone is going to need
@ -190,7 +193,7 @@ else()
endif() endif()
# # # Tests, Examples and other CI suites that come with sol2 # # # Tests, Examples and other CI suites that come with sol2
if (DO_TESTS OR DO_EXAMPLES) if (SOL2_IS_TOP_LEVEL)
# # # General project output locations # # # General project output locations
if (IS_X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4) if (IS_X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/lib") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x86/lib")
@ -217,6 +220,8 @@ if (DO_TESTS OR DO_EXAMPLES)
else() else()
string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REGEX REPLACE "/MT" "/MD" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
string(REGEX REPLACE "/MT" "/MD" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
endif() endif()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)

View File

@ -28,7 +28,7 @@ include(Common/Core)
if (Catch_FIND_VERSION) if (Catch_FIND_VERSION)
set(catch_version ${Catch_FIND_VERSION}) set(catch_version ${Catch_FIND_VERSION})
else() else()
set(catch_version 2.1.2) set(catch_version 2.11.0)
endif() endif()
set(catch_lib catch_lib_${catch_version}) set(catch_lib catch_lib_${catch_version})

View File

@ -185,7 +185,27 @@ if (MSVC)
"C:/Program Files/Microsoft Visual Studio/2017/Professional/VC" "C:/Program Files/Microsoft Visual Studio/2017/Professional/VC"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary/Build" "C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary" "C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC") "C:/Program Files/Microsoft Visual Studio/2017/Enterprise/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary"
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Community/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Professional/VC"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary"
"C:/Program Files/Microsoft Visual Studio/2019/Enterprise/VC")
if (VCVARS_ALL_BAT MATCHES "VCVARS_ALL_BAT-NOTFOUND") if (VCVARS_ALL_BAT MATCHES "VCVARS_ALL_BAT-NOTFOUND")
MESSAGE(FATAL_ERROR "Cannot find 'vcvarsall.bat' file or similar needed to build LuaJIT ${LUA_VERSION} on Windows") MESSAGE(FATAL_ERROR "Cannot find 'vcvarsall.bat' file or similar needed to build LuaJIT ${LUA_VERSION} on Windows")
endif() endif()
@ -195,6 +215,9 @@ if (MSVC)
set(LUA_JIT_MAKE_COMMAND "${VCVARS_ALL_BAT}" x64) set(LUA_JIT_MAKE_COMMAND "${VCVARS_ALL_BAT}" x64)
endif() endif()
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} && cd src && msvcbuild.bat) set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} && cd src && msvcbuild.bat)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} debug)
endif()
if (NOT BUILD_LUA_AS_DLL) if (NOT BUILD_LUA_AS_DLL)
set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} static) set(LUA_JIT_MAKE_COMMAND ${LUA_JIT_MAKE_COMMAND} static)
endif() endif()

View File

@ -78,10 +78,7 @@ function (MAKE_EXAMPLE example_source_file example_suffix target_sol)
if (MSVC) if (MSVC)
target_compile_options(${example_name} target_compile_options(${example_name}
PRIVATE /std:c++latest /EHsc "$<$<CONFIG:Debug>:/MDd>" PRIVATE /std:c++latest /EHsc)
"$<$<CONFIG:Release>:/MD>"
"$<$<CONFIG:RelWithDebInfo>:/MD>"
"$<$<CONFIG:MinSizeRel>:/MD>")
target_compile_definitions(${example_name} target_compile_definitions(${example_name}
PRIVATE UNICODE _UNICODE PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE ) _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE )

View File

@ -15,10 +15,7 @@ int main() {
lua_State* L = ts; lua_State* L = ts;
// references the object that called this function // references the object that called this function
// in constructors: // in constructors:
sol::stack_object selfobj(L, -1); sol::stack_object selfobj(L, 1);
// the -1 (NEGATIVE one) above
// means "off the top fo the stack"
// (-1 is the top, -2 is one below, etc...)
// definitely the same // definitely the same
thing& self = selfobj.as<thing>(); thing& self = selfobj.as<thing>();
@ -42,10 +39,7 @@ int main() {
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing", lua.new_usertype<thing>("thing", sol::constructors<thing(sol::this_state)>(), "func", &thing::func);
sol::constructors<thing(sol::this_state)>(),
"func", &thing::func
);
lua.script(R"( lua.script(R"(
obj = thing.new() obj = thing.new()

View File

@ -217,15 +217,17 @@ namespace sol {
start, start,
std::forward<Args>(args)...); std::forward<Args>(args)...);
} }
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) { if constexpr (!traits::runtime_variadics_t::value) {
return overload_match_arity(types<>(), if (traits::free_arity != fxarity) {
std::index_sequence<>(), return overload_match_arity(types<>(),
std::index_sequence<traits::free_arity, M...>(), std::index_sequence<>(),
std::forward<Match>(matchfx), std::index_sequence<traits::free_arity, M...>(),
L, std::forward<Match>(matchfx),
fxarity, L,
start, fxarity,
std::forward<Args>(args)...); start,
std::forward<Args>(args)...);
}
} }
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...); return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
} }
@ -315,6 +317,8 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>); stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf(); umf();
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax)); construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
userdataref.push(); userdataref.push();
@ -639,7 +643,9 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>); stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf(); umf();
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + static_cast<int>(syntax)); // put userdata at the first index
lua_insert(L, 1);
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
userdataref.push(); userdataref.push();
return 1; return 1;
@ -660,7 +666,9 @@ namespace sol {
umf(); umf();
auto& func = std::get<I>(f.functions); auto& func = std::get<I>(f.functions);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj)); // put userdata at the first index
lua_insert(L, 1);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
userdataref.push(); userdataref.push();
return 1; return 1;

View File

@ -52,6 +52,14 @@ namespace sol {
return result_code; return result_code;
} }
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) { inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0 #if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
return dump_panic_on_error(L, result_code, writer_function, userdata, strip); return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
@ -64,14 +72,6 @@ namespace sol {
#endif // no exceptions stuff #endif // no exceptions stuff
} }
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
} // namespace sol } // namespace sol
#endif // SOL_DUMP_HANDLER_HPP #endif // SOL_DUMP_HANDLER_HPP

View File

@ -1,4 +1,4 @@
// sol3 // sol3
// The MIT License (MIT) // The MIT License (MIT)
@ -46,10 +46,9 @@ namespace sol {
std::size_t len; std::size_t len;
template <typename... Args> template <typename... Args>
stack_dependencies(int stack_target, Args&&... args) stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
: target(stack_target), stack_indices(), len(sizeof...(Args)) {
std::size_t i = 0; std::size_t i = 0;
(void)detail::swallow{int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())...}; (void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
} }
int& operator[](std::size_t i) { int& operator[](std::size_t i) {
@ -73,8 +72,7 @@ namespace sol {
std::tuple<Policies...> policies; std::tuple<Policies...> policies;
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler> template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
policy_wrapper(Fx&& fx, Args&&... args) policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
: value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
} }
policy_wrapper(const policy_wrapper&) = default; policy_wrapper(const policy_wrapper&) = default;
@ -91,10 +89,10 @@ namespace sol {
namespace detail { namespace detail {
template <typename T> template <typename T>
using is_policy = meta::is_specialization_of<T, policy_wrapper>; using is_policy = meta::is_specialization_of<T, policy_wrapper>;
template <typename T> template <typename T>
inline constexpr bool is_policy_v = is_policy<T>::value; inline constexpr bool is_policy_v = is_policy<T>::value;
} } // namespace detail
} // namespace sol } // namespace sol
#endif // SOL_FILTERS_HPP #endif // SOL_FILTERS_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 2019-11-24 05:21:55.164513 UTC // Generated 2019-11-29 18:08:19.653548 UTC
// This header was generated with sol v3.0.3 (revision fd9e282) // This header was generated with sol v3.0.3 (revision 21c0309)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
@ -99,13 +99,13 @@
#endif // vc++ || clang++/g++ #endif // vc++ || clang++/g++
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS #if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS != 0
#if defined(SOL_ALL_SAFETIES_ON) #if defined(SOL_ALL_SAFETIES_ON)
#define SOL_ALL_SAFETIES_ON 1 #define SOL_ALL_SAFETIES_ON 1
#endif // turn all the safeties on #endif // turn all the safeties on
#endif // Compatibility define #endif // Compatibility Define for Safety
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON #if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON != 0
// Checks low-level getter function // Checks low-level getter function
// (and thusly, affects nearly entire framework) // (and thusly, affects nearly entire framework)
@ -174,7 +174,7 @@
#endif // Turn on Safety for all if top-level macro is defined #endif // Turn on Safety for all if top-level macro is defined
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED #if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED != 0
#if !defined(SOL_SAFE_REFERENCES) #if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction // Ensure that references are forcefully type-checked upon construction

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 2019-11-24 05:21:54.660860 UTC // Generated 2019-11-29 18:08:19.142496 UTC
// This header was generated with sol v3.0.3 (revision fd9e282) // This header was generated with sol v3.0.3 (revision 21c0309)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -125,13 +125,13 @@
#endif // vc++ || clang++/g++ #endif // vc++ || clang++/g++
#if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS #if defined(SOL_CHECK_ARGUMENTS) && SOL_CHECK_ARGUMENTS != 0
#if defined(SOL_ALL_SAFETIES_ON) #if defined(SOL_ALL_SAFETIES_ON)
#define SOL_ALL_SAFETIES_ON 1 #define SOL_ALL_SAFETIES_ON 1
#endif // turn all the safeties on #endif // turn all the safeties on
#endif // Compatibility define #endif // Compatibility Define for Safety
#if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON #if defined(SOL_ALL_SAFETIES_ON) && SOL_ALL_SAFETIES_ON != 0
// Checks low-level getter function // Checks low-level getter function
// (and thusly, affects nearly entire framework) // (and thusly, affects nearly entire framework)
@ -200,7 +200,7 @@
#endif // Turn on Safety for all if top-level macro is defined #endif // Turn on Safety for all if top-level macro is defined
#if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED #if defined(SOL_IN_DEBUG_DETECTED) && SOL_IN_DEBUG_DETECTED != 0
#if !defined(SOL_SAFE_REFERENCES) #if !defined(SOL_SAFE_REFERENCES)
// Ensure that references are forcefully type-checked upon construction // Ensure that references are forcefully type-checked upon construction
@ -6114,10 +6114,9 @@ namespace sol {
std::size_t len; std::size_t len;
template <typename... Args> template <typename... Args>
stack_dependencies(int stack_target, Args&&... args) stack_dependencies(int stack_target, Args&&... args) : target(stack_target), stack_indices(), len(sizeof...(Args)) {
: target(stack_target), stack_indices(), len(sizeof...(Args)) {
std::size_t i = 0; std::size_t i = 0;
(void)detail::swallow{int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())...}; (void)detail::swallow{ int(), (stack_indices[i++] = static_cast<int>(std::forward<Args>(args)), int())... };
} }
int& operator[](std::size_t i) { int& operator[](std::size_t i) {
@ -6141,8 +6140,7 @@ namespace sol {
std::tuple<Policies...> policies; std::tuple<Policies...> policies;
template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler> template <typename Fx, typename... Args, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Fx>, policy_wrapper>>> = meta::enabler>
policy_wrapper(Fx&& fx, Args&&... args) policy_wrapper(Fx&& fx, Args&&... args) : value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
: value(std::forward<Fx>(fx)), policies(std::forward<Args>(args)...) {
} }
policy_wrapper(const policy_wrapper&) = default; policy_wrapper(const policy_wrapper&) = default;
@ -6159,10 +6157,10 @@ namespace sol {
namespace detail { namespace detail {
template <typename T> template <typename T>
using is_policy = meta::is_specialization_of<T, policy_wrapper>; using is_policy = meta::is_specialization_of<T, policy_wrapper>;
template <typename T> template <typename T>
inline constexpr bool is_policy_v = is_policy<T>::value; inline constexpr bool is_policy_v = is_policy<T>::value;
} } // namespace detail
} // namespace sol } // namespace sol
// end of sol/policies.hpp // end of sol/policies.hpp
@ -16346,15 +16344,17 @@ namespace sol {
start, start,
std::forward<Args>(args)...); std::forward<Args>(args)...);
} }
if (!traits::runtime_variadics_t::value && traits::free_arity != fxarity) { if constexpr (!traits::runtime_variadics_t::value) {
return overload_match_arity(types<>(), if (traits::free_arity != fxarity) {
std::index_sequence<>(), return overload_match_arity(types<>(),
std::index_sequence<traits::free_arity, M...>(), std::index_sequence<>(),
std::forward<Match>(matchfx), std::index_sequence<traits::free_arity, M...>(),
L, std::forward<Match>(matchfx),
fxarity, L,
start, fxarity,
std::forward<Args>(args)...); start,
std::forward<Args>(args)...);
}
} }
return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...); return matchfx(types<Fx>(), meta::index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
} }
@ -16444,6 +16444,8 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>); stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf(); umf();
// put userdata at the first index
lua_insert(L, 1);
construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax)); construct_match<T, TypeLists...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, 1 + static_cast<int>(syntax));
userdataref.push(); userdataref.push();
@ -16768,7 +16770,9 @@ namespace sol {
stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>); stack::stack_detail::undefined_metatable umf(L, &meta[0], &stack::stack_detail::set_undefined_methods_on<T>);
umf(); umf();
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + static_cast<int>(syntax)); // put userdata at the first index
lua_insert(L, 1);
construct_match<T, Args...>(constructor_match<T, checked, clean_stack>(obj), L, argcount, boost + 1 + 1 + static_cast<int>(syntax));
userdataref.push(); userdataref.push();
return 1; return 1;
@ -16789,7 +16793,9 @@ namespace sol {
umf(); umf();
auto& func = std::get<I>(f.functions); auto& func = std::get<I>(f.functions);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj)); // put userdata at the first index
lua_insert(L, 1);
stack::call_into_lua<checked, clean_stack>(r, a, L, boost + 1 + start, func, detail::implicit_wrapper<T>(obj));
userdataref.push(); userdataref.push();
return 1; return 1;
@ -18375,6 +18381,14 @@ namespace sol {
return result_code; return result_code;
} }
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) { inline int dump_throw_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
#if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0 #if defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS != 0
return dump_panic_on_error(L, result_code, writer_function, userdata, strip); return dump_panic_on_error(L, result_code, writer_function, userdata, strip);
@ -18387,14 +18401,6 @@ namespace sol {
#endif // no exceptions stuff #endif // no exceptions stuff
} }
inline int dump_panic_on_error(lua_State* L, int result_code, lua_Writer writer_function, void* userdata, bool strip) {
(void)L;
(void)writer_function;
(void)userdata;
(void)strip;
return luaL_error(L, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
}
} // namespace sol } // namespace sol
// end of sol/dump_handler.hpp // end of sol/dump_handler.hpp

View File

@ -25,7 +25,7 @@
if (CMAKE_GENERATOR MATCHES "Visual Studio 14 2015") if (CMAKE_GENERATOR MATCHES "Visual Studio 14 2015")
find_package(Catch 1.12.1 REQUIRED) find_package(Catch 1.12.1 REQUIRED)
else() else()
find_package(Catch 2.1.2 REQUIRED) find_package(Catch REQUIRED)
endif() endif()
file(GLOB SOL2_RUNTIME_TEST_SOURCES source/*.cpp) file(GLOB SOL2_RUNTIME_TEST_SOURCES source/*.cpp)
@ -70,10 +70,7 @@ function(CREATE_TEST test_target_name test_name target_sol)
endif() endif()
if (MSVC) if (MSVC)
target_compile_options(${test_target_name} target_compile_options(${test_target_name}
PRIVATE /EHsc /std:c++latest "$<$<CONFIG:Debug>:/MDd>" PRIVATE /EHsc /std:c++latest)
"$<$<CONFIG:Release>:/MD>"
"$<$<CONFIG:RelWithDebInfo>:/MD>"
"$<$<CONFIG:MinSizeRel>:/MD>")
target_compile_definitions(${test_target_name} target_compile_definitions(${test_target_name}
PRIVATE UNICODE _UNICODE PRIVATE UNICODE _UNICODE
_CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE) _CRT_SECURE_NO_WARNINGS _CRT_SECURE_NO_DEPRECATE)

View File

@ -69,33 +69,34 @@ TEST_CASE("plain/indestructible", "test that we error for types that are innatel
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
std::unique_ptr<indestructible, indestructible::insider> i std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
= sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
lua["i"] = *i; lua["i"] = *i;
lua.safe_script("i = nil"); lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error); auto result = lua.safe_script("collectgarbage() collectgarbage()", sol::script_pass_on_error);
#if SOL_LUA_VERSION > 503
REQUIRE(result.valid());
#else
REQUIRE_FALSE(result.valid()); REQUIRE_FALSE(result.valid());
#endif
} }
SECTION("saved") { SECTION("saved") {
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
std::unique_ptr<indestructible, indestructible::insider> i std::unique_ptr<indestructible, indestructible::insider> i = sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
= sol::detail::make_unique_deleter<indestructible, indestructible::insider>();
lua["i"] = *i; lua["i"] = *i;
lua.new_usertype<indestructible>("indestructible", sol::default_constructor, lua.new_usertype<indestructible>(
sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) { "indestructible", sol::default_constructor, sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) {
indestructible::insider del; indestructible::insider del;
del(&i); del(&i);
})); }));
lua.safe_script("i = nil"); lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error); auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
REQUIRE(result.valid()); REQUIRE(result.valid());
} }
} }
TEST_CASE("plain/constructors and destructors", TEST_CASE("plain/constructors and destructors", "Make sure that constructors, destructors, deallocators and others work properly with the desired type") {
"Make sure that constructors, destructors, deallocators and others work properly with the desired type") {
static int constructed = 0; static int constructed = 0;
static int destructed = 0; static int destructed = 0;
static int copied = 0; static int copied = 0;

View File

@ -1,4 +1,4 @@
// sol3 // sol3
// The MIT License (MIT) // The MIT License (MIT)
@ -52,10 +52,7 @@ TEST_CASE("policies/self", "ensure we return a direct reference to the lua userd
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
lua.new_usertype<vec2>("vec2", lua.new_usertype<vec2>("vec2", "x", &vec2::x, "y", &vec2::y, "normalize", sol::policies(&vec2::normalize, sol::returns_self()));
"x", &vec2::x,
"y", &vec2::y,
"normalize", sol::policies(&vec2::normalize, sol::returns_self()));
auto result1 = lua.safe_script(R"( auto result1 = lua.safe_script(R"(
v1 = vec2.new() v1 = vec2.new()
@ -68,7 +65,8 @@ assert(rawequal(v1, v2))
v1 = nil v1 = nil
collectgarbage() collectgarbage()
print(v2) -- v2 points to same, is not destroyed print(v2) -- v2 points to same, is not destroyed
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result1.valid()); REQUIRE(result1.valid());
} }
@ -82,7 +80,7 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
int value = 20; int value = 20;
~dep() { ~dep() {
std::cout << "\t" std::cout << "\t"
<< "[C++] ~dep" << std::endl; << "[C++] ~dep" << std::endl;
value = std::numeric_limits<int>::max(); value = std::numeric_limits<int>::max();
deps_destroyed.push_back(this); deps_destroyed.push_back(this);
} }
@ -94,7 +92,7 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
~gc_test() { ~gc_test() {
std::cout << "\t" std::cout << "\t"
<< "[C++] ~gc_test" << std::endl; << "[C++] ~gc_test" << std::endl;
gc_tests_destroyed.push_back(this); gc_tests_destroyed.push_back(this);
} }
}; };
@ -102,23 +100,18 @@ TEST_CASE("policies/self_dependency", "ensure we can keep a userdata instance al
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
lua.new_usertype<dep>("dep", lua.new_usertype<dep>("dep", "value", &dep::value, sol::meta_function::to_string, [](dep& d) { return "{ " + std::to_string(d.value) + " }"; });
"value", &dep::value, lua.new_usertype<gc_test>("gc_test", "d", sol::policies(&gc_test::d, sol::self_dependency()), sol::meta_function::to_string, [](gc_test& g) {
sol::meta_function::to_string, [](dep& d) { return "{ d: { " + std::to_string(g.d.value) + " } }";
return "{ " + std::to_string(d.value) + " }"; });
});
lua.new_usertype<gc_test>("gc_test",
"d", sol::policies(&gc_test::d, sol::self_dependency()),
sol::meta_function::to_string, [](gc_test& g) {
return "{ d: { " + std::to_string(g.d.value) + " } }";
});
auto result1 = lua.safe_script(R"( auto result1 = lua.safe_script(R"(
g = gc_test.new() g = gc_test.new()
d = g.d d = g.d
print("new gc_test, d = g.d") print("new gc_test, d = g.d")
print("", g) print("", g)
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result1.valid()); REQUIRE(result1.valid());
REQUIRE(deps_destroyed.empty()); REQUIRE(deps_destroyed.empty());
REQUIRE(gc_tests_destroyed.empty()); REQUIRE(gc_tests_destroyed.empty());
@ -131,7 +124,8 @@ print("g = nil, collectgarbage")
g = nil g = nil
collectgarbage() collectgarbage()
print("", d) print("", d)
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result2.valid()); REQUIRE(result2.valid());
REQUIRE(deps_destroyed.empty()); REQUIRE(deps_destroyed.empty());
@ -141,7 +135,8 @@ print("", d)
print("d = nil, collectgarbage") print("d = nil, collectgarbage")
d = nil d = nil
collectgarbage() collectgarbage()
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result3.valid()); REQUIRE(result3.valid());
REQUIRE(deps_destroyed.size() == 1); REQUIRE(deps_destroyed.size() == 1);
@ -182,8 +177,7 @@ TEST_CASE("policies/stack_dependencies", "ensure we can take dependencies even t
std::reference_wrapper<holder> href; std::reference_wrapper<holder> href;
composition_related comp; composition_related comp;
depends_on_reference(holder& h) depends_on_reference(holder& h) : href(h) {
: href(h) {
} }
~depends_on_reference() { ~depends_on_reference() {
@ -195,17 +189,19 @@ TEST_CASE("policies/stack_dependencies", "ensure we can take dependencies even t
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
lua.new_usertype<holder>("holder", lua.new_usertype<holder>("holder", "value", &holder::value);
"value", &holder::value);
lua.new_usertype<depends_on_reference>("depends_on_reference", lua.new_usertype<depends_on_reference>("depends_on_reference",
"new", sol::policies(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 1)), "new",
"comp", &depends_on_reference::comp); sol::policies(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 2)),
"comp",
&depends_on_reference::comp);
auto result1 = lua.safe_script(R"( auto result1 = lua.safe_script(R"(
h = holder.new() h = holder.new()
dor = depends_on_reference.new(h) dor = depends_on_reference.new(h)
c = dor.comp c = dor.comp
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result1.valid()); REQUIRE(result1.valid());
REQUIRE(composition_relateds_destroyed.empty()); REQUIRE(composition_relateds_destroyed.empty());
REQUIRE(holders_destroyed.empty()); REQUIRE(holders_destroyed.empty());
@ -230,7 +226,8 @@ collectgarbage()
auto result3 = lua.safe_script(R"( auto result3 = lua.safe_script(R"(
c = nil c = nil
collectgarbage() collectgarbage()
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result3.valid()); REQUIRE(result3.valid());
REQUIRE(composition_relateds_destroyed.empty()); REQUIRE(composition_relateds_destroyed.empty());
@ -240,7 +237,8 @@ collectgarbage()
auto result4 = lua.safe_script(R"( auto result4 = lua.safe_script(R"(
dor = nil dor = nil
collectgarbage() collectgarbage()
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result4.valid()); REQUIRE(result4.valid());
REQUIRE(composition_relateds_destroyed.size() == 1); REQUIRE(composition_relateds_destroyed.size() == 1);

View File

@ -226,7 +226,7 @@ TEST_CASE("inheritance/bad_base-class", "check to make sure bad/unregistered bas
struct a { struct a {
a(sol::this_state ts, sol::this_environment) { a(sol::this_state ts, sol::this_environment) {
lua_State* L = ts; lua_State* L = ts;
ud = sol::userdata(L, -2); ud = sol::userdata(L, 1);
} }

View File

@ -1,4 +1,4 @@
// sol3 // sol3
// The MIT License (MIT) // The MIT License (MIT)
@ -30,6 +30,46 @@
#include <functional> #include <functional>
#include <string> #include <string>
struct self_cons_0 {
self_cons_0(sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_0* pself = sol::stack::get<self_cons_0*>(L);
REQUIRE(pself == this);
REQUIRE(args.size() == 0);
}
};
struct self_cons_1 {
self_cons_1(sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_1* pself = sol::stack::get<self_cons_1*>(L, 1);
REQUIRE(pself == this);
REQUIRE(args.size() == 1);
}
};
struct self_cons_2 {
static void init_self_cons_2(self_cons_2& mem, sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_2* pself = sol::stack::get<self_cons_2*>(L, 1);
std::allocator<self_cons_2> alloc{};
std::allocator_traits<std::allocator<self_cons_2>>::construct(alloc, &mem);
REQUIRE(pself == &mem);
REQUIRE(args.size() == 2);
}
};
struct self_cons_3 {
static void init_self_cons_3(self_cons_3* mem, sol::variadic_args args, sol::this_state thisL) {
lua_State* L = thisL;
self_cons_3* pself = sol::stack::get<self_cons_3*>(L, 1);
std::allocator<self_cons_3> alloc{};
std::allocator_traits<std::allocator<self_cons_3>>::construct(alloc, mem);
REQUIRE(pself == mem);
REQUIRE(args.size() == 3);
}
};
TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple arguments through a variadic") { TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple arguments through a variadic") {
struct structure { struct structure {
int x; int x;
@ -66,9 +106,7 @@ TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple argum
TEST_CASE("variadics/required with variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") { TEST_CASE("variadics/required with variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") {
sol::state lua; sol::state lua;
lua.set_function("v", lua.set_function("v", [](sol::this_state, sol::variadic_args, int, int) {});
[](sol::this_state, sol::variadic_args, int, int) {
});
{ {
auto result = lua.safe_script("v(20, 25, 30)", sol::script_pass_on_error); auto result = lua.safe_script("v(20, 25, 30)", sol::script_pass_on_error);
REQUIRE(result.valid()); REQUIRE(result.valid());
@ -88,11 +126,7 @@ TEST_CASE("variadics/variadic_args get type", "Make sure we can inspect types pr
sol::stack_guard luasg(lua); sol::stack_guard luasg(lua);
lua.set_function("f", [](sol::variadic_args va) { lua.set_function("f", [](sol::variadic_args va) {
sol::type types[] = { sol::type types[] = { sol::type::number, sol::type::string, sol::type::boolean };
sol::type::number,
sol::type::string,
sol::type::boolean
};
bool working = true; bool working = true;
auto b = va.begin(); auto b = va.begin();
for (std::size_t i = 0; i < va.size(); ++i, ++b) { for (std::size_t i = 0; i < va.size(); ++i, ++b) {
@ -145,14 +179,13 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
sol::state lua; sol::state lua;
sol::stack_guard luasg(lua); sol::stack_guard luasg(lua);
lua.set_function("f", [](sol::variadic_args args) { lua.set_function("f", [](sol::variadic_args args) { return sol::variadic_results(args.cbegin(), args.cend()); });
return sol::variadic_results(args.cbegin(), args.cend());
});
auto result1 = lua.safe_script(R"( auto result1 = lua.safe_script(R"(
v1, v2, v3 = f(1, 'bark', true) v1, v2, v3 = f(1, 'bark', true)
v4, v5 = f(25, 82) v4, v5 = f(25, 82)
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result1.valid()); REQUIRE(result1.valid());
int v1 = lua["v1"]; int v1 = lua["v1"];
@ -192,7 +225,8 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
auto result1 = lua.safe_script(R"( auto result1 = lua.safe_script(R"(
v1, v2, v3 = f(true) v1, v2, v3 = f(true)
v4, v5, v6, v7 = f(false) v4, v5, v6, v7 = f(false)
)", sol::script_pass_on_error); )",
sol::script_pass_on_error);
REQUIRE(result1.valid()); REQUIRE(result1.valid());
int v1 = lua["v1"]; int v1 = lua["v1"];
@ -221,20 +255,24 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
sol::state lua; sol::state lua;
lua.new_usertype<vec2x>("vec2x", lua.new_usertype<vec2x>("vec2x",
sol::call_constructor, sol::factories([]() { return vec2x{}; }, [](vec2x const& v) -> vec2x { return v; }, [](sol::variadic_args va) { sol::call_constructor,
vec2x res{}; sol::factories([]() { return vec2x{}; },
if (va.size() == 1) { [](vec2x const& v) -> vec2x { return v; },
res.x = va[0].get<float>(); [](sol::variadic_args va) {
res.y = va[0].get<float>(); vec2x res{};
} if (va.size() == 1) {
else if (va.size() == 2) { res.x = va[0].get<float>();
res.x = va[0].get<float>(); res.y = va[0].get<float>();
res.y = va[1].get<float>(); }
} else if (va.size() == 2) {
else { res.x = va[0].get<float>();
throw sol::error("invalid args"); res.y = va[1].get<float>();
} }
return res; })); else {
throw sol::error("invalid args");
}
return res;
}));
auto result1 = lua.safe_script("v0 = vec2x();", sol::script_pass_on_error); auto result1 = lua.safe_script("v0 = vec2x();", sol::script_pass_on_error);
auto result2 = lua.safe_script("v1 = vec2x(1);", sol::script_pass_on_error); auto result2 = lua.safe_script("v1 = vec2x(1);", sol::script_pass_on_error);
@ -244,7 +282,7 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
REQUIRE(result2.valid()); REQUIRE(result2.valid());
REQUIRE(result3.valid()); REQUIRE(result3.valid());
REQUIRE(result4.valid()); REQUIRE(result4.valid());
vec2x& v0 = lua["v0"]; vec2x& v0 = lua["v0"];
vec2x& v1 = lua["v1"]; vec2x& v1 = lua["v1"];
vec2x& v2 = lua["v2"]; vec2x& v2 = lua["v2"];
@ -259,3 +297,23 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
REQUIRE(v3.x == v2.x); REQUIRE(v3.x == v2.x);
REQUIRE(v3.y == v2.y); REQUIRE(v3.y == v2.y);
} }
TEST_CASE("variadics/self_test", "test argument count and self object reference") {
sol::state lua;
lua.open_libraries();
lua.new_usertype<self_cons_0>("foo0", sol::constructors<self_cons_0(sol::variadic_args, sol::this_state)>());
lua.new_usertype<self_cons_1>("foo1", sol::constructors<self_cons_1(sol::variadic_args, sol::this_state)>());
lua.new_usertype<self_cons_2>("foo2", "new", sol::initializers(&self_cons_2::init_self_cons_2));
lua.new_usertype<self_cons_3>("foo3", "new", sol::initializers(&self_cons_3::init_self_cons_3));
sol::optional<sol::error> maybe_err = lua.safe_script(R"(
local obj0 = foo0.new()
local obj1 = foo1.new(0)
local obj2 = foo2.new(0, 1)
local obj3 = foo3.new(0, 1, 2)
)",
sol::script_pass_on_error);
REQUIRE_FALSE(maybe_err.has_value());
}