1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #include <luabind/lua_include.hpp>
25 #include <luabind/detail/stack_utils.hpp>
26 #include <luabind/luabind.hpp>
29 using namespace luabind::detail
;
31 namespace luabind
{ namespace detail
35 method_name(char const* n
): name(n
) {}
36 bool operator()(method_rep
const& o
) const
37 { return std::strcmp(o
.name
, name
) == 0; }
43 #ifndef LUABIND_NO_ERROR_CHECKING
45 std::string
luabind::detail::get_overload_signatures_candidates(
47 , std::vector
<const overload_rep_base
*>::iterator start
48 , std::vector
<const overload_rep_base
*>::iterator end
52 for (; start
!= end
; ++start
)
55 (*start
)->get_signature(L
, s
);
64 luabind::detail::class_rep::class_rep(LUABIND_TYPE_INFO type
67 , void(*destructor
)(void*)
68 , void(*const_holder_destructor
)(void*)
69 , LUABIND_TYPE_INFO holder_type
70 , LUABIND_TYPE_INFO const_holder_type
71 , void*(*extractor
)(void*)
72 , const void*(*const_extractor
)(void*)
73 , void(*const_converter
)(void*,void*)
74 , void(*construct_holder
)(void*,void*)
75 , void(*construct_const_holder
)(void*,void*)
76 , void(*default_construct_holder
)(void*)
77 , void(*default_construct_const_holder
)(void*)
78 , void(*adopt_fun
)(void*)
80 , int holder_alignment
)
83 , m_holder_type(holder_type
)
84 , m_const_holder_type(const_holder_type
)
85 , m_extractor(extractor
)
86 , m_const_extractor(const_extractor
)
87 , m_const_converter(const_converter
)
88 , m_construct_holder(construct_holder
)
89 , m_construct_const_holder(construct_const_holder
)
90 , m_default_construct_holder(default_construct_holder
)
91 , m_default_construct_const_holder(default_construct_const_holder
)
92 , m_adopt_fun(adopt_fun
)
93 , m_holder_size(holder_size
)
94 , m_holder_alignment(holder_alignment
)
96 , m_class_type(cpp_class
)
97 , m_destructor(destructor
)
98 , m_const_holder_destructor(const_holder_destructor
)
101 assert(m_holder_alignment
>= 1 && "internal error");
104 handle(L
, -1).swap(m_table
);
106 handle(L
, -1).swap(m_default_table
);
109 class_registry
* r
= class_registry::get_registry(L
);
110 assert((r
->cpp_class() != LUA_NOREF
) && "you must call luabind::open()");
112 detail::getref(L
, r
->cpp_class());
113 lua_setmetatable(L
, -2);
115 lua_pushvalue(L
, -1); // duplicate our user data
118 m_instance_metatable
= r
->cpp_instance();
121 luabind::detail::class_rep::class_rep(lua_State
* L
, const char* name
)
122 : m_type(LUABIND_INVALID_TYPE_INFO
)
123 , m_holder_type(LUABIND_INVALID_TYPE_INFO
)
124 , m_const_holder_type(LUABIND_INVALID_TYPE_INFO
)
126 , m_const_extractor(0)
127 , m_const_converter(0)
128 , m_construct_holder(0)
129 , m_construct_const_holder(0)
130 , m_default_construct_holder(0)
131 , m_default_construct_const_holder(0)
134 , m_holder_alignment(1)
136 , m_class_type(lua_class
)
138 , m_const_holder_destructor(0)
139 , m_operator_cache(0)
142 handle(L
, -1).swap(m_table
);
144 handle(L
, -1).swap(m_default_table
);
147 class_registry
* r
= class_registry::get_registry(L
);
148 assert((r
->cpp_class() != LUA_NOREF
) && "you must call luabind::open()");
150 detail::getref(L
, r
->lua_class());
151 lua_setmetatable(L
, -2);
152 lua_pushvalue(L
, -1); // duplicate our user data
155 m_instance_metatable
= r
->lua_instance();
158 luabind::detail::class_rep::~class_rep()
162 // leaves object on lua stack
163 std::pair
<void*,void*>
164 luabind::detail::class_rep::allocate(lua_State
* L
) const
166 const int overlap
= sizeof(object_rep
)&(m_holder_alignment
-1);
167 const int padding
= overlap
==0?0:m_holder_alignment
-overlap
;
168 const int size
= sizeof(object_rep
) + padding
+ m_holder_size
;
170 char* mem
= static_cast<char*>(lua_newuserdata(L
, size
));
171 char* ptr
= mem
+ sizeof(object_rep
) + padding
;
173 return std::pair
<void*,void*>(mem
,ptr
);
179 void dump_stack(lua_State* L)
181 for (int i = 1; i <= lua_gettop(L); ++i)
183 int t = lua_type(L, i);
187 std::cout << "[" << i << "] number: " << lua_tonumber(L, i) << "\n";
190 std::cout << "[" << i << "] string: " << lua_tostring(L, i) << "\n";
193 std::cout << "[" << i << "] userdata: " << lua_touserdata(L, i) << "\n";
196 std::cout << "[" << i << "] table:\n";
199 std::cout << "[" << i << "] nil:\n";
207 void luabind::detail::class_rep::adopt(bool const_obj
, void* obj
)
209 if (m_adopt_fun
== 0) return;
213 assert(m_const_extractor
);
215 m_adopt_fun(const_cast<void*>(m_const_extractor(obj
)));
217 m_adopt_fun(m_extractor(obj
));
225 // lua stack: userdata, key
226 int luabind::detail::class_rep::gettable(lua_State
* L
)
228 // if key is nil, return nil
235 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
237 // we have to ignore the first argument since this may point to
238 // a method that is not present in this class (but in a subclass)
239 const char* key
= lua_tostring(L
, 2);
241 #ifndef LUABIND_NO_ERROR_CHECKING
243 if (std::strlen(key
) != lua_strlen(L
, 2))
246 std::string
msg("luabind does not support "
247 "member names with extra nulls:\n");
248 msg
+= std::string(lua_tostring(L
, 2), lua_strlen(L
, 2));
249 lua_pushstring(L
, msg
.c_str());
256 // special case to see if this is a null-pointer
257 if (key
&& !std::strcmp(key
, "__ok"))
259 class_rep
* crep
= obj
->crep();
261 void* p
= crep
->extractor() ? crep
->extractor()(obj
->ptr())
264 lua_pushboolean(L
, p
!= 0);
268 // First, look in the instance's table
269 detail::lua_reference
const& tbl
= obj
->get_lua_table();
275 if (!lua_isnil(L
, -1))
277 lua_remove(L
, -2); // remove table
283 // Then look in the class' table for this member
284 obj
->crep()->get_table(L
);
288 if (!lua_isnil(L
, -1))
290 lua_remove(L
, -2); // remove table
295 std::map
<const char*, callback
, ltstr
>::iterator j
= m_getters
.find(key
);
296 if (j
!= m_getters
.end())
298 // the name is a data member
299 return j
->second
.func(L
, j
->second
.pointer_offset
);
306 // called from the metamethod for __newindex
307 // the object pointer is passed on the lua stack
308 // lua stack: userdata, key, value
309 bool luabind::detail::class_rep::settable(lua_State
* L
)
311 // if the key is 'nil' fail
312 if (lua_isnil(L
, 2)) return false;
314 // we have to ignore the first argument since this may point to
315 // a method that is not present in this class (but in a subclass)
317 const char* key
= lua_tostring(L
, 2);
319 if (std::strlen(key
) == lua_strlen(L
, 2))
321 std::map
<const char*, callback
, ltstr
>::iterator j
= m_setters
.find(key
);
322 if (j
!= m_setters
.end())
324 // the name is a data member
325 #ifndef LUABIND_NO_ERROR_CHECKING
326 if (j
->second
.match(L
, 3) < 0)
328 std::string
msg("the attribute '");
332 msg
+= "' is of type: ";
333 j
->second
.sig(L
, msg
);
334 msg
+= "\nand does not match: (";
335 msg
+= stack_content_by_name(L
, 3);
337 lua_pushstring(L
, msg
.c_str());
341 j
->second
.func(L
, j
->second
.pointer_offset
);
345 if (m_getters
.find(key
) != m_getters
.end())
347 // this means that we have a getter but no
348 // setter for an attribute. We will then fail
349 // because that attribute is read-only
350 std::string
msg("the attribute '");
354 msg
+= "' is read only";
355 lua_pushstring(L
, msg
.c_str());
360 // set the attribute to the object's table
361 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
362 detail::lua_reference
& tbl
= obj
->get_lua_table();
365 // this is the first time we are trying to add
366 // a member to this instance, create the table.
368 lua_pushvalue(L
, -1);
382 int class_rep::gettable_dispatcher(lua_State
* L
)
384 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
385 return obj
->crep()->gettable(L
);
388 // this is called as __newindex metamethod on every instance of this class
389 int luabind::detail::class_rep::settable_dispatcher(lua_State
* L
)
391 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
393 bool success
= obj
->crep()->settable(L
);
395 #ifndef LUABIND_NO_ERROR_CHECKING
399 // class_rep::settable() will leave
400 // error message on the stack in case
411 int luabind::detail::class_rep::operator_dispatcher(lua_State
* L
)
413 for (int i
= 0; i
< 2; ++i
)
415 if (is_class_object(L
, 1 + i
))
417 int nargs
= lua_gettop(L
);
419 lua_pushvalue(L
, lua_upvalueindex(1));
420 lua_gettable(L
, 1 + i
);
422 if (lua_isnil(L
, -1))
428 lua_insert(L
, 1); // move the function to the bottom
430 nargs
= lua_toboolean(L
, lua_upvalueindex(2)) ? 1 : nargs
;
432 if (lua_toboolean(L
, lua_upvalueindex(2))) // remove trailing nil
435 lua_call(L
, nargs
, 1);
440 lua_pop(L
, lua_gettop(L
));
441 lua_pushstring(L
, "No such operator defined");
447 // this is called as metamethod __call on the class_rep.
448 int luabind::detail::class_rep::constructor_dispatcher(lua_State
* L
)
450 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
451 construct_rep
* rep
= &crep
->m_constructor
;
453 bool ambiguous
= false;
454 int match_index
= -1;
455 int min_match
= std::numeric_limits
<int>::max();
458 #ifdef LUABIND_NO_ERROR_CHECKING
460 if (rep
->overloads
.size() == 1)
469 int num_params
= lua_gettop(L
) - 1;
470 found
= find_best_match(L
, &rep
->overloads
.front(), rep
->overloads
.size(), sizeof(construct_rep::overload_t
), ambiguous
, min_match
, match_index
, num_params
);
472 #ifdef LUABIND_NO_ERROR_CHECKING
480 std::string
msg("no constructor of '");
482 msg
+= "' matched the arguments (";
483 msg
+= stack_content_by_name(L
, 2);
484 msg
+= ")\n candidates are:\n";
486 msg
+= get_overload_signatures(L
, rep
->overloads
.begin(), rep
->overloads
.end(), crep
->name());
488 lua_pushstring(L
, msg
.c_str());
495 std::string
msg("call of overloaded constructor '");
498 msg
+= stack_content_by_name(L
, 2);
499 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
501 std::vector
<const overload_rep_base
*> candidates
;
502 find_exact_match(L
, &rep
->overloads
.front(), rep
->overloads
.size(), sizeof(construct_rep::overload_t
), min_match
, num_params
, candidates
);
503 msg
+= get_overload_signatures_candidates(L
, candidates
.begin(), candidates
.end(), crep
->name());
505 lua_pushstring(L
, msg
.c_str());
512 #ifndef LUABIND_NO_EXCEPTIONS
521 boost::tie(obj_rep
,held
) = crep
->allocate(L
);
523 weak_ref
backref(L
, -1);
525 void* object_ptr
= rep
->overloads
[match_index
].construct(L
, backref
);
527 if (crep
->has_holder())
529 crep
->m_construct_holder(held
, object_ptr
);
532 new(obj_rep
) object_rep(object_ptr
, crep
, object_rep::owner
, crep
->destructor());
534 detail::getref(L
, crep
->m_instance_metatable
);
535 lua_setmetatable(L
, -2);
538 #ifndef LUABIND_NO_EXCEPTIONS
545 catch(const std::exception
& e
)
547 lua_pushstring(L
, e
.what());
551 lua_pushstring(L
, s
);
556 std::string msg
= crep
->name();
557 msg
+= "() threw an exception";
558 lua_pushstring(L
, msg
.c_str());
562 // we can only reach this line if an exception was thrown
564 return 0; // will never be reached
571 the functions dispatcher assumes the following:
574 1: method_rep* method, points to the method_rep that this dispatcher is to call
575 2: boolean force_static, is true if this is to be a static call
576 and false if it is a normal call (= virtual if possible).
579 1: object_rep* self, points to the object the call is being made on
582 int luabind::detail::class_rep::function_dispatcher(lua_State
* L
)
587 assert(lua_getinfo(L, "u", &tmp_));
588 assert(tmp_.nups == 2);*/
589 assert(lua_type(L
, lua_upvalueindex(1)) == LUA_TLIGHTUSERDATA
);
590 assert(lua_type(L
, lua_upvalueindex(2)) == LUA_TBOOLEAN
);
591 assert(lua_type(L
, lua_upvalueindex(3)) == LUA_TLIGHTUSERDATA
);
592 assert(lua_touserdata(L
, lua_upvalueindex(3)) == reinterpret_cast<void*>(0x1337));
596 // assert(lua_type(L, 1) == LUA_TUSERDATA);
600 method_rep
* rep
= static_cast<method_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
601 int force_static_call
= lua_toboolean(L
, lua_upvalueindex(2));
603 bool ambiguous
= false;
604 int match_index
= -1;
605 int min_match
= std::numeric_limits
<int>::max();
608 #ifdef LUABIND_NO_ERROR_CHECKING
609 if (rep
->overloads().size() == 1)
617 int num_params
= lua_gettop(L
) /*- 1*/;
618 found
= find_best_match(L
, &rep
->overloads().front(), rep
->overloads().size()
619 , sizeof(overload_rep
), ambiguous
, min_match
, match_index
, num_params
);
621 #ifdef LUABIND_NO_ERROR_CHECKING
630 std::string msg
= "no overload of '";
631 msg
+= rep
->crep
->name();
634 msg
+= "' matched the arguments (";
635 msg
+= stack_content_by_name(L
, 1);
636 msg
+= ")\ncandidates are:\n";
638 std::string function_name
;
639 function_name
+= rep
->crep
->name();
640 function_name
+= ":";
641 function_name
+= rep
->name
;
643 msg
+= get_overload_signatures(L
, rep
->overloads().begin()
644 , rep
->overloads().end(), function_name
);
646 lua_pushstring(L
, msg
.c_str());
653 std::string msg
= "call of overloaded '";
654 msg
+= rep
->crep
->name();
658 msg
+= stack_content_by_name(L
, 1);
659 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
661 std::vector
<const overload_rep_base
*> candidates
;
662 find_exact_match(L
, &rep
->overloads().front(), rep
->overloads().size()
663 , sizeof(overload_rep
), min_match
, num_params
, candidates
);
665 std::string function_name
;
666 function_name
+= rep
->crep
->name();
667 function_name
+= ":";
668 function_name
+= rep
->name
;
670 msg
+= get_overload_signatures_candidates(L
, candidates
.begin()
671 , candidates
.end(), function_name
);
673 lua_pushstring(L
, msg
.c_str());
680 #ifndef LUABIND_NO_EXCEPTIONS
687 const overload_rep
& o
= rep
->overloads()[match_index
];
689 if (force_static_call
&& !o
.has_static())
691 lua_pushstring(L
, "pure virtual function called");
695 return o
.call(L
, force_static_call
!= 0);
698 #ifndef LUABIND_NO_EXCEPTIONS
704 catch(const std::exception
& e
)
706 lua_pushstring(L
, e
.what());
708 catch (const char* s
)
710 lua_pushstring(L
, s
);
714 std::string msg
= rep
->crep
->name();
717 msg
+= "() threw an exception";
718 lua_pushstring(L
, msg
.c_str());
723 // we can only reach this line if an error occured
725 return 0; // will never be reached
730 #ifndef BOOST_NO_STRINGSTREAM
738 std::string
to_string(luabind::object
const& o
)
740 using namespace luabind
;
741 if (type(o
) == LUA_TSTRING
) return object_cast
<std::string
>(o
);
742 lua_State
* L
= o
.interpreter();
743 LUABIND_CHECK_STACK(L
);
745 #ifdef BOOST_NO_STRINGSTREAM
751 if (type(o
) == LUA_TNUMBER
)
753 s
<< object_cast
<float>(o
);
757 s
<< "<" << lua_typename(L
, type(o
)) << ">";
758 #ifdef BOOST_NO_STRINGSTREAM
765 std::string
member_to_string(luabind::object
const& e
)
767 #if !defined(LUABIND_NO_ERROR_CHECKING)
768 using namespace luabind
;
769 lua_State
* L
= e
.interpreter();
770 LUABIND_CHECK_STACK(L
);
772 if (type(e
) == LUA_TFUNCTION
)
775 detail::stack_pop
p(L
, 1);
778 if (lua_getupvalue(L
, -1, 3) == 0) return to_string(e
);
779 detail::stack_pop
p2(L
, 1);
780 if (lua_touserdata(L
, -1) != reinterpret_cast<void*>(0x1337)) return to_string(e
);
783 #ifdef BOOST_NO_STRINGSTREAM
789 lua_getupvalue(L
, -1, 2);
790 detail::stack_pop
p2(L
, 1);
791 int b
= lua_toboolean(L
, -1);
792 s
<< "<c++ function";
793 if (b
) s
<< " (default)";
798 lua_getupvalue(L
, -1, 1);
799 detail::stack_pop
p2(L
, 1);
800 method_rep
* m
= static_cast<method_rep
*>(lua_touserdata(L
, -1));
802 for (std::vector
<overload_rep
>::const_iterator i
= m
->overloads().begin();
803 i
!= m
->overloads().end(); ++i
)
806 i
->get_signature(L
, str
);
807 s
<< " " << str
<< "\n";
810 #ifdef BOOST_NO_STRINGSTREAM
823 std::string
luabind::detail::class_rep::class_info_string(lua_State
* L
) const
825 #ifdef BOOST_NO_STRINGSTREAM
828 std::stringstream ret
;
831 ret
<< "CLASS: " << m_name
<< "\n";
833 ret
<< "dynamic dispatch functions:\n------------------\n";
835 for (luabind::iterator
i(m_table
), end
; i
!= end
; ++i
)
837 luabind::object e
= *i
;
838 ret
<< " " << to_string(i
.key()) << ": " << member_to_string(e
) << "\n";
841 ret
<< "default implementations:\n------------------\n";
843 for (luabind::iterator
i(m_default_table
), end
; i
!= end
; ++i
)
845 luabind::object e
= *i
;
846 ret
<< " " << to_string(i
.key()) << ": " << member_to_string(e
) << "\n";
848 #ifdef BOOST_NO_STRINGSTREAM
855 void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info
& binfo
)
857 // If you hit this assert you are deriving from a type that is not registered
858 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
859 // Please note that if you don't need to have access to the base class or the
860 // conversion from the derived class to the base class, you don't need
861 // to tell luabind that it derives.
862 assert(binfo
.base
&& "You cannot derive from an unregistered type");
864 class_rep
* bcrep
= binfo
.base
;
866 // import all functions from the base
867 typedef std::list
<detail::method_rep
> methods_t
;
869 for (methods_t::const_iterator i
= bcrep
->m_methods
.begin();
870 i
!= bcrep
->m_methods
.end(); ++i
)
875 // import all getters from the base
876 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_getters
.begin();
877 i
!= bcrep
->m_getters
.end(); ++i
)
879 callback
& m
= m_getters
[i
->first
];
880 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
881 m
.func
= i
->second
.func
;
883 #ifndef LUABIND_NO_ERROR_CHECKING
884 m
.match
= i
->second
.match
;
885 m
.sig
= i
->second
.sig
;
889 // import all setters from the base
890 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_setters
.begin();
891 i
!= bcrep
->m_setters
.end(); ++i
)
893 callback
& m
= m_setters
[i
->first
];
894 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
895 m
.func
= i
->second
.func
;
897 #ifndef LUABIND_NO_ERROR_CHECKING
898 m
.match
= i
->second
.match
;
899 m
.sig
= i
->second
.sig
;
903 // import all static constants
904 for (std::map
<const char*, int, ltstr
>::const_iterator i
= bcrep
->m_static_constants
.begin();
905 i
!= bcrep
->m_static_constants
.end(); ++i
)
907 int& v
= m_static_constants
[i
->first
];
911 // import all operators
912 for (int i
= 0; i
< number_of_operators
; ++i
)
914 for (std::vector
<operator_callback
>::const_iterator j
= bcrep
->m_operators
[i
].begin();
915 j
!= bcrep
->m_operators
[i
].end(); ++j
)
916 m_operators
[i
].push_back(*j
);
919 // also, save the baseclass info to be used for typecasts
920 m_bases
.push_back(binfo
);
923 int luabind::detail::class_rep::super_callback(lua_State
* L
)
925 int args
= lua_gettop(L
);
927 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, lua_upvalueindex(2)));
928 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
929 class_rep
* base
= crep
->bases()[0].base
;
931 if (base
->get_class_type() == class_rep::lua_class
)
933 if (base
->bases().empty())
935 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
937 lua_pushstring(L
, "super");
939 lua_settable(L
, LUA_GLOBALSINDEX
);
943 lua_pushstring(L
, "super");
944 lua_pushlightuserdata(L
, base
);
945 lua_pushvalue(L
, lua_upvalueindex(2));
946 lua_pushcclosure(L
, super_callback
, 2);
947 lua_settable(L
, LUA_GLOBALSINDEX
);
951 lua_pushstring(L
, "__init");
956 lua_pushvalue(L
, lua_upvalueindex(2));
959 lua_call(L
, args
+ 1, 0);
961 // TODO: instead of clearing the global variable "super"
962 // store it temporarily in the registry. maybe we should
963 // have some kind of warning if the super global is used?
964 lua_pushstring(L
, "super");
966 lua_settable(L
, LUA_GLOBALSINDEX
);
970 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
972 // we need to push some garbage at index 1 to make the construction work
973 lua_pushboolean(L
, 1);
976 construct_rep
* rep
= &base
->m_constructor
;
978 bool ambiguous
= false;
979 int match_index
= -1;
980 int min_match
= std::numeric_limits
<int>::max();
983 #ifdef LUABIND_NO_ERROR_CHECKING
985 if (rep
->overloads
.size() == 1)
994 int num_params
= lua_gettop(L
) - 1;
995 found
= find_best_match(L
, &rep
->overloads
.front(), rep
->overloads
.size(), sizeof(construct_rep::overload_t
), ambiguous
, min_match
, match_index
, num_params
);
997 #ifdef LUABIND_NO_ERROR_CHECKING
1006 std::string msg
= "no constructor of '";
1007 msg
+= base
->m_name
;
1008 msg
+= "' matched the arguments (";
1009 msg
+= stack_content_by_name(L
, 2);
1011 lua_pushstring(L
, msg
.c_str());
1018 std::string msg
= "call of overloaded constructor '";
1019 msg
+= base
->m_name
;
1021 msg
+= stack_content_by_name(L
, 2);
1022 msg
+= ")' is ambiguous";
1023 lua_pushstring(L
, msg
.c_str());
1028 // TODO: should this be a warning or something?
1030 // since the derived class is a lua class
1031 // it may have reimplemented virtual functions
1032 // therefore, we have to instantiate the Basewrapper
1033 // if there is no basewrapper, throw a run-time error
1034 if (!rep->overloads[match_index].has_wrapped_construct())
1037 std::string msg = "Cannot derive from C++ class '";
1038 msg += base->name();
1039 msg += "'. It does not have a wrapped type";
1040 lua_pushstring(L, msg.c_str());
1047 #ifndef LUABIND_NO_EXCEPTIONS
1053 lua_pushvalue(L
, lua_upvalueindex(2));
1054 weak_ref
backref(L
, -1);
1057 void* storage_ptr
= obj
->ptr();
1059 if (!rep
->overloads
[match_index
].has_wrapped_construct())
1061 // if the type doesn't have a wrapped type, use the ordinary constructor
1062 void* instance
= rep
->overloads
[match_index
].construct(L
, backref
);
1064 if (crep
->has_holder())
1066 crep
->m_construct_holder(storage_ptr
, instance
);
1070 obj
->set_object(instance
);
1075 // get reference to lua object
1076 /* lua_pushvalue(L, lua_upvalueindex(2));
1077 detail::lua_reference ref;
1079 void* instance = rep->overloads[match_index].construct_wrapped(L, ref);*/
1081 void* instance
= rep
->overloads
[match_index
].construct_wrapped(L
, backref
);
1083 if (crep
->has_holder())
1085 crep
->m_construct_holder(storage_ptr
, instance
);
1089 obj
->set_object(instance
);
1092 // TODO: is the wrapped type destructed correctly?
1093 // it should, since the destructor is either the wrapped type's
1094 // destructor or the base type's destructor, depending on wether
1095 // the type has a wrapped type or not.
1096 obj
->set_destructor(base
->destructor());
1099 #ifndef LUABIND_NO_EXCEPTIONS
1105 catch(const std::exception
& e
)
1107 lua_pushstring(L
, e
.what());
1109 catch(const char* s
)
1111 lua_pushstring(L
, s
);
1115 std::string msg
= base
->m_name
;
1116 msg
+= "() threw an exception";
1117 lua_pushstring(L
, msg
.c_str());
1119 // can only be reached if an exception was thrown
1130 int luabind::detail::class_rep::lua_settable_dispatcher(lua_State
* L
)
1132 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1138 lua_pushvalue(L
, -3);
1139 lua_pushvalue(L
, -3);
1144 // get default table
1145 crep
->get_default_table(L
);
1149 crep
->m_operator_cache
= 0; // invalidate cache
1154 int luabind::detail::class_rep::construct_lua_class_callback(lua_State
* L
)
1156 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1158 int args
= lua_gettop(L
);
1160 // lua stack: crep <arguments>
1163 detail::lua_reference ref
;
1166 bool has_bases
= !crep
->bases().empty();
1170 lua_pushstring(L
, "super");
1171 lua_pushvalue(L
, 1); // crep
1174 // lua stack: crep <arguments> "super" crep
1176 // lua stack: crep <arguments>
1178 // if we have a baseclass we set the flag to say that the super has not yet been called
1179 // we will use this flag later to check that it actually was called from __init()
1180 int flags
= object_rep::lua_class
| object_rep::owner
| (has_bases
? object_rep::call_super
: 0);
1182 // void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));
1186 boost::tie(obj_ptr
, held_storage
) = crep
->allocate(L
);
1187 (new(obj_ptr
) object_rep(crep
, flags
, ref
))->set_object(held_storage
);
1189 detail::getref(L
, crep
->metatable_ref());
1190 lua_setmetatable(L
, -2);
1192 // lua stack: crep <arguments> "super" crep obj_ptr
1194 // lua stack: crep <arguments> obj_ptr
1196 if (has_bases
) lua_pushvalue(L
, -1); // obj_ptr
1197 lua_replace(L
, 1); // obj_ptr
1199 // lua stack: obj_ptr <arguments> "super" crep obj_ptr
1201 // lua stack: obj_ptr <arguments>
1205 lua_pushcclosure(L
, super_callback
, 2);
1206 // lua stack: crep <arguments> "super" function
1207 lua_settable(L
, LUA_GLOBALSINDEX
);
1210 // lua stack: crep <arguments>
1212 lua_pushvalue(L
, 1);
1216 lua_pushstring(L
, "__init");
1217 lua_gettable(L
, -2);
1219 #ifndef LUABIND_NO_ERROR_CHECKING
1221 // TODO: should this be a run-time error?
1222 // maybe the default behavior should be to just call
1223 // the base calss' constructor. We should register
1224 // the super callback funktion as __init
1225 if (!lua_isfunction(L
, -1))
1228 std::string msg
= crep
->name();
1229 msg
+= ":__init is not defined";
1230 lua_pushstring(L
, msg
.c_str());
1237 lua_insert(L
, 2); // function first on stack
1239 // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
1240 // we don't have any stack objects here
1241 lua_call(L
, args
, 0);
1243 #ifndef LUABIND_NO_ERROR_CHECKING
1245 object_rep
* obj
= static_cast<object_rep
*>(obj_ptr
);
1246 if (obj
->flags() & object_rep::call_super
)
1248 lua_pushstring(L
, "derived class must call super on base");
1257 // called from the metamethod for __index
1258 // obj is the object pointer
1259 int luabind::detail::class_rep::lua_class_gettable(lua_State
* L
)
1261 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1262 class_rep
* crep
= obj
->crep();
1264 #ifndef LUABIND_NO_ERROR_CHECKING
1266 if (obj
->flags() & object_rep::call_super
)
1268 lua_pushstring(L
, "derived class must call super on base");
1274 // we have to ignore the first argument since this may point to
1275 // a method that is not present in this class (but in a subclass)
1277 // BUG: This might catch members called "__ok\0foobar"
1278 const char* key
= lua_tostring(L
, 2);
1280 if (key
&& !std::strcmp(key
, "__ok"))
1282 class_rep
* crep
= obj
->crep();
1284 void* p
= crep
->extractor() ? crep
->extractor()(obj
->ptr())
1287 lua_pushboolean(L
, p
!= 0);
1291 // first look in the instance's table
1292 detail::lua_reference
const& tbl
= obj
->get_lua_table();
1293 assert(tbl
.is_valid());
1295 lua_pushvalue(L
, 2);
1296 lua_gettable(L
, -2);
1297 if (!lua_isnil(L
, -1))
1299 lua_remove(L
, -2); // remove table
1304 // then look in the class' table
1306 lua_pushvalue(L
, 2);
1307 lua_gettable(L
, -2);
1309 if (!lua_isnil(L
, -1))
1311 lua_remove(L
, -2); // more table
1317 if (lua_isnil(L
, 2))
1323 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_getters
.find(key
);
1324 if (j
!= crep
->m_getters
.end())
1326 // the name is a data member
1327 return j
->second
.func(L
, j
->second
.pointer_offset
);
1334 // called from the metamethod for __newindex
1335 // obj is the object pointer
1336 int luabind::detail::class_rep::lua_class_settable(lua_State
* L
)
1338 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1339 class_rep
* crep
= obj
->crep();
1341 #ifndef LUABIND_NO_ERROR_CHECKING
1343 if (obj
->flags() & object_rep::call_super
)
1345 // this block makes sure the std::string is destructed
1346 // before lua_error is called
1348 std::string msg
= "derived class '";
1349 msg
+= crep
->name();
1350 msg
+= "'must call super on base";
1351 lua_pushstring(L
, msg
.c_str());
1358 // we have to ignore the first argument since this may point to
1359 // a method that is not present in this class (but in a subclass)
1360 // BUG: This will not work with keys with extra nulls in them
1361 const char* key
= lua_tostring(L
, 2);
1364 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_setters
.find(key
);
1366 // if the strlen(key) is not the true length,
1367 // it means that the member-name contains
1368 // extra nulls. luabind does not support such
1369 // names as member names. So, use the lua
1370 // table as fall-back
1371 if (j
== crep
->m_setters
.end()
1372 || std::strlen(key
) != lua_strlen(L
, 2))
1374 std::map
<const char*, class_rep::callback
, ltstr
>::iterator k
= crep
->m_getters
.find(key
);
1376 #ifndef LUABIND_NO_ERROR_CHECKING
1378 if (k
!= crep
->m_getters
.end())
1381 std::string msg
= "cannot set property '";
1382 msg
+= crep
->name();
1385 msg
+= "', because it's read only";
1386 lua_pushstring(L
, msg
.c_str());
1393 detail::lua_reference
const& tbl
= obj
->get_lua_table();
1394 assert(tbl
.is_valid());
1401 // the name is a data member
1402 j
->second
.func(L
, j
->second
.pointer_offset
);
1413 int luabind::detail::class_rep::static_class_gettable(lua_State
* L
)
1415 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1417 // look in the static function table
1418 crep
->get_default_table(L
);
1419 lua_pushvalue(L
, 2);
1420 lua_gettable(L
, -2);
1421 if (!lua_isnil(L
, -1)) return 1;
1424 const char* key
= lua_tostring(L
, 2);
1426 if (std::strlen(key
) != lua_strlen(L
, 2))
1432 std::map
<const char*, int, ltstr
>::const_iterator j
= crep
->m_static_constants
.find(key
);
1434 if (j
!= crep
->m_static_constants
.end())
1436 lua_pushnumber(L
, j
->second
);
1440 #ifndef LUABIND_NO_ERROR_CHECKING
1443 std::string msg
= "no static '";
1445 msg
+= "' in class '";
1446 msg
+= crep
->name();
1448 lua_pushstring(L
, msg
.c_str());
1459 bool luabind::detail::is_class_rep(lua_State
* L
, int index
)
1461 if (lua_getmetatable(L
, index
) == 0) return false;
1463 lua_pushstring(L
, "__luabind_classrep");
1464 lua_gettable(L
, -2);
1465 if (lua_toboolean(L
, -1))
1475 void luabind::detail::finalize(lua_State
* L
, class_rep
* crep
)
1477 if (crep
->get_class_type() != class_rep::lua_class
) return;
1479 // lua_pushvalue(L, -1); // copy the object ref
1481 lua_pushstring(L
, "__finalize");
1482 lua_gettable(L
, -2);
1485 if (lua_isnil(L
, -1))
1491 lua_pushvalue(L
, -2);
1495 for (std::vector
<class_rep::base_info
>::const_iterator
1496 i
= crep
->bases().begin(); i
!= crep
->bases().end(); ++i
)
1498 if (i
->base
) finalize(L
, i
->base
);
1502 void* luabind::detail::class_rep::convert_to(
1503 LUABIND_TYPE_INFO target_type
1504 , const object_rep
* obj
1505 , void* target_memory
) const
1507 // TODO: since this is a member function, we don't have to use the accesor functions for
1508 // the types and the extractor
1510 assert(obj
== 0 || obj
->crep() == this);
1514 if (!(LUABIND_TYPE_INFO_EQUAL(holder_type(), target_type
))
1515 && !(LUABIND_TYPE_INFO_EQUAL(const_holder_type(), target_type
)))
1517 steps
= implicit_cast(this, target_type
, offset
);
1520 // should never be called with a type that can't be cast
1521 assert((steps
>= 0) && "internal error, please report");
1523 if (LUABIND_TYPE_INFO_EQUAL(target_type
, holder_type()))
1527 // we are trying to convert nil to a holder type
1528 m_default_construct_holder(target_memory
);
1529 return target_memory
;
1531 // if the type we are trying to convert to is the holder_type
1532 // it means that his crep has a holder_type (since it would have
1533 // been invalid otherwise, and T cannot be invalid). It also means
1534 // that we need no conversion, since the holder_type is what the
1535 // object points to.
1539 if (LUABIND_TYPE_INFO_EQUAL(target_type
, const_holder_type()))
1543 // we are trying to convert nil to a const holder type
1544 m_default_construct_const_holder(target_memory
);
1545 return target_memory
;
1548 if (obj
->flags() & object_rep::constant
)
1550 // we are holding a constant
1555 // we are holding a non-constant, we need to convert it
1556 // to a const_holder.
1557 m_const_converter(obj
->ptr(), target_memory
);
1558 return target_memory
;
1567 // this means that we have a holder type where the
1568 // raw-pointer needs to be extracted
1569 raw_pointer
= extractor()(obj
->ptr());
1573 if (obj
== 0) raw_pointer
= 0;
1574 else raw_pointer
= obj
->ptr();
1577 return static_cast<char*>(raw_pointer
) + offset
;
1580 void luabind::detail::class_rep::cache_operators(lua_State
* L
)
1582 m_operator_cache
= 0x1;
1584 for (int i
= 0; i
< number_of_operators
; ++i
)
1587 lua_pushstring(L
, get_operator_name(i
));
1590 if (lua_isfunction(L
, -1)) m_operator_cache
|= 1 << (i
+ 1);
1596 bool luabind::detail::class_rep::has_operator_in_lua(lua_State
* L
, int id
)
1598 if ((m_operator_cache
& 0x1) == 0)
1601 const int mask
= 1 << (id
+ 1);
1603 return (m_operator_cache
& mask
) != 0;
1607 // this will merge all overloads of fun into the list of
1608 // overloads in this class
1609 void luabind::detail::class_rep::add_method(luabind::detail::method_rep
const& fun
)
1611 typedef std::list
<detail::method_rep
> methods_t
;
1613 methods_t::iterator m
= std::find_if(
1616 , method_name(fun
.name
));
1617 if (m
== m_methods
.end())
1619 m_methods
.push_back(method_rep());
1620 m
= m_methods
.end();
1621 std::advance(m
, -1);
1626 typedef std::vector
<detail::overload_rep
> overloads_t
;
1628 for (overloads_t::const_iterator j
= fun
.overloads().begin();
1629 j
!= fun
.overloads().end(); ++j
)
1631 detail::overload_rep o
= *j
;
1636 // this function will add all the overloads in method rep to
1637 // this class' lua tables. If there already are overloads with this
1638 // name, thses will simply be appended to the overload list
1639 void luabind::detail::class_rep::register_methods(lua_State
* L
)
1641 LUABIND_CHECK_STACK(L
);
1642 // insert the function in the normal member table
1643 // and in the default member table
1644 m_default_table
.push(L
);
1648 detail::stack_pop
pop_tables(L
, 2);
1650 for (std::list
<method_rep
>::const_iterator m
= m_methods
.begin();
1651 m
!= m_methods
.end(); ++m
)
1653 // create the function closure in m_table
1654 lua_pushstring(L
, m
->name
);
1655 lua_pushlightuserdata(L
, const_cast<void*>((const void*)&(*m
)));
1656 lua_pushboolean(L
, 0);
1657 lua_pushlightuserdata(L
, reinterpret_cast<void*>(0x1337));
1658 lua_pushcclosure(L
, function_dispatcher
, 3);
1659 lua_settable(L
, -3);
1661 // create the function closure in m_default_table
1662 lua_pushstring(L
, m
->name
);
1663 lua_pushlightuserdata(L
, const_cast<void*>((const void*)&(*m
)));
1664 lua_pushboolean(L
, 1);
1665 lua_pushlightuserdata(L
, reinterpret_cast<void*>(0x1337));
1666 lua_pushcclosure(L
, function_dispatcher
, 3);
1667 lua_settable(L
, -4);
1671 const class_rep::property_map
& luabind::detail::class_rep::properties() const