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)
470 int num_params
= lua_gettop(L
) - 1;
471 overload_rep_base
const* first
=
472 rep
->overloads
.empty() ? 0 : &rep
->overloads
.front();
473 found
= find_best_match(L
, first
, rep
->overloads
.size(), sizeof(construct_rep::overload_t
), ambiguous
, min_match
, match_index
, num_params
);
475 #ifdef LUABIND_NO_ERROR_CHECKING
483 std::string
msg("no constructor of '");
485 msg
+= "' matched the arguments (";
486 msg
+= stack_content_by_name(L
, 2);
487 msg
+= ")\n candidates are:\n";
489 msg
+= get_overload_signatures(L
, rep
->overloads
.begin(), rep
->overloads
.end(), crep
->name());
491 lua_pushstring(L
, msg
.c_str());
498 std::string
msg("call of overloaded constructor '");
501 msg
+= stack_content_by_name(L
, 2);
502 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
504 std::vector
<const overload_rep_base
*> candidates
;
505 find_exact_match(L
, &rep
->overloads
.front(), rep
->overloads
.size(), sizeof(construct_rep::overload_t
), min_match
, num_params
, candidates
);
506 msg
+= get_overload_signatures_candidates(L
, candidates
.begin(), candidates
.end(), crep
->name());
508 lua_pushstring(L
, msg
.c_str());
515 #ifndef LUABIND_NO_EXCEPTIONS
524 boost::tie(obj_rep
,held
) = crep
->allocate(L
);
526 weak_ref
backref(L
, -1);
528 void* object_ptr
= rep
->overloads
[match_index
].construct(L
, backref
);
530 if (crep
->has_holder())
532 crep
->m_construct_holder(held
, object_ptr
);
535 new(obj_rep
) object_rep(object_ptr
, crep
, object_rep::owner
, crep
->destructor());
537 detail::getref(L
, crep
->m_instance_metatable
);
538 lua_setmetatable(L
, -2);
541 #ifndef LUABIND_NO_EXCEPTIONS
548 catch(const std::exception
& e
)
550 lua_pushstring(L
, e
.what());
554 lua_pushstring(L
, s
);
559 std::string msg
= crep
->name();
560 msg
+= "() threw an exception";
561 lua_pushstring(L
, msg
.c_str());
565 // we can only reach this line if an exception was thrown
567 return 0; // will never be reached
574 the functions dispatcher assumes the following:
577 1: method_rep* method, points to the method_rep that this dispatcher is to call
578 2: boolean force_static, is true if this is to be a static call
579 and false if it is a normal call (= virtual if possible).
582 1: object_rep* self, points to the object the call is being made on
585 int luabind::detail::class_rep::function_dispatcher(lua_State
* L
)
590 assert(lua_getinfo(L, "u", &tmp_));
591 assert(tmp_.nups == 2);*/
592 assert(lua_type(L
, lua_upvalueindex(1)) == LUA_TLIGHTUSERDATA
);
593 assert(lua_type(L
, lua_upvalueindex(2)) == LUA_TBOOLEAN
);
594 assert(lua_type(L
, lua_upvalueindex(3)) == LUA_TLIGHTUSERDATA
);
595 assert(lua_touserdata(L
, lua_upvalueindex(3)) == reinterpret_cast<void*>(0x1337));
599 // assert(lua_type(L, 1) == LUA_TUSERDATA);
603 method_rep
* rep
= static_cast<method_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
604 int force_static_call
= lua_toboolean(L
, lua_upvalueindex(2));
606 bool ambiguous
= false;
607 int match_index
= -1;
608 int min_match
= std::numeric_limits
<int>::max();
611 #ifdef LUABIND_NO_ERROR_CHECKING
612 if (rep
->overloads().size() == 1)
620 int num_params
= lua_gettop(L
) /*- 1*/;
621 found
= find_best_match(L
, &rep
->overloads().front(), rep
->overloads().size()
622 , sizeof(overload_rep
), ambiguous
, min_match
, match_index
, num_params
);
624 #ifdef LUABIND_NO_ERROR_CHECKING
633 std::string msg
= "no overload of '";
634 msg
+= rep
->crep
->name();
637 msg
+= "' matched the arguments (";
638 msg
+= stack_content_by_name(L
, 1);
639 msg
+= ")\ncandidates are:\n";
641 std::string function_name
;
642 function_name
+= rep
->crep
->name();
643 function_name
+= ":";
644 function_name
+= rep
->name
;
646 msg
+= get_overload_signatures(L
, rep
->overloads().begin()
647 , rep
->overloads().end(), function_name
);
649 lua_pushstring(L
, msg
.c_str());
656 std::string msg
= "call of overloaded '";
657 msg
+= rep
->crep
->name();
661 msg
+= stack_content_by_name(L
, 1);
662 msg
+= ")' is ambiguous\nnone of the overloads have a best conversion:\n";
664 std::vector
<const overload_rep_base
*> candidates
;
665 find_exact_match(L
, &rep
->overloads().front(), rep
->overloads().size()
666 , sizeof(overload_rep
), min_match
, num_params
, candidates
);
668 std::string function_name
;
669 function_name
+= rep
->crep
->name();
670 function_name
+= ":";
671 function_name
+= rep
->name
;
673 msg
+= get_overload_signatures_candidates(L
, candidates
.begin()
674 , candidates
.end(), function_name
);
676 lua_pushstring(L
, msg
.c_str());
683 #ifndef LUABIND_NO_EXCEPTIONS
690 const overload_rep
& o
= rep
->overloads()[match_index
];
692 if (force_static_call
&& !o
.has_static())
694 lua_pushstring(L
, "pure virtual function called");
698 return o
.call(L
, force_static_call
!= 0);
701 #ifndef LUABIND_NO_EXCEPTIONS
707 catch(const std::exception
& e
)
709 lua_pushstring(L
, e
.what());
711 catch (const char* s
)
713 lua_pushstring(L
, s
);
717 std::string msg
= rep
->crep
->name();
720 msg
+= "() threw an exception";
721 lua_pushstring(L
, msg
.c_str());
726 // we can only reach this line if an error occured
728 return 0; // will never be reached
733 #ifndef BOOST_NO_STRINGSTREAM
741 std::string
to_string(luabind::object
const& o
)
743 using namespace luabind
;
744 if (type(o
) == LUA_TSTRING
) return object_cast
<std::string
>(o
);
745 lua_State
* L
= o
.interpreter();
746 LUABIND_CHECK_STACK(L
);
748 #ifdef BOOST_NO_STRINGSTREAM
754 if (type(o
) == LUA_TNUMBER
)
756 s
<< object_cast
<float>(o
);
760 s
<< "<" << lua_typename(L
, type(o
)) << ">";
761 #ifdef BOOST_NO_STRINGSTREAM
768 std::string
member_to_string(luabind::object
const& e
)
770 #if !defined(LUABIND_NO_ERROR_CHECKING)
771 using namespace luabind
;
772 lua_State
* L
= e
.interpreter();
773 LUABIND_CHECK_STACK(L
);
775 if (type(e
) == LUA_TFUNCTION
)
778 detail::stack_pop
p(L
, 1);
781 if (lua_getupvalue(L
, -1, 3) == 0) return to_string(e
);
782 detail::stack_pop
p2(L
, 1);
783 if (lua_touserdata(L
, -1) != reinterpret_cast<void*>(0x1337)) return to_string(e
);
786 #ifdef BOOST_NO_STRINGSTREAM
792 lua_getupvalue(L
, -1, 2);
793 detail::stack_pop
p2(L
, 1);
794 int b
= lua_toboolean(L
, -1);
795 s
<< "<c++ function";
796 if (b
) s
<< " (default)";
801 lua_getupvalue(L
, -1, 1);
802 detail::stack_pop
p2(L
, 1);
803 method_rep
* m
= static_cast<method_rep
*>(lua_touserdata(L
, -1));
805 for (std::vector
<overload_rep
>::const_iterator i
= m
->overloads().begin();
806 i
!= m
->overloads().end(); ++i
)
809 i
->get_signature(L
, str
);
810 s
<< " " << str
<< "\n";
813 #ifdef BOOST_NO_STRINGSTREAM
826 std::string
luabind::detail::class_rep::class_info_string(lua_State
* L
) const
828 #ifdef BOOST_NO_STRINGSTREAM
831 std::stringstream ret
;
834 ret
<< "CLASS: " << m_name
<< "\n";
836 ret
<< "dynamic dispatch functions:\n------------------\n";
838 for (luabind::iterator
i(m_table
), end
; i
!= end
; ++i
)
840 luabind::object e
= *i
;
841 ret
<< " " << to_string(i
.key()) << ": " << member_to_string(e
) << "\n";
844 ret
<< "default implementations:\n------------------\n";
846 for (luabind::iterator
i(m_default_table
), end
; i
!= end
; ++i
)
848 luabind::object e
= *i
;
849 ret
<< " " << to_string(i
.key()) << ": " << member_to_string(e
) << "\n";
851 #ifdef BOOST_NO_STRINGSTREAM
858 void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info
& binfo
)
860 // If you hit this assert you are deriving from a type that is not registered
861 // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
862 // Please note that if you don't need to have access to the base class or the
863 // conversion from the derived class to the base class, you don't need
864 // to tell luabind that it derives.
865 assert(binfo
.base
&& "You cannot derive from an unregistered type");
867 class_rep
* bcrep
= binfo
.base
;
869 // import all functions from the base
870 typedef std::list
<detail::method_rep
> methods_t
;
872 for (methods_t::const_iterator i
= bcrep
->m_methods
.begin();
873 i
!= bcrep
->m_methods
.end(); ++i
)
878 // import all getters from the base
879 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_getters
.begin();
880 i
!= bcrep
->m_getters
.end(); ++i
)
882 callback
& m
= m_getters
[i
->first
];
883 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
884 m
.func
= i
->second
.func
;
886 #ifndef LUABIND_NO_ERROR_CHECKING
887 m
.match
= i
->second
.match
;
888 m
.sig
= i
->second
.sig
;
892 // import all setters from the base
893 for (std::map
<const char*, callback
, ltstr
>::const_iterator i
= bcrep
->m_setters
.begin();
894 i
!= bcrep
->m_setters
.end(); ++i
)
896 callback
& m
= m_setters
[i
->first
];
897 m
.pointer_offset
= i
->second
.pointer_offset
+ binfo
.pointer_offset
;
898 m
.func
= i
->second
.func
;
900 #ifndef LUABIND_NO_ERROR_CHECKING
901 m
.match
= i
->second
.match
;
902 m
.sig
= i
->second
.sig
;
906 // import all static constants
907 for (std::map
<const char*, int, ltstr
>::const_iterator i
= bcrep
->m_static_constants
.begin();
908 i
!= bcrep
->m_static_constants
.end(); ++i
)
910 int& v
= m_static_constants
[i
->first
];
914 // import all operators
915 for (int i
= 0; i
< number_of_operators
; ++i
)
917 for (std::vector
<operator_callback
>::const_iterator j
= bcrep
->m_operators
[i
].begin();
918 j
!= bcrep
->m_operators
[i
].end(); ++j
)
919 m_operators
[i
].push_back(*j
);
922 // also, save the baseclass info to be used for typecasts
923 m_bases
.push_back(binfo
);
926 int luabind::detail::class_rep::super_callback(lua_State
* L
)
928 int args
= lua_gettop(L
);
930 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, lua_upvalueindex(2)));
931 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, lua_upvalueindex(1)));
932 class_rep
* base
= crep
->bases()[0].base
;
934 if (base
->get_class_type() == class_rep::lua_class
)
936 if (base
->bases().empty())
938 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
940 lua_pushstring(L
, "super");
942 lua_settable(L
, LUA_GLOBALSINDEX
);
946 lua_pushstring(L
, "super");
947 lua_pushlightuserdata(L
, base
);
948 lua_pushvalue(L
, lua_upvalueindex(2));
949 lua_pushcclosure(L
, super_callback
, 2);
950 lua_settable(L
, LUA_GLOBALSINDEX
);
954 lua_pushstring(L
, "__init");
959 lua_pushvalue(L
, lua_upvalueindex(2));
962 lua_call(L
, args
+ 1, 0);
964 // TODO: instead of clearing the global variable "super"
965 // store it temporarily in the registry. maybe we should
966 // have some kind of warning if the super global is used?
967 lua_pushstring(L
, "super");
969 lua_settable(L
, LUA_GLOBALSINDEX
);
973 obj
->set_flags(obj
->flags() & ~object_rep::call_super
);
975 // we need to push some garbage at index 1 to make the construction work
976 lua_pushboolean(L
, 1);
979 construct_rep
* rep
= &base
->m_constructor
;
981 bool ambiguous
= false;
982 int match_index
= -1;
983 int min_match
= std::numeric_limits
<int>::max();
986 #ifdef LUABIND_NO_ERROR_CHECKING
988 if (rep
->overloads
.size() == 1)
997 int num_params
= lua_gettop(L
) - 1;
998 found
= find_best_match(L
, &rep
->overloads
.front(), rep
->overloads
.size(), sizeof(construct_rep::overload_t
), ambiguous
, min_match
, match_index
, num_params
);
1000 #ifdef LUABIND_NO_ERROR_CHECKING
1009 std::string msg
= "no constructor of '";
1010 msg
+= base
->m_name
;
1011 msg
+= "' matched the arguments (";
1012 msg
+= stack_content_by_name(L
, 2);
1014 lua_pushstring(L
, msg
.c_str());
1021 std::string msg
= "call of overloaded constructor '";
1022 msg
+= base
->m_name
;
1024 msg
+= stack_content_by_name(L
, 2);
1025 msg
+= ")' is ambiguous";
1026 lua_pushstring(L
, msg
.c_str());
1031 // TODO: should this be a warning or something?
1033 // since the derived class is a lua class
1034 // it may have reimplemented virtual functions
1035 // therefore, we have to instantiate the Basewrapper
1036 // if there is no basewrapper, throw a run-time error
1037 if (!rep->overloads[match_index].has_wrapped_construct())
1040 std::string msg = "Cannot derive from C++ class '";
1041 msg += base->name();
1042 msg += "'. It does not have a wrapped type";
1043 lua_pushstring(L, msg.c_str());
1050 #ifndef LUABIND_NO_EXCEPTIONS
1056 lua_pushvalue(L
, lua_upvalueindex(2));
1057 weak_ref
backref(L
, -1);
1060 void* storage_ptr
= obj
->ptr();
1062 if (!rep
->overloads
[match_index
].has_wrapped_construct())
1064 // if the type doesn't have a wrapped type, use the ordinary constructor
1065 void* instance
= rep
->overloads
[match_index
].construct(L
, backref
);
1067 if (crep
->has_holder())
1069 crep
->m_construct_holder(storage_ptr
, instance
);
1073 obj
->set_object(instance
);
1078 // get reference to lua object
1079 /* lua_pushvalue(L, lua_upvalueindex(2));
1080 detail::lua_reference ref;
1082 void* instance = rep->overloads[match_index].construct_wrapped(L, ref);*/
1084 void* instance
= rep
->overloads
[match_index
].construct_wrapped(L
, backref
);
1086 if (crep
->has_holder())
1088 crep
->m_construct_holder(storage_ptr
, instance
);
1092 obj
->set_object(instance
);
1095 // TODO: is the wrapped type destructed correctly?
1096 // it should, since the destructor is either the wrapped type's
1097 // destructor or the base type's destructor, depending on wether
1098 // the type has a wrapped type or not.
1099 obj
->set_destructor(base
->destructor());
1102 #ifndef LUABIND_NO_EXCEPTIONS
1108 catch(const std::exception
& e
)
1110 lua_pushstring(L
, e
.what());
1112 catch(const char* s
)
1114 lua_pushstring(L
, s
);
1118 std::string msg
= base
->m_name
;
1119 msg
+= "() threw an exception";
1120 lua_pushstring(L
, msg
.c_str());
1122 // can only be reached if an exception was thrown
1133 int luabind::detail::class_rep::lua_settable_dispatcher(lua_State
* L
)
1135 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1141 lua_pushvalue(L
, -3);
1142 lua_pushvalue(L
, -3);
1147 // get default table
1148 crep
->get_default_table(L
);
1152 crep
->m_operator_cache
= 0; // invalidate cache
1157 int luabind::detail::class_rep::construct_lua_class_callback(lua_State
* L
)
1159 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1161 int args
= lua_gettop(L
);
1163 // lua stack: crep <arguments>
1166 detail::lua_reference ref
;
1169 bool has_bases
= !crep
->bases().empty();
1173 lua_pushstring(L
, "super");
1174 lua_pushvalue(L
, 1); // crep
1177 // lua stack: crep <arguments> "super" crep
1179 // lua stack: crep <arguments>
1181 // if we have a baseclass we set the flag to say that the super has not yet been called
1182 // we will use this flag later to check that it actually was called from __init()
1183 int flags
= object_rep::lua_class
| object_rep::owner
| (has_bases
? object_rep::call_super
: 0);
1185 // void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));
1189 boost::tie(obj_ptr
, held_storage
) = crep
->allocate(L
);
1190 (new(obj_ptr
) object_rep(crep
, flags
, ref
))->set_object(held_storage
);
1192 detail::getref(L
, crep
->metatable_ref());
1193 lua_setmetatable(L
, -2);
1195 // lua stack: crep <arguments> "super" crep obj_ptr
1197 // lua stack: crep <arguments> obj_ptr
1199 if (has_bases
) lua_pushvalue(L
, -1); // obj_ptr
1200 lua_replace(L
, 1); // obj_ptr
1202 // lua stack: obj_ptr <arguments> "super" crep obj_ptr
1204 // lua stack: obj_ptr <arguments>
1208 lua_pushcclosure(L
, super_callback
, 2);
1209 // lua stack: crep <arguments> "super" function
1210 lua_settable(L
, LUA_GLOBALSINDEX
);
1213 // lua stack: crep <arguments>
1215 lua_pushvalue(L
, 1);
1219 lua_pushstring(L
, "__init");
1220 lua_gettable(L
, -2);
1222 #ifndef LUABIND_NO_ERROR_CHECKING
1224 // TODO: should this be a run-time error?
1225 // maybe the default behavior should be to just call
1226 // the base calss' constructor. We should register
1227 // the super callback funktion as __init
1228 if (!lua_isfunction(L
, -1))
1231 std::string msg
= crep
->name();
1232 msg
+= ":__init is not defined";
1233 lua_pushstring(L
, msg
.c_str());
1240 lua_insert(L
, 2); // function first on stack
1242 // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
1243 // we don't have any stack objects here
1244 lua_call(L
, args
, 0);
1246 #ifndef LUABIND_NO_ERROR_CHECKING
1248 object_rep
* obj
= static_cast<object_rep
*>(obj_ptr
);
1249 if (obj
->flags() & object_rep::call_super
)
1251 lua_pushstring(L
, "derived class must call super on base");
1260 // called from the metamethod for __index
1261 // obj is the object pointer
1262 int luabind::detail::class_rep::lua_class_gettable(lua_State
* L
)
1264 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1265 class_rep
* crep
= obj
->crep();
1267 #ifndef LUABIND_NO_ERROR_CHECKING
1269 if (obj
->flags() & object_rep::call_super
)
1271 lua_pushstring(L
, "derived class must call super on base");
1277 // we have to ignore the first argument since this may point to
1278 // a method that is not present in this class (but in a subclass)
1280 // BUG: This might catch members called "__ok\0foobar"
1281 const char* key
= lua_tostring(L
, 2);
1283 if (key
&& !std::strcmp(key
, "__ok"))
1285 class_rep
* crep
= obj
->crep();
1287 void* p
= crep
->extractor() ? crep
->extractor()(obj
->ptr())
1290 lua_pushboolean(L
, p
!= 0);
1294 // first look in the instance's table
1295 detail::lua_reference
const& tbl
= obj
->get_lua_table();
1296 assert(tbl
.is_valid());
1298 lua_pushvalue(L
, 2);
1299 lua_gettable(L
, -2);
1300 if (!lua_isnil(L
, -1))
1302 lua_remove(L
, -2); // remove table
1307 // then look in the class' table
1309 lua_pushvalue(L
, 2);
1310 lua_gettable(L
, -2);
1312 if (!lua_isnil(L
, -1))
1314 lua_remove(L
, -2); // more table
1320 if (lua_isnil(L
, 2))
1326 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_getters
.find(key
);
1327 if (j
!= crep
->m_getters
.end())
1329 // the name is a data member
1330 return j
->second
.func(L
, j
->second
.pointer_offset
);
1337 // called from the metamethod for __newindex
1338 // obj is the object pointer
1339 int luabind::detail::class_rep::lua_class_settable(lua_State
* L
)
1341 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, 1));
1342 class_rep
* crep
= obj
->crep();
1344 #ifndef LUABIND_NO_ERROR_CHECKING
1346 if (obj
->flags() & object_rep::call_super
)
1348 // this block makes sure the std::string is destructed
1349 // before lua_error is called
1351 std::string msg
= "derived class '";
1352 msg
+= crep
->name();
1353 msg
+= "'must call super on base";
1354 lua_pushstring(L
, msg
.c_str());
1361 // we have to ignore the first argument since this may point to
1362 // a method that is not present in this class (but in a subclass)
1363 // BUG: This will not work with keys with extra nulls in them
1364 const char* key
= lua_tostring(L
, 2);
1367 std::map
<const char*, class_rep::callback
, ltstr
>::iterator j
= crep
->m_setters
.find(key
);
1369 // if the strlen(key) is not the true length,
1370 // it means that the member-name contains
1371 // extra nulls. luabind does not support such
1372 // names as member names. So, use the lua
1373 // table as fall-back
1374 if (j
== crep
->m_setters
.end()
1375 || std::strlen(key
) != lua_strlen(L
, 2))
1377 std::map
<const char*, class_rep::callback
, ltstr
>::iterator k
= crep
->m_getters
.find(key
);
1379 #ifndef LUABIND_NO_ERROR_CHECKING
1381 if (k
!= crep
->m_getters
.end())
1384 std::string msg
= "cannot set property '";
1385 msg
+= crep
->name();
1388 msg
+= "', because it's read only";
1389 lua_pushstring(L
, msg
.c_str());
1396 detail::lua_reference
const& tbl
= obj
->get_lua_table();
1397 assert(tbl
.is_valid());
1404 // the name is a data member
1405 j
->second
.func(L
, j
->second
.pointer_offset
);
1416 int luabind::detail::class_rep::static_class_gettable(lua_State
* L
)
1418 class_rep
* crep
= static_cast<class_rep
*>(lua_touserdata(L
, 1));
1420 // look in the static function table
1421 crep
->get_default_table(L
);
1422 lua_pushvalue(L
, 2);
1423 lua_gettable(L
, -2);
1424 if (!lua_isnil(L
, -1)) return 1;
1427 const char* key
= lua_tostring(L
, 2);
1429 if (std::strlen(key
) != lua_strlen(L
, 2))
1435 std::map
<const char*, int, ltstr
>::const_iterator j
= crep
->m_static_constants
.find(key
);
1437 if (j
!= crep
->m_static_constants
.end())
1439 lua_pushnumber(L
, j
->second
);
1443 #ifndef LUABIND_NO_ERROR_CHECKING
1446 std::string msg
= "no static '";
1448 msg
+= "' in class '";
1449 msg
+= crep
->name();
1451 lua_pushstring(L
, msg
.c_str());
1462 bool luabind::detail::is_class_rep(lua_State
* L
, int index
)
1464 if (lua_getmetatable(L
, index
) == 0) return false;
1466 lua_pushstring(L
, "__luabind_classrep");
1467 lua_gettable(L
, -2);
1468 if (lua_toboolean(L
, -1))
1478 void luabind::detail::finalize(lua_State
* L
, class_rep
* crep
)
1480 if (crep
->get_class_type() != class_rep::lua_class
) return;
1482 // lua_pushvalue(L, -1); // copy the object ref
1484 lua_pushstring(L
, "__finalize");
1485 lua_gettable(L
, -2);
1488 if (lua_isnil(L
, -1))
1494 lua_pushvalue(L
, -2);
1498 for (std::vector
<class_rep::base_info
>::const_iterator
1499 i
= crep
->bases().begin(); i
!= crep
->bases().end(); ++i
)
1501 if (i
->base
) finalize(L
, i
->base
);
1505 void* luabind::detail::class_rep::convert_to(
1506 LUABIND_TYPE_INFO target_type
1507 , const object_rep
* obj
1508 , void* target_memory
) const
1510 // TODO: since this is a member function, we don't have to use the accesor functions for
1511 // the types and the extractor
1513 assert(obj
== 0 || obj
->crep() == this);
1517 if (!(LUABIND_TYPE_INFO_EQUAL(holder_type(), target_type
))
1518 && !(LUABIND_TYPE_INFO_EQUAL(const_holder_type(), target_type
)))
1520 steps
= implicit_cast(this, target_type
, offset
);
1523 // should never be called with a type that can't be cast
1524 assert((steps
>= 0) && "internal error, please report");
1526 if (LUABIND_TYPE_INFO_EQUAL(target_type
, holder_type()))
1530 // we are trying to convert nil to a holder type
1531 m_default_construct_holder(target_memory
);
1532 return target_memory
;
1534 // if the type we are trying to convert to is the holder_type
1535 // it means that his crep has a holder_type (since it would have
1536 // been invalid otherwise, and T cannot be invalid). It also means
1537 // that we need no conversion, since the holder_type is what the
1538 // object points to.
1542 if (LUABIND_TYPE_INFO_EQUAL(target_type
, const_holder_type()))
1546 // we are trying to convert nil to a const holder type
1547 m_default_construct_const_holder(target_memory
);
1548 return target_memory
;
1551 if (obj
->flags() & object_rep::constant
)
1553 // we are holding a constant
1558 // we are holding a non-constant, we need to convert it
1559 // to a const_holder.
1560 m_const_converter(obj
->ptr(), target_memory
);
1561 return target_memory
;
1570 // this means that we have a holder type where the
1571 // raw-pointer needs to be extracted
1572 raw_pointer
= extractor()(obj
->ptr());
1576 if (obj
== 0) raw_pointer
= 0;
1577 else raw_pointer
= obj
->ptr();
1580 return static_cast<char*>(raw_pointer
) + offset
;
1583 void luabind::detail::class_rep::cache_operators(lua_State
* L
)
1585 m_operator_cache
= 0x1;
1587 for (int i
= 0; i
< number_of_operators
; ++i
)
1590 lua_pushstring(L
, get_operator_name(i
));
1593 if (lua_isfunction(L
, -1)) m_operator_cache
|= 1 << (i
+ 1);
1599 bool luabind::detail::class_rep::has_operator_in_lua(lua_State
* L
, int id
)
1601 if ((m_operator_cache
& 0x1) == 0)
1604 const int mask
= 1 << (id
+ 1);
1606 return (m_operator_cache
& mask
) != 0;
1610 // this will merge all overloads of fun into the list of
1611 // overloads in this class
1612 void luabind::detail::class_rep::add_method(luabind::detail::method_rep
const& fun
)
1614 typedef std::list
<detail::method_rep
> methods_t
;
1616 methods_t::iterator m
= std::find_if(
1619 , method_name(fun
.name
));
1620 if (m
== m_methods
.end())
1622 m_methods
.push_back(method_rep());
1623 m
= m_methods
.end();
1624 std::advance(m
, -1);
1629 typedef std::vector
<detail::overload_rep
> overloads_t
;
1631 for (overloads_t::const_iterator j
= fun
.overloads().begin();
1632 j
!= fun
.overloads().end(); ++j
)
1634 detail::overload_rep o
= *j
;
1639 // this function will add all the overloads in method rep to
1640 // this class' lua tables. If there already are overloads with this
1641 // name, thses will simply be appended to the overload list
1642 void luabind::detail::class_rep::register_methods(lua_State
* L
)
1644 LUABIND_CHECK_STACK(L
);
1645 // insert the function in the normal member table
1646 // and in the default member table
1647 m_default_table
.push(L
);
1651 detail::stack_pop
pop_tables(L
, 2);
1653 for (std::list
<method_rep
>::const_iterator m
= m_methods
.begin();
1654 m
!= m_methods
.end(); ++m
)
1656 // create the function closure in m_table
1657 lua_pushstring(L
, m
->name
);
1658 lua_pushlightuserdata(L
, const_cast<void*>((const void*)&(*m
)));
1659 lua_pushboolean(L
, 0);
1660 lua_pushlightuserdata(L
, reinterpret_cast<void*>(0x1337));
1661 lua_pushcclosure(L
, function_dispatcher
, 3);
1662 lua_settable(L
, -3);
1664 // create the function closure in m_default_table
1665 lua_pushstring(L
, m
->name
);
1666 lua_pushlightuserdata(L
, const_cast<void*>((const void*)&(*m
)));
1667 lua_pushboolean(L
, 1);
1668 lua_pushlightuserdata(L
, reinterpret_cast<void*>(0x1337));
1669 lua_pushcclosure(L
, function_dispatcher
, 3);
1670 lua_settable(L
, -4);
1674 const class_rep::property_map
& luabind::detail::class_rep::properties() const