diff --git a/sol/coroutine.hpp b/sol/coroutine.hpp index 535194ac..635192b2 100644 --- a/sol/coroutine.hpp +++ b/sol/coroutine.hpp @@ -67,7 +67,11 @@ private: } public: - coroutine(lua_State* L, int index = -1) noexcept : reference(L, index) {} + coroutine(lua_State* L, int index = -1) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::function); +#endif // Safety + } coroutine() noexcept = default; coroutine(const coroutine&) noexcept = default; coroutine& operator=(const coroutine&) noexcept = default; diff --git a/sol/function.hpp b/sol/function.hpp index 2e67fb8e..5bf3789d 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -65,7 +65,16 @@ private: } public: - using reference::reference; + function() = default; + function(const function&) = default; + function& operator=(const function&) = default; + function( function&& ) = default; + function& operator=( function&& ) = default; + function(lua_State* L, int index = -1): reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::function); +#endif // Safety + } template function_result operator()( Args&&... args ) const { diff --git a/sol/protected_function.hpp b/sol/protected_function.hpp index 009f7910..83e4ce59 100644 --- a/sol/protected_function.hpp +++ b/sol/protected_function.hpp @@ -130,13 +130,15 @@ public: reference error_handler; protected_function() = default; - protected_function(lua_State* L, int index = -1): reference(L, index), error_handler(get_default_handler()) { - type_assert(L, index, type::function); - } protected_function(const protected_function&) = default; protected_function& operator=(const protected_function&) = default; protected_function( protected_function&& ) = default; protected_function& operator=( protected_function&& ) = default; + protected_function(lua_State* L, int index = -1): reference(L, index), error_handler(get_default_handler()) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::function); +#endif // Safety + } template protected_function_result operator()(Args&&... args) const { diff --git a/sol/stack_get.hpp b/sol/stack_get.hpp index 5b5abd38..cf4207de 100644 --- a/sol/stack_get.hpp +++ b/sol/stack_get.hpp @@ -143,8 +143,20 @@ struct getter { template<> struct getter { - static c_closure get(lua_State* L, int index = -1) { - return c_closure(lua_tocfunction(L, index), -1); + static c_closure get(lua_State* L, int index = -1) { + return c_closure(lua_tocfunction(L, index), -1); + } +}; + +template<> +struct getter { + static error get(lua_State* L, int index = -1) { + size_t sz = 0; + const char* err = lua_tolstring(L, index, &sz); + if (err == nullptr) { + return error(detail::direct_error, ""); + } + return error(detail::direct_error, std::string(err, sz)); } }; diff --git a/sol/stack_guard.hpp b/sol/stack_guard.hpp new file mode 100644 index 00000000..ebfe50f3 --- /dev/null +++ b/sol/stack_guard.hpp @@ -0,0 +1,59 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2016 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_STACK_GUARD_HPP +#define SOL_STACK_GUARD_HPP + +#include "compatibility/version.hpp" +#include "error.hpp" +#include + +namespace sol { +namespace detail { +inline void stack_fail(int, int) { +#ifndef SOL_NO_EXCEPTIONS + throw error(detail::direct_error, "imbalanced stack after operation finish"); +#else + // Lol, what do you want, an error printout? :3c + // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so + // hopefully someone will register their own stack_fail thing here +#endif // No Exceptions +} +} // detail + +struct stack_guard { + lua_State* L; + int top; + std::function fx; + + stack_guard(lua_State* L) : stack_guard(L, lua_gettop(L)) {} + stack_guard(lua_State* L, int top, std::function fx = detail::stack_fail) : L(L), top(top), fx(std::move(fx)) {} + ~stack_guard() { + int bottom = lua_gettop(L); + if (top == bottom) { + return; + } + fx(top, bottom); + } +}; +} // sol + +#endif // SOL_STACK_GUARD_HPP diff --git a/sol/table_core.hpp b/sol/table_core.hpp index 09e769f9..6ea76f1f 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -152,7 +152,9 @@ public: table_core( ) noexcept : reference( ) { } table_core( const table_core& global ) noexcept : reference( global ) { } table_core( lua_State* L, int index = -1 ) : reference( L, index ) { +#ifdef SOL_CHECK_ARGUMENTS type_assert( L, index, type::table ); +#endif // Safety } table_iterator begin () const { diff --git a/sol/thread.hpp b/sol/thread.hpp index 9d5a44ff..97e465e4 100644 --- a/sol/thread.hpp +++ b/sol/thread.hpp @@ -28,7 +28,16 @@ namespace sol { class thread : public reference { public: - using reference::reference; + thread () noexcept = default; + thread(const thread&) = default; + thread(thread&&) = default; + thread& operator=(const thread&) = default; + thread& operator=(thread&&) = default; + thread(lua_State* L, int index = -1) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::thread); +#endif // Safety + } state_view state() const { return state_view(this->thread_state()); diff --git a/sol/types.hpp b/sol/types.hpp index 72a9545e..e218e469 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -213,7 +213,7 @@ class coroutine; class thread; class object; class userdata; -class light_userdata; +class lightuserdata; template struct lua_type_of : std::integral_constant {}; @@ -264,7 +264,7 @@ template <> struct lua_type_of : std::integral_constant {}; template <> -struct lua_type_of : std::integral_constant {}; +struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; diff --git a/sol/userdata.hpp b/sol/userdata.hpp index 578c09a1..23003b27 100644 --- a/sol/userdata.hpp +++ b/sol/userdata.hpp @@ -27,12 +27,30 @@ namespace sol { class userdata : public reference { public: - using reference::reference; + userdata () noexcept = default; + userdata(const userdata&) = default; + userdata(userdata&&) = default; + userdata& operator=(const userdata&) = default; + userdata& operator=(userdata&&) = default; + userdata(lua_State* L, int index = -1) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::userdata); +#endif // Safety + } }; -class light_userdata : public reference { +class lightuserdata : public reference { public: - using reference::reference; + lightuserdata () noexcept = default; + lightuserdata(const lightuserdata&) = default; + lightuserdata(lightuserdata&&) = default; + lightuserdata& operator=(const lightuserdata&) = default; + lightuserdata& operator=(lightuserdata&&) = default; + lightuserdata(lua_State* L, int index = -1) : reference(L, index) { +#ifdef SOL_CHECK_ARGUMENTS + type_assert(L, index, type::lightuserdata); +#endif // Safety + } }; } // sol