1 // Copyright (c) 2004 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.
25 #include <luabind/lua_include.hpp>
27 #include <luabind/config.hpp>
28 #include <luabind/weak_ref.hpp>
33 // allocation code from lauxlib.c
34 /******************************************************************************
35 * Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved.
37 * Permission is hereby granted, free of charge, to any person obtaining
38 * a copy of this software and associated documentation files (the
39 * "Software"), to deal in the Software without restriction, including
40 * without limitation the rights to use, copy, modify, merge, publish,
41 * distribute, sublicense, and/or sell copies of the Software, and to
42 * permit persons to whom the Software is furnished to do so, subject to
43 * the following conditions:
45 * The above copyright notice and this permission notice shall be
46 * included in all copies or substantial portions of the Software.
48 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
49 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
50 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
51 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
52 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
53 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
54 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55 ******************************************************************************/
61 freelist_ref
= 1, count_ref
= 2
64 void get_weak_table(lua_State
* L
)
66 lua_pushliteral(L
, "__luabind_weak_refs");
67 lua_gettable(L
, LUA_REGISTRYINDEX
);
75 lua_pushliteral(L
, "__mode");
76 lua_pushliteral(L
, "v");
79 lua_setmetatable(L
, -2);
81 lua_rawseti(L
, -2, freelist_ref
);
83 lua_rawseti(L
, -2, count_ref
);
85 lua_pushliteral(L
, "__luabind_weak_refs");
87 lua_settable(L
, LUA_REGISTRYINDEX
);
91 } // namespace unnamed
95 impl(lua_State
* s
, int index
)
100 lua_pushvalue(s
, index
);
103 lua_rawgeti(s
, -1, freelist_ref
);
104 ref
= (int)lua_tonumber(s
, -1);
109 lua_rawgeti(s
, -1, count_ref
);
110 ref
= (int)lua_tonumber(s
, -1) + 1;
112 lua_pushnumber(s
, ref
);
113 lua_rawseti(s
, -2, count_ref
);
117 lua_rawgeti(s
, -1, ref
);
118 lua_rawseti(s
, -2, freelist_ref
);
121 lua_pushvalue(s
, -2); // duplicate value
122 lua_rawseti(s
, -2, ref
);
123 lua_pop(s
, 2); // pop weakref table and value
128 get_weak_table(state
);
129 lua_rawgeti(state
, -1, freelist_ref
);
130 lua_rawseti(state
, -2, ref
);
131 lua_pushnumber(state
, ref
);
132 lua_rawseti(state
, -2, freelist_ref
);
146 weak_ref::weak_ref(lua_State
* L
, int index
)
147 : m_impl(new impl(L
, index
))
152 weak_ref::weak_ref(weak_ref
const& other
)
153 : m_impl(other
.m_impl
)
155 if (m_impl
) ++m_impl
->count
;
158 weak_ref::~weak_ref()
160 if (m_impl
&& --m_impl
->count
== 0)
166 weak_ref
& weak_ref::operator=(weak_ref
const& other
)
168 weak_ref(other
).swap(*this);
172 void weak_ref::swap(weak_ref
& other
)
174 std::swap(m_impl
, other
.m_impl
);
177 void weak_ref::get() const
180 get_weak_table(m_impl
->state
);
181 lua_rawgeti(m_impl
->state
, -1, m_impl
->ref
);
182 lua_remove(m_impl
->state
, -2);
185 lua_State
* weak_ref::state() const
188 return m_impl
->state
;
191 } // namespace luabind