1*c697fb7fSBrooks Davis // Copyright 2011 Google Inc.
2*c697fb7fSBrooks Davis // All rights reserved.
3*c697fb7fSBrooks Davis //
4*c697fb7fSBrooks Davis // Redistribution and use in source and binary forms, with or without
5*c697fb7fSBrooks Davis // modification, are permitted provided that the following conditions are
6*c697fb7fSBrooks Davis // met:
7*c697fb7fSBrooks Davis //
8*c697fb7fSBrooks Davis // * Redistributions of source code must retain the above copyright
9*c697fb7fSBrooks Davis // notice, this list of conditions and the following disclaimer.
10*c697fb7fSBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*c697fb7fSBrooks Davis // notice, this list of conditions and the following disclaimer in the
12*c697fb7fSBrooks Davis // documentation and/or other materials provided with the distribution.
13*c697fb7fSBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*c697fb7fSBrooks Davis // may be used to endorse or promote products derived from this software
15*c697fb7fSBrooks Davis // without specific prior written permission.
16*c697fb7fSBrooks Davis //
17*c697fb7fSBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*c697fb7fSBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*c697fb7fSBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*c697fb7fSBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*c697fb7fSBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*c697fb7fSBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*c697fb7fSBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*c697fb7fSBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*c697fb7fSBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*c697fb7fSBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*c697fb7fSBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*c697fb7fSBrooks Davis
29*c697fb7fSBrooks Davis extern "C" {
30*c697fb7fSBrooks Davis #include <unistd.h>
31*c697fb7fSBrooks Davis }
32*c697fb7fSBrooks Davis
33*c697fb7fSBrooks Davis #include <cassert>
34*c697fb7fSBrooks Davis #include <cstring>
35*c697fb7fSBrooks Davis
36*c697fb7fSBrooks Davis #include "c_gate.hpp"
37*c697fb7fSBrooks Davis #include "exceptions.hpp"
38*c697fb7fSBrooks Davis #include "state.ipp"
39*c697fb7fSBrooks Davis
40*c697fb7fSBrooks Davis
41*c697fb7fSBrooks Davis namespace {
42*c697fb7fSBrooks Davis
43*c697fb7fSBrooks Davis
44*c697fb7fSBrooks Davis /// Wrapper around lua_getglobal to run in a protected environment.
45*c697fb7fSBrooks Davis ///
46*c697fb7fSBrooks Davis /// \pre stack(-1) is the name of the global to get.
47*c697fb7fSBrooks Davis /// \post stack(-1) is the value of the global.
48*c697fb7fSBrooks Davis ///
49*c697fb7fSBrooks Davis /// \param state The Lua C API state.
50*c697fb7fSBrooks Davis ///
51*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the stack.
52*c697fb7fSBrooks Davis static int
protected_getglobal(lua_State * state)53*c697fb7fSBrooks Davis protected_getglobal(lua_State* state)
54*c697fb7fSBrooks Davis {
55*c697fb7fSBrooks Davis lua_getglobal(state, lua_tostring(state, -1));
56*c697fb7fSBrooks Davis return 1;
57*c697fb7fSBrooks Davis }
58*c697fb7fSBrooks Davis
59*c697fb7fSBrooks Davis
60*c697fb7fSBrooks Davis /// Wrapper around lua_gettable to run in a protected environment.
61*c697fb7fSBrooks Davis ///
62*c697fb7fSBrooks Davis /// \pre stack(-2) is the table to get the element from.
63*c697fb7fSBrooks Davis /// \pre stack(-1) is the table index.
64*c697fb7fSBrooks Davis /// \post stack(-1) is the value of stack(-2)[stack(-1)].
65*c697fb7fSBrooks Davis ///
66*c697fb7fSBrooks Davis /// \param state The Lua C API state.
67*c697fb7fSBrooks Davis ///
68*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the stack.
69*c697fb7fSBrooks Davis static int
protected_gettable(lua_State * state)70*c697fb7fSBrooks Davis protected_gettable(lua_State* state)
71*c697fb7fSBrooks Davis {
72*c697fb7fSBrooks Davis lua_gettable(state, -2);
73*c697fb7fSBrooks Davis return 1;
74*c697fb7fSBrooks Davis }
75*c697fb7fSBrooks Davis
76*c697fb7fSBrooks Davis
77*c697fb7fSBrooks Davis /// Wrapper around lua_next to run in a protected environment.
78*c697fb7fSBrooks Davis ///
79*c697fb7fSBrooks Davis /// \pre stack(-2) is the table to get the next element from.
80*c697fb7fSBrooks Davis /// \pre stack(-1) is the last processed key.
81*c697fb7fSBrooks Davis /// \post stack(-1) is the value of next(stack(-2), stack(-1)).
82*c697fb7fSBrooks Davis ///
83*c697fb7fSBrooks Davis /// \param state The Lua C API state.
84*c697fb7fSBrooks Davis ///
85*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the stack.
86*c697fb7fSBrooks Davis static int
protected_next(lua_State * state)87*c697fb7fSBrooks Davis protected_next(lua_State* state)
88*c697fb7fSBrooks Davis {
89*c697fb7fSBrooks Davis const int more = lua_next(state, -2) != 0;
90*c697fb7fSBrooks Davis lua_pushboolean(state, more);
91*c697fb7fSBrooks Davis return more ? 3 : 1;
92*c697fb7fSBrooks Davis }
93*c697fb7fSBrooks Davis
94*c697fb7fSBrooks Davis
95*c697fb7fSBrooks Davis /// Wrapper around lua_setglobal to run in a protected environment.
96*c697fb7fSBrooks Davis ///
97*c697fb7fSBrooks Davis /// \pre stack(-2) is the name of the global to set.
98*c697fb7fSBrooks Davis /// \pre stack(-1) is the value to set the global to.
99*c697fb7fSBrooks Davis ///
100*c697fb7fSBrooks Davis /// \param state The Lua C API state.
101*c697fb7fSBrooks Davis ///
102*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the stack.
103*c697fb7fSBrooks Davis static int
protected_setglobal(lua_State * state)104*c697fb7fSBrooks Davis protected_setglobal(lua_State* state)
105*c697fb7fSBrooks Davis {
106*c697fb7fSBrooks Davis lua_setglobal(state, lua_tostring(state, -2));
107*c697fb7fSBrooks Davis return 0;
108*c697fb7fSBrooks Davis }
109*c697fb7fSBrooks Davis
110*c697fb7fSBrooks Davis
111*c697fb7fSBrooks Davis /// Wrapper around lua_settable to run in a protected environment.
112*c697fb7fSBrooks Davis ///
113*c697fb7fSBrooks Davis /// \pre stack(-3) is the table to set the element into.
114*c697fb7fSBrooks Davis /// \pre stack(-2) is the table index.
115*c697fb7fSBrooks Davis /// \pre stack(-1) is the value to set.
116*c697fb7fSBrooks Davis ///
117*c697fb7fSBrooks Davis /// \param state The Lua C API state.
118*c697fb7fSBrooks Davis ///
119*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the stack.
120*c697fb7fSBrooks Davis static int
protected_settable(lua_State * state)121*c697fb7fSBrooks Davis protected_settable(lua_State* state)
122*c697fb7fSBrooks Davis {
123*c697fb7fSBrooks Davis lua_settable(state, -3);
124*c697fb7fSBrooks Davis return 0;
125*c697fb7fSBrooks Davis }
126*c697fb7fSBrooks Davis
127*c697fb7fSBrooks Davis
128*c697fb7fSBrooks Davis /// Calls a C++ Lua function from a C calling environment.
129*c697fb7fSBrooks Davis ///
130*c697fb7fSBrooks Davis /// Any errors reported by the C++ function are caught and reported to the
131*c697fb7fSBrooks Davis /// caller as Lua errors.
132*c697fb7fSBrooks Davis ///
133*c697fb7fSBrooks Davis /// \param function The C++ function to call.
134*c697fb7fSBrooks Davis /// \param raw_state The raw Lua state.
135*c697fb7fSBrooks Davis ///
136*c697fb7fSBrooks Davis /// \return The number of return values pushed onto the Lua stack by the
137*c697fb7fSBrooks Davis /// function.
138*c697fb7fSBrooks Davis static int
call_cxx_function_from_c(lutok::cxx_function function,lua_State * raw_state)139*c697fb7fSBrooks Davis call_cxx_function_from_c(lutok::cxx_function function,
140*c697fb7fSBrooks Davis lua_State* raw_state) throw()
141*c697fb7fSBrooks Davis {
142*c697fb7fSBrooks Davis char error_buf[1024];
143*c697fb7fSBrooks Davis
144*c697fb7fSBrooks Davis try {
145*c697fb7fSBrooks Davis lutok::state state = lutok::state_c_gate::connect(raw_state);
146*c697fb7fSBrooks Davis return function(state);
147*c697fb7fSBrooks Davis } catch (const std::exception& e) {
148*c697fb7fSBrooks Davis std::strncpy(error_buf, e.what(), sizeof(error_buf));
149*c697fb7fSBrooks Davis } catch (...) {
150*c697fb7fSBrooks Davis std::strncpy(error_buf, "Unhandled exception in Lua C++ hook",
151*c697fb7fSBrooks Davis sizeof(error_buf));
152*c697fb7fSBrooks Davis }
153*c697fb7fSBrooks Davis error_buf[sizeof(error_buf) - 1] = '\0';
154*c697fb7fSBrooks Davis // We raise the Lua error from outside the try/catch context and we use
155*c697fb7fSBrooks Davis // a stack-based buffer to hold the message to ensure that we do not leak
156*c697fb7fSBrooks Davis // any C++ objects (and, as a likely result, memory) when Lua performs its
157*c697fb7fSBrooks Davis // longjmp.
158*c697fb7fSBrooks Davis return luaL_error(raw_state, "%s", error_buf);
159*c697fb7fSBrooks Davis }
160*c697fb7fSBrooks Davis
161*c697fb7fSBrooks Davis
162*c697fb7fSBrooks Davis /// Lua glue to call a C++ closure.
163*c697fb7fSBrooks Davis ///
164*c697fb7fSBrooks Davis /// This Lua binding is actually a closure that we have constructed from the
165*c697fb7fSBrooks Davis /// state.push_cxx_closure() method. The closure contains the same upvalues
166*c697fb7fSBrooks Davis /// provided by the user plus an extra upvalue that contains the address of the
167*c697fb7fSBrooks Davis /// C++ function we have to call. All we do here is safely delegate the
168*c697fb7fSBrooks Davis /// execution to the wrapped C++ closure.
169*c697fb7fSBrooks Davis ///
170*c697fb7fSBrooks Davis /// \param raw_state The Lua C API state.
171*c697fb7fSBrooks Davis ///
172*c697fb7fSBrooks Davis /// \return The number of return values of the called closure.
173*c697fb7fSBrooks Davis static int
cxx_closure_trampoline(lua_State * raw_state)174*c697fb7fSBrooks Davis cxx_closure_trampoline(lua_State* raw_state)
175*c697fb7fSBrooks Davis {
176*c697fb7fSBrooks Davis lutok::state state = lutok::state_c_gate::connect(raw_state);
177*c697fb7fSBrooks Davis
178*c697fb7fSBrooks Davis int nupvalues;
179*c697fb7fSBrooks Davis {
180*c697fb7fSBrooks Davis lua_Debug debug;
181*c697fb7fSBrooks Davis lua_getstack(raw_state, 0, &debug);
182*c697fb7fSBrooks Davis lua_getinfo(raw_state, "u", &debug);
183*c697fb7fSBrooks Davis nupvalues = debug.nups;
184*c697fb7fSBrooks Davis }
185*c697fb7fSBrooks Davis
186*c697fb7fSBrooks Davis lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
187*c697fb7fSBrooks Davis state.upvalue_index(nupvalues));
188*c697fb7fSBrooks Davis return call_cxx_function_from_c(*function, raw_state);
189*c697fb7fSBrooks Davis }
190*c697fb7fSBrooks Davis
191*c697fb7fSBrooks Davis
192*c697fb7fSBrooks Davis /// Lua glue to call a C++ function.
193*c697fb7fSBrooks Davis ///
194*c697fb7fSBrooks Davis /// This Lua binding is actually a closure that we have constructed from the
195*c697fb7fSBrooks Davis /// state.push_cxx_function() method. The closure has a single upvalue that
196*c697fb7fSBrooks Davis /// contains the address of the C++ function we have to call. All we do here is
197*c697fb7fSBrooks Davis /// safely delegate the execution to the wrapped C++ function.
198*c697fb7fSBrooks Davis ///
199*c697fb7fSBrooks Davis /// \param raw_state The Lua C API state.
200*c697fb7fSBrooks Davis ///
201*c697fb7fSBrooks Davis /// \return The number of return values of the called function.
202*c697fb7fSBrooks Davis static int
cxx_function_trampoline(lua_State * raw_state)203*c697fb7fSBrooks Davis cxx_function_trampoline(lua_State* raw_state)
204*c697fb7fSBrooks Davis {
205*c697fb7fSBrooks Davis lutok::state state = lutok::state_c_gate::connect(raw_state);
206*c697fb7fSBrooks Davis lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
207*c697fb7fSBrooks Davis state.upvalue_index(1));
208*c697fb7fSBrooks Davis return call_cxx_function_from_c(*function, raw_state);
209*c697fb7fSBrooks Davis }
210*c697fb7fSBrooks Davis
211*c697fb7fSBrooks Davis
212*c697fb7fSBrooks Davis } // anonymous namespace
213*c697fb7fSBrooks Davis
214*c697fb7fSBrooks Davis
215*c697fb7fSBrooks Davis const int lutok::registry_index = LUA_REGISTRYINDEX;
216*c697fb7fSBrooks Davis
217*c697fb7fSBrooks Davis
218*c697fb7fSBrooks Davis /// Internal implementation for lutok::state.
219*c697fb7fSBrooks Davis struct lutok::state::impl {
220*c697fb7fSBrooks Davis /// The Lua internal state.
221*c697fb7fSBrooks Davis lua_State* lua_state;
222*c697fb7fSBrooks Davis
223*c697fb7fSBrooks Davis /// Whether we own the state or not (to decide if we close it).
224*c697fb7fSBrooks Davis bool owned;
225*c697fb7fSBrooks Davis
226*c697fb7fSBrooks Davis /// Constructor.
227*c697fb7fSBrooks Davis ///
228*c697fb7fSBrooks Davis /// \param lua_ The Lua internal state.
229*c697fb7fSBrooks Davis /// \param owned_ Whether we own the state or not.
impllutok::state::impl230*c697fb7fSBrooks Davis impl(lua_State* lua_, bool owned_) :
231*c697fb7fSBrooks Davis lua_state(lua_),
232*c697fb7fSBrooks Davis owned(owned_)
233*c697fb7fSBrooks Davis {
234*c697fb7fSBrooks Davis }
235*c697fb7fSBrooks Davis };
236*c697fb7fSBrooks Davis
237*c697fb7fSBrooks Davis
238*c697fb7fSBrooks Davis /// Initializes the Lua state.
239*c697fb7fSBrooks Davis ///
240*c697fb7fSBrooks Davis /// You must share the same state object alongside the lifetime of your Lua
241*c697fb7fSBrooks Davis /// session. As soon as the object is destroyed, the session is terminated.
state(void)242*c697fb7fSBrooks Davis lutok::state::state(void)
243*c697fb7fSBrooks Davis {
244*c697fb7fSBrooks Davis lua_State* lua = luaL_newstate();
245*c697fb7fSBrooks Davis if (lua == NULL)
246*c697fb7fSBrooks Davis throw lutok::error("lua open failed");
247*c697fb7fSBrooks Davis _pimpl.reset(new impl(lua, true));
248*c697fb7fSBrooks Davis }
249*c697fb7fSBrooks Davis
250*c697fb7fSBrooks Davis
251*c697fb7fSBrooks Davis /// Initializes the Lua state from an existing raw state.
252*c697fb7fSBrooks Davis ///
253*c697fb7fSBrooks Davis /// Instances constructed using this method do NOT own the raw state. This
254*c697fb7fSBrooks Davis /// means that, on exit, the state will not be destroyed.
255*c697fb7fSBrooks Davis ///
256*c697fb7fSBrooks Davis /// \param raw_state_ The raw Lua state to wrap.
state(void * raw_state_)257*c697fb7fSBrooks Davis lutok::state::state(void* raw_state_) :
258*c697fb7fSBrooks Davis _pimpl(new impl(reinterpret_cast< lua_State* >(raw_state_), false))
259*c697fb7fSBrooks Davis {
260*c697fb7fSBrooks Davis }
261*c697fb7fSBrooks Davis
262*c697fb7fSBrooks Davis
263*c697fb7fSBrooks Davis /// Destructor for the Lua state.
264*c697fb7fSBrooks Davis ///
265*c697fb7fSBrooks Davis /// Closes the session unless it has already been closed by calling the
266*c697fb7fSBrooks Davis /// close() method. It is recommended to explicitly close the session in the
267*c697fb7fSBrooks Davis /// code.
~state(void)268*c697fb7fSBrooks Davis lutok::state::~state(void)
269*c697fb7fSBrooks Davis {
270*c697fb7fSBrooks Davis if (_pimpl->owned && _pimpl->lua_state != NULL)
271*c697fb7fSBrooks Davis close();
272*c697fb7fSBrooks Davis }
273*c697fb7fSBrooks Davis
274*c697fb7fSBrooks Davis
275*c697fb7fSBrooks Davis /// Terminates this Lua session.
276*c697fb7fSBrooks Davis ///
277*c697fb7fSBrooks Davis /// It is recommended to call this instead of relying on the destructor to do
278*c697fb7fSBrooks Davis /// the cleanup, but it is not a requirement to use close().
279*c697fb7fSBrooks Davis ///
280*c697fb7fSBrooks Davis /// \pre close() has not yet been called.
281*c697fb7fSBrooks Davis /// \pre The Lua stack is empty. This is not truly necessary but ensures that
282*c697fb7fSBrooks Davis /// our code is consistent and clears the stack explicitly.
283*c697fb7fSBrooks Davis void
close(void)284*c697fb7fSBrooks Davis lutok::state::close(void)
285*c697fb7fSBrooks Davis {
286*c697fb7fSBrooks Davis assert(_pimpl->lua_state != NULL);
287*c697fb7fSBrooks Davis assert(lua_gettop(_pimpl->lua_state) == 0);
288*c697fb7fSBrooks Davis lua_close(_pimpl->lua_state);
289*c697fb7fSBrooks Davis _pimpl->lua_state = NULL;
290*c697fb7fSBrooks Davis }
291*c697fb7fSBrooks Davis
292*c697fb7fSBrooks Davis
293*c697fb7fSBrooks Davis /// Wrapper around lua_getglobal.
294*c697fb7fSBrooks Davis ///
295*c697fb7fSBrooks Davis /// \param name The second parameter to lua_getglobal.
296*c697fb7fSBrooks Davis ///
297*c697fb7fSBrooks Davis /// \throw api_error If lua_getglobal fails.
298*c697fb7fSBrooks Davis ///
299*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
300*c697fb7fSBrooks Davis /// the Lua stack.
301*c697fb7fSBrooks Davis void
get_global(const std::string & name)302*c697fb7fSBrooks Davis lutok::state::get_global(const std::string& name)
303*c697fb7fSBrooks Davis {
304*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, protected_getglobal);
305*c697fb7fSBrooks Davis lua_pushstring(_pimpl->lua_state, name.c_str());
306*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 1, 1, 0) != 0)
307*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_getglobal");
308*c697fb7fSBrooks Davis }
309*c697fb7fSBrooks Davis
310*c697fb7fSBrooks Davis
311*c697fb7fSBrooks Davis /// Pushes a reference to the global table onto the stack.
312*c697fb7fSBrooks Davis ///
313*c697fb7fSBrooks Davis /// This is a wrapper around the incompatible differences between Lua 5.1 and
314*c697fb7fSBrooks Davis /// 5.2 to access to the globals table.
315*c697fb7fSBrooks Davis ///
316*c697fb7fSBrooks Davis /// \post state(-1) Contains the reference to the globals table.
317*c697fb7fSBrooks Davis void
get_global_table(void)318*c697fb7fSBrooks Davis lutok::state::get_global_table(void)
319*c697fb7fSBrooks Davis {
320*c697fb7fSBrooks Davis #if LUA_VERSION_NUM >= 502
321*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, registry_index);
322*c697fb7fSBrooks Davis lua_pushinteger(_pimpl->lua_state, LUA_RIDX_GLOBALS);
323*c697fb7fSBrooks Davis lua_gettable(_pimpl->lua_state, -2);
324*c697fb7fSBrooks Davis lua_remove(_pimpl->lua_state, -2);
325*c697fb7fSBrooks Davis #else
326*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, LUA_GLOBALSINDEX);
327*c697fb7fSBrooks Davis #endif
328*c697fb7fSBrooks Davis }
329*c697fb7fSBrooks Davis
330*c697fb7fSBrooks Davis
331*c697fb7fSBrooks Davis /// Wrapper around luaL_getmetafield.
332*c697fb7fSBrooks Davis ///
333*c697fb7fSBrooks Davis /// \param index The second parameter to luaL_getmetafield.
334*c697fb7fSBrooks Davis /// \param name The third parameter to luaL_getmetafield.
335*c697fb7fSBrooks Davis ///
336*c697fb7fSBrooks Davis /// \return The return value of luaL_getmetafield.
337*c697fb7fSBrooks Davis ///
338*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
339*c697fb7fSBrooks Davis /// the Lua stack.
340*c697fb7fSBrooks Davis bool
get_metafield(const int index,const std::string & name)341*c697fb7fSBrooks Davis lutok::state::get_metafield(const int index, const std::string& name)
342*c697fb7fSBrooks Davis {
343*c697fb7fSBrooks Davis return luaL_getmetafield(_pimpl->lua_state, index, name.c_str()) != 0;
344*c697fb7fSBrooks Davis }
345*c697fb7fSBrooks Davis
346*c697fb7fSBrooks Davis
347*c697fb7fSBrooks Davis /// Wrapper around lua_getmetatable.
348*c697fb7fSBrooks Davis ///
349*c697fb7fSBrooks Davis /// \param index The second parameter to lua_getmetatable.
350*c697fb7fSBrooks Davis ///
351*c697fb7fSBrooks Davis /// \return The return value of lua_getmetatable.
352*c697fb7fSBrooks Davis bool
get_metatable(const int index)353*c697fb7fSBrooks Davis lutok::state::get_metatable(const int index)
354*c697fb7fSBrooks Davis {
355*c697fb7fSBrooks Davis return lua_getmetatable(_pimpl->lua_state, index) != 0;
356*c697fb7fSBrooks Davis }
357*c697fb7fSBrooks Davis
358*c697fb7fSBrooks Davis
359*c697fb7fSBrooks Davis /// Wrapper around lua_gettable.
360*c697fb7fSBrooks Davis ///
361*c697fb7fSBrooks Davis /// \param index The second parameter to lua_gettable.
362*c697fb7fSBrooks Davis ///
363*c697fb7fSBrooks Davis /// \throw api_error If lua_gettable fails.
364*c697fb7fSBrooks Davis ///
365*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
366*c697fb7fSBrooks Davis /// the Lua stack.
367*c697fb7fSBrooks Davis void
get_table(const int index)368*c697fb7fSBrooks Davis lutok::state::get_table(const int index)
369*c697fb7fSBrooks Davis {
370*c697fb7fSBrooks Davis assert(lua_gettop(_pimpl->lua_state) >= 2);
371*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, protected_gettable);
372*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
373*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, -3);
374*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 2, 1, 0) != 0)
375*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_gettable");
376*c697fb7fSBrooks Davis lua_remove(_pimpl->lua_state, -2);
377*c697fb7fSBrooks Davis }
378*c697fb7fSBrooks Davis
379*c697fb7fSBrooks Davis
380*c697fb7fSBrooks Davis /// Wrapper around lua_gettop.
381*c697fb7fSBrooks Davis ///
382*c697fb7fSBrooks Davis /// \return The return value of lua_gettop.
383*c697fb7fSBrooks Davis int
get_top(void)384*c697fb7fSBrooks Davis lutok::state::get_top(void)
385*c697fb7fSBrooks Davis {
386*c697fb7fSBrooks Davis return lua_gettop(_pimpl->lua_state);
387*c697fb7fSBrooks Davis }
388*c697fb7fSBrooks Davis
389*c697fb7fSBrooks Davis
390*c697fb7fSBrooks Davis /// Wrapper around lua_insert.
391*c697fb7fSBrooks Davis ///
392*c697fb7fSBrooks Davis /// \param index The second parameter to lua_insert.
393*c697fb7fSBrooks Davis void
insert(const int index)394*c697fb7fSBrooks Davis lutok::state::insert(const int index)
395*c697fb7fSBrooks Davis {
396*c697fb7fSBrooks Davis lua_insert(_pimpl->lua_state, index);
397*c697fb7fSBrooks Davis }
398*c697fb7fSBrooks Davis
399*c697fb7fSBrooks Davis
400*c697fb7fSBrooks Davis /// Wrapper around lua_isboolean.
401*c697fb7fSBrooks Davis ///
402*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isboolean.
403*c697fb7fSBrooks Davis ///
404*c697fb7fSBrooks Davis /// \return The return value of lua_isboolean.
405*c697fb7fSBrooks Davis bool
is_boolean(const int index)406*c697fb7fSBrooks Davis lutok::state::is_boolean(const int index)
407*c697fb7fSBrooks Davis {
408*c697fb7fSBrooks Davis return lua_isboolean(_pimpl->lua_state, index);
409*c697fb7fSBrooks Davis }
410*c697fb7fSBrooks Davis
411*c697fb7fSBrooks Davis
412*c697fb7fSBrooks Davis /// Wrapper around lua_isfunction.
413*c697fb7fSBrooks Davis ///
414*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isfunction.
415*c697fb7fSBrooks Davis ///
416*c697fb7fSBrooks Davis /// \return The return value of lua_isfunction.
417*c697fb7fSBrooks Davis bool
is_function(const int index)418*c697fb7fSBrooks Davis lutok::state::is_function(const int index)
419*c697fb7fSBrooks Davis {
420*c697fb7fSBrooks Davis return lua_isfunction(_pimpl->lua_state, index);
421*c697fb7fSBrooks Davis }
422*c697fb7fSBrooks Davis
423*c697fb7fSBrooks Davis
424*c697fb7fSBrooks Davis /// Wrapper around lua_isnil.
425*c697fb7fSBrooks Davis ///
426*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isnil.
427*c697fb7fSBrooks Davis ///
428*c697fb7fSBrooks Davis /// \return The return value of lua_isnil.
429*c697fb7fSBrooks Davis bool
is_nil(const int index)430*c697fb7fSBrooks Davis lutok::state::is_nil(const int index)
431*c697fb7fSBrooks Davis {
432*c697fb7fSBrooks Davis return lua_isnil(_pimpl->lua_state, index);
433*c697fb7fSBrooks Davis }
434*c697fb7fSBrooks Davis
435*c697fb7fSBrooks Davis
436*c697fb7fSBrooks Davis /// Wrapper around lua_isnumber.
437*c697fb7fSBrooks Davis ///
438*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isnumber.
439*c697fb7fSBrooks Davis ///
440*c697fb7fSBrooks Davis /// \return The return value of lua_isnumber.
441*c697fb7fSBrooks Davis bool
is_number(const int index)442*c697fb7fSBrooks Davis lutok::state::is_number(const int index)
443*c697fb7fSBrooks Davis {
444*c697fb7fSBrooks Davis return lua_isnumber(_pimpl->lua_state, index);
445*c697fb7fSBrooks Davis }
446*c697fb7fSBrooks Davis
447*c697fb7fSBrooks Davis
448*c697fb7fSBrooks Davis /// Wrapper around lua_isstring.
449*c697fb7fSBrooks Davis ///
450*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isstring.
451*c697fb7fSBrooks Davis ///
452*c697fb7fSBrooks Davis /// \return The return value of lua_isstring.
453*c697fb7fSBrooks Davis bool
is_string(const int index)454*c697fb7fSBrooks Davis lutok::state::is_string(const int index)
455*c697fb7fSBrooks Davis {
456*c697fb7fSBrooks Davis return lua_isstring(_pimpl->lua_state, index);
457*c697fb7fSBrooks Davis }
458*c697fb7fSBrooks Davis
459*c697fb7fSBrooks Davis
460*c697fb7fSBrooks Davis /// Wrapper around lua_istable.
461*c697fb7fSBrooks Davis ///
462*c697fb7fSBrooks Davis /// \param index The second parameter to lua_istable.
463*c697fb7fSBrooks Davis ///
464*c697fb7fSBrooks Davis /// \return The return value of lua_istable.
465*c697fb7fSBrooks Davis bool
is_table(const int index)466*c697fb7fSBrooks Davis lutok::state::is_table(const int index)
467*c697fb7fSBrooks Davis {
468*c697fb7fSBrooks Davis return lua_istable(_pimpl->lua_state, index);
469*c697fb7fSBrooks Davis }
470*c697fb7fSBrooks Davis
471*c697fb7fSBrooks Davis
472*c697fb7fSBrooks Davis /// Wrapper around lua_isuserdata.
473*c697fb7fSBrooks Davis ///
474*c697fb7fSBrooks Davis /// \param index The second parameter to lua_isuserdata.
475*c697fb7fSBrooks Davis ///
476*c697fb7fSBrooks Davis /// \return The return value of lua_isuserdata.
477*c697fb7fSBrooks Davis bool
is_userdata(const int index)478*c697fb7fSBrooks Davis lutok::state::is_userdata(const int index)
479*c697fb7fSBrooks Davis {
480*c697fb7fSBrooks Davis return lua_isuserdata(_pimpl->lua_state, index);
481*c697fb7fSBrooks Davis }
482*c697fb7fSBrooks Davis
483*c697fb7fSBrooks Davis
484*c697fb7fSBrooks Davis /// Wrapper around luaL_loadfile.
485*c697fb7fSBrooks Davis ///
486*c697fb7fSBrooks Davis /// \param file The second parameter to luaL_loadfile.
487*c697fb7fSBrooks Davis ///
488*c697fb7fSBrooks Davis /// \throw api_error If luaL_loadfile returns an error.
489*c697fb7fSBrooks Davis /// \throw file_not_found_error If the file cannot be accessed.
490*c697fb7fSBrooks Davis ///
491*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
492*c697fb7fSBrooks Davis void
load_file(const std::string & file)493*c697fb7fSBrooks Davis lutok::state::load_file(const std::string& file)
494*c697fb7fSBrooks Davis {
495*c697fb7fSBrooks Davis if (::access(file.c_str(), R_OK) == -1)
496*c697fb7fSBrooks Davis throw lutok::file_not_found_error(file);
497*c697fb7fSBrooks Davis if (luaL_loadfile(_pimpl->lua_state, file.c_str()) != 0)
498*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "luaL_loadfile");
499*c697fb7fSBrooks Davis }
500*c697fb7fSBrooks Davis
501*c697fb7fSBrooks Davis
502*c697fb7fSBrooks Davis /// Wrapper around luaL_loadstring.
503*c697fb7fSBrooks Davis ///
504*c697fb7fSBrooks Davis /// \param str The second parameter to luaL_loadstring.
505*c697fb7fSBrooks Davis ///
506*c697fb7fSBrooks Davis /// \throw api_error If luaL_loadstring returns an error.
507*c697fb7fSBrooks Davis ///
508*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
509*c697fb7fSBrooks Davis void
load_string(const std::string & str)510*c697fb7fSBrooks Davis lutok::state::load_string(const std::string& str)
511*c697fb7fSBrooks Davis {
512*c697fb7fSBrooks Davis if (luaL_loadstring(_pimpl->lua_state, str.c_str()) != 0)
513*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "luaL_loadstring");
514*c697fb7fSBrooks Davis }
515*c697fb7fSBrooks Davis
516*c697fb7fSBrooks Davis
517*c697fb7fSBrooks Davis /// Wrapper around lua_newtable.
518*c697fb7fSBrooks Davis ///
519*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
520*c697fb7fSBrooks Davis void
new_table(void)521*c697fb7fSBrooks Davis lutok::state::new_table(void)
522*c697fb7fSBrooks Davis {
523*c697fb7fSBrooks Davis lua_newtable(_pimpl->lua_state);
524*c697fb7fSBrooks Davis }
525*c697fb7fSBrooks Davis
526*c697fb7fSBrooks Davis
527*c697fb7fSBrooks Davis /// Wrapper around lua_newuserdata.
528*c697fb7fSBrooks Davis ///
529*c697fb7fSBrooks Davis /// This is internal. The public type-safe interface of this method should be
530*c697fb7fSBrooks Davis /// used instead.
531*c697fb7fSBrooks Davis ///
532*c697fb7fSBrooks Davis /// \param size The second parameter to lua_newuserdata.
533*c697fb7fSBrooks Davis ///
534*c697fb7fSBrooks Davis /// \return The return value of lua_newuserdata.
535*c697fb7fSBrooks Davis ///
536*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
537*c697fb7fSBrooks Davis void*
new_userdata_voidp(const size_t size)538*c697fb7fSBrooks Davis lutok::state::new_userdata_voidp(const size_t size)
539*c697fb7fSBrooks Davis {
540*c697fb7fSBrooks Davis return lua_newuserdata(_pimpl->lua_state, size);
541*c697fb7fSBrooks Davis }
542*c697fb7fSBrooks Davis
543*c697fb7fSBrooks Davis
544*c697fb7fSBrooks Davis /// Wrapper around lua_next.
545*c697fb7fSBrooks Davis ///
546*c697fb7fSBrooks Davis /// \param index The second parameter to lua_next.
547*c697fb7fSBrooks Davis ///
548*c697fb7fSBrooks Davis /// \return True if there are more elements to process; false otherwise.
549*c697fb7fSBrooks Davis ///
550*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
551*c697fb7fSBrooks Davis bool
next(const int index)552*c697fb7fSBrooks Davis lutok::state::next(const int index)
553*c697fb7fSBrooks Davis {
554*c697fb7fSBrooks Davis assert(lua_istable(_pimpl->lua_state, index));
555*c697fb7fSBrooks Davis assert(lua_gettop(_pimpl->lua_state) >= 1);
556*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, protected_next);
557*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
558*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, -3);
559*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 2, LUA_MULTRET, 0) != 0)
560*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_next");
561*c697fb7fSBrooks Davis const bool more = lua_toboolean(_pimpl->lua_state, -1);
562*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 1);
563*c697fb7fSBrooks Davis if (more)
564*c697fb7fSBrooks Davis lua_remove(_pimpl->lua_state, -3);
565*c697fb7fSBrooks Davis else
566*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 1);
567*c697fb7fSBrooks Davis return more;
568*c697fb7fSBrooks Davis }
569*c697fb7fSBrooks Davis
570*c697fb7fSBrooks Davis
571*c697fb7fSBrooks Davis /// Wrapper around luaL_openlibs.
572*c697fb7fSBrooks Davis ///
573*c697fb7fSBrooks Davis /// \throw api_error If luaL_openlibs fails.
574*c697fb7fSBrooks Davis ///
575*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
576*c697fb7fSBrooks Davis void
open_all(void)577*c697fb7fSBrooks Davis lutok::state::open_all(void)
578*c697fb7fSBrooks Davis {
579*c697fb7fSBrooks Davis luaL_openlibs(_pimpl->lua_state);
580*c697fb7fSBrooks Davis }
581*c697fb7fSBrooks Davis
582*c697fb7fSBrooks Davis
583*c697fb7fSBrooks Davis /// Wrapper around luaopen_base.
584*c697fb7fSBrooks Davis ///
585*c697fb7fSBrooks Davis /// \throw api_error If luaopen_base fails.
586*c697fb7fSBrooks Davis ///
587*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
588*c697fb7fSBrooks Davis void
open_base(void)589*c697fb7fSBrooks Davis lutok::state::open_base(void)
590*c697fb7fSBrooks Davis {
591*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, luaopen_base);
592*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
593*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "luaopen_base");
594*c697fb7fSBrooks Davis }
595*c697fb7fSBrooks Davis
596*c697fb7fSBrooks Davis
597*c697fb7fSBrooks Davis /// Wrapper around luaopen_string.
598*c697fb7fSBrooks Davis ///
599*c697fb7fSBrooks Davis /// \throw api_error If luaopen_string fails.
600*c697fb7fSBrooks Davis ///
601*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
602*c697fb7fSBrooks Davis void
open_string(void)603*c697fb7fSBrooks Davis lutok::state::open_string(void)
604*c697fb7fSBrooks Davis {
605*c697fb7fSBrooks Davis #if LUA_VERSION_NUM >= 502
606*c697fb7fSBrooks Davis luaL_requiref(_pimpl->lua_state, LUA_STRLIBNAME, luaopen_string, 1);
607*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 1);
608*c697fb7fSBrooks Davis #else
609*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, luaopen_string);
610*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
611*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "luaopen_string");
612*c697fb7fSBrooks Davis #endif
613*c697fb7fSBrooks Davis }
614*c697fb7fSBrooks Davis
615*c697fb7fSBrooks Davis
616*c697fb7fSBrooks Davis /// Wrapper around luaopen_table.
617*c697fb7fSBrooks Davis ///
618*c697fb7fSBrooks Davis /// \throw api_error If luaopen_table fails.
619*c697fb7fSBrooks Davis ///
620*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
621*c697fb7fSBrooks Davis void
open_table(void)622*c697fb7fSBrooks Davis lutok::state::open_table(void)
623*c697fb7fSBrooks Davis {
624*c697fb7fSBrooks Davis #if LUA_VERSION_NUM >= 502
625*c697fb7fSBrooks Davis luaL_requiref(_pimpl->lua_state, LUA_TABLIBNAME, luaopen_table, 1);
626*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 1);
627*c697fb7fSBrooks Davis #else
628*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, luaopen_table);
629*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
630*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "luaopen_table");
631*c697fb7fSBrooks Davis #endif
632*c697fb7fSBrooks Davis }
633*c697fb7fSBrooks Davis
634*c697fb7fSBrooks Davis
635*c697fb7fSBrooks Davis /// Wrapper around lua_pcall.
636*c697fb7fSBrooks Davis ///
637*c697fb7fSBrooks Davis /// \param nargs The second parameter to lua_pcall.
638*c697fb7fSBrooks Davis /// \param nresults The third parameter to lua_pcall.
639*c697fb7fSBrooks Davis /// \param errfunc The fourth parameter to lua_pcall.
640*c697fb7fSBrooks Davis ///
641*c697fb7fSBrooks Davis /// \throw api_error If lua_pcall returns an error.
642*c697fb7fSBrooks Davis void
pcall(const int nargs,const int nresults,const int errfunc)643*c697fb7fSBrooks Davis lutok::state::pcall(const int nargs, const int nresults, const int errfunc)
644*c697fb7fSBrooks Davis {
645*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0)
646*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_pcall");
647*c697fb7fSBrooks Davis }
648*c697fb7fSBrooks Davis
649*c697fb7fSBrooks Davis
650*c697fb7fSBrooks Davis /// Wrapper around lua_pop.
651*c697fb7fSBrooks Davis ///
652*c697fb7fSBrooks Davis /// \param count The second parameter to lua_pop.
653*c697fb7fSBrooks Davis void
pop(const int count)654*c697fb7fSBrooks Davis lutok::state::pop(const int count)
655*c697fb7fSBrooks Davis {
656*c697fb7fSBrooks Davis assert(count <= lua_gettop(_pimpl->lua_state));
657*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, count);
658*c697fb7fSBrooks Davis assert(lua_gettop(_pimpl->lua_state) >= 0);
659*c697fb7fSBrooks Davis }
660*c697fb7fSBrooks Davis
661*c697fb7fSBrooks Davis
662*c697fb7fSBrooks Davis /// Wrapper around lua_pushboolean.
663*c697fb7fSBrooks Davis ///
664*c697fb7fSBrooks Davis /// \param value The second parameter to lua_pushboolean.
665*c697fb7fSBrooks Davis void
push_boolean(const bool value)666*c697fb7fSBrooks Davis lutok::state::push_boolean(const bool value)
667*c697fb7fSBrooks Davis {
668*c697fb7fSBrooks Davis lua_pushboolean(_pimpl->lua_state, value ? 1 : 0);
669*c697fb7fSBrooks Davis }
670*c697fb7fSBrooks Davis
671*c697fb7fSBrooks Davis
672*c697fb7fSBrooks Davis /// Wrapper around lua_pushcclosure.
673*c697fb7fSBrooks Davis ///
674*c697fb7fSBrooks Davis /// This is not a pure wrapper around lua_pushcclosure because this has to do
675*c697fb7fSBrooks Davis /// extra magic to allow passing C++ functions instead of plain C functions.
676*c697fb7fSBrooks Davis ///
677*c697fb7fSBrooks Davis /// \param function The C++ function to be pushed as a closure.
678*c697fb7fSBrooks Davis /// \param nvalues The number of upvalues that the function receives.
679*c697fb7fSBrooks Davis void
push_cxx_closure(cxx_function function,const int nvalues)680*c697fb7fSBrooks Davis lutok::state::push_cxx_closure(cxx_function function, const int nvalues)
681*c697fb7fSBrooks Davis {
682*c697fb7fSBrooks Davis cxx_function *data = static_cast< cxx_function* >(
683*c697fb7fSBrooks Davis lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
684*c697fb7fSBrooks Davis *data = function;
685*c697fb7fSBrooks Davis lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1);
686*c697fb7fSBrooks Davis }
687*c697fb7fSBrooks Davis
688*c697fb7fSBrooks Davis
689*c697fb7fSBrooks Davis /// Wrapper around lua_pushcfunction.
690*c697fb7fSBrooks Davis ///
691*c697fb7fSBrooks Davis /// This is not a pure wrapper around lua_pushcfunction because this has to do
692*c697fb7fSBrooks Davis /// extra magic to allow passing C++ functions instead of plain C functions.
693*c697fb7fSBrooks Davis ///
694*c697fb7fSBrooks Davis /// \param function The C++ function to be pushed.
695*c697fb7fSBrooks Davis void
push_cxx_function(cxx_function function)696*c697fb7fSBrooks Davis lutok::state::push_cxx_function(cxx_function function)
697*c697fb7fSBrooks Davis {
698*c697fb7fSBrooks Davis cxx_function *data = static_cast< cxx_function* >(
699*c697fb7fSBrooks Davis lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
700*c697fb7fSBrooks Davis *data = function;
701*c697fb7fSBrooks Davis lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1);
702*c697fb7fSBrooks Davis }
703*c697fb7fSBrooks Davis
704*c697fb7fSBrooks Davis
705*c697fb7fSBrooks Davis /// Wrapper around lua_pushinteger.
706*c697fb7fSBrooks Davis ///
707*c697fb7fSBrooks Davis /// \param value The second parameter to lua_pushinteger.
708*c697fb7fSBrooks Davis void
push_integer(const int value)709*c697fb7fSBrooks Davis lutok::state::push_integer(const int value)
710*c697fb7fSBrooks Davis {
711*c697fb7fSBrooks Davis lua_pushinteger(_pimpl->lua_state, value);
712*c697fb7fSBrooks Davis }
713*c697fb7fSBrooks Davis
714*c697fb7fSBrooks Davis
715*c697fb7fSBrooks Davis /// Wrapper around lua_pushnil.
716*c697fb7fSBrooks Davis void
push_nil(void)717*c697fb7fSBrooks Davis lutok::state::push_nil(void)
718*c697fb7fSBrooks Davis {
719*c697fb7fSBrooks Davis lua_pushnil(_pimpl->lua_state);
720*c697fb7fSBrooks Davis }
721*c697fb7fSBrooks Davis
722*c697fb7fSBrooks Davis
723*c697fb7fSBrooks Davis /// Wrapper around lua_pushstring.
724*c697fb7fSBrooks Davis ///
725*c697fb7fSBrooks Davis /// \param str The second parameter to lua_pushstring.
726*c697fb7fSBrooks Davis ///
727*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
728*c697fb7fSBrooks Davis void
push_string(const std::string & str)729*c697fb7fSBrooks Davis lutok::state::push_string(const std::string& str)
730*c697fb7fSBrooks Davis {
731*c697fb7fSBrooks Davis lua_pushstring(_pimpl->lua_state, str.c_str());
732*c697fb7fSBrooks Davis }
733*c697fb7fSBrooks Davis
734*c697fb7fSBrooks Davis
735*c697fb7fSBrooks Davis /// Wrapper around lua_pushvalue.
736*c697fb7fSBrooks Davis ///
737*c697fb7fSBrooks Davis /// \param index The second parameter to lua_pushvalue.
738*c697fb7fSBrooks Davis void
push_value(const int index)739*c697fb7fSBrooks Davis lutok::state::push_value(const int index)
740*c697fb7fSBrooks Davis {
741*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, index);
742*c697fb7fSBrooks Davis }
743*c697fb7fSBrooks Davis
744*c697fb7fSBrooks Davis
745*c697fb7fSBrooks Davis /// Wrapper around lua_rawget.
746*c697fb7fSBrooks Davis ///
747*c697fb7fSBrooks Davis /// \param index The second parameter to lua_rawget.
748*c697fb7fSBrooks Davis void
raw_get(const int index)749*c697fb7fSBrooks Davis lutok::state::raw_get(const int index)
750*c697fb7fSBrooks Davis {
751*c697fb7fSBrooks Davis lua_rawget(_pimpl->lua_state, index);
752*c697fb7fSBrooks Davis }
753*c697fb7fSBrooks Davis
754*c697fb7fSBrooks Davis
755*c697fb7fSBrooks Davis /// Wrapper around lua_rawset.
756*c697fb7fSBrooks Davis ///
757*c697fb7fSBrooks Davis /// \param index The second parameter to lua_rawset.
758*c697fb7fSBrooks Davis ///
759*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
760*c697fb7fSBrooks Davis /// the Lua stack.
761*c697fb7fSBrooks Davis void
raw_set(const int index)762*c697fb7fSBrooks Davis lutok::state::raw_set(const int index)
763*c697fb7fSBrooks Davis {
764*c697fb7fSBrooks Davis lua_rawset(_pimpl->lua_state, index);
765*c697fb7fSBrooks Davis }
766*c697fb7fSBrooks Davis
767*c697fb7fSBrooks Davis
768*c697fb7fSBrooks Davis /// Wrapper around lua_setglobal.
769*c697fb7fSBrooks Davis ///
770*c697fb7fSBrooks Davis /// \param name The second parameter to lua_setglobal.
771*c697fb7fSBrooks Davis ///
772*c697fb7fSBrooks Davis /// \throw api_error If lua_setglobal fails.
773*c697fb7fSBrooks Davis ///
774*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
775*c697fb7fSBrooks Davis /// the Lua stack.
776*c697fb7fSBrooks Davis void
set_global(const std::string & name)777*c697fb7fSBrooks Davis lutok::state::set_global(const std::string& name)
778*c697fb7fSBrooks Davis {
779*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, protected_setglobal);
780*c697fb7fSBrooks Davis lua_pushstring(_pimpl->lua_state, name.c_str());
781*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, -3);
782*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0)
783*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_setglobal");
784*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 1);
785*c697fb7fSBrooks Davis }
786*c697fb7fSBrooks Davis
787*c697fb7fSBrooks Davis
788*c697fb7fSBrooks Davis /// Wrapper around lua_setmetatable.
789*c697fb7fSBrooks Davis ///
790*c697fb7fSBrooks Davis /// \param index The second parameter to lua_setmetatable.
791*c697fb7fSBrooks Davis void
set_metatable(const int index)792*c697fb7fSBrooks Davis lutok::state::set_metatable(const int index)
793*c697fb7fSBrooks Davis {
794*c697fb7fSBrooks Davis lua_setmetatable(_pimpl->lua_state, index);
795*c697fb7fSBrooks Davis }
796*c697fb7fSBrooks Davis
797*c697fb7fSBrooks Davis
798*c697fb7fSBrooks Davis /// Wrapper around lua_settable.
799*c697fb7fSBrooks Davis ///
800*c697fb7fSBrooks Davis /// \param index The second parameter to lua_settable.
801*c697fb7fSBrooks Davis ///
802*c697fb7fSBrooks Davis /// \throw api_error If lua_settable fails.
803*c697fb7fSBrooks Davis ///
804*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory to manipulate
805*c697fb7fSBrooks Davis /// the Lua stack.
806*c697fb7fSBrooks Davis void
set_table(const int index)807*c697fb7fSBrooks Davis lutok::state::set_table(const int index)
808*c697fb7fSBrooks Davis {
809*c697fb7fSBrooks Davis lua_pushcfunction(_pimpl->lua_state, protected_settable);
810*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
811*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, -4);
812*c697fb7fSBrooks Davis lua_pushvalue(_pimpl->lua_state, -4);
813*c697fb7fSBrooks Davis if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0)
814*c697fb7fSBrooks Davis throw lutok::api_error::from_stack(*this, "lua_settable");
815*c697fb7fSBrooks Davis lua_pop(_pimpl->lua_state, 2);
816*c697fb7fSBrooks Davis }
817*c697fb7fSBrooks Davis
818*c697fb7fSBrooks Davis
819*c697fb7fSBrooks Davis /// Wrapper around lua_toboolean.
820*c697fb7fSBrooks Davis ///
821*c697fb7fSBrooks Davis /// \param index The second parameter to lua_toboolean.
822*c697fb7fSBrooks Davis ///
823*c697fb7fSBrooks Davis /// \return The return value of lua_toboolean.
824*c697fb7fSBrooks Davis bool
to_boolean(const int index)825*c697fb7fSBrooks Davis lutok::state::to_boolean(const int index)
826*c697fb7fSBrooks Davis {
827*c697fb7fSBrooks Davis assert(is_boolean(index));
828*c697fb7fSBrooks Davis return lua_toboolean(_pimpl->lua_state, index);
829*c697fb7fSBrooks Davis }
830*c697fb7fSBrooks Davis
831*c697fb7fSBrooks Davis
832*c697fb7fSBrooks Davis /// Wrapper around lua_tointeger.
833*c697fb7fSBrooks Davis ///
834*c697fb7fSBrooks Davis /// \param index The second parameter to lua_tointeger.
835*c697fb7fSBrooks Davis ///
836*c697fb7fSBrooks Davis /// \return The return value of lua_tointeger.
837*c697fb7fSBrooks Davis long
to_integer(const int index)838*c697fb7fSBrooks Davis lutok::state::to_integer(const int index)
839*c697fb7fSBrooks Davis {
840*c697fb7fSBrooks Davis assert(is_number(index));
841*c697fb7fSBrooks Davis return lua_tointeger(_pimpl->lua_state, index);
842*c697fb7fSBrooks Davis }
843*c697fb7fSBrooks Davis
844*c697fb7fSBrooks Davis
845*c697fb7fSBrooks Davis /// Wrapper around lua_touserdata.
846*c697fb7fSBrooks Davis ///
847*c697fb7fSBrooks Davis /// This is internal. The public type-safe interface of this method should be
848*c697fb7fSBrooks Davis /// used instead.
849*c697fb7fSBrooks Davis ///
850*c697fb7fSBrooks Davis /// \param index The second parameter to lua_touserdata.
851*c697fb7fSBrooks Davis ///
852*c697fb7fSBrooks Davis /// \return The return value of lua_touserdata.
853*c697fb7fSBrooks Davis ///
854*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
855*c697fb7fSBrooks Davis void*
to_userdata_voidp(const int index)856*c697fb7fSBrooks Davis lutok::state::to_userdata_voidp(const int index)
857*c697fb7fSBrooks Davis {
858*c697fb7fSBrooks Davis return lua_touserdata(_pimpl->lua_state, index);
859*c697fb7fSBrooks Davis }
860*c697fb7fSBrooks Davis
861*c697fb7fSBrooks Davis
862*c697fb7fSBrooks Davis
863*c697fb7fSBrooks Davis /// Wrapper around lua_tostring.
864*c697fb7fSBrooks Davis ///
865*c697fb7fSBrooks Davis /// \param index The second parameter to lua_tostring.
866*c697fb7fSBrooks Davis ///
867*c697fb7fSBrooks Davis /// \return The return value of lua_tostring.
868*c697fb7fSBrooks Davis ///
869*c697fb7fSBrooks Davis /// \warning Terminates execution if there is not enough memory.
870*c697fb7fSBrooks Davis std::string
to_string(const int index)871*c697fb7fSBrooks Davis lutok::state::to_string(const int index)
872*c697fb7fSBrooks Davis {
873*c697fb7fSBrooks Davis assert(is_string(index));
874*c697fb7fSBrooks Davis const char *raw_string = lua_tostring(_pimpl->lua_state, index);
875*c697fb7fSBrooks Davis // Note that the creation of a string object below (explicit for clarity)
876*c697fb7fSBrooks Davis // implies that the raw string is duplicated and, henceforth, the string is
877*c697fb7fSBrooks Davis // safe even if the corresponding element is popped from the Lua stack.
878*c697fb7fSBrooks Davis return std::string(raw_string);
879*c697fb7fSBrooks Davis }
880*c697fb7fSBrooks Davis
881*c697fb7fSBrooks Davis
882*c697fb7fSBrooks Davis /// Wrapper around lua_upvalueindex.
883*c697fb7fSBrooks Davis ///
884*c697fb7fSBrooks Davis /// \param index The first parameter to lua_upvalueindex.
885*c697fb7fSBrooks Davis ///
886*c697fb7fSBrooks Davis /// \return The return value of lua_upvalueindex.
887*c697fb7fSBrooks Davis int
upvalue_index(const int index)888*c697fb7fSBrooks Davis lutok::state::upvalue_index(const int index)
889*c697fb7fSBrooks Davis {
890*c697fb7fSBrooks Davis return lua_upvalueindex(index);
891*c697fb7fSBrooks Davis }
892*c697fb7fSBrooks Davis
893*c697fb7fSBrooks Davis
894*c697fb7fSBrooks Davis /// Gets the internal lua_State object.
895*c697fb7fSBrooks Davis ///
896*c697fb7fSBrooks Davis /// \return The raw Lua state. This is returned as a void pointer to prevent
897*c697fb7fSBrooks Davis /// including the lua.hpp header file from our public interface. The only way
898*c697fb7fSBrooks Davis /// to call this method is by using the c_gate module, and c_gate takes care of
899*c697fb7fSBrooks Davis /// casting this object to the appropriate type.
900*c697fb7fSBrooks Davis void*
raw_state(void)901*c697fb7fSBrooks Davis lutok::state::raw_state(void)
902*c697fb7fSBrooks Davis {
903*c697fb7fSBrooks Davis return _pimpl->lua_state;
904*c697fb7fSBrooks Davis }
905