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>;
|
||||
|
||||
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) {
|
||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||
|
@ -105,9 +105,9 @@ namespace sol {
|
|||
try {
|
||||
#endif // Safe Exception Propagation
|
||||
#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);
|
||||
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);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
#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>
|
||||
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
|
||||
if (error_handler.valid()) {
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
|
@ -326,12 +326,12 @@ namespace sol {
|
|||
// 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
|
||||
// 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
|
||||
base_t::push();
|
||||
}
|
||||
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);
|
||||
h.stackindex = lua_absindex(lua_state(), -2);
|
||||
}
|
||||
|
|
|
@ -67,10 +67,12 @@ namespace sol {
|
|||
}
|
||||
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
if constexpr (!is_stack::value) {
|
||||
if (stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename base_t, typename T>
|
||||
|
|
|
@ -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 2019-04-29 05:20:05.556326 UTC
|
||||
// This header was generated with sol v3.0.1-beta2 (revision 67231f7)
|
||||
// Generated 2019-04-29 09:16:12.925937 UTC
|
||||
// This header was generated with sol v3.0.1-beta2 (revision c442c6c)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_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 2019-04-29 05:20:05.284047 UTC
|
||||
// This header was generated with sol v3.0.1-beta2 (revision 67231f7)
|
||||
// Generated 2019-04-29 09:16:12.648677 UTC
|
||||
// This header was generated with sol v3.0.1-beta2 (revision c442c6c)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -18153,10 +18153,12 @@ namespace sol {
|
|||
}
|
||||
|
||||
~protected_handler() {
|
||||
if (!is_stack::value && stackindex != 0) {
|
||||
if constexpr (!is_stack::value) {
|
||||
if (stackindex != 0) {
|
||||
lua_remove(target.lua_state(), stackindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename base_t, typename T>
|
||||
|
@ -18219,7 +18221,7 @@ namespace sol {
|
|||
using base_t = basic_object<ref_t>;
|
||||
|
||||
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) {
|
||||
return detail::get_default_handler<handler_t, is_main_threaded<base_t>::value>(L);
|
||||
|
@ -18265,9 +18267,9 @@ namespace sol {
|
|||
try {
|
||||
#endif // Safe Exception Propagation
|
||||
#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);
|
||||
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);
|
||||
#ifndef SOL_NO_EXCEPTIONS
|
||||
#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>
|
||||
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
|
||||
if (error_handler.valid()) {
|
||||
detail::protected_handler<true, handler_t> h(error_handler);
|
||||
|
@ -18486,12 +18488,12 @@ namespace sol {
|
|||
// 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
|
||||
// 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
|
||||
base_t::push();
|
||||
}
|
||||
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);
|
||||
h.stackindex = lua_absindex(lua_state(), -2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user