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 #define LUABIND_BUILDING
7 #include <luabind/make_function.hpp>
9 namespace luabind
{ namespace detail
{
14 int function_destroy(lua_State
* L
)
16 function_object
* fn
= *(function_object
**)lua_touserdata(L
, 1);
21 void push_function_metatable(lua_State
* L
)
23 lua_pushstring(L
, "luabind.function");
24 lua_rawget(L
, LUA_REGISTRYINDEX
);
26 if (lua_istable(L
, -1))
33 lua_pushstring(L
, "__gc");
34 lua_pushcclosure(L
, &function_destroy
, 0);
37 lua_pushstring(L
, "luabind.function");
39 lua_rawset(L
, LUA_REGISTRYINDEX
);
42 // A pointer to this is used as a tag value to identify functions exported
46 } // namespace unnamed
48 LUABIND_API
bool is_luabind_function(lua_State
* L
, int index
)
50 if (!lua_getupvalue(L
, index
, 2))
52 bool result
= lua_touserdata(L
, -1) == &function_tag
;
60 inline bool is_luabind_function(object
const& obj
)
62 obj
.push(obj
.interpreter());
63 bool result
= detail::is_luabind_function(obj
.interpreter(), -1);
64 lua_pop(obj
.interpreter(), 1);
68 } // namespace unnamed
70 LUABIND_API
void add_overload(
71 object
const& context
, char const* name
, object
const& fn
)
73 function_object
* f
= *touserdata
<function_object
*>(getupvalue(fn
, 1));
76 if (object overloads
= context
[name
])
78 if (is_luabind_function(overloads
) && is_luabind_function(fn
))
80 f
->next
= *touserdata
<function_object
*>(getupvalue(overloads
, 1));
81 f
->keepalive
= overloads
;
88 LUABIND_API object
make_function_aux(lua_State
* L
, function_object
* impl
)
90 void* storage
= lua_newuserdata(L
, sizeof(function_object
*));
91 push_function_metatable(L
);
92 *(function_object
**)storage
= impl
;
93 lua_setmetatable(L
, -2);
95 lua_pushlightuserdata(L
, &function_tag
);
96 lua_pushcclosure(L
, impl
->entry
, 2);
99 return object(from_stack(L
, -1));
102 void invoke_context::format_error(
103 lua_State
* L
, function_object
const* overloads
) const
105 char const* function_name
=
106 overloads
->name
.empty() ? "<unknown>" : overloads
->name
.c_str();
108 if (candidate_index
== 0)
110 lua_pushstring(L
, "No matching overload found, candidates:\n");
112 for (function_object
const* f
= overloads
; f
!= 0; f
= f
->next
)
115 lua_pushstring(L
, "\n");
116 f
->format_signature(L
, function_name
);
119 lua_concat(L
, count
* 2);
124 lua_pushstring(L
, "Ambiguous, candidates:\n");
125 for (int i
= 0; i
< candidate_index
; ++i
)
128 lua_pushstring(L
, "\n");
129 candidates
[i
]->format_signature(L
, function_name
);
131 lua_concat(L
, candidate_index
* 2);
135 }} // namespace luabind::detail