mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
This adds the additional safety features. stack_guard should probably be migrated into the tests too, since a lesser form is already used there.
Closes #54 #55
This commit is contained in:
parent
5efbae5798
commit
204bd5d5ed
|
@ -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;
|
||||
|
|
|
@ -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<typename... Args>
|
||||
function_result operator()( Args&&... args ) const {
|
||||
|
|
|
@ -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<typename... Args>
|
||||
protected_function_result operator()(Args&&... args) const {
|
||||
|
|
|
@ -148,6 +148,18 @@ struct getter<c_closure> {
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct getter<error> {
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct getter<void*> {
|
||||
static void* get(lua_State* L, int index = -1) {
|
||||
|
|
59
sol/stack_guard.hpp
Normal file
59
sol/stack_guard.hpp
Normal file
|
@ -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 <functional>
|
||||
|
||||
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<void(int, int)> fx;
|
||||
|
||||
stack_guard(lua_State* L) : stack_guard(L, lua_gettop(L)) {}
|
||||
stack_guard(lua_State* L, int top, std::function<void(int, int)> 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
|
|
@ -152,7 +152,9 @@ public:
|
|||
table_core( ) noexcept : reference( ) { }
|
||||
table_core( const table_core<true>& 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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -213,7 +213,7 @@ class coroutine;
|
|||
class thread;
|
||||
class object;
|
||||
class userdata;
|
||||
class light_userdata;
|
||||
class lightuserdata;
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct lua_type_of : std::integral_constant<type, type::userdata> {};
|
||||
|
@ -264,7 +264,7 @@ template <>
|
|||
struct lua_type_of<userdata_value> : std::integral_constant<type, type::userdata> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<light_userdata> : std::integral_constant<type, type::lightuserdata> {};
|
||||
struct lua_type_of<lightuserdata> : std::integral_constant<type, type::lightuserdata> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<userdata> : std::integral_constant<type, type::userdata> {};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user