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
);
85 } // namespace unnamed
89 impl(lua_State
* s
, int index
)
94 lua_pushvalue(s
, index
);
97 lua_rawgeti(s
, -1, freelist_ref
);
98 ref
= (int)lua_tonumber(s
, -1);
103 lua_rawgeti(s
, -1, count_ref
);
104 ref
= (int)lua_tonumber(s
, -1) + 1;
106 lua_pushnumber(s
, ref
);
107 lua_rawseti(s
, -2, count_ref
);
111 lua_rawgeti(s
, -1, ref
);
112 lua_rawseti(s
, -2, freelist_ref
);
115 lua_pushvalue(s
, -2); // duplicate value
116 lua_rawseti(s
, -2, ref
);
117 lua_pop(s
, 1); // pop weakref table
122 get_weak_table(state
);
123 lua_rawgeti(state
, -1, freelist_ref
);
124 lua_rawseti(state
, -2, ref
);
125 lua_pushnumber(state
, ref
);
126 lua_rawseti(state
, -2, freelist_ref
);
139 weak_ref::weak_ref(lua_State
* L
, int index
)
140 : m_impl(new impl(L
, index
))
145 weak_ref::weak_ref(weak_ref
const& other
)
146 : m_impl(other
.m_impl
)
148 if (m_impl
) ++m_impl
->count
;
151 weak_ref::~weak_ref()
153 if (m_impl
&& --m_impl
->count
== 0)
159 weak_ref
& weak_ref::operator=(weak_ref
const& other
)
161 weak_ref(other
).swap(*this);
165 void weak_ref::swap(weak_ref
& other
)
167 std::swap(m_impl
, other
.m_impl
);
170 void weak_ref::get() const
173 get_weak_table(m_impl
->state
);
174 lua_rawgeti(m_impl
->state
, -1, m_impl
->ref
);
175 lua_remove(m_impl
->state
, -2);
178 lua_State
* weak_ref::state() const
181 return m_impl
->state
;
184 } // namespace luabind