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.
24 #ifndef LUABIND_CLASS_REP_HPP_INCLUDED
25 #define LUABIND_CLASS_REP_HPP_INCLUDED
29 #include <boost/limits.hpp>
30 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
32 #include <luabind/config.hpp>
33 #include <luabind/detail/object_rep.hpp>
34 #include <luabind/detail/construct_rep.hpp>
35 #include <luabind/detail/method_rep.hpp>
36 #include <luabind/detail/garbage_collector.hpp>
37 #include <luabind/detail/operator_id.hpp>
38 #include <luabind/detail/signature_match.hpp>
39 #include <luabind/detail/class_registry.hpp>
40 #include <luabind/detail/find_best_match.hpp>
41 #include <luabind/detail/get_overload_signature.hpp>
42 #include <luabind/error.hpp>
47 template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(LUABIND_MAX_BASES
, class A
, detail::null_type
)>
49 typedef bases
<detail::null_type
> no_bases
;
55 namespace luabind
{ namespace detail
57 std::string
stack_content_by_name(lua_State
* L
, int start_index
);
58 int construct_lua_class_callback(lua_State
* L
);
60 // this is class-specific information, poor man's vtable
61 // this is allocated statically (removed by the compiler)
62 // a pointer to this structure is stored in the lua tables'
63 // metatable with the name __classrep
64 // it is used when matching parameters to function calls
65 // to determine possible implicit casts
66 // it is also used when finding the best match for overloaded
70 friend struct luabind::class_base
;
71 friend int super_callback(lua_State
*);
72 //TODO: avoid the lua-prefix
73 friend int lua_class_gettable(lua_State
*);
74 friend int lua_class_settable(lua_State
*);
75 friend int static_class_gettable(lua_State
*);
84 // destructor is a lua callback function that is hooked as garbage collector event on every instance
85 // of this class (including those that is not owned by lua). It gets an object_rep as argument
86 // on the lua stack. It should delete the object pointed to by object_rep::ptr if object_pre::flags
87 // is object_rep::owner (which means that lua owns the object)
89 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
90 // BE THE USER DATA WHERE THIS CLASS IS BEING
92 class_rep(LUABIND_TYPE_INFO t
, const char* name
, lua_State
* L
, void(*destructor
)(void*), LUABIND_TYPE_INFO held_t
, void*(*extractor
)(void*))
95 , m_extract_underlying_fun(extractor
)
97 , m_class_type(cpp_class
)
98 , m_destructor(destructor
)
101 // TODO: don't we need to copy the name?
102 class_registry
* r
= class_registry::get_registry(L
);
103 assert((r
->cpp_class() != LUA_NOREF
) && "you must call luabind::open()"); // you must call luabind::open()
105 detail::getref(L
, r
->cpp_class());
106 lua_setmetatable(L
, -2);
108 lua_pushvalue(L
, -1); // duplicate our user data
109 m_self_ref
= detail::ref(L
); // pop one of them
111 m_instance_metatable
= r
->cpp_instance();
114 // used when creating a lua class
115 // EXPECTS THE TOP VALUE ON THE LUA STACK TO
116 // BE THE USER DATA WHERE THIS CLASS IS BEING
118 class_rep(lua_State
* L
, const char* name
)
119 : m_type(LUABIND_TYPEID(int))
121 , m_extract_underlying_fun(0)
123 , m_class_type(lua_class
)
125 // TODO: don't we need to copy the name?
127 m_table_ref
= detail::ref(L
);
129 class_registry
* r
= class_registry::get_registry(L
);
130 assert((r
->cpp_class() != LUA_NOREF
) && "you must call luabind::open()"); // you must call luabind::open()
132 detail::getref(L
, r
->lua_class());
133 lua_setmetatable(L
, -2);
134 lua_pushvalue(L
, -1); // duplicate our user data
135 m_self_ref
= detail::ref(L
); // pop one of them
137 m_instance_metatable
= r
->lua_instance();
142 #ifndef LUABIND_DONT_COPY_STRINGS
143 for (std::vector
<char*>::iterator i
= m_strings
.begin(); i
!= m_strings
.end(); ++i
)
151 // called from the metamethod for __index
152 // the object pointer is passed on the lua stack
153 int gettable(lua_State
* L
)
161 // we have to ignore the first argument since this may point to
162 // a method that is not present in this class (but in a subclass)
163 const char* key
= lua_tostring(L
, 2);
164 std::map
<const char*, method_rep
, ltstr
>::iterator i
= m_methods
.find(key
);
165 if (i
!= m_methods
.end())
167 // the name is a method, return it
168 lua_pushlightuserdata(L
, &i
->second
);
169 lua_pushcclosure(L
, function_dispatcher
, 1);
173 std::map
<const char*, callback
, ltstr
>::iterator j
= m_getters
.find(key
);
174 if (j
!= m_getters
.end())
176 // the name is a data member
177 return j
->second
.func(L
, j
->second
.pointer_offset
);
184 // called from the metamethod for __newindex
185 // the object pointer is passed on the lua stack
186 bool settable(lua_State
* L
)
193 // we have to ignore the first argument since this may point to
194 // a method that is not present in this class (but in a subclass)
195 const char* key
= lua_tostring(L
, 2);
196 std::map
<const char*, callback
, ltstr
>::iterator j
= m_setters
.find(key
);
197 if (j
!= m_setters
.end())
199 // the name is a data member
200 j
->second
.func(L
, j
->second
.pointer_offset
);
204 return false; // false means that we don't have a member with the given name
207 // this is called as __index metamethod on every instance of this class
208 static int gettable_dispatcher(lua_State
* L
)
210 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
211 return obj
->crep()->gettable(L
);
214 // this is called as __newindex metamethod on every instance of this class
215 static int settable_dispatcher(lua_State
* L
)
217 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
219 bool success
= obj
->crep()->settable(L
);
221 #ifndef LUABIND_NO_ERROR_CHECKING
225 // this block is needed to make sure the std::string is destructed before
226 // lua_error() is called
229 // msvc has a bug which deletes the string twice, that's
230 // why we have to create it on the heap
231 std::string
* msg
= new std::string("cannot set attribute '");
232 *msg
+= obj
->crep()->m_name
;
234 *msg
+= lua_tostring(L
, -2);
236 lua_pushstring(L
, msg
->c_str());
241 std::string msg
= "cannot set attribute '";
242 msg
+= obj
->crep()->m_name
;
244 msg
+= lua_tostring(L
, -2);
246 lua_pushstring(L
, msg
.c_str());
257 static int operator_dispatcher(lua_State
* L
)
259 int id
= static_cast<int>(lua_tonumber(L
, lua_upvalueindex(1)));
263 object_rep
* operand
[2];
264 for (int i
= 0; i
< 2; ++i
)
265 operand
[i
] = detail::is_class_object(L
, i
+ 1);
267 if (operand
[0] && operand
[1])
268 if (LUABIND_TYPE_INFO_EQUAL(operand
[0]->crep()->type(), operand
[1]->crep()->type())) operand
[1] = 0;
270 std::vector
<operator_callback
>* overloads
[2];
271 for (int i
= 0; i
< 2; ++i
)
272 if (operand
[i
]) overloads
[i
] = &operand
[i
]->crep()->m_operators
[id
]; else overloads
[i
] = 0;
274 std::size_t num_overloads
[2];
275 for (int i
= 0; i
< 2; ++i
)
276 if (overloads
[i
]) num_overloads
[i
] = overloads
[i
]->size(); else num_overloads
[i
] = 0;
278 bool ambiguous
= false;
279 int match_index
= -1;
280 int min_match
= std::numeric_limits
<int>::max();
282 // std::cout << "operator_dispatcher\n";
283 // std::cout << "num overloads: " << num_overloads[0] + num_overloads[1] << "\n";
284 // std::cout << "operator: " << id << "\n";
286 #ifdef LUABIND_NO_ERROR_CHECKING
288 if (num_overloads
[0] == 1 && num_overloads
[1] == 0)
293 else if (num_overloads
[0] == 0 && num_overloads
[1] == 1)
303 int num_params
= lua_gettop(L
);
306 if (find_best_match(L
, overloads
[0]->begin(), overloads
[0]->end(), ambiguous
, min_match
, match_index
, num_params
))
310 // have look at the right operand.
311 // if the right operand is a class and
312 // not the same class as this, we have to
313 // try to match it's operators too
317 if(find_best_match(L
, overloads
[1]->begin(), overloads
[1]->end(), ambiguous
, min_match
, match_index
, num_params
))
321 #ifdef LUABIND_NO_ERROR_CHECKING
327 if (match_index
== -1)
329 // this block is needed to make sure the std::string is destructed before
330 // lua_error() is called
332 std::string msg
= "no operator ";
333 msg
+= get_operator_symbol(id
);
334 msg
+= " matched the arguments (";
335 msg
+= stack_content_by_name(L
, 1);
336 msg
+= ")\ncandidates are:\n";
339 msg
+= get_overload_signatures(L
, overloads
[0]->begin(), overloads
[0]->end(), get_operator_symbol(id
));
342 msg
+= get_overload_signatures(L
, overloads
[1]->begin(), overloads
[1]->end(), get_operator_symbol(id
));
344 lua_pushstring(L
, msg
.c_str());
350 // this block is needed to make sure the std::string is destructed before
351 // lua_error() is called
353 std::string msg
= "call of overloaded operator ";
354 msg
+= get_operator_symbol(id
);
356 msg
+= stack_content_by_name(L
, 1);
357 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
359 std::vector
<operator_callback
> candidates
;
361 find_exact_match(L
, overloads
[0]->begin(), overloads
[0]->end(), min_match
, num_params
, candidates
);
364 find_exact_match(L
, overloads
[1]->begin(), overloads
[1]->end(), min_match
, num_params
, candidates
);
366 msg
+= get_overload_signatures(L
, candidates
.begin(), candidates
.end(), get_operator_symbol(id
));
369 lua_pushstring(L
, msg
.c_str());
376 return (*overloads
[operand_id
])[match_index
].call(L
);
380 // this is called as metamethod __call on the class_rep.
381 static int constructor_dispatcher(lua_State
* L
)
383 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
384 construct_rep
* rep
= &crep
->m_constructor
;
386 bool ambiguous
= false;
387 int match_index
= -1;
388 int min_match
= std::numeric_limits
<int>::max();
391 #ifdef LUABIND_NO_ERROR_CHECKING
393 if (rep
->overloads
.size() == 1)
402 int num_params
= lua_gettop(L
) - 1;
403 found
= find_best_match(L
, rep
->overloads
.begin(), rep
->overloads
.end(), ambiguous
, min_match
, match_index
, num_params
);
405 #ifdef LUABIND_NO_ERROR_CHECKING
413 // this block is needed to make sure the std::string is destructed before
414 // lua_error() is called
416 std::string msg
= "no constructor of '";
418 msg
+= "' matched the arguments (";
419 msg
+= stack_content_by_name(L
, 2);
420 msg
+= ")\n candidates are:\n";
422 msg
+= get_overload_signatures(L
, rep
->overloads
.begin(), rep
->overloads
.end(), crep
->name());
424 lua_pushstring(L
, msg
.c_str());
430 // this block is needed to make sure the std::string is destructed before
431 // lua_error() is called
433 std::string msg
= "call of overloaded constructor '";
436 msg
+= stack_content_by_name(L
, 2);
437 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
439 std::vector
<construct_rep::overload_t
> candidates
;
440 find_exact_match(L
, rep
->overloads
.begin(), rep
->overloads
.end(), min_match
, num_params
, candidates
);
441 msg
+= get_overload_signatures(L
, candidates
.begin(), candidates
.end(), crep
->name());
443 lua_pushstring(L
, msg
.c_str());
450 #ifndef LUABIND_NO_EXCEPTIONS
457 void* object_ptr
= rep
->overloads
[match_index
].construct(L
);
459 void* obj_rep
= lua_newuserdata(L
, sizeof(object_rep
));
460 new(obj_rep
) object_rep(object_ptr
, crep
, object_rep::owner
, crep
->destructor());
462 detail::getref(L
, crep
->m_instance_metatable
);
463 lua_setmetatable(L
, -2);
466 #ifndef LUABIND_NO_EXCEPTIONS
470 catch(const std::exception
& e
)
472 lua_pushstring(L
, e
.what());
476 lua_pushstring(L
, s
);
481 std::string msg
= crep
->name();
482 msg
+= "() threw an exception";
483 lua_pushstring(L
, msg
.c_str());
487 // we can only reach this line if an exception was thrown
489 return 0; // will never be reached
495 static int implicit_cast(const class_rep
* from
, const class_rep
* to
, int& pointer_offset
)
498 if (LUABIND_TYPE_INFO_EQUAL(from
->type(), to
->type())) return 0;
500 for (std::vector
<class_rep::base_info
>::const_iterator i
= from
->bases().begin(); i
!= from
->bases().end(); ++i
)
502 int steps
= implicit_cast(i
->base
, to
, offset
);
503 pointer_offset
= offset
+ i
->pointer_offset
;
504 if (steps
>= 0) return steps
+ 2;
509 // the functions dispatcher assumes the following:
510 // there is one upvalue that points to the method_rep that this dispatcher is to call
511 // the first parameter on the lua stack is an object_rep that points to the object the
512 // call is being made on
513 static int function_dispatcher(lua_State
* L
)
515 method_rep
* rep
= static_cast<method_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
516 object_rep
* obj
= reinterpret_cast<object_rep
*>(lua_touserdata(L
, 1));
518 #ifndef LUABIND_NO_ERROR_CHECKING
520 if (is_class_object(L
, 1) == 0)
523 std::string msg
= "No self reference given as first parameter to member function '";
524 msg
+= rep
->crep
->name();
527 msg
+= "'. Have you used '.' instead of ':'?";
529 lua_pushstring(L
, msg
.c_str());
535 if (implicit_cast(obj
->crep(), rep
->crep
, p
) < 0)
538 std::string msg
= "invalid self reference given to '";
539 msg
+= rep
->crep
->name();
543 lua_pushstring(L
, msg
.c_str());
550 bool ambiguous
= false;
551 int match_index
= -1;
552 int min_match
= std::numeric_limits
<int>::max();
555 #ifdef LUABIND_NO_ERROR_CHECKING
556 if (rep
->overloads().size() == 1)
564 int num_params
= lua_gettop(L
) - 1;
565 found
= find_best_match(L
, rep
->overloads().begin(), rep
->overloads().end(), ambiguous
, min_match
, match_index
, num_params
);
567 #ifdef LUABIND_NO_ERROR_CHECKING
576 std::string msg
= "no overload of '";
577 msg
+= rep
->crep
->name();
580 msg
+= "' matched the arguments (";
581 msg
+= stack_content_by_name(L
, 2);
582 msg
+= ")\ncandidates are:\n";
584 std::string function_name
;
585 function_name
+= rep
->crep
->name();
586 function_name
+= ":";
587 function_name
+= rep
->name
;
589 msg
+= get_overload_signatures(L
, rep
->overloads().begin(), rep
->overloads().end(), function_name
);
591 lua_pushstring(L
, msg
.c_str());
598 std::string msg
= "call of overloaded '";
599 msg
+= rep
->crep
->name();
603 msg
+= stack_content_by_name(L
, 2);
604 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
606 std::vector
<overload_rep
> candidates
;
607 find_exact_match(L
, rep
->overloads().begin(), rep
->overloads().end(), min_match
, num_params
, candidates
);
609 std::string function_name
;
610 function_name
+= rep
->crep
->name();
611 function_name
+= ":";
612 function_name
+= rep
->name
;
614 msg
+= get_overload_signatures(L
, candidates
.begin(), candidates
.end(), function_name
);
616 lua_pushstring(L
, msg
.c_str());
623 #ifndef LUABIND_NO_EXCEPTIONS
630 const overload_rep
& o
= rep
->overloads()[match_index
];
631 return o
.call(L
, *obj
);
633 #ifndef LUABIND_NO_EXCEPTIONS
636 catch(const std::exception
& e
)
638 lua_pushstring(L
, e
.what());
640 catch (const char* s
)
642 lua_pushstring(L
, s
);
646 std::string msg
= rep
->crep
->name();
649 msg
+= "() threw an exception";
650 lua_pushstring(L
, msg
.c_str());
652 // we can only reach this line if an exception was thrown
654 return 0; // will never be reached
667 int pointer_offset
; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance)
672 inline void add_base_class(const base_info
& binfo
)
674 // If you hit this assert you are deriving from a type that is not registered
675 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
676 // Please note that if you don't need to have access to the base class or the
677 // conversion from the derived class to the base class, you don't need
678 // to tell luabind that it derives.
679 assert(binfo
.base
&& "You cannot derive from an unregistered type");
681 class_rep
* bcrep
= binfo
.base
;
683 // import all functions from the base
684 for (std::map
<const char*, method_rep
, ltstr
>::const_iterator i
= bcrep
->m_methods
.begin(); i
!= bcrep
->m_methods
.end(); ++i
)
686 #ifndef LUABIND_DONT_COPY_STRINGS
687 m_strings
.push_back(dup_string(i
->first
));
688 method_rep
& m
= m_methods
[m_strings
.back()];
690 method_rep
& m
= m_methods
[i
->first
];
695 for (std::vector
<overload_rep
>::const_iterator j
= i
->second
.overloads().begin(); j
!= i
->second
.overloads().end(); ++j
)
698 o
.add_offset(binfo
.pointer_offset
);
703 // import all getters from the base
704 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_getters
.begin(); i
!= bcrep
->m_getters
.end(); ++i
)
706 #ifndef LUABIND_DONT_COPY_STRINGS
707 m_strings
.push_back(dup_string(i
->first
));
708 callback
& m
= m_getters
[m_strings
.back()];
710 callback
& m
= m_getters
[i
->first
];
712 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
713 m
.func
= i
->second
.func
;
716 // import all setters from the base
717 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_setters
.begin(); i
!= bcrep
->m_setters
.end(); ++i
)
719 #ifndef LUABIND_DONT_COPY_STRINGS
720 // TODO: optimize this by not copying the string if it already exists in m_setters.
721 // This goes for m_getters, m_static_constants and m_functions too. Both here
722 // in add_base() and in the add_function(), add_getter() ... functions.
723 m_strings
.push_back(dup_string(i
->first
));
724 callback
& m
= m_setters
[m_strings
.back()];
726 callback
& m
= m_setters
[i
->first
];
728 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
729 m
.func
= i
->second
.func
;
732 // import all static constants
733 for (std::map
<const char*, int, ltstr
>::const_iterator i
= bcrep
->m_static_constants
.begin(); i
!= bcrep
->m_static_constants
.end(); ++i
)
735 #ifndef LUABIND_DONT_COPY_STRINGS
736 m_strings
.push_back(dup_string(i
->first
));
737 int& v
= m_static_constants
[m_strings
.back()];
739 int& v
= m_static_constants
[i
->first
];
744 // import all operators
745 for (int i
= 0; i
< number_of_operators
; ++i
)
747 for (std::vector
<operator_callback
>::const_iterator j
= bcrep
->m_operators
[i
].begin(); j
!= bcrep
->m_operators
[i
].end(); ++j
)
748 m_operators
[i
].push_back(*j
);
751 // also, save the baseclass info to be used for typecasts
752 m_bases
.push_back(binfo
);
756 inline const std::vector
<base_info
>& bases() const throw() { return m_bases
; }
757 inline LUABIND_TYPE_INFO
type() const throw() { return m_type
; }
758 inline void set_type(LUABIND_TYPE_INFO t
) { m_type
= t
; }
760 inline void add_function(const char* name
, const overload_rep
& o
)
763 #ifdef LUABIND_DONT_COPY_STRINGS
764 detail::method_rep
& method
= m_methods
[name
];
767 m_strings
.push_back(dup_string(name
));
768 detail::method_rep
& method
= m_methods
[m_strings
.back()];
769 method
.name
= m_strings
.back();
772 method
.add_overload(o
);
776 inline void add_constructor(const detail::construct_rep::overload_t
& o
)
778 m_constructor
.overloads
.push_back(o
);
781 inline void add_wrapped_constructor(const detail::construct_rep::overload_t
& o
)
783 m_wrapped_constructor
.overloads
.push_back(o
);
786 inline const char* name() const throw()
788 #ifdef LUABIND_DONT_COPY_STRINGS
791 return m_name
.c_str();
795 inline void add_getter(const char* name
, const boost::function2
<int, lua_State
*, int>& g
)
799 c
.pointer_offset
= 0;
800 #ifndef LUABIND_DONT_COPY_STRINGS
801 m_strings
.push_back(dup_string(name
));
802 m_getters
[m_strings
.back()] = c
;
808 inline void add_setter(const char* name
, const boost::function2
<int, lua_State
*, int>& s
)
812 c
.pointer_offset
= 0;
813 #ifndef LUABIND_DONT_COPY_STRINGS
814 m_strings
.push_back(dup_string(name
));
815 m_setters
[m_strings
.back()] = c
;
821 #ifndef LUABIND_NO_ERROR_CHECKING
822 inline void add_operator(lua_State
*, int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), void(*sig
)(lua_State
*, std::string
&), int arity
)
824 inline void add_operator(lua_State
*, int op_id
, int(*func
)(lua_State
*), int(*matcher
)(lua_State
*), int arity
)
829 o
.set_match_fun(matcher
);
832 #ifndef LUABIND_NO_ERROR_CHECKING
837 m_operators
[op_id
].push_back(o
);
840 // the lua reference to this class_rep
841 inline int self_ref() const throw() { return m_self_ref
; }
843 // the lua reference to the metatable for this class' instances
844 inline int metatable_ref() const throw() { return m_instance_metatable
; }
846 inline int table_ref() const { return m_table_ref
; }
848 inline void(*destructor() const)(void*) { return m_destructor
; }
850 inline class_type
get_class_type() const { return m_class_type
; }
852 void add_static_constant(const char* name
, int val
)
854 #ifndef LUABIND_DONT_COPY_STRINGS
855 m_strings
.push_back(dup_string(name
));
856 m_static_constants
[m_strings
.back()] = val
;
858 m_static_constants
[name
] = val
;
862 static inline int super_callback(lua_State
* L
)
864 int args
= lua_gettop(L
);
866 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, lua_upvalueindex(2)));
867 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
868 class_rep
* base
= crep
->bases()[0].base
;
870 // std::cout << "__super of " << base->name() << "\n";
872 if (base
->get_class_type() == class_rep::lua_class
)
874 if (base
->bases().empty())
876 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
878 lua_pushstring(L
, "super");
880 lua_settable(L
, LUA_GLOBALSINDEX
);
884 lua_pushstring(L
, "super");
885 lua_pushlightuserdata(L
, base
);
886 lua_pushvalue(L
, lua_upvalueindex(2));
887 lua_pushcclosure(L
, super_callback
, 2);
888 lua_settable(L
, LUA_GLOBALSINDEX
);
891 // std::cout << " lua_class\n";
892 detail::getref(L
, base
->table_ref());
893 lua_pushstring(L
, "__init");
898 lua_pushvalue(L
, lua_upvalueindex(2));
901 lua_call(L
, args
+ 1, 0);
903 // TODO: instead of clearing the global variable "super"
904 // store it temporarily in the registry. maybe we should
905 // have some kind of warning if the super global is used?
906 lua_pushstring(L
, "super");
908 lua_settable(L
, LUA_GLOBALSINDEX
);
912 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
913 // std::cout << " cpp_class\n";
915 // we need to push some garbage at index 1 to make the construction work
916 lua_pushboolean(L
, 1);
919 construct_rep
* rep
= &base
->m_constructor
;
921 bool ambiguous
= false;
922 int match_index
= -1;
923 int min_match
= std::numeric_limits
<int>::max();
926 #ifdef LUABIND_NO_ERROR_CHECKING
928 if (rep
->overloads
.size() == 1)
937 int num_params
= lua_gettop(L
) - 1;
938 found
= find_best_match(L
, rep
->overloads
.begin(), rep
->overloads
.end(), ambiguous
, min_match
, match_index
, num_params
);
940 #ifdef LUABIND_NO_ERROR_CHECKING
949 std::string msg
= "no constructor of '";
951 msg
+= "' matched the arguments (";
952 msg
+= stack_content_by_name(L
, 2);
954 lua_pushstring(L
, msg
.c_str());
961 std::string msg
= "call of overloaded constructor '";
964 msg
+= stack_content_by_name(L
, 2);
965 msg
+= ")' is ambiguous";
966 lua_pushstring(L
, msg
.c_str());
971 // TODO: should this be a warning or something?
973 // since the derived class is a lua class
974 // it may have reimplemented virtual functions
975 // therefore, we have to instantiate the Basewrapper
976 // if there is no basewrapper, throw a run-time error
977 if (!rep->overloads[match_index].has_wrapped_construct())
980 std::string msg = "Cannot derive from C++ class '";
982 msg += "'. It does not have a wrapped type";
983 lua_pushstring(L, msg.c_str());
990 #ifndef LUABIND_NO_EXCEPTIONS
997 if (!rep
->overloads
[match_index
].has_wrapped_construct())
999 // if the type doesn't have a wrapped type, use the ordinary constructor
1000 obj
->set_object(rep
->overloads
[match_index
].construct(L
));
1004 // get reference to lua object
1005 lua_pushvalue(L
, lua_upvalueindex(2));
1006 int ref
= detail::ref(L
);
1007 obj
->set_object(rep
->overloads
[match_index
].construct_wrapped(L
, ref
));
1009 // TODO: is the wrapped type destructed correctly?
1010 // it should, since the destructor is either the wrapped type's
1011 // destructor or the base type's destructor, depending on wether
1012 // the type has a wrapped type or not.
1013 obj
->set_destructor(base
->destructor());
1016 #ifndef LUABIND_NO_EXCEPTIONS
1019 catch(const std::exception
& e
)
1021 lua_pushstring(L
, e
.what());
1023 catch(const char* s
)
1025 lua_pushstring(L
, s
);
1029 std::string msg
= base
->m_name
;
1030 msg
+= "() threw an exception";
1031 lua_pushstring(L
, msg
.c_str());
1033 // can only be reached if an exception was thrown
1042 static int lua_settable_dispatcher(lua_State
* L
)
1044 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1045 detail::getref(L
, crep
->m_table_ref
);
1051 static int construct_lua_class_callback(lua_State
* L
)
1053 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1055 int args
= lua_gettop(L
);
1057 // lua stack: crep <arguments>
1060 int ref
= detail::ref(L
);
1062 bool has_bases
= !crep
->bases().empty();
1066 lua_pushstring(L
, "super");
1067 lua_pushvalue(L
, 1); // crep
1070 // lua stack: crep <arguments> "super" crep
1072 // lua stack: crep <arguments>
1075 // if we have a baseclass we set the flag to say that the super has not yet been called
1076 // we will use this flag later to check that it actually was called from __init()
1077 int flags
= object_rep::lua_class
| object_rep::owner
| (has_bases
? object_rep::call_super
: 0);
1079 void* obj_ptr
= lua_newuserdata(L
, sizeof(object_rep
));
1080 new(obj_ptr
) object_rep(crep
, flags
, ref
);
1082 detail::getref(L
, crep
->metatable_ref());
1083 lua_setmetatable(L
, -2);
1085 // lua stack: crep <arguments> "super" crep obj_ptr
1087 // lua stack: crep <arguments> obj_ptr
1089 if (has_bases
) lua_pushvalue(L
, -1); // obj_ptr
1090 lua_replace(L
, 1); // obj_ptr
1092 // lua stack: obj_ptr <arguments> "super" crep obj_ptr
1094 // lua stack: obj_ptr <arguments>
1098 lua_pushcclosure(L
, super_callback
, 2);
1099 // lua stack: crep <arguments> "super" function
1100 lua_settable(L
, LUA_GLOBALSINDEX
);
1103 // lua stack: crep <arguments>
1105 lua_pushvalue(L
, 1);
1108 detail::getref(L
, crep
->table_ref());
1109 lua_pushstring(L
, "__init");
1110 lua_gettable(L
, -2);
1112 #ifndef LUABIND_NO_ERROR_CHECKING
1114 // TODO: should this be a run-time error?
1115 // maybe the default behavior should be to just call
1116 // the base calss' constructor. We should register
1117 // the super callback funktion as __init
1118 if (!lua_isfunction(L
, -1))
1121 std::string msg
= crep
->name();
1122 msg
+= ":__init is not defined";
1123 lua_pushstring(L
, msg
.c_str());
1130 lua_insert(L
, 2); // function first on stack
1132 // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
1133 // we don't have any stack objects here
1134 lua_call(L
, args
, 0);
1136 #ifndef LUABIND_NO_ERROR_CHECKING
1138 object_rep
* obj
= static_cast<object_rep
*>(obj_ptr
);
1139 if (obj
->flags() & object_rep::call_super
)
1141 lua_pushstring(L
, "derived class must call super on base");
1150 // called from the metamethod for __index
1151 // obj is the object pointer
1152 static int lua_class_gettable(lua_State
* L
)
1154 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1155 class_rep
* crep
= obj
->crep();
1157 #ifndef LUABIND_NO_ERROR_CHECKING
1159 if (obj
->flags() & object_rep::call_super
)
1161 lua_pushstring(L
, "derived class must call super on base");
1167 detail::getref(L
, obj
->lua_table_ref());
1168 lua_pushvalue(L
, 2);
1169 lua_gettable(L
, -2);
1171 if (!lua_isnil(L
, -1)) return 1;
1175 detail::getref(L
, crep
->table_ref());
1176 lua_pushvalue(L
, 2);
1177 lua_gettable(L
, -2);
1179 if (!lua_isnil(L
, -1)) return 1;
1184 if (lua_isnil(L
, 2))
1190 // we have to ignore the first argument since this may point to
1191 // a method that is not present in this class (but in a subclass)
1192 const char* key
= lua_tostring(L
, 2);
1194 std::map
<const char*, method_rep
, ltstr
>::iterator i
= crep
->m_methods
.find(key
);
1195 if (i
!= crep
->m_methods
.end())
1197 // the name is a method, return it
1198 lua_pushlightuserdata(L
, &i
->second
);
1199 lua_pushcclosure(L
, class_rep::function_dispatcher
, 1);
1203 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_getters
.find(key
);
1204 if (j
!= crep
->m_getters
.end())
1206 // the name is a data member
1207 return j
->second
.func(L
, j
->second
.pointer_offset
);
1214 // called from the metamethod for __newindex
1215 // obj is the object pointer
1216 static int lua_class_settable(lua_State
* L
)
1218 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1219 class_rep
* crep
= obj
->crep();
1221 #ifndef LUABIND_NO_ERROR_CHECKING
1223 if (obj
->flags() & object_rep::call_super
)
1225 // this block makes sure the std::string is destructed
1226 // before lua_error is called
1228 std::string msg
= "derived class '";
1229 msg
+= crep
->name();
1230 msg
+= "'must call super on base";
1231 lua_pushstring(L
, msg
.c_str());
1238 // we have to ignore the first argument since this may point to
1239 // a method that is not present in this class (but in a subclass)
1240 const char* key
= lua_tostring(L
, 2);
1241 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_setters
.find(key
);
1243 if (j
== crep
->m_setters
.end())
1245 std::map
<const char*, class_rep::callback
, ltstr
>::iterator k
= crep
->m_getters
.find(key
);
1247 #ifndef LUABIND_NO_ERROR_CHECKING
1249 if (k
!= crep
->m_getters
.end())
1252 std::string msg
= "cannot set property '";
1253 msg
+= crep
->name();
1256 msg
+= "', because it's read only";
1257 lua_pushstring(L
, msg
.c_str());
1264 detail::getref(L
, obj
->lua_table_ref());
1270 // the name is a data member
1271 j
->second
.func(L
, j
->second
.pointer_offset
);
1277 static int static_class_gettable(lua_State
* L
)
1279 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1281 if (crep
->get_class_type() == class_rep::lua_class
)
1283 detail::getref(L
, crep
->m_table_ref
);
1284 lua_pushvalue(L
, 2);
1285 lua_gettable(L
, -2);
1286 if (!lua_isnil(L
, -1)) return 1;
1290 const char* key
= lua_tostring(L
, 2);
1292 std::map
<const char*, method_rep
, ltstr
>::iterator i
= crep
->m_methods
.find(key
);
1293 if (i
!= crep
->m_methods
.end())
1295 // the name is a method, return it
1296 lua_pushlightuserdata(L
, &i
->second
);
1297 lua_pushcclosure(L
, class_rep::function_dispatcher
, 1);
1301 #ifndef LUABIND_NO_ERROR_CHECKING
1303 std::map
<const char*, int, ltstr
>::const_iterator j
= crep
->m_static_constants
.find(key
);
1305 if (j
!= crep
->m_static_constants
.end())
1307 lua_pushnumber(L
, j
->second
);
1312 std::string msg
= "no static '";
1314 msg
+= "' in class '";
1315 msg
+= crep
->name();
1317 lua_pushstring(L
, msg
.c_str());
1328 // this is a pointer to the type_info structure for
1330 // warning: this may be a problem when using dll:s, since
1331 // typeid() may actually return different pointers for the same
1333 LUABIND_TYPE_INFO m_type
;
1334 LUABIND_TYPE_INFO m_held_type
;
1336 typedef void*(*extract_ptr_t
)(void*);
1337 extract_ptr_t m_extract_underlying_fun
;
1339 // a list of info for every class this class derives from
1340 // the information stored here is sufficient to do
1341 // type casts to the base classes
1342 std::vector
<base_info
> m_bases
;
1344 // the class' name (as given when registered to lua with class_)
1345 #ifdef LUABIND_DONT_COPY_STRINGS
1351 // contains signatures for all constructors
1352 construct_rep m_constructor
;
1353 construct_rep m_wrapped_constructor
;
1355 // a reference to this structure itself. Since this struct
1356 // is kept inside lua (to let lua collect it when lua_close()
1357 // is called) we need to lock it to prevent collection.
1358 // the actual reference is not currently used.
1361 // a reference to the lua table that represents this class
1362 // (only used if it is a lua class)
1365 // the type of this class.. determines if it's written in c++ or lua
1366 class_type m_class_type
;
1368 // this is a lua reference that points to the lua table
1369 // that is to be used as meta table for all instances
1371 int m_instance_metatable
;
1373 // ***** the maps below contains all members in this class *****
1375 // maps method names to a structure with more
1376 // information about that method.
1377 // that struct contains the function-signatures
1378 // for every overload
1379 std::map
<const char*, method_rep
, ltstr
> m_methods
;
1381 #ifndef LUABIND_DONT_COPY_STRINGS
1382 // this is where the strings that the maps contains
1383 // pointer to are kept. To make sure they are destructed.
1384 std::vector
<char*> m_strings
;
1389 boost::function2
<int, lua_State
*, int> func
;
1393 // datamembers, some members may be readonly, and
1394 // only have a getter function
1395 std::map
<const char*, callback
, ltstr
> m_getters
;
1396 std::map
<const char*, callback
, ltstr
> m_setters
;
1398 struct operator_callback
: public overload_rep_base
1400 inline void set_fun(int (*f
)(lua_State
*)) { func
= f
; }
1401 inline int call(lua_State
* L
) { return func(L
); }
1402 inline void set_arity(int arity
) { m_arity
= arity
; }
1406 int(*func
)(lua_State
*);
1409 std::vector
<operator_callback
> m_operators
[number_of_operators
]; // the operators in lua
1411 void(*m_destructor
)(void*);
1413 std::map
<const char*, int, ltstr
> m_static_constants
;
1417 inline bool is_class_rep(lua_State
* L
, int index
)
1419 if (lua_getmetatable(L
, index
) == 0) return false;
1421 lua_pushstring(L
, "__luabind_classrep");
1422 lua_gettable(L
, -2);
1423 if (lua_toboolean(L
, -1))
1436 #endif // LUABIND_CLASS_REP_HPP_INCLUDED