| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // Copyright Daniel Wallin 2008. Use, modification and distribution is
- // subject to the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #define LUABIND_BUILDING
- #include <luabind/make_function.hpp>
- namespace luabind { namespace detail {
- namespace
- {
- int function_destroy(lua_State* L)
- {
- function_object* fn = *(function_object**)lua_touserdata(L, 1);
- delete fn;
- return 0;
- }
- void push_function_metatable(lua_State* L)
- {
- lua_pushstring(L, "luabind.function");
- lua_rawget(L, LUA_REGISTRYINDEX);
- if (lua_istable(L, -1))
- return;
- lua_pop(L, 1);
- lua_newtable(L);
- lua_pushstring(L, "__gc");
- lua_pushcclosure(L, &function_destroy, 0);
- lua_rawset(L, -3);
- lua_pushstring(L, "luabind.function");
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX);
- }
- // A pointer to this is used as a tag value to identify functions exported
- // by luabind.
- int function_tag = 0;
- } // namespace unnamed
- LUABIND_API bool is_luabind_function(lua_State* L, int index)
- {
- if (!lua_getupvalue(L, index, 2))
- return false;
- bool result = lua_touserdata(L, -1) == &function_tag;
- lua_pop(L, 1);
- return result;
- }
- namespace
- {
- inline bool is_luabind_function(object const& obj)
- {
- obj.push(obj.interpreter());
- bool result = detail::is_luabind_function(obj.interpreter(), -1);
- lua_pop(obj.interpreter(), 1);
- return result;
- }
- } // namespace unnamed
- LUABIND_API void add_overload(
- object const& context, char const* name, object const& fn)
- {
- function_object* f = *touserdata<function_object*>(getupvalue(fn, 1));
- f->name = name;
- if (object overloads = context[name])
- {
- if (is_luabind_function(overloads) && is_luabind_function(fn))
- {
- f->next = *touserdata<function_object*>(getupvalue(overloads, 1));
- f->keepalive = overloads;
- }
- }
- context[name] = fn;
- }
- LUABIND_API object make_function_aux(lua_State* L, function_object* impl)
- {
- void* storage = lua_newuserdata(L, sizeof(function_object*));
- push_function_metatable(L);
- *(function_object**)storage = impl;
- lua_setmetatable(L, -2);
- lua_pushlightuserdata(L, &function_tag);
- lua_pushcclosure(L, impl->entry, 2);
- stack_pop pop(L, 1);
- return object(from_stack(L, -1));
- }
- void invoke_context::format_error(
- lua_State* L, function_object const* overloads) const
- {
- char const* function_name =
- overloads->name.empty() ? "<unknown>" : overloads->name.c_str();
- if (candidate_index == 0)
- {
- lua_pushstring(L, "No matching overload found, candidates:\n");
- int count = 0;
- for (function_object const* f = overloads; f != 0; f = f->next)
- {
- if (count != 0)
- lua_pushstring(L, "\n");
- f->format_signature(L, function_name);
- ++count;
- }
- lua_concat(L, count * 2);
- }
- else
- {
- // Ambiguous
- lua_pushstring(L, "Ambiguous, candidates:\n");
- for (int i = 0; i < candidate_index; ++i)
- {
- if (i != 0)
- lua_pushstring(L, "\n");
- candidates[i]->format_signature(L, function_name);
- }
- lua_concat(L, candidate_index * 2);
- }
- }
- }} // namespace luabind::detail
|