Move lua_error out of catch handler to defer longjmp.
[luabind.git] / luabind / make_function.hpp
bloba1ac8716bbfd1edb8deeb8293ddb340a3817d49f
1 // Copyright Daniel Wallin 2008. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef LUABIND_MAKE_FUNCTION_081014_HPP
6 # define LUABIND_MAKE_FUNCTION_081014_HPP
8 # include <luabind/config.hpp>
9 # include <luabind/object.hpp>
10 # include <luabind/detail/call.hpp>
11 # include <luabind/detail/compute_score.hpp>
12 # include <luabind/detail/deduce_signature.hpp>
13 # include <luabind/detail/format_signature.hpp>
15 namespace luabind {
17 namespace detail
19 # ifndef LUABIND_NO_EXCEPTIONS
20 LUABIND_API void handle_exception_aux(lua_State* L);
21 # endif
23 // MSVC complains about member being sensitive to alignment (C4121)
24 // when F is a pointer to member of a class with virtual bases.
25 # ifdef BOOST_MSVC
26 # pragma pack(push)
27 # pragma pack(16)
28 # endif
30 template <class F, class Signature, class Policies>
31 struct function_object_impl : function_object
33 function_object_impl(F f, Policies const& policies)
34 : function_object(&entry_point)
35 , f(f)
36 , policies(policies)
39 int call(lua_State* L, invoke_context& ctx) const
41 return invoke(L, *this, ctx, f, Signature(), policies);
44 void format_signature(lua_State* L, char const* function) const
46 detail::format_signature(L, function, Signature());
49 static int entry_point(lua_State* L)
51 function_object_impl const* impl =
52 *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1));
54 invoke_context ctx;
56 int results = 0;
58 # ifndef LUABIND_NO_EXCEPTIONS
59 bool exception_caught = false;
61 try
63 results = invoke(
64 L, *impl, ctx, impl->f, Signature(), impl->policies);
66 catch (...)
68 exception_caught = true;
69 handle_exception_aux(L);
72 if (exception_caught)
73 lua_error(L);
74 # else
75 results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies);
76 # endif
78 if (!ctx)
80 ctx.format_error(L, impl);
81 lua_error(L);
84 return results;
87 F f;
88 Policies policies;
91 # ifdef BOOST_MSVC
92 # pragma pack(pop)
93 # endif
95 LUABIND_API object make_function_aux(
96 lua_State* L, function_object* impl
99 LUABIND_API void add_overload(object const&, char const*, object const&);
101 } // namespace detail
103 template <class F, class Signature, class Policies>
104 object make_function(lua_State* L, F f, Signature, Policies)
106 return detail::make_function_aux(
108 , new detail::function_object_impl<F, Signature, Policies>(
109 f, Policies()
114 template <class F>
115 object make_function(lua_State* L, F f)
117 return make_function(L, detail::deduce_signature(f), detail::null_type());
120 } // namespace luabind
122 #endif // LUABIND_MAKE_FUNCTION_081014_HPP