mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
make sure that stack_aligned_stack_handler_function behaves properly
This commit is contained in:
parent
c442c6c620
commit
8f88e104be
45
examples/source/stack_aligned_stack_handler_function.cpp
Normal file
45
examples/source/stack_aligned_stack_handler_function.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS 1
|
||||||
|
#include <sol/sol.hpp>
|
||||||
|
|
||||||
|
#include "assert.hpp"
|
||||||
|
|
||||||
|
int main(int, char* []) {
|
||||||
|
sol::state lua;
|
||||||
|
lua.script("function func (a, b) return (a + b) * 2 end");
|
||||||
|
|
||||||
|
sol::reference func_ref = lua["func"];
|
||||||
|
|
||||||
|
// maybe this is in a lua_CFunction you bind,
|
||||||
|
// or maybe you're trying to work with a pre-existing system
|
||||||
|
// maybe you've used a custom lua_load call, or you're working
|
||||||
|
// with state_view's load(lua_Reader, ...) call...
|
||||||
|
// here's a little bit of how you can work with the stack
|
||||||
|
lua_State* L = lua.lua_state();
|
||||||
|
|
||||||
|
// this is a handler:
|
||||||
|
// stack_aligned_stack_handler,
|
||||||
|
// as its type name explains so verbosely,
|
||||||
|
// expects the handler on the stack
|
||||||
|
sol::stack_reference traceback_handler(L, -sol::stack::push(L, sol::default_traceback_error_handler));
|
||||||
|
// then, you need the function
|
||||||
|
// to be on the stack
|
||||||
|
func_ref.push();
|
||||||
|
sol::stack_aligned_stack_handler_function func(L, -1, traceback_handler);
|
||||||
|
lua_pushinteger(L, 5); // argument 1, using plain API
|
||||||
|
lua_pushinteger(L, 6); // argument 2
|
||||||
|
|
||||||
|
// take 2 arguments from the top,
|
||||||
|
// and use "stack_aligned_function" to call
|
||||||
|
int result = func(sol::stack_count(2));
|
||||||
|
// function call pops function and arguments,
|
||||||
|
// leaves result on the stack for us
|
||||||
|
// but we must manually clean the traceback handler
|
||||||
|
// manually pop traceback handler
|
||||||
|
traceback_handler.pop();
|
||||||
|
|
||||||
|
// make sure everything is clean
|
||||||
|
c_assert(result == 22);
|
||||||
|
c_assert(lua.stack_top() == 0); // stack is empty/balanced
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -59,7 +59,7 @@ namespace sol {
|
||||||
using base_t = basic_object<ref_t>;
|
using base_t = basic_object<ref_t>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef is_stack_based<handler_t> is_stack_handler;
|
using is_stack_handler = is_stack_based<handler_t>;
|
||||||
|
|
||||||
static handler_t get_default_handler(lua_State* L) {
|
static handler_t get_default_handler(lua_State* L) {
|
||||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||||
|
@ -105,9 +105,9 @@ namespace sol {
|
||||||
try {
|
try {
|
||||||
#endif // Safe Exception Propagation
|
#endif // Safe Exception Propagation
|
||||||
#endif // No Exceptions
|
#endif // No Exceptions
|
||||||
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid())));
|
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler::value)));
|
||||||
code = luacall(n, LUA_MULTRET, h);
|
code = luacall(n, LUA_MULTRET, h);
|
||||||
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid());
|
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler::value);
|
||||||
returncount = poststacksize - (firstreturn - 1);
|
returncount = poststacksize - (firstreturn - 1);
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
#ifndef SOL_NO_EXCEPTIONS
|
||||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
||||||
|
@ -305,7 +305,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename... Ret, typename... Args>
|
template <typename... Ret, typename... Args>
|
||||||
decltype(auto) call(Args&&... args) const {
|
decltype(auto) call(Args&&... args) const {
|
||||||
if (!aligned) {
|
if constexpr (!aligned) {
|
||||||
// we do not expect the function to already be on the stack: push it
|
// we do not expect the function to already be on the stack: push it
|
||||||
if (error_handler.valid()) {
|
if (error_handler.valid()) {
|
||||||
detail::protected_handler<true, handler_t> h(error_handler);
|
detail::protected_handler<true, handler_t> h(error_handler);
|
||||||
|
@ -326,12 +326,12 @@ namespace sol {
|
||||||
// the handler will be pushed onto the stack manually,
|
// the handler will be pushed onto the stack manually,
|
||||||
// since it's not already on the stack this means we need to push our own
|
// since it's not already on the stack this means we need to push our own
|
||||||
// function on the stack too and swap things to be in-place
|
// function on the stack too and swap things to be in-place
|
||||||
if (!is_stack_handler::value) {
|
if constexpr (!is_stack_handler::value) {
|
||||||
// so, we need to remove the function at the top and then dump the handler out ourselves
|
// so, we need to remove the function at the top and then dump the handler out ourselves
|
||||||
base_t::push();
|
base_t::push();
|
||||||
}
|
}
|
||||||
detail::protected_handler<true, handler_t> h(error_handler);
|
detail::protected_handler<true, handler_t> h(error_handler);
|
||||||
if (!is_stack_handler::value) {
|
if constexpr (!is_stack_handler::value) {
|
||||||
lua_replace(lua_state(), -3);
|
lua_replace(lua_state(), -3);
|
||||||
h.stackindex = lua_absindex(lua_state(), -2);
|
h.stackindex = lua_absindex(lua_state(), -2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,10 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
~protected_handler() {
|
~protected_handler() {
|
||||||
if (!is_stack::value && stackindex != 0) {
|
if constexpr (!is_stack::value) {
|
||||||
lua_remove(target.lua_state(), stackindex);
|
if (stackindex != 0) {
|
||||||
|
lua_remove(target.lua_state(), stackindex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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-04-29 05:20:05.556326 UTC
|
// Generated 2019-04-29 09:16:12.925937 UTC
|
||||||
// This header was generated with sol v3.0.1-beta2 (revision 67231f7)
|
// This header was generated with sol v3.0.1-beta2 (revision c442c6c)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||||
|
|
|
@ -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-04-29 05:20:05.284047 UTC
|
// Generated 2019-04-29 09:16:12.648677 UTC
|
||||||
// This header was generated with sol v3.0.1-beta2 (revision 67231f7)
|
// This header was generated with sol v3.0.1-beta2 (revision c442c6c)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -18153,8 +18153,10 @@ namespace sol {
|
||||||
}
|
}
|
||||||
|
|
||||||
~protected_handler() {
|
~protected_handler() {
|
||||||
if (!is_stack::value && stackindex != 0) {
|
if constexpr (!is_stack::value) {
|
||||||
lua_remove(target.lua_state(), stackindex);
|
if (stackindex != 0) {
|
||||||
|
lua_remove(target.lua_state(), stackindex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18219,7 +18221,7 @@ namespace sol {
|
||||||
using base_t = basic_object<ref_t>;
|
using base_t = basic_object<ref_t>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef is_stack_based<handler_t> is_stack_handler;
|
using is_stack_handler = is_stack_based<handler_t>;
|
||||||
|
|
||||||
static handler_t get_default_handler(lua_State* L) {
|
static handler_t get_default_handler(lua_State* L) {
|
||||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||||
|
@ -18265,9 +18267,9 @@ namespace sol {
|
||||||
try {
|
try {
|
||||||
#endif // Safe Exception Propagation
|
#endif // Safe Exception Propagation
|
||||||
#endif // No Exceptions
|
#endif // No Exceptions
|
||||||
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid())));
|
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler::value)));
|
||||||
code = luacall(n, LUA_MULTRET, h);
|
code = luacall(n, LUA_MULTRET, h);
|
||||||
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid());
|
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler::value);
|
||||||
returncount = poststacksize - (firstreturn - 1);
|
returncount = poststacksize - (firstreturn - 1);
|
||||||
#ifndef SOL_NO_EXCEPTIONS
|
#ifndef SOL_NO_EXCEPTIONS
|
||||||
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
#if (!defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) || !SOL_NO_EXCEPTIONS_SAFE_PROPAGATION) || (defined(SOL_LUAJIT) && SOL_LUAJIT)
|
||||||
|
@ -18465,7 +18467,7 @@ namespace sol {
|
||||||
|
|
||||||
template <typename... Ret, typename... Args>
|
template <typename... Ret, typename... Args>
|
||||||
decltype(auto) call(Args&&... args) const {
|
decltype(auto) call(Args&&... args) const {
|
||||||
if (!aligned) {
|
if constexpr (!aligned) {
|
||||||
// we do not expect the function to already be on the stack: push it
|
// we do not expect the function to already be on the stack: push it
|
||||||
if (error_handler.valid()) {
|
if (error_handler.valid()) {
|
||||||
detail::protected_handler<true, handler_t> h(error_handler);
|
detail::protected_handler<true, handler_t> h(error_handler);
|
||||||
|
@ -18486,12 +18488,12 @@ namespace sol {
|
||||||
// the handler will be pushed onto the stack manually,
|
// the handler will be pushed onto the stack manually,
|
||||||
// since it's not already on the stack this means we need to push our own
|
// since it's not already on the stack this means we need to push our own
|
||||||
// function on the stack too and swap things to be in-place
|
// function on the stack too and swap things to be in-place
|
||||||
if (!is_stack_handler::value) {
|
if constexpr (!is_stack_handler::value) {
|
||||||
// so, we need to remove the function at the top and then dump the handler out ourselves
|
// so, we need to remove the function at the top and then dump the handler out ourselves
|
||||||
base_t::push();
|
base_t::push();
|
||||||
}
|
}
|
||||||
detail::protected_handler<true, handler_t> h(error_handler);
|
detail::protected_handler<true, handler_t> h(error_handler);
|
||||||
if (!is_stack_handler::value) {
|
if constexpr (!is_stack_handler::value) {
|
||||||
lua_replace(lua_state(), -3);
|
lua_replace(lua_state(), -3);
|
||||||
h.stackindex = lua_absindex(lua_state(), -2);
|
h.stackindex = lua_absindex(lua_state(), -2);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user