1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
2 
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:
9 
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 
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.
22 
23 
24 #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED
25 #define LUABIND_OBJECT_REP_HPP_INCLUDED
26 
27 #include <luabind/config.hpp>
28 #include <luabind/detail/class_rep.hpp>
29 #include <luabind/detail/instance_holder.hpp>
30 
31 #include <boost/aligned_storage.hpp>
32 
33 namespace luabind { namespace detail
34 {
35     // implements the selection between dynamic dispatch
36     // or default implementation calls from within a virtual
37     // function wrapper. The input is the self reference on
38     // the top of the stack. Output is the function to call
39     // on the top of the stack (the input self reference will
40     // be popped)
41     LUABIND_API void do_call_member_selection(lua_State* L, char const* name);
42 
43     void finalize(lua_State* L, class_rep* crep);
44 
45     // this class is allocated inside lua for each pointer.
46     // it contains the actual c++ object-pointer.
47     // it also tells if it is const or not.
48     class LUABIND_API object_rep
49     {
50     public:
51         object_rep(instance_holder* instance, class_rep* crep);
52         ~object_rep();
53 
crep() const54         const class_rep* crep() const { return m_classrep; }
crep()55         class_rep* crep() { return m_classrep; }
56 
set_instance(instance_holder * instance)57         void set_instance(instance_holder* instance) { m_instance = instance; }
58 
59         void add_dependency(lua_State* L, int index);
60         void release_dependency_refs(lua_State* L);
61 
get_instance(class_id target) const62         std::pair<void*, int> get_instance(class_id target) const
63         {
64             if (m_instance == 0)
65                 return std::pair<void*, int>(static_cast<void*>(0), -1);
66             return m_instance->get(m_classrep->casts(), target);
67         }
68 
is_const() const69         bool is_const() const
70         {
71             return m_instance && m_instance->pointee_const();
72         }
73 
release()74         void release()
75         {
76             if (m_instance)
77                 m_instance->release();
78         }
79 
allocate(std::size_t size)80         void* allocate(std::size_t size)
81         {
82             if (size <= instance_buffer_size)
83                 return &m_instance_buffer;
84             return std::malloc(size);
85         }
86 
deallocate(void * storage)87         void deallocate(void* storage)
88         {
89             if (storage == &m_instance_buffer)
90                 return;
91             std::free(storage);
92         }
93 
94     private:
95 
96         object_rep(object_rep const&);
97 
98         void operator=(object_rep const&);
99 
100         BOOST_STATIC_CONSTANT(std::size_t, instance_buffer_size=32);
101         boost::aligned_storage<instance_buffer_size> m_instance_buffer;
102         instance_holder* m_instance;
103         class_rep* m_classrep; // the class information about this object's type
104         std::size_t m_dependency_cnt; // counts dependencies
105     };
106 
107     template<class T>
108     struct delete_s
109     {
applyluabind::detail::delete_s110         static void apply(void* ptr)
111         {
112             delete static_cast<T*>(ptr);
113         }
114     };
115 
116     template<class T>
117     struct destruct_only_s
118     {
applyluabind::detail::destruct_only_s119         static void apply(void* ptr)
120         {
121             // Removes unreferenced formal parameter warning on VC7.
122             (void)ptr;
123 #ifndef NDEBUG
124             int completeness_check[sizeof(T)];
125             (void)completeness_check;
126 #endif
127             static_cast<T*>(ptr)->~T();
128         }
129     };
130 
131     LUABIND_API object_rep* get_instance(lua_State* L, int index);
132     LUABIND_API void push_instance_metatable(lua_State* L);
133     LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls);
134 
135 }}
136 
137 #endif // LUABIND_OBJECT_REP_HPP_INCLUDED
138