🛠 Address lifetime issues through Lua references in iterators.

📝 Fixes #1315, #1374, and #1400.
— 📝 Lifetime in iterators was referencing the wrong stack (the main thread) rather than the coroutine's stack at time of creation.
— 📝 Using main_reference/main_* objects was a suitable enough fix for most of these problems.
— 🛠 Prevent performance and usability issues from changing containers by storing the being/end iterator separately, rather than continually invoking `deferred_uc::end(…)` every time.
— 🛠 Improve sizes for stored iterators in select cases.
— 🛠 Allow for sentinel-style C++20-and-beyond ranges.
— 🔧 Improve single file generation CMake.
— 👷‍♀️ Fix up internal Lua build system issues.
This commit is contained in:
ShepherdSoasis 2023-07-17 14:45:56 -04:00
parent eab1430ccd
commit e5e6932d72
No known key found for this signature in database
GPG Key ID: C92B2293E783EFEF
46 changed files with 702 additions and 137 deletions

View File

@ -60,7 +60,7 @@ ExternalProject_Add(KAGUYA_BUILD_SOURCE
add_library(${kaguya_lib} INTERFACE)
add_dependencies(${kaguya_lib} KAGUYA_BUILD_SOURCE)
target_include_directories(${kaguya_lib} INTERFACE ${kaguya_include_dirs})
target_link_libraries(${kaguya_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${kaguya_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${kaguya_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -59,7 +59,7 @@ ExternalProject_Add(LUABRIDGE_BUILD_SOURCE
add_library(${luabridge_lib} INTERFACE)
add_dependencies(${luabridge_lib} LUABRIDGE_BUILD_SOURCE)
target_include_directories(${luabridge_lib} INTERFACE ${luabridge_include_dirs})
target_link_libraries(${luabridge_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${luabridge_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${luabridge_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -88,7 +88,7 @@ function(find_lua_build LUA_VERSION)
endif()
# # Export variables to the parent scope
set(LUA_LIBRARIES ${LUA_LIBRARIES} PARENT_SCOPE)
set(LUA_LIBRARIES Lua::Lua PARENT_SCOPE)
set(LUA_INTERPRETER ${LUA_INTERPRETER} PARENT_SCOPE)
set(LUA_INCLUDE_DIRS ${LUA_INCLUDE_DIRS} PARENT_SCOPE)
set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)

View File

@ -108,7 +108,7 @@ if (LUA_BUILD_LUA_COMPILER)
endif()
set(LUA_VANILLA_GENERATE_LUA_HPP true)
elseif (LUA_VANILLA_VERSION MATCHES "^5\\.2")
set(LUA_VANILLA_LIB_SOURCES lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c
set(LUA_VANILLA_LIB_SOURCES lapi.c lbitlib.c lcode.c lctype.c ldebug.c ldo.c ldump.c
lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c
lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c
lauxlib.c lbaselib.c lcorolib.c ldblib.c liolib.c
@ -217,6 +217,7 @@ set(luacompiler "luac-${LUA_VANILLA_VERSION}")
# make an actual, buildable target
# that other parts of the code can depend on
add_library(${liblua} ${LUA_BUILD_LIBRARY_TYPE} ${LUA_VANILLA_LIB_SOURCES})
add_library(Lua::Lua ALIAS ${liblua})
set_target_properties(${liblua}
PROPERTIES
LANGUAGE ${LUA_VANILLA_LANGUAGE}
@ -233,7 +234,9 @@ set_source_files_properties(${LUA_VANILLA_LIB_SOURCES}
target_include_directories(${liblua}
PUBLIC "${LUA_VANILLA_INCLUDE_DIRS}")
target_compile_definitions(${liblua}
PUBLIC LUA_COMPAT_ALL ${LUA_VANILLA_DLL_DEFINE})
PUBLIC
LUA_COMPAT_ALL
${LUA_VANILLA_DLL_DEFINE})
if (MSVC)
target_compile_options(${liblua}
PRIVATE /W1)

View File

@ -59,7 +59,7 @@ ExternalProject_Add(LUWRA_BUILD_SOURCE
add_library(${luwra_lib} INTERFACE)
add_dependencies(${luwra_lib} LUWRA_BUILD_SOURCE)
target_include_directories(${luwra_lib} INTERFACE ${luwra_include_dirs})
target_link_libraries(${luwra_lib} INTERFACE ${LUA_LIBRARIES})
target_link_libraries(${luwra_lib} INTERFACE Lua::Lua)
if (NOT MSVC)
target_compile_options(${luwra_lib} INTERFACE
-Wno-noexcept-type -Wno-ignored-qualifiers -Wno-unused-parameter)

View File

@ -65,7 +65,7 @@ set_target_properties(${toluapp_lib} PROPERTIES
POSITION_INDEPENDENT_CODE TRUE)
target_include_directories(${toluapp_lib}
PUBLIC ${toluapp_include_dirs})
target_link_libraries(${toluapp_lib} PRIVATE ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
target_link_libraries(${toluapp_lib} PRIVATE Lua::Lua ${CMAKE_DL_LIBS})
if (MSVC)
target_compile_options(${toluapp_lib}
PRIVATE /W1)

View File

@ -24,7 +24,7 @@
function(sol2_add_example_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
PUBLIC Threads::Threads Lua::Lua ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}

View File

@ -50,7 +50,7 @@ function (MAKE_CUSTOMIZATION_EXAMPLE example_suffix target_sol)
endif()
target_link_libraries(${customization_example_name}
PRIVATE Threads::Threads ${target_sol} ${LUA_LIBRARIES})
PRIVATE Threads::Threads ${target_sol} Lua::Lua)
target_include_directories(${customization_example_name}
PRIVATE include)
endfunction()

View File

@ -30,7 +30,7 @@ function (make_luabridge_interop_example target_library example_suffix)
add_executable(${example_name} source/LuaBridge.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${LUABRIDGE_LIBRARIES}
PRIVATE Lua::Lua ${LUABRIDGE_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -30,7 +30,7 @@ function (make_kaguya_interop_example target_library example_suffix)
add_executable(${example_name} source/kaguya.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${KAGUYA_LIBRARIES}
PRIVATE Lua::Lua ${KAGUYA_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -30,7 +30,7 @@ function (make_luwra_interop_example target_library example_suffix)
add_executable(${example_name} source/luwra.cpp)
target_link_libraries(${example_name}
PRIVATE ${LUA_LIBRARIES} ${LUWRA_LIBRARIES}
PRIVATE Lua::Lua ${LUWRA_LIBRARIES}
${target_library} ${CMAKE_DL_LIBS})
if (MSVC)

View File

@ -31,7 +31,7 @@ function(make_tolua_interop_example target_library example_suffix)
add_executable(${example_name} source/tolua.cpp)
target_link_libraries(${example_name}
PRIVATE
${LUA_LIBRARIES} ${TOLUAPP_LIBRARIES} ${target_library} ${CMAKE_DL_LIBS})
Lua::Lua ${TOLUAPP_LIBRARIES} ${target_library} ${CMAKE_DL_LIBS})
if (MSVC)
target_compile_options(${example_name}

View File

@ -46,7 +46,7 @@ function(make_require_from_dll_example target_lib example_lib_name_suffix)
PUBLIC MY_OBJECT_DLL
PRIVATE MY_OBJECT_BUILD)
target_link_libraries(${example_lib_name}
PUBLIC ${target_lib} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS})
PUBLIC ${target_lib} Lua::Lua ${CMAKE_DL_LIBS})
target_include_directories(${example_lib_name}
PUBLIC "${LUA_INCLUDE_DIRS}")
@ -83,7 +83,7 @@ function(make_require_from_dll_example target_lib example_lib_name_suffix)
# add executable target that represents require_from_dll program
add_executable(${example_name} ${require_from_dll_sources})
target_link_libraries(${example_name}
PRIVATE my_object ${LUA_LIBRARIES} ${target_lib} ${CMAKE_DL_LIBS})
PRIVATE my_object Lua::Lua ${target_lib} ${CMAKE_DL_LIBS})
target_include_directories(${example_name}
PRIVATE ${LUA_INCLUDE_DIRS})

47
include/sol/abort.hpp Normal file
View File

@ -0,0 +1,47 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_ABORT_HPP
#define SOL_ABORT_HPP
#include <sol/version.hpp>
#include <sol/base_traits.hpp>
#include <cstdlib>
// clang-format off
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_DEBUG_ABORT() \
if (true) { ::std::abort(); } \
static_assert(true, "")
#else
#define SOL_DEBUG_ABORT() ::std::abort()
#endif
#else
#define SOL_DEBUG_ABORT() static_assert(true, "")
#endif
// clang-format on
#endif // SOL_ABORT_HPP

View File

@ -62,6 +62,39 @@ namespace sol {
template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <typename _Default, typename _Void, template <typename...> typename _Op, typename... _Args>
class detector {
public:
using value_t = ::std::false_type;
using type = _Default;
};
template <typename _Default, template <typename...> typename _Op, typename... _Args>
class detector<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
public:
using value_t = ::std::true_type;
using type = _Op<_Args...>;
};
class nonesuch {
public:
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
nonesuch& operator=(nonesuch const&) = delete;
};
template <template <typename...> typename _Op, typename... _Args>
using detected_t = typename detector<nonesuch, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or = detector<_Default, void, _Op, _Args...>;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or_t = typename detector<_Default, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
constexpr inline bool detected_or_v = detector<_Default, void, _Op, _Args...>::value;
template <std::size_t I>
using index_value = std::integral_constant<std::size_t, I>;

View File

@ -34,7 +34,8 @@
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
#if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
// clang-format off
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
@ -42,10 +43,9 @@
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#endif
// clang-format on
#endif // SOL_COMPATIBILITY_HPP

View File

@ -28,7 +28,7 @@
// clang-format off
#if SOL_IS_ON(SOL_USE_CXX_LUA)
#if SOL_IS_ON(SOL_USING_CXX_LUA)
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
@ -54,7 +54,7 @@
#define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
#endif // luajit
#if SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#if SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#include <luajit.h>
#elif SOL_IS_ON(SOL_USE_LUAJIT)
extern "C" {
@ -146,9 +146,9 @@
#else
#if SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#elif SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUA)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
@ -192,7 +192,11 @@
#else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#if (SOL_LUA_VERSION_I_ == 502)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF

View File

@ -30,7 +30,7 @@
#include <type_traits>
#include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA) || SOL_IS_ON(SOL_USE_CXX_LUAJIT)
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
struct lua_State;
#else
extern "C" {
@ -253,7 +253,7 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \
template <> \
@ -261,6 +261,6 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#endif // SOL_FORWARD_HPP

View File

@ -0,0 +1,44 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_FORWARD_AS_HPP
#define SOL_FORWARD_AS_HPP
#include <sol/version.hpp>
#include <utility>
#include <type_traits>
namespace sol {
template <typename T, typename U>
constexpr decltype(auto) forward_as(U&& value) noexcept {
if constexpr (::std::is_lvalue_reference_v<T>) {
return value;
}
else {
return ::std::move(value);
}
}
}
#endif // SOL_FORWARD_AS_HPP

View File

@ -32,6 +32,7 @@
#include <sol/overload.hpp>
#include <sol/error.hpp>
#include <sol/unicode.hpp>
#include <sol/abort.hpp>
#include <memory>
#include <functional>
@ -212,11 +213,9 @@ namespace sol { namespace stack {
}
actual r {};
if constexpr (!derive<element>::value) {
#if SOL_IS_ON(SOL_DEBUG_BUILD)
// In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over
std::abort();
#endif
SOL_DEBUG_ABORT();
return static_cast<actual>(std::move(r));
}
else {
@ -249,11 +248,7 @@ namespace sol { namespace stack {
// uh oh..
break;
}
#if SOL_IS_ON(SOL_DEBUG_BUILD)
// In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over
std::abort();
#endif
SOL_DEBUG_ABORT();
return static_cast<actual>(r);
}
}

View File

@ -530,8 +530,20 @@ namespace sol { namespace meta {
template <typename T>
using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
template <typename T>
using detect_sentinel = typename T::sentinel;
} // namespace meta_detail
template <typename T, typename Fallback>
class sentinel_or {
public:
using type = detected_or_t<Fallback, meta_detail::detect_sentinel, T>;
};
template <typename T, typename Fallback>
using sentinel_or_t = typename sentinel_or<T, Fallback>::type;
template <typename T, typename U = T>
class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
@ -626,7 +638,8 @@ namespace sol { namespace meta {
constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
template <typename T>
using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char,
using is_string_literal_array = boolean<std::is_array_v<T>
&& any_same_v<std::remove_all_extents_t<T>, char,
#if SOL_IS_ON(SOL_CHAR8_T)
char8_t,
#endif
@ -661,9 +674,8 @@ namespace sol { namespace meta {
constexpr inline bool is_string_like_v = is_string_like<T>::value;
template <typename T, typename CharT = char>
using is_string_constructible = meta::boolean<
is_string_literal_array_of_v<T,
CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT> || is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
using is_string_constructible = meta::boolean<is_string_literal_array_of_v<T, CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT>
|| is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
template <typename T, typename CharT = char>
constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
@ -733,7 +745,6 @@ namespace sol { namespace meta {
struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
using type = typename std::iterator_traits<T>::iterator_category;
};
}} // namespace sol::meta
#endif // SOL_TRAITS_HPP

View File

@ -0,0 +1,37 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_UNREACHABLE_HPP
#define SOL_UNREACHABLE_HPP
#include <sol/version.hpp>
#if SOL_HAS_BUILTIN_I_(__builtin_unreachable)
#define SOL_UNREACHABLE() __builtin_unreachable();
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_UNREACHABLE() __assume(false);
#else
#define SOL_UNREACHABLE() __builtin_unreachable();
#endif
#endif

View File

@ -400,6 +400,7 @@ namespace sol {
public:
typedef lua_nil_t iterator;
typedef iterator sentinel;
typedef lua_nil_t value_type;
static int at(lua_State* L_) {
@ -472,7 +473,7 @@ namespace sol {
return lua_nil;
}
static iterator end(lua_State* L_, T&) {
static sentinel end(lua_State* L_, T&) {
luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle<T>().c_str());
return lua_nil;
}
@ -492,6 +493,7 @@ namespace sol {
using is_ordered = meta::is_ordered<T>;
using is_matched_lookup = meta::is_matched_lookup<T>;
using iterator = typename T::iterator;
using sentinel = meta::sentinel_or_t<T, iterator>;
using value_type = typename T::value_type;
typedef meta::conditional_t<is_matched_lookup::value, std::pair<value_type, value_type>,
meta::conditional_t<is_associative::value || is_lookup::value, value_type, std::pair<std::ptrdiff_t, value_type>>>
@ -511,16 +513,30 @@ namespace sol {
typedef meta::unqualified_t<decltype(get_key(is_associative(), std::declval<std::add_lvalue_reference_t<value_type>>()))> key_type;
typedef meta::all<std::is_integral<K>, meta::neg<meta::any<is_associative, is_lookup>>> is_linear_integral;
struct iter {
reference keep_alive;
T& source;
iterator it;
struct iter : detail::ebco<iterator, 0>, detail::ebco<sentinel, 1> {
using it_base = detail::ebco<iterator, 0>;
using sen_base = detail::ebco<sentinel, 1>;
main_reference keep_alive;
std::size_t index;
iter(lua_State* L_, int stack_index, T& source_, iterator it_) : keep_alive(sol::main_thread(L_, L_), stack_index), source(source_), it(std::move(it_)), index(0) {
iter(lua_State* L_, int stack_index_, iterator it_, sentinel sen_) noexcept
: it_base(std::move(it_)), sen_base(std::move(sen_)), keep_alive(L_, stack_index_), index(0) {
}
~iter() {
iterator& it() noexcept {
return it_base::value();
}
const iterator& it() const noexcept {
return it_base::value();
}
sentinel& sen() noexcept {
return sen_base::value();
}
const sentinel& sen() const noexcept {
return sen_base::value();
}
};
@ -1172,9 +1188,9 @@ namespace sol {
template <bool ip>
static int next_associative(std::true_type, lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
if (it == deferred_uc::end(L_, source)) {
auto& end = i.end;
if (it == end) {
return stack::push(L_, lua_nil);
}
int p;
@ -1193,10 +1209,10 @@ namespace sol {
template <bool>
static int next_associative(std::false_type, lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
auto& it = i.it();
auto& end = i.sen();
next_K k = stack::unqualified_get<next_K>(L_, 2);
if (it == deferred_uc::end(L_, source)) {
if (it == end) {
return stack::push(L_, lua_nil);
}
int p;
@ -1221,7 +1237,7 @@ namespace sol {
static int pairs_associative(std::true_type, lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter<ip>);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::begin(L_, src));
stack::push(L_, lua_nil);
return 3;
}
@ -1230,7 +1246,7 @@ namespace sol {
static int pairs_associative(std::false_type, lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter<ip>);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::end(L_, src));
stack::push(L_, 0);
return 3;
}
@ -1322,7 +1338,7 @@ namespace sol {
}
}
static iterator end(lua_State*, T& self) {
static sentinel end(lua_State*, T& self) {
if constexpr (meta::has_begin_end_v<T>) {
return self.end();
}
@ -1387,19 +1403,32 @@ namespace sol {
public:
typedef std::remove_extent_t<T> value_type;
typedef value_type* iterator;
typedef iterator sentinel;
private:
struct iter {
struct iter : detail::ebco<iterator, 0>, detail::ebco<sentinel, 1> {
using it_base = detail::ebco<iterator, 0>;
using sen_base = detail::ebco<sentinel, 1>;
reference keep_alive;
T& source;
iterator it;
iter(lua_State* L_, int stack_index, T& source, iterator it) noexcept
: keep_alive(sol::main_thread(L_, L_), stack_index), source(source), it(std::move(it)) {
iter(lua_State* L_, int stack_index_, iterator it_, sentinel sen_) noexcept
: it_base(std::move(it_)), sen_base(std::move(sen_)), keep_alive(sol::main_thread(L_, L_), stack_index_) {
}
~iter() {
iterator& it() noexcept {
return it_base::value();
}
const iterator& it() const noexcept {
return it_base::value();
}
sentinel& sen() noexcept {
return sen_base::value();
}
const sentinel& sen() const noexcept {
return sen_base::value();
}
};
@ -1440,10 +1469,10 @@ namespace sol {
static int next_iter(lua_State* L_) {
iter& i = stack::unqualified_get<user<iter>>(L_, 1);
auto& source = i.source;
auto& it = i.it;
auto& it = i.it();
auto& end = i.sen();
std::size_t k = stack::unqualified_get<std::size_t>(L_, 2);
if (it == deferred_uc::end(L_, source)) {
if (it == end) {
return 0;
}
int p;
@ -1525,7 +1554,7 @@ namespace sol {
static int pairs(lua_State* L_) {
auto& src = get_src(L_);
stack::push(L_, next_iter);
stack::push<user<iter>>(L_, L_, 1, src, deferred_uc::begin(L_, src));
stack::push<user<iter>>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::end(L_, src));
stack::push(L_, 0);
return 3;
}
@ -1546,7 +1575,7 @@ namespace sol {
return std::addressof(self[0]);
}
static iterator end(lua_State*, T& self) {
static sentinel end(lua_State*, T& self) {
return std::addressof(self[0]) + std::extent<T>::value;
}
};

View File

@ -89,6 +89,14 @@
#include <climits>
#endif
#if defined(SOL_HAS_BUILTIN)
#define SOL_HAS_BUILTIN_I_(...) SOL_HAS_BUILTIN(__VA_ARGS__)
#elif defined(__has_builtin)
#define SOL_HAS_BUILTIN_I_(...) __has_builtin(__VA_ARGS__)
#else
#define SOL_HAS_BUILTIN_I_(...) 0
#endif
#if defined(SOL_COMPILER_VCXX)
#if defined(SOL_COMPILER_VCXX != 0)
#define SOL_COMPILER_VCXX_I_ SOL_ON
@ -638,34 +646,35 @@
#if defined(SOL_USING_CXX_LUA)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#define SOL_USING_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#define SOL_USING_CXX_LUA_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUA)
// alternative spelling
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#define SOL_USING_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#define SOL_USING_CXX_LUA_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUA_I_ SOL_DEFAULT_OFF
#define SOL_USING_CXX_LUA_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_USING_CXX_LUAJIT)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#if (SOL_USING_CXX_LUAJIT != 0)
#define SOL_USING_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUAJIT)
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#if (SOL_USE_CXX_LUAJIT != 0)
#define SOL_USING_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
#define SOL_USING_CXX_LUAJIT_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_NO_LUA_HPP)
@ -674,7 +683,7 @@
#else
#define SOL_USE_LUA_HPP_I_ SOL_ON
#endif
#elif defined(SOL_USING_CXX_LUA)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
#define SOL_USE_LUA_HPP_I_ SOL_OFF
#elif defined(__has_include)
#if __has_include(<lua.hpp>)

View File

@ -34,10 +34,10 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/include/sol"
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/single.py" --input "${CMAKE_CURRENT_SOURCE_DIR}/../include" --output "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/single.py" "${sol2_generated_header_sources}"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp")
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/config.hpp")
add_custom_target(sol2_single_header_generator ALL
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/single.py"
"${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp"
"${CMAKE_CURRENT_BINARY_DIR}/include/sol/sol.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/forward.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/sol/config.hpp"
"${sol2_generated_header_sources}")
# # # sol3 generated single header library

View File

@ -107,10 +107,10 @@ intro = """// The MIT License (MIT)
"""
includes = set([])
standard_include = re.compile(r'#include <(.*?)>')
local_include = re.compile(r'#(\s*?)include "(.*?)"')
project_include = re.compile(r'#(\s*?)include <(sol/.*?)>')
project_config_include = re.compile(r'#(\s*?)include <sol/config.hpp>')
standard_include = re.compile(r'\s*#include <(.*?)>')
local_include = re.compile(r'\s*#(\s*?)include "(.*?)"')
project_include = re.compile(r'\s*#(\s*?)include <(sol/.*?)>')
project_config_include = re.compile(r'\s*#(\s*?)include <sol/config.hpp>')
pragma_once_cpp = re.compile(r'(\s*)#(\s*)pragma(\s+)once')
ifndef_cpp = re.compile(r'#ifndef SOL_.*?_HPP')
define_cpp = re.compile(r'#define SOL_.*?_HPP')
@ -223,9 +223,9 @@ def process_file(filename, out):
version = get_version()
revision = get_revision()
include_guard = 'SOL_SINGLE_INCLUDE_HPP'
forward_include_guard = 'SOL_SINGLE_INCLUDE_FORWARD_HPP'
config_include_guard = 'SOL_SINGLE_CONFIG_HPP'
include_guard = 'SOL_SINGLE_INCLUDE_SOL_HPP'
forward_include_guard = 'SOL_SINGLE_INCLUDE_SOL_FORWARD_HPP'
config_include_guard = 'SOL_SINGLE_SOL_CONFIG_HPP'
processed_files = [os.path.join(script_path, x) for x in ['sol/sol.hpp']]
forward_processed_files = [

View File

@ -24,15 +24,15 @@
# # Dependencies
FetchContent_Declare(
catch2
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG devel
)
FetchContent_MakeAvailable(catch2)
FetchContent_MakeAvailable(Catch2)
function(sol2_add_test_properties target-name)
target_link_libraries(${target-name}
PUBLIC Threads::Threads ${LUA_LIBRARIES} Catch2::Catch2 ${CMAKE_DL_LIBS})
PUBLIC Threads::Threads Lua::Lua Catch2::Catch2 ${CMAKE_DL_LIBS})
target_compile_definitions(${target-name}
PUBLIC SOL_PRINT_ERRORS=1)
target_compile_options(${target-name}
@ -84,6 +84,7 @@ endfunction()
add_subdirectory(inclusion)
add_subdirectory(container_exhaustive)
add_subdirectory(coroutines)
add_subdirectory(enum)
add_subdirectory(environment)
add_subdirectory(exceptions)

View File

@ -0,0 +1,40 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2022 Rapptz, ThePhD, and contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests - special configurations - unsafe function pointers
file(GLOB sources
LIST_DIRECTORIES FALSE
CONFIGURE_DEPENDS
source/*.cpp)
sol2_create_basic_test(sol2.tests.coroutines sol2::sol2 ${sources})
sol2_create_basic_test(sol2.tests.coroutines.SOL_ALL_SAFETIES_ON sol2::sol2 ${sources})
target_compile_definitions(sol2.tests.coroutines PRIVATE
SOL_GET_FUNCTION_POINTER_UNSAFE=1)
target_compile_definitions(sol2.tests.coroutines.SOL_ALL_SAFETIES_ON PRIVATE
SOL_ALL_SAFETIES_ON=1 SOL_GET_FUNCTION_POINTER_UNSAFE=1)
if (SOL2_TESTS_SINGLE)
sol2_create_basic_test(sol2.single.tests.coroutines sol2::sol2::single ${sources})
target_compile_definitions(sol2.single.tests.coroutines PRIVATE
SOL_GET_FUNCTION_POINTER_UNSAFE=1)
endif()

View File

@ -0,0 +1,185 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch_all.hpp>
#include <sol/sol.hpp>
#include <vector>
#include <memory>
#include <iterator>
inline namespace sol2_regression_test_coroutines_array_proxy_lifetime {
struct A {
public:
A(int value_) : value(value_) {
}
int value;
int getValue() {
return value;
}
std::vector<std::shared_ptr<A>> children;
};
struct ArrayProxy {
using value_type = std::weak_ptr<A>;
struct iterator {
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = std::weak_ptr<A>;
using pointer = std::weak_ptr<A>*; // or also value_type*
using reference = std::weak_ptr<A>&; // or also value_type&
const ArrayProxy& a;
size_t index;
iterator(const ArrayProxy& a_, size_t index_) : a(a_), index(index_) {
}
value_type operator*() const {
size_t size = a.mpParent.children.size();
if (index >= 0 && index < size) {
return a.mpParent.children[index];
}
return std::weak_ptr<A>();
}
// Operators : arithmetic
inline iterator& operator++() {
++index;
return *this;
}
inline iterator& operator--() {
--index;
return *this;
}
inline iterator& operator+=(const size_t& rhs) {
index += rhs;
return *this;
}
inline iterator& operator-=(const size_t& rhs) {
index -= rhs;
return *this;
}
// Operators : comparison
inline bool operator==(const iterator& rhs) {
return index == rhs.index;
}
inline bool operator!=(const iterator& rhs) {
return index != rhs.index;
}
inline bool operator>(const iterator& rhs) {
return index > rhs.index;
}
inline bool operator<(const iterator& rhs) {
return index < rhs.index;
}
inline bool operator>=(const iterator& rhs) {
return index >= rhs.index;
}
inline bool operator<=(const iterator& rhs) {
return index <= rhs.index;
}
};
ArrayProxy(const A& parent) : mpParent(parent) {
}
~ArrayProxy() {
}
auto begin() const {
return iterator(*this, 0);
}
auto end() const {
return iterator(*this, mpParent.children.size());
}
size_t size() const {
return mpParent.children.size();
}
const A& mpParent;
};
static ArrayProxy getChildren(const A& a) {
return ArrayProxy(a);
}
} // namespace sol2_regression_test_coroutines_array_proxy_lifetime
namespace sol {
template <typename T>
struct unique_usertype_traits<std::weak_ptr<T>> {
static T* get(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.lock().get();
}
static bool is_null(lua_State*, const std::weak_ptr<T>& ptr) noexcept {
return ptr.expired();
}
};
template <>
struct is_container<ArrayProxy> : std::true_type { };
} // namespace sol
TEST_CASE("test for issue #1400 - array proxy tests", "[sol2][regression][issue-1400]") {
sol::state lua;
lua.open_libraries(
sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::debug, sol::lib::string, sol::lib::math, sol::lib::bit32, sol::lib::coroutine);
const int outer = 10;
const int inner = 100;
A a(0);
for (int i = 0; i < outer; i++) {
auto child = std::make_shared<A>(i * outer);
for (int j = 0; j < inner; j++) {
auto child2 = std::make_shared<A>(i * outer + j);
child->children.push_back(child2);
}
a.children.push_back(child);
}
lua.new_usertype<A>("A", "value", sol::property(&A::getValue), "children", sol::property(&getChildren));
lua.globals()["A"] = &a;
const auto& code = R"(
print(A.value)
for i=1, 10 do
co = coroutine.create( function()
print("A")
for _, child in pairs(A.children) do
for _, child2 in pairs(child.children) do
print(child2.value)
end
end
end)
coroutine.resume(co)
end
)";
// call lua code directly
sol::optional<sol::error> result = lua.safe_script(code);
REQUIRE_FALSE(result.has_value());
}

View File

@ -0,0 +1,31 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CATCH_CONFIG_RUNNER
#include <catch2/catch_all.hpp>
int main(int argc, char* argv[]) {
int result = Catch::Session().run(argc, argv);
return result;
}

View File

@ -0,0 +1,96 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <catch2/catch_all.hpp>
#include <sol/sol.hpp>
inline namespace sol2_regression_test_coroutines_properties_lifetime {
struct A {
public:
A() {
}
sol::object index(sol::object key) {
if (mProperties.valid()) {
auto prop = mProperties[key];
return prop.get<sol::object>();
}
return sol::object();
}
void new_index(sol::object key, sol::object value, sol::this_main_state L) {
if (!mProperties.valid()) {
sol::state_view lua(L);
mProperties = lua.create_table();
}
if (mProperties.lua_state() != key.lua_state()) {
std::cout << "scream A" << std::endl;
}
if (mProperties.lua_state() != value.lua_state()) {
std::cout << "scream B" << std::endl;
}
if (mProperties.lua_state() != L.lua_state()) {
std::cout << "scream C" << std::endl;
}
mProperties[key] = value;
}
protected:
// ❗❗ Here ❗❗
sol::main_table mProperties;
};
} // namespace sol2_regression_test_coroutines_properties_lifetime
TEST_CASE("issue #1374 - coroutine lifetime tests (using main_* classes)", "[sol2][regression][issue-1374]") {
sol::state lua;
A a;
lua.open_libraries(
sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::debug, sol::lib::string, sol::lib::math, sol::lib::bit32, sol::lib::coroutine);
lua.new_usertype<A>("A", sol::meta_function::index, &A::index, sol::meta_function::new_index, &A::new_index);
lua["A"] = &a;
const auto& code = R"(
for i=1, 300 do
co = coroutine.create( function()
A.foo = 7
A.bar = {}
for j=1, 170 do
A.bar[j] = j
end
end)
coroutine.resume(co)
print(A.foo)
for _, value in pairs(A.bar) do
print(value)
end
end)";
// call lua code directly
sol::optional<sol::error> result = lua.safe_script(code);
REQUIRE_FALSE(result.has_value());
}

View File

@ -34,7 +34,7 @@ inline namespace sol2_regression_test_1000 {
};
} // namespace sol2_regression_test_1000
TEST_CASE("Test for Issue #1000 - readonly warning", "[sol2][regression][Issue-1000]") {
TEST_CASE("issue #1000 - readonly warning", "[sol2][regression][issue1000]") {
sol::state lua;
lua.create_named_table("t");

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1008 - as_function binding must trigger correctly", "[sol2][regression][Issue-1008]") {
TEST_CASE("issue #1008 - as_function binding must trigger correctly", "[sol2][regression][issue1008]") {
sol::state lua;
lua.create_named_table("t");

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1067 - as_function binding not triggering properly", "[sol2][regression][Issue-1067]") {
TEST_CASE("issue #1067 - as_function binding not triggering properly", "[sol2][regression][issue1067]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1072 - capture exception propagation", "[sol2][regression][Issue-1072]") {
TEST_CASE("issue #1072 - capture exception propagation", "[sol2][regression][issue1072]") {
auto lua = sol::state {};
// If you remove the capture, the problem goes away.
lua["foo"] = [&] { throw std::runtime_error(""); };

View File

@ -31,7 +31,7 @@ inline namespace sol2_regression_test_1087 {
};
} // namespace sol2_regression_test_1087
TEST_CASE("Test for Issue #1087 - readonly property error checking", "[sol2][regression][Issue-1087]") {
TEST_CASE("issue #1087 - readonly property error checking", "[sol2][regression][issue1087]") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<MyStruct>("MyStruct", "prop", sol::readonly_property(&MyStruct::prop));

View File

@ -28,7 +28,7 @@
#include <iostream>
#include <string>
TEST_CASE("Test for Issue #1095 - raw_get from global table should NOT fail at all", "[sol2][regression][Issue-1095]") {
TEST_CASE("issue #1095 - raw_get from global table should NOT fail at all", "[sol2][regression][issue1095]") {
const std::string magic_value = "test_value";
sol::state lua;

View File

@ -35,7 +35,7 @@ inline namespace sol2_regression_test_1096 {
}
} // namespace sol2_regression_test_1096
TEST_CASE("Test for Issue #1096 - checking different functions/lambdas/structures bind as intendedcorrectly", "[sol2][regression][Issue-1096]") {
TEST_CASE("issue #1096 - checking different functions/lambdas/structures bind as intendedcorrectly", "[sol2][regression][issue1096]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -40,7 +40,7 @@ inline namespace sol2_regression_test_1144 {
}
} // namespace sol2_regression_test_1144
TEST_CASE("Test for Issue #1144 -", "[sol2][regression][Issue-1144]") {
TEST_CASE("issue #1144 -", "[sol2][regression][issue1144]") {
sol::state state;
bind_class(state);
sol::protected_function_result pr = state.do_string("local a = MyClass();");

View File

@ -36,7 +36,7 @@ inline namespace sol2_regression_test_1149 {
};
} // namespace sol2_regression_test_1149
TEST_CASE("Test for Issue #1149 - static method should not be morphed to const and error internally", "[sol2][regression][Issue-1149]") {
TEST_CASE("issue #1149 - static method should not be morphed to const and error internally", "[sol2][regression][issue1149]") {
sol::state lua = {};
auto T = lua.new_usertype<Test>("Test");
// Does compile ok.

View File

@ -37,7 +37,7 @@ inline namespace sol2_regression_test_1192 {
};
} // namespace sol2_regression_test_1192
TEST_CASE("Test for Issue #1192 - alignment test should not fail for strangely-aligned / over-aligned objects", "[sol2][regression][Issue-1192]") {
TEST_CASE("issue #1192 - alignment test should not fail for strangely-aligned / over-aligned objects", "[sol2][regression][issue1192]") {
sol::state lua;
static_assert(sizeof(Test) == 8);

View File

@ -25,7 +25,7 @@
#include <sol/sol.hpp>
TEST_CASE("Test for Issue #1211 - default-constructed protected_function_result should destruct fine", "[sol2][regression][Issue-1211]") {
TEST_CASE("issue #1211 - default-constructed protected_function_result should destruct fine", "[sol2][regression][issue1211]") {
{
// Should destruct properly, without issue.
[[maybe_unused]] sol::protected_function_result let_die;

View File

@ -27,7 +27,7 @@
#include <string>
TEST_CASE("Test for Issue #1266 - add method in Lua 5.4 exposes freelist in table, unfortunately", "[sol2][regression][Issue-1266]") {
TEST_CASE("issue #1266 - add method in Lua 5.4 exposes freelist in table, unfortunately", "[sol2][regression][issue1266]") {
sol::state lua;
lua.open_libraries(sol::lib::base);

View File

@ -49,7 +49,7 @@ inline namespace sol2_regression_test_1315 {
} // namespace sol2_regression_test_1315
TEST_CASE("Test for Issue #1315 - memory keep-alive with iteration functions, using a pointer", "[sol2][regression][Issue-1315][pointer]") {
TEST_CASE("issue #1315 - memory keep-alive with iteration functions, using a pointer", "[sol2][regression][issue1315][pointer]") {
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::coroutine);

View File

@ -88,11 +88,11 @@ end
REQUIRE(r.valid());
}
{
auto r = lua.safe_script("c[Issue-c + 1] = 18", sol::script_pass_on_error);
auto r = lua.safe_script("c[issuec + 1] = 18", sol::script_pass_on_error);
REQUIRE(r.valid());
}
{
auto r = lua.safe_script("v3 = c[Issue-c]", sol::script_pass_on_error);
auto r = lua.safe_script("v3 = c[issuec]", sol::script_pass_on_error);
REQUIRE(r.valid());
}
auto backit = items.begin();

View File

@ -387,8 +387,8 @@ function f_fill(vec)
end
function f_append(vec)
print("#vec in lua: " .. #vec)
vec[Issue-vec] = -10456407
vec[Issue-vec + 1] = -54
vec[issuevec] = -10456407
vec[issuevec + 1] = -54
print("#vec in lua: " .. #vec)
end
)",