diff --git a/docs/source/conf.py b/docs/source/conf.py index 44c7d9b5..88aef545 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -61,7 +61,7 @@ author = 'ThePhD' # The short X.Y version. version = '2.17' # The full version, including alpha/beta/rc tags. -release = '2.17.1' +release = '2.17.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 4c3ceea3..f3705d3f 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2017-05-07 14:16:38.081474 UTC -// This header was generated with sol v2.17.1 (revision 5bc5def) +// Generated 2017-05-09 17:26:55.402266 UTC +// This header was generated with sol v2.17.3 (revision 5800366) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -3619,6 +3619,7 @@ namespace sol { class thread; struct variadic_args; struct this_state; + struct this_environment; namespace detail { template @@ -3771,6 +3772,9 @@ namespace sol { template <> struct lua_type_of : std::integral_constant {}; + template <> + struct lua_type_of : std::integral_constant {}; + template <> struct lua_type_of : std::integral_constant {}; @@ -3887,6 +3891,9 @@ namespace sol { template <> struct is_transparent_argument : std::true_type {}; + template <> + struct is_transparent_argument : std::true_type {}; + template <> struct is_transparent_argument : std::true_type {}; @@ -5138,6 +5145,15 @@ namespace sol { } }; + template + struct checker { + template + static bool check(lua_State*, int, Handler&&, record& tracking) { + tracking.use(0); + return true; + } + }; + template struct checker { template @@ -7310,7 +7326,7 @@ namespace sol { } template - inline std::pair get_as_upvalues(lua_State* L, int index = 1) { + inline std::pair get_as_upvalues(lua_State* L, int index = 2) { const static std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*); typedef std::array data_t; data_t voiddata{ {} }; @@ -7936,9 +7952,9 @@ namespace sol { namespace sol { namespace function_detail { - template + template inline int call(lua_State* L) { - Fx& fx = stack::get>(L, upvalue_index(1)); + Fx& fx = stack::get>(L, upvalue_index(start)); return fx(L); } } // function_detail @@ -8636,9 +8652,9 @@ namespace sol { return lua_call_wrapper, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward(fx), std::forward(args)...); } - template + template inline int call_user(lua_State* L) { - auto& fx = stack::get>(L, upvalue_index(1)); + auto& fx = stack::get>(L, upvalue_index(start)); return call_wrapped(L, fx); } @@ -8810,7 +8826,7 @@ namespace sol { // idx n + 1: is the object's void pointer // We don't need to store the size, because the other side is templated // with the same member function pointer type - auto memberdata = stack::stack_detail::get_as_upvalues(L, 1); + auto memberdata = stack::stack_detail::get_as_upvalues(L); auto objdata = stack::stack_detail::get_as_upvalues(L, memberdata.second); function_type& memfx = memberdata.first; auto& item = *objdata.first; @@ -8837,7 +8853,7 @@ namespace sol { // idx n + 1: is the object's void pointer // We don't need to store the size, because the other side is templated // with the same member function pointer type - auto memberdata = stack::stack_detail::get_as_upvalues(L, 1); + auto memberdata = stack::stack_detail::get_as_upvalues(L); auto objdata = stack::stack_detail::get_as_upvalues(L, memberdata.second); auto& mem = *objdata.first; function_type& var = memberdata.first; @@ -8868,7 +8884,7 @@ namespace sol { static int real_call(lua_State* L) { // Layout: // idx 1...n: verbatim data of member variable pointer - auto memberdata = stack::stack_detail::get_as_upvalues(L, 1); + auto memberdata = stack::stack_detail::get_as_upvalues(L); function_type& memfx = memberdata.first; return call_detail::call_wrapped(L, memfx); } @@ -8890,7 +8906,7 @@ namespace sol { static int real_call(lua_State* L) { // Layout: // idx 1...n: verbatim data of member variable pointer - auto memberdata = stack::stack_detail::get_as_upvalues(L, 1); + auto memberdata = stack::stack_detail::get_as_upvalues(L); function_type& var = memberdata.first; switch (lua_gettop(L)) { case 1: @@ -9227,7 +9243,9 @@ namespace sol { auto userptr = detail::ptr(std::forward(obj), std::forward(args)...); lua_CFunction freefunc = &function_detail::upvalue_member_variable, meta::unqualified_t>::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr); upvalues += stack::push(L, lightuserdata_value(static_cast(userptr))); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9246,7 +9264,9 @@ namespace sol { template static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator) { lua_CFunction freefunc = &function_detail::upvalue_this_member_variable::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, fx); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, fx); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9254,7 +9274,9 @@ namespace sol { static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) { typedef typename meta::bind_traits>::object_type C; lua_CFunction freefunc = &function_detail::upvalue_this_member_variable::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, fx); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, fx); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9272,7 +9294,9 @@ namespace sol { auto userptr = detail::ptr(std::forward(obj), std::forward(args)...); lua_CFunction freefunc = &function_detail::upvalue_member_function, meta::unqualified_t>::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, memfxptr); upvalues += stack::push(L, lightuserdata_value(static_cast(userptr))); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9291,7 +9315,9 @@ namespace sol { template static void select_member_function(std::true_type, lua_State* L, Fx&& fx, function_detail::class_indicator) { lua_CFunction freefunc = &function_detail::upvalue_this_member_function::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, fx); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, fx); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9299,7 +9325,9 @@ namespace sol { static void select_member_function(std::true_type, lua_State* L, Fx&& fx) { typedef typename meta::bind_traits>::object_type C; lua_CFunction freefunc = &function_detail::upvalue_this_member_function::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, fx); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, fx); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9313,7 +9341,9 @@ namespace sol { std::decay_t target(std::forward(fx), std::forward(args)...); lua_CFunction freefunc = &function_detail::upvalue_free_function::call; - int upvalues = stack::stack_detail::push_as_upvalues(L, target); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::stack_detail::push_as_upvalues(L, target); stack::push(L, c_closure(freefunc, upvalues)); } @@ -9328,10 +9358,12 @@ namespace sol { template static void set_fx(lua_State* L, Args&&... args) { - lua_CFunction freefunc = function_detail::call>; + lua_CFunction freefunc = function_detail::call, 2>; - stack::push>(L, std::forward(args)...); - stack::push(L, c_closure(freefunc, 1)); + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, std::forward(args)...); + stack::push(L, c_closure(freefunc, upvalues)); } template @@ -9399,15 +9431,19 @@ namespace sol { template struct pusher> { static int push(lua_State* L, protect_t&& pw) { - lua_CFunction cf = call_detail::call_user>; - int closures = stack::push>>(L, std::move(pw.value)); - return stack::push(L, c_closure(cf, closures)); + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>>(L, std::move(pw.value)); + return stack::push(L, c_closure(cf, upvalues)); } static int push(lua_State* L, const protect_t& pw) { - lua_CFunction cf = call_detail::call_user>; - int closures = stack::push>>(L, pw.value); - return stack::push(L, c_closure(cf, closures)); + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>>(L, pw.value); + return stack::push(L, c_closure(cf, upvalues)); } }; @@ -9502,9 +9538,11 @@ namespace sol { struct pusher>> { template static int push(lua_State* L, C&& c) { - lua_CFunction cf = call_detail::call_user>; - int closures = stack::push>>(L, std::forward(c)); - return stack::push(L, c_closure(cf, closures)); + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>>(L, std::forward(c)); + return stack::push(L, c_closure(cf, upvalues)); } }; @@ -9519,9 +9557,11 @@ namespace sol { template struct pusher>> { static int push(lua_State* L, destructor_wrapper c) { - lua_CFunction cf = call_detail::call_user>; - int closures = stack::push>(L, std::move(c)); - return stack::push(L, c_closure(cf, closures)); + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, std::move(c)); + return stack::push(L, c_closure(cf, upvalues)); } }; @@ -13019,7 +13059,8 @@ namespace sol { #else // Use upvalues as explained in Lua 5.2 and beyond's manual this->push(); - if (lua_setupvalue(L, -2, 1) == nullptr) { + const char* name = lua_setupvalue(L, -2, 1); + if (name == nullptr) { this->pop(); } #endif @@ -13038,13 +13079,74 @@ namespace sol { return basic_environment(L, -1); } + struct this_environment { + optional env; + + this_environment() : env(nullopt) {} + this_environment(sol::environment e) : env(std::move(e)) {} + this_environment(const this_environment&) = default; + this_environment(this_environment&&) = default; + this_environment& operator=(const this_environment&) = default; + this_environment& operator=(this_environment&&) = default; + + explicit operator bool() const { + return static_cast(env); + } + + operator optional& () { + return env; + } + + operator const optional& () const { + return env; + } + + operator environment& () { + return env.value(); + } + + operator const environment& () const { + return env.value(); + } + }; + namespace stack { template <> struct getter { - static environment get(lua_State* L, int index = -1) { + static environment get(lua_State* L, int index, record& tracking) { + tracking.use(1); return get_environment(stack_reference(L, raw_index(index))); } }; + + template <> + struct getter { + static this_environment get(lua_State* L, int index, record& tracking) { + tracking.use(0); + lua_Debug info; + // Level 0 means current function (this C function, which may or may not be useful for us?) + // Level 1 means next call frame up the stack. (Can be nothing if function called directly from C++ with lua_p/call) + int pre_stack_size = lua_gettop(L); + if (lua_getstack(L, 1, &info) != 1) { + if (lua_getstack(L, 0, &info) != 1) { + lua_settop(L, pre_stack_size); + return this_environment(); + } + } + if (lua_getinfo(L, "f", &info) == 0) { + lua_settop(L, pre_stack_size); + return this_environment(); + } + + sol::stack_reference f(L, -1); + sol::environment env(sol::env_key, f); + if (!env.valid()) { + lua_settop(L, pre_stack_size); + return this_environment(); + } + return this_environment(std::move(env)); + } + }; } // stack } // sol