xref: /minix3/external/bsd/lutok/dist/state.cpp (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
111be35a1SLionel Sambuc // Copyright 2011 Google Inc.
211be35a1SLionel Sambuc // All rights reserved.
311be35a1SLionel Sambuc //
411be35a1SLionel Sambuc // Redistribution and use in source and binary forms, with or without
511be35a1SLionel Sambuc // modification, are permitted provided that the following conditions are
611be35a1SLionel Sambuc // met:
711be35a1SLionel Sambuc //
811be35a1SLionel Sambuc // * Redistributions of source code must retain the above copyright
911be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer.
1011be35a1SLionel Sambuc // * Redistributions in binary form must reproduce the above copyright
1111be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer in the
1211be35a1SLionel Sambuc //   documentation and/or other materials provided with the distribution.
1311be35a1SLionel Sambuc // * Neither the name of Google Inc. nor the names of its contributors
1411be35a1SLionel Sambuc //   may be used to endorse or promote products derived from this software
1511be35a1SLionel Sambuc //   without specific prior written permission.
1611be35a1SLionel Sambuc //
1711be35a1SLionel Sambuc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1811be35a1SLionel Sambuc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1911be35a1SLionel Sambuc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2011be35a1SLionel Sambuc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2111be35a1SLionel Sambuc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2211be35a1SLionel Sambuc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2311be35a1SLionel Sambuc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2411be35a1SLionel Sambuc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2511be35a1SLionel Sambuc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2611be35a1SLionel Sambuc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2711be35a1SLionel Sambuc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811be35a1SLionel Sambuc 
2911be35a1SLionel Sambuc extern "C" {
3011be35a1SLionel Sambuc #include <unistd.h>
3111be35a1SLionel Sambuc }
3211be35a1SLionel Sambuc 
3311be35a1SLionel Sambuc #include <cassert>
3411be35a1SLionel Sambuc #include <cstring>
3511be35a1SLionel Sambuc 
3611be35a1SLionel Sambuc #include "c_gate.hpp"
3711be35a1SLionel Sambuc #include "exceptions.hpp"
3811be35a1SLionel Sambuc #include "state.ipp"
3911be35a1SLionel Sambuc 
4011be35a1SLionel Sambuc 
4111be35a1SLionel Sambuc namespace {
4211be35a1SLionel Sambuc 
4311be35a1SLionel Sambuc 
4411be35a1SLionel Sambuc /// Wrapper around lua_getglobal to run in a protected environment.
4511be35a1SLionel Sambuc ///
4611be35a1SLionel Sambuc /// \pre stack(-1) is the name of the global to get.
4711be35a1SLionel Sambuc /// \post stack(-1) is the value of the global.
4811be35a1SLionel Sambuc ///
4911be35a1SLionel Sambuc /// \param state The Lua C API state.
5011be35a1SLionel Sambuc ///
5111be35a1SLionel Sambuc /// \return The number of return values pushed onto the stack.
5211be35a1SLionel Sambuc static int
protected_getglobal(lua_State * state)5311be35a1SLionel Sambuc protected_getglobal(lua_State* state)
5411be35a1SLionel Sambuc {
5511be35a1SLionel Sambuc     lua_getglobal(state, lua_tostring(state, -1));
5611be35a1SLionel Sambuc     return 1;
5711be35a1SLionel Sambuc }
5811be35a1SLionel Sambuc 
5911be35a1SLionel Sambuc 
6011be35a1SLionel Sambuc /// Wrapper around lua_gettable to run in a protected environment.
6111be35a1SLionel Sambuc ///
6211be35a1SLionel Sambuc /// \pre stack(-2) is the table to get the element from.
6311be35a1SLionel Sambuc /// \pre stack(-1) is the table index.
6411be35a1SLionel Sambuc /// \post stack(-1) is the value of stack(-2)[stack(-1)].
6511be35a1SLionel Sambuc ///
6611be35a1SLionel Sambuc /// \param state The Lua C API state.
6711be35a1SLionel Sambuc ///
6811be35a1SLionel Sambuc /// \return The number of return values pushed onto the stack.
6911be35a1SLionel Sambuc static int
protected_gettable(lua_State * state)7011be35a1SLionel Sambuc protected_gettable(lua_State* state)
7111be35a1SLionel Sambuc {
7211be35a1SLionel Sambuc     lua_gettable(state, -2);
7311be35a1SLionel Sambuc     return 1;
7411be35a1SLionel Sambuc }
7511be35a1SLionel Sambuc 
7611be35a1SLionel Sambuc 
7711be35a1SLionel Sambuc /// Wrapper around lua_next to run in a protected environment.
7811be35a1SLionel Sambuc ///
7911be35a1SLionel Sambuc /// \pre stack(-2) is the table to get the next element from.
8011be35a1SLionel Sambuc /// \pre stack(-1) is the last processed key.
8111be35a1SLionel Sambuc /// \post stack(-1) is the value of next(stack(-2), stack(-1)).
8211be35a1SLionel Sambuc ///
8311be35a1SLionel Sambuc /// \param state The Lua C API state.
8411be35a1SLionel Sambuc ///
8511be35a1SLionel Sambuc /// \return The number of return values pushed onto the stack.
8611be35a1SLionel Sambuc static int
protected_next(lua_State * state)8711be35a1SLionel Sambuc protected_next(lua_State* state)
8811be35a1SLionel Sambuc {
8911be35a1SLionel Sambuc     const int more = lua_next(state, -2) != 0;
9011be35a1SLionel Sambuc     lua_pushboolean(state, more);
9111be35a1SLionel Sambuc     return more ? 3 : 1;
9211be35a1SLionel Sambuc }
9311be35a1SLionel Sambuc 
9411be35a1SLionel Sambuc 
9511be35a1SLionel Sambuc /// Wrapper around lua_setglobal to run in a protected environment.
9611be35a1SLionel Sambuc ///
9711be35a1SLionel Sambuc /// \pre stack(-2) is the name of the global to set.
9811be35a1SLionel Sambuc /// \pre stack(-1) is the value to set the global to.
9911be35a1SLionel Sambuc ///
10011be35a1SLionel Sambuc /// \param state The Lua C API state.
10111be35a1SLionel Sambuc ///
10211be35a1SLionel Sambuc /// \return The number of return values pushed onto the stack.
10311be35a1SLionel Sambuc static int
protected_setglobal(lua_State * state)10411be35a1SLionel Sambuc protected_setglobal(lua_State* state)
10511be35a1SLionel Sambuc {
10611be35a1SLionel Sambuc     lua_setglobal(state, lua_tostring(state, -2));
10711be35a1SLionel Sambuc     return 0;
10811be35a1SLionel Sambuc }
10911be35a1SLionel Sambuc 
11011be35a1SLionel Sambuc 
11111be35a1SLionel Sambuc /// Wrapper around lua_settable to run in a protected environment.
11211be35a1SLionel Sambuc ///
11311be35a1SLionel Sambuc /// \pre stack(-3) is the table to set the element into.
11411be35a1SLionel Sambuc /// \pre stack(-2) is the table index.
11511be35a1SLionel Sambuc /// \pre stack(-1) is the value to set.
11611be35a1SLionel Sambuc ///
11711be35a1SLionel Sambuc /// \param state The Lua C API state.
11811be35a1SLionel Sambuc ///
11911be35a1SLionel Sambuc /// \return The number of return values pushed onto the stack.
12011be35a1SLionel Sambuc static int
protected_settable(lua_State * state)12111be35a1SLionel Sambuc protected_settable(lua_State* state)
12211be35a1SLionel Sambuc {
12311be35a1SLionel Sambuc     lua_settable(state, -3);
12411be35a1SLionel Sambuc     return 0;
12511be35a1SLionel Sambuc }
12611be35a1SLionel Sambuc 
12711be35a1SLionel Sambuc 
12811be35a1SLionel Sambuc /// Calls a C++ Lua function from a C calling environment.
12911be35a1SLionel Sambuc ///
13011be35a1SLionel Sambuc /// Any errors reported by the C++ function are caught and reported to the
13111be35a1SLionel Sambuc /// caller as Lua errors.
13211be35a1SLionel Sambuc ///
13311be35a1SLionel Sambuc /// \param function The C++ function to call.
13411be35a1SLionel Sambuc /// \param raw_state The raw Lua state.
13511be35a1SLionel Sambuc ///
13611be35a1SLionel Sambuc /// \return The number of return values pushed onto the Lua stack by the
13711be35a1SLionel Sambuc /// function.
13811be35a1SLionel Sambuc static int
call_cxx_function_from_c(lutok::cxx_function function,lua_State * raw_state)13911be35a1SLionel Sambuc call_cxx_function_from_c(lutok::cxx_function function,
14011be35a1SLionel Sambuc                          lua_State* raw_state) throw()
14111be35a1SLionel Sambuc {
14211be35a1SLionel Sambuc     char error_buf[1024];
14311be35a1SLionel Sambuc 
14411be35a1SLionel Sambuc     try {
14511be35a1SLionel Sambuc         lutok::state state = lutok::state_c_gate::connect(raw_state);
14611be35a1SLionel Sambuc         return function(state);
14711be35a1SLionel Sambuc     } catch (const std::exception& e) {
14811be35a1SLionel Sambuc         std::strncpy(error_buf, e.what(), sizeof(error_buf));
14911be35a1SLionel Sambuc     } catch (...) {
15011be35a1SLionel Sambuc         std::strncpy(error_buf, "Unhandled exception in Lua C++ hook",
15111be35a1SLionel Sambuc                      sizeof(error_buf));
15211be35a1SLionel Sambuc     }
15311be35a1SLionel Sambuc     error_buf[sizeof(error_buf) - 1] = '\0';
15411be35a1SLionel Sambuc     // We raise the Lua error from outside the try/catch context and we use
15511be35a1SLionel Sambuc     // a stack-based buffer to hold the message to ensure that we do not leak
15611be35a1SLionel Sambuc     // any C++ objects (and, as a likely result, memory) when Lua performs its
15711be35a1SLionel Sambuc     // longjmp.
15811be35a1SLionel Sambuc     return luaL_error(raw_state, "%s", error_buf);
15911be35a1SLionel Sambuc }
16011be35a1SLionel Sambuc 
16111be35a1SLionel Sambuc 
16211be35a1SLionel Sambuc /// Lua glue to call a C++ closure.
16311be35a1SLionel Sambuc ///
16411be35a1SLionel Sambuc /// This Lua binding is actually a closure that we have constructed from the
16511be35a1SLionel Sambuc /// state.push_cxx_closure() method.  The closure contains the same upvalues
16611be35a1SLionel Sambuc /// provided by the user plus an extra upvalue that contains the address of the
16711be35a1SLionel Sambuc /// C++ function we have to call.  All we do here is safely delegate the
16811be35a1SLionel Sambuc /// execution to the wrapped C++ closure.
16911be35a1SLionel Sambuc ///
17011be35a1SLionel Sambuc /// \param raw_state The Lua C API state.
17111be35a1SLionel Sambuc ///
17211be35a1SLionel Sambuc /// \return The number of return values of the called closure.
17311be35a1SLionel Sambuc static int
cxx_closure_trampoline(lua_State * raw_state)17411be35a1SLionel Sambuc cxx_closure_trampoline(lua_State* raw_state)
17511be35a1SLionel Sambuc {
17611be35a1SLionel Sambuc     lutok::state state = lutok::state_c_gate::connect(raw_state);
17711be35a1SLionel Sambuc 
17811be35a1SLionel Sambuc     int nupvalues;
17911be35a1SLionel Sambuc     {
18011be35a1SLionel Sambuc         lua_Debug debug;
18111be35a1SLionel Sambuc         lua_getstack(raw_state, 0, &debug);
18211be35a1SLionel Sambuc         lua_getinfo(raw_state, "u", &debug);
18311be35a1SLionel Sambuc         nupvalues = debug.nups;
18411be35a1SLionel Sambuc     }
18511be35a1SLionel Sambuc 
18611be35a1SLionel Sambuc     lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
18711be35a1SLionel Sambuc         state.upvalue_index(nupvalues));
18811be35a1SLionel Sambuc     return call_cxx_function_from_c(*function, raw_state);
18911be35a1SLionel Sambuc }
19011be35a1SLionel Sambuc 
19111be35a1SLionel Sambuc 
19211be35a1SLionel Sambuc /// Lua glue to call a C++ function.
19311be35a1SLionel Sambuc ///
19411be35a1SLionel Sambuc /// This Lua binding is actually a closure that we have constructed from the
19511be35a1SLionel Sambuc /// state.push_cxx_function() method.  The closure has a single upvalue that
19611be35a1SLionel Sambuc /// contains the address of the C++ function we have to call.  All we do here is
19711be35a1SLionel Sambuc /// safely delegate the execution to the wrapped C++ function.
19811be35a1SLionel Sambuc ///
19911be35a1SLionel Sambuc /// \param raw_state The Lua C API state.
20011be35a1SLionel Sambuc ///
20111be35a1SLionel Sambuc /// \return The number of return values of the called function.
20211be35a1SLionel Sambuc static int
cxx_function_trampoline(lua_State * raw_state)20311be35a1SLionel Sambuc cxx_function_trampoline(lua_State* raw_state)
20411be35a1SLionel Sambuc {
20511be35a1SLionel Sambuc     lutok::state state = lutok::state_c_gate::connect(raw_state);
20611be35a1SLionel Sambuc     lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(
20711be35a1SLionel Sambuc         state.upvalue_index(1));
20811be35a1SLionel Sambuc     return call_cxx_function_from_c(*function, raw_state);
20911be35a1SLionel Sambuc }
21011be35a1SLionel Sambuc 
21111be35a1SLionel Sambuc 
21211be35a1SLionel Sambuc }  // anonymous namespace
21311be35a1SLionel Sambuc 
21411be35a1SLionel Sambuc 
215*84d9c625SLionel Sambuc const int lutok::registry_index = LUA_REGISTRYINDEX;
21611be35a1SLionel Sambuc 
21711be35a1SLionel Sambuc 
21811be35a1SLionel Sambuc /// Internal implementation for lutok::state.
21911be35a1SLionel Sambuc struct lutok::state::impl {
22011be35a1SLionel Sambuc     /// The Lua internal state.
22111be35a1SLionel Sambuc     lua_State* lua_state;
22211be35a1SLionel Sambuc 
22311be35a1SLionel Sambuc     /// Whether we own the state or not (to decide if we close it).
22411be35a1SLionel Sambuc     bool owned;
22511be35a1SLionel Sambuc 
22611be35a1SLionel Sambuc     /// Constructor.
22711be35a1SLionel Sambuc     ///
22811be35a1SLionel Sambuc     /// \param lua_ The Lua internal state.
22911be35a1SLionel Sambuc     /// \param owned_ Whether we own the state or not.
impllutok::state::impl23011be35a1SLionel Sambuc     impl(lua_State* lua_, bool owned_) :
23111be35a1SLionel Sambuc         lua_state(lua_),
23211be35a1SLionel Sambuc         owned(owned_)
23311be35a1SLionel Sambuc     {
23411be35a1SLionel Sambuc     }
23511be35a1SLionel Sambuc };
23611be35a1SLionel Sambuc 
23711be35a1SLionel Sambuc 
23811be35a1SLionel Sambuc /// Initializes the Lua state.
23911be35a1SLionel Sambuc ///
24011be35a1SLionel Sambuc /// You must share the same state object alongside the lifetime of your Lua
24111be35a1SLionel Sambuc /// session.  As soon as the object is destroyed, the session is terminated.
state(void)24211be35a1SLionel Sambuc lutok::state::state(void)
24311be35a1SLionel Sambuc {
244*84d9c625SLionel Sambuc     lua_State* lua = luaL_newstate();
24511be35a1SLionel Sambuc     if (lua == NULL)
24611be35a1SLionel Sambuc         throw lutok::error("lua open failed");
24711be35a1SLionel Sambuc     _pimpl.reset(new impl(lua, true));
24811be35a1SLionel Sambuc }
24911be35a1SLionel Sambuc 
25011be35a1SLionel Sambuc 
25111be35a1SLionel Sambuc /// Initializes the Lua state from an existing raw state.
25211be35a1SLionel Sambuc ///
25311be35a1SLionel Sambuc /// Instances constructed using this method do NOT own the raw state.  This
25411be35a1SLionel Sambuc /// means that, on exit, the state will not be destroyed.
25511be35a1SLionel Sambuc ///
25611be35a1SLionel Sambuc /// \param raw_state_ The raw Lua state to wrap.
state(void * raw_state_)25711be35a1SLionel Sambuc lutok::state::state(void* raw_state_) :
25811be35a1SLionel Sambuc     _pimpl(new impl(reinterpret_cast< lua_State* >(raw_state_), false))
25911be35a1SLionel Sambuc {
26011be35a1SLionel Sambuc }
26111be35a1SLionel Sambuc 
26211be35a1SLionel Sambuc 
26311be35a1SLionel Sambuc /// Destructor for the Lua state.
26411be35a1SLionel Sambuc ///
26511be35a1SLionel Sambuc /// Closes the session unless it has already been closed by calling the
26611be35a1SLionel Sambuc /// close() method.  It is recommended to explicitly close the session in the
26711be35a1SLionel Sambuc /// code.
~state(void)26811be35a1SLionel Sambuc lutok::state::~state(void)
26911be35a1SLionel Sambuc {
27011be35a1SLionel Sambuc     if (_pimpl->owned && _pimpl->lua_state != NULL)
27111be35a1SLionel Sambuc         close();
27211be35a1SLionel Sambuc }
27311be35a1SLionel Sambuc 
27411be35a1SLionel Sambuc 
27511be35a1SLionel Sambuc /// Terminates this Lua session.
27611be35a1SLionel Sambuc ///
27711be35a1SLionel Sambuc /// It is recommended to call this instead of relying on the destructor to do
27811be35a1SLionel Sambuc /// the cleanup, but it is not a requirement to use close().
27911be35a1SLionel Sambuc ///
28011be35a1SLionel Sambuc /// \pre close() has not yet been called.
28111be35a1SLionel Sambuc /// \pre The Lua stack is empty.  This is not truly necessary but ensures that
28211be35a1SLionel Sambuc ///     our code is consistent and clears the stack explicitly.
28311be35a1SLionel Sambuc void
close(void)28411be35a1SLionel Sambuc lutok::state::close(void)
28511be35a1SLionel Sambuc {
28611be35a1SLionel Sambuc     assert(_pimpl->lua_state != NULL);
28711be35a1SLionel Sambuc     assert(lua_gettop(_pimpl->lua_state) == 0);
28811be35a1SLionel Sambuc     lua_close(_pimpl->lua_state);
28911be35a1SLionel Sambuc     _pimpl->lua_state = NULL;
29011be35a1SLionel Sambuc }
29111be35a1SLionel Sambuc 
29211be35a1SLionel Sambuc 
29311be35a1SLionel Sambuc /// Wrapper around lua_getglobal.
29411be35a1SLionel Sambuc ///
29511be35a1SLionel Sambuc /// \param name The second parameter to lua_getglobal.
29611be35a1SLionel Sambuc ///
29711be35a1SLionel Sambuc /// \throw api_error If lua_getglobal fails.
29811be35a1SLionel Sambuc ///
29911be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
30011be35a1SLionel Sambuc /// the Lua stack.
30111be35a1SLionel Sambuc void
get_global(const std::string & name)30211be35a1SLionel Sambuc lutok::state::get_global(const std::string& name)
30311be35a1SLionel Sambuc {
30411be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, protected_getglobal);
30511be35a1SLionel Sambuc     lua_pushstring(_pimpl->lua_state, name.c_str());
30611be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 1, 1, 0) != 0)
30711be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_getglobal");
30811be35a1SLionel Sambuc }
30911be35a1SLionel Sambuc 
31011be35a1SLionel Sambuc 
311*84d9c625SLionel Sambuc /// Pushes a reference to the global table onto the stack.
312*84d9c625SLionel Sambuc ///
313*84d9c625SLionel Sambuc /// This is a wrapper around the incompatible differences between Lua 5.1 and
314*84d9c625SLionel Sambuc /// 5.2 to access to the globals table.
315*84d9c625SLionel Sambuc ///
316*84d9c625SLionel Sambuc /// \post state(-1) Contains the reference to the globals table.
317*84d9c625SLionel Sambuc void
get_global_table(void)318*84d9c625SLionel Sambuc lutok::state::get_global_table(void)
319*84d9c625SLionel Sambuc {
320*84d9c625SLionel Sambuc #if LUA_VERSION_NUM >= 502
321*84d9c625SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, registry_index);
322*84d9c625SLionel Sambuc     lua_pushinteger(_pimpl->lua_state, LUA_RIDX_GLOBALS);
323*84d9c625SLionel Sambuc     lua_gettable(_pimpl->lua_state, -2);
324*84d9c625SLionel Sambuc     lua_remove(_pimpl->lua_state, -2);
325*84d9c625SLionel Sambuc #else
326*84d9c625SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, LUA_GLOBALSINDEX);
327*84d9c625SLionel Sambuc #endif
328*84d9c625SLionel Sambuc }
329*84d9c625SLionel Sambuc 
330*84d9c625SLionel Sambuc 
33111be35a1SLionel Sambuc /// Wrapper around luaL_getmetafield.
33211be35a1SLionel Sambuc ///
33311be35a1SLionel Sambuc /// \param index The second parameter to luaL_getmetafield.
33411be35a1SLionel Sambuc /// \param name The third parameter to luaL_getmetafield.
33511be35a1SLionel Sambuc ///
33611be35a1SLionel Sambuc /// \return The return value of luaL_getmetafield.
33711be35a1SLionel Sambuc ///
33811be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
33911be35a1SLionel Sambuc /// the Lua stack.
34011be35a1SLionel Sambuc bool
get_metafield(const int index,const std::string & name)34111be35a1SLionel Sambuc lutok::state::get_metafield(const int index, const std::string& name)
34211be35a1SLionel Sambuc {
34311be35a1SLionel Sambuc     return luaL_getmetafield(_pimpl->lua_state, index, name.c_str()) != 0;
34411be35a1SLionel Sambuc }
34511be35a1SLionel Sambuc 
34611be35a1SLionel Sambuc 
34711be35a1SLionel Sambuc /// Wrapper around lua_getmetatable.
34811be35a1SLionel Sambuc ///
34911be35a1SLionel Sambuc /// \param index The second parameter to lua_getmetatable.
35011be35a1SLionel Sambuc ///
35111be35a1SLionel Sambuc /// \return The return value of lua_getmetatable.
35211be35a1SLionel Sambuc bool
get_metatable(const int index)35311be35a1SLionel Sambuc lutok::state::get_metatable(const int index)
35411be35a1SLionel Sambuc {
35511be35a1SLionel Sambuc     return lua_getmetatable(_pimpl->lua_state, index) != 0;
35611be35a1SLionel Sambuc }
35711be35a1SLionel Sambuc 
35811be35a1SLionel Sambuc 
35911be35a1SLionel Sambuc /// Wrapper around lua_gettable.
36011be35a1SLionel Sambuc ///
36111be35a1SLionel Sambuc /// \param index The second parameter to lua_gettable.
36211be35a1SLionel Sambuc ///
36311be35a1SLionel Sambuc /// \throw api_error If lua_gettable fails.
36411be35a1SLionel Sambuc ///
36511be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
36611be35a1SLionel Sambuc /// the Lua stack.
36711be35a1SLionel Sambuc void
get_table(const int index)36811be35a1SLionel Sambuc lutok::state::get_table(const int index)
36911be35a1SLionel Sambuc {
37011be35a1SLionel Sambuc     assert(lua_gettop(_pimpl->lua_state) >= 2);
37111be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, protected_gettable);
37211be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
37311be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, -3);
37411be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 2, 1, 0) != 0)
37511be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_gettable");
37611be35a1SLionel Sambuc     lua_remove(_pimpl->lua_state, -2);
37711be35a1SLionel Sambuc }
37811be35a1SLionel Sambuc 
37911be35a1SLionel Sambuc 
38011be35a1SLionel Sambuc /// Wrapper around lua_gettop.
38111be35a1SLionel Sambuc ///
38211be35a1SLionel Sambuc /// \return The return value of lua_gettop.
38311be35a1SLionel Sambuc int
get_top(void)38411be35a1SLionel Sambuc lutok::state::get_top(void)
38511be35a1SLionel Sambuc {
38611be35a1SLionel Sambuc     return lua_gettop(_pimpl->lua_state);
38711be35a1SLionel Sambuc }
38811be35a1SLionel Sambuc 
38911be35a1SLionel Sambuc 
39011be35a1SLionel Sambuc /// Wrapper around lua_insert.
39111be35a1SLionel Sambuc ///
39211be35a1SLionel Sambuc /// \param index The second parameter to lua_insert.
39311be35a1SLionel Sambuc void
insert(const int index)39411be35a1SLionel Sambuc lutok::state::insert(const int index)
39511be35a1SLionel Sambuc {
39611be35a1SLionel Sambuc     lua_insert(_pimpl->lua_state, index);
39711be35a1SLionel Sambuc }
39811be35a1SLionel Sambuc 
39911be35a1SLionel Sambuc 
40011be35a1SLionel Sambuc /// Wrapper around lua_isboolean.
40111be35a1SLionel Sambuc ///
40211be35a1SLionel Sambuc /// \param index The second parameter to lua_isboolean.
40311be35a1SLionel Sambuc ///
40411be35a1SLionel Sambuc /// \return The return value of lua_isboolean.
40511be35a1SLionel Sambuc bool
is_boolean(const int index)40611be35a1SLionel Sambuc lutok::state::is_boolean(const int index)
40711be35a1SLionel Sambuc {
40811be35a1SLionel Sambuc     return lua_isboolean(_pimpl->lua_state, index);
40911be35a1SLionel Sambuc }
41011be35a1SLionel Sambuc 
41111be35a1SLionel Sambuc 
41211be35a1SLionel Sambuc /// Wrapper around lua_isfunction.
41311be35a1SLionel Sambuc ///
41411be35a1SLionel Sambuc /// \param index The second parameter to lua_isfunction.
41511be35a1SLionel Sambuc ///
41611be35a1SLionel Sambuc /// \return The return value of lua_isfunction.
41711be35a1SLionel Sambuc bool
is_function(const int index)41811be35a1SLionel Sambuc lutok::state::is_function(const int index)
41911be35a1SLionel Sambuc {
42011be35a1SLionel Sambuc     return lua_isfunction(_pimpl->lua_state, index);
42111be35a1SLionel Sambuc }
42211be35a1SLionel Sambuc 
42311be35a1SLionel Sambuc 
42411be35a1SLionel Sambuc /// Wrapper around lua_isnil.
42511be35a1SLionel Sambuc ///
42611be35a1SLionel Sambuc /// \param index The second parameter to lua_isnil.
42711be35a1SLionel Sambuc ///
42811be35a1SLionel Sambuc /// \return The return value of lua_isnil.
42911be35a1SLionel Sambuc bool
is_nil(const int index)43011be35a1SLionel Sambuc lutok::state::is_nil(const int index)
43111be35a1SLionel Sambuc {
43211be35a1SLionel Sambuc     return lua_isnil(_pimpl->lua_state, index);
43311be35a1SLionel Sambuc }
43411be35a1SLionel Sambuc 
43511be35a1SLionel Sambuc 
43611be35a1SLionel Sambuc /// Wrapper around lua_isnumber.
43711be35a1SLionel Sambuc ///
43811be35a1SLionel Sambuc /// \param index The second parameter to lua_isnumber.
43911be35a1SLionel Sambuc ///
44011be35a1SLionel Sambuc /// \return The return value of lua_isnumber.
44111be35a1SLionel Sambuc bool
is_number(const int index)44211be35a1SLionel Sambuc lutok::state::is_number(const int index)
44311be35a1SLionel Sambuc {
44411be35a1SLionel Sambuc     return lua_isnumber(_pimpl->lua_state, index);
44511be35a1SLionel Sambuc }
44611be35a1SLionel Sambuc 
44711be35a1SLionel Sambuc 
44811be35a1SLionel Sambuc /// Wrapper around lua_isstring.
44911be35a1SLionel Sambuc ///
45011be35a1SLionel Sambuc /// \param index The second parameter to lua_isstring.
45111be35a1SLionel Sambuc ///
45211be35a1SLionel Sambuc /// \return The return value of lua_isstring.
45311be35a1SLionel Sambuc bool
is_string(const int index)45411be35a1SLionel Sambuc lutok::state::is_string(const int index)
45511be35a1SLionel Sambuc {
45611be35a1SLionel Sambuc     return lua_isstring(_pimpl->lua_state, index);
45711be35a1SLionel Sambuc }
45811be35a1SLionel Sambuc 
45911be35a1SLionel Sambuc 
46011be35a1SLionel Sambuc /// Wrapper around lua_istable.
46111be35a1SLionel Sambuc ///
46211be35a1SLionel Sambuc /// \param index The second parameter to lua_istable.
46311be35a1SLionel Sambuc ///
46411be35a1SLionel Sambuc /// \return The return value of lua_istable.
46511be35a1SLionel Sambuc bool
is_table(const int index)46611be35a1SLionel Sambuc lutok::state::is_table(const int index)
46711be35a1SLionel Sambuc {
46811be35a1SLionel Sambuc     return lua_istable(_pimpl->lua_state, index);
46911be35a1SLionel Sambuc }
47011be35a1SLionel Sambuc 
47111be35a1SLionel Sambuc 
47211be35a1SLionel Sambuc /// Wrapper around lua_isuserdata.
47311be35a1SLionel Sambuc ///
47411be35a1SLionel Sambuc /// \param index The second parameter to lua_isuserdata.
47511be35a1SLionel Sambuc ///
47611be35a1SLionel Sambuc /// \return The return value of lua_isuserdata.
47711be35a1SLionel Sambuc bool
is_userdata(const int index)47811be35a1SLionel Sambuc lutok::state::is_userdata(const int index)
47911be35a1SLionel Sambuc {
48011be35a1SLionel Sambuc     return lua_isuserdata(_pimpl->lua_state, index);
48111be35a1SLionel Sambuc }
48211be35a1SLionel Sambuc 
48311be35a1SLionel Sambuc 
48411be35a1SLionel Sambuc /// Wrapper around luaL_loadfile.
48511be35a1SLionel Sambuc ///
48611be35a1SLionel Sambuc /// \param file The second parameter to luaL_loadfile.
48711be35a1SLionel Sambuc ///
48811be35a1SLionel Sambuc /// \throw api_error If luaL_loadfile returns an error.
48911be35a1SLionel Sambuc /// \throw file_not_found_error If the file cannot be accessed.
49011be35a1SLionel Sambuc ///
49111be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
49211be35a1SLionel Sambuc void
load_file(const std::string & file)49311be35a1SLionel Sambuc lutok::state::load_file(const std::string& file)
49411be35a1SLionel Sambuc {
49511be35a1SLionel Sambuc     if (!::access(file.c_str(), R_OK) == 0)
49611be35a1SLionel Sambuc         throw lutok::file_not_found_error(file);
49711be35a1SLionel Sambuc     if (luaL_loadfile(_pimpl->lua_state, file.c_str()) != 0)
49811be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "luaL_loadfile");
49911be35a1SLionel Sambuc }
50011be35a1SLionel Sambuc 
50111be35a1SLionel Sambuc 
50211be35a1SLionel Sambuc /// Wrapper around luaL_loadstring.
50311be35a1SLionel Sambuc ///
50411be35a1SLionel Sambuc /// \param str The second parameter to luaL_loadstring.
50511be35a1SLionel Sambuc ///
50611be35a1SLionel Sambuc /// \throw api_error If luaL_loadstring returns an error.
50711be35a1SLionel Sambuc ///
50811be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
50911be35a1SLionel Sambuc void
load_string(const std::string & str)51011be35a1SLionel Sambuc lutok::state::load_string(const std::string& str)
51111be35a1SLionel Sambuc {
51211be35a1SLionel Sambuc     if (luaL_loadstring(_pimpl->lua_state, str.c_str()) != 0)
51311be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "luaL_loadstring");
51411be35a1SLionel Sambuc }
51511be35a1SLionel Sambuc 
51611be35a1SLionel Sambuc 
51711be35a1SLionel Sambuc /// Wrapper around lua_newtable.
51811be35a1SLionel Sambuc ///
51911be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
52011be35a1SLionel Sambuc void
new_table(void)52111be35a1SLionel Sambuc lutok::state::new_table(void)
52211be35a1SLionel Sambuc {
52311be35a1SLionel Sambuc     lua_newtable(_pimpl->lua_state);
52411be35a1SLionel Sambuc }
52511be35a1SLionel Sambuc 
52611be35a1SLionel Sambuc 
52711be35a1SLionel Sambuc /// Wrapper around lua_newuserdata.
52811be35a1SLionel Sambuc ///
52911be35a1SLionel Sambuc /// This is internal.  The public type-safe interface of this method should be
53011be35a1SLionel Sambuc /// used instead.
53111be35a1SLionel Sambuc ///
53211be35a1SLionel Sambuc /// \param size The second parameter to lua_newuserdata.
53311be35a1SLionel Sambuc ///
53411be35a1SLionel Sambuc /// \return The return value of lua_newuserdata.
53511be35a1SLionel Sambuc ///
53611be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
53711be35a1SLionel Sambuc void*
new_userdata_voidp(const size_t size)53811be35a1SLionel Sambuc lutok::state::new_userdata_voidp(const size_t size)
53911be35a1SLionel Sambuc {
54011be35a1SLionel Sambuc     return lua_newuserdata(_pimpl->lua_state, size);
54111be35a1SLionel Sambuc }
54211be35a1SLionel Sambuc 
54311be35a1SLionel Sambuc 
54411be35a1SLionel Sambuc /// Wrapper around lua_next.
54511be35a1SLionel Sambuc ///
54611be35a1SLionel Sambuc /// \param index The second parameter to lua_next.
54711be35a1SLionel Sambuc ///
54811be35a1SLionel Sambuc /// \return True if there are more elements to process; false otherwise.
54911be35a1SLionel Sambuc ///
55011be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
55111be35a1SLionel Sambuc bool
next(const int index)55211be35a1SLionel Sambuc lutok::state::next(const int index)
55311be35a1SLionel Sambuc {
55411be35a1SLionel Sambuc     assert(lua_istable(_pimpl->lua_state, index));
55511be35a1SLionel Sambuc     assert(lua_gettop(_pimpl->lua_state) >= 1);
55611be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, protected_next);
55711be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
55811be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, -3);
55911be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 2, LUA_MULTRET, 0) != 0)
56011be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_next");
56111be35a1SLionel Sambuc     const bool more = lua_toboolean(_pimpl->lua_state, -1);
56211be35a1SLionel Sambuc     lua_pop(_pimpl->lua_state, 1);
56311be35a1SLionel Sambuc     if (more)
56411be35a1SLionel Sambuc         lua_remove(_pimpl->lua_state, -3);
56511be35a1SLionel Sambuc     else
56611be35a1SLionel Sambuc         lua_pop(_pimpl->lua_state, 1);
56711be35a1SLionel Sambuc     return more;
56811be35a1SLionel Sambuc }
56911be35a1SLionel Sambuc 
57011be35a1SLionel Sambuc 
57111be35a1SLionel Sambuc /// Wrapper around luaopen_base.
57211be35a1SLionel Sambuc ///
57311be35a1SLionel Sambuc /// \throw api_error If luaopen_base fails.
57411be35a1SLionel Sambuc ///
57511be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
57611be35a1SLionel Sambuc void
open_base(void)57711be35a1SLionel Sambuc lutok::state::open_base(void)
57811be35a1SLionel Sambuc {
57911be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, luaopen_base);
58011be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
58111be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "luaopen_base");
58211be35a1SLionel Sambuc }
58311be35a1SLionel Sambuc 
58411be35a1SLionel Sambuc 
58511be35a1SLionel Sambuc /// Wrapper around luaopen_string.
58611be35a1SLionel Sambuc ///
58711be35a1SLionel Sambuc /// \throw api_error If luaopen_string fails.
58811be35a1SLionel Sambuc ///
58911be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
59011be35a1SLionel Sambuc void
open_string(void)59111be35a1SLionel Sambuc lutok::state::open_string(void)
59211be35a1SLionel Sambuc {
593*84d9c625SLionel Sambuc #if LUA_VERSION_NUM >= 502
594*84d9c625SLionel Sambuc     luaL_requiref(_pimpl->lua_state, LUA_STRLIBNAME, luaopen_string, 1);
595*84d9c625SLionel Sambuc     lua_pop(_pimpl->lua_state, 1);
596*84d9c625SLionel Sambuc #else
59711be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, luaopen_string);
59811be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
59911be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "luaopen_string");
600*84d9c625SLionel Sambuc #endif
60111be35a1SLionel Sambuc }
60211be35a1SLionel Sambuc 
60311be35a1SLionel Sambuc 
60411be35a1SLionel Sambuc /// Wrapper around luaopen_table.
60511be35a1SLionel Sambuc ///
60611be35a1SLionel Sambuc /// \throw api_error If luaopen_table fails.
60711be35a1SLionel Sambuc ///
60811be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
60911be35a1SLionel Sambuc void
open_table(void)61011be35a1SLionel Sambuc lutok::state::open_table(void)
61111be35a1SLionel Sambuc {
612*84d9c625SLionel Sambuc #if LUA_VERSION_NUM >= 502
613*84d9c625SLionel Sambuc     luaL_requiref(_pimpl->lua_state, LUA_TABLIBNAME, luaopen_table, 1);
614*84d9c625SLionel Sambuc     lua_pop(_pimpl->lua_state, 1);
615*84d9c625SLionel Sambuc #else
61611be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, luaopen_table);
61711be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)
61811be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "luaopen_table");
619*84d9c625SLionel Sambuc #endif
62011be35a1SLionel Sambuc }
62111be35a1SLionel Sambuc 
62211be35a1SLionel Sambuc 
62311be35a1SLionel Sambuc /// Wrapper around lua_pcall.
62411be35a1SLionel Sambuc ///
62511be35a1SLionel Sambuc /// \param nargs The second parameter to lua_pcall.
62611be35a1SLionel Sambuc /// \param nresults The third parameter to lua_pcall.
62711be35a1SLionel Sambuc /// \param errfunc The fourth parameter to lua_pcall.
62811be35a1SLionel Sambuc ///
62911be35a1SLionel Sambuc /// \throw api_error If lua_pcall returns an error.
63011be35a1SLionel Sambuc void
pcall(const int nargs,const int nresults,const int errfunc)63111be35a1SLionel Sambuc lutok::state::pcall(const int nargs, const int nresults, const int errfunc)
63211be35a1SLionel Sambuc {
63311be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0)
63411be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_pcall");
63511be35a1SLionel Sambuc }
63611be35a1SLionel Sambuc 
63711be35a1SLionel Sambuc 
63811be35a1SLionel Sambuc /// Wrapper around lua_pop.
63911be35a1SLionel Sambuc ///
64011be35a1SLionel Sambuc /// \param count The second parameter to lua_pop.
64111be35a1SLionel Sambuc void
pop(const int count)64211be35a1SLionel Sambuc lutok::state::pop(const int count)
64311be35a1SLionel Sambuc {
64411be35a1SLionel Sambuc     assert(count <= lua_gettop(_pimpl->lua_state));
64511be35a1SLionel Sambuc     lua_pop(_pimpl->lua_state, count);
64611be35a1SLionel Sambuc     assert(lua_gettop(_pimpl->lua_state) >= 0);
64711be35a1SLionel Sambuc }
64811be35a1SLionel Sambuc 
64911be35a1SLionel Sambuc 
65011be35a1SLionel Sambuc /// Wrapper around lua_pushboolean.
65111be35a1SLionel Sambuc ///
65211be35a1SLionel Sambuc /// \param value The second parameter to lua_pushboolean.
65311be35a1SLionel Sambuc void
push_boolean(const bool value)65411be35a1SLionel Sambuc lutok::state::push_boolean(const bool value)
65511be35a1SLionel Sambuc {
65611be35a1SLionel Sambuc     lua_pushboolean(_pimpl->lua_state, value ? 1 : 0);
65711be35a1SLionel Sambuc }
65811be35a1SLionel Sambuc 
65911be35a1SLionel Sambuc 
66011be35a1SLionel Sambuc /// Wrapper around lua_pushcclosure.
66111be35a1SLionel Sambuc ///
66211be35a1SLionel Sambuc /// This is not a pure wrapper around lua_pushcclosure because this has to do
66311be35a1SLionel Sambuc /// extra magic to allow passing C++ functions instead of plain C functions.
66411be35a1SLionel Sambuc ///
66511be35a1SLionel Sambuc /// \param function The C++ function to be pushed as a closure.
66611be35a1SLionel Sambuc /// \param nvalues The number of upvalues that the function receives.
66711be35a1SLionel Sambuc void
push_cxx_closure(cxx_function function,const int nvalues)66811be35a1SLionel Sambuc lutok::state::push_cxx_closure(cxx_function function, const int nvalues)
66911be35a1SLionel Sambuc {
67011be35a1SLionel Sambuc     cxx_function *data = static_cast< cxx_function* >(
67111be35a1SLionel Sambuc         lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
67211be35a1SLionel Sambuc     *data = function;
67311be35a1SLionel Sambuc     lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1);
67411be35a1SLionel Sambuc }
67511be35a1SLionel Sambuc 
67611be35a1SLionel Sambuc 
67711be35a1SLionel Sambuc /// Wrapper around lua_pushcfunction.
67811be35a1SLionel Sambuc ///
67911be35a1SLionel Sambuc /// This is not a pure wrapper around lua_pushcfunction because this has to do
68011be35a1SLionel Sambuc /// extra magic to allow passing C++ functions instead of plain C functions.
68111be35a1SLionel Sambuc ///
68211be35a1SLionel Sambuc /// \param function The C++ function to be pushed.
68311be35a1SLionel Sambuc void
push_cxx_function(cxx_function function)68411be35a1SLionel Sambuc lutok::state::push_cxx_function(cxx_function function)
68511be35a1SLionel Sambuc {
68611be35a1SLionel Sambuc     cxx_function *data = static_cast< cxx_function* >(
68711be35a1SLionel Sambuc         lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));
68811be35a1SLionel Sambuc     *data = function;
68911be35a1SLionel Sambuc     lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1);
69011be35a1SLionel Sambuc }
69111be35a1SLionel Sambuc 
69211be35a1SLionel Sambuc 
69311be35a1SLionel Sambuc /// Wrapper around lua_pushinteger.
69411be35a1SLionel Sambuc ///
69511be35a1SLionel Sambuc /// \param value The second parameter to lua_pushinteger.
69611be35a1SLionel Sambuc void
push_integer(const int value)69711be35a1SLionel Sambuc lutok::state::push_integer(const int value)
69811be35a1SLionel Sambuc {
69911be35a1SLionel Sambuc     lua_pushinteger(_pimpl->lua_state, value);
70011be35a1SLionel Sambuc }
70111be35a1SLionel Sambuc 
70211be35a1SLionel Sambuc 
70311be35a1SLionel Sambuc /// Wrapper around lua_pushnil.
70411be35a1SLionel Sambuc void
push_nil(void)70511be35a1SLionel Sambuc lutok::state::push_nil(void)
70611be35a1SLionel Sambuc {
70711be35a1SLionel Sambuc     lua_pushnil(_pimpl->lua_state);
70811be35a1SLionel Sambuc }
70911be35a1SLionel Sambuc 
71011be35a1SLionel Sambuc 
71111be35a1SLionel Sambuc /// Wrapper around lua_pushstring.
71211be35a1SLionel Sambuc ///
71311be35a1SLionel Sambuc /// \param str The second parameter to lua_pushstring.
71411be35a1SLionel Sambuc ///
71511be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
71611be35a1SLionel Sambuc void
push_string(const std::string & str)71711be35a1SLionel Sambuc lutok::state::push_string(const std::string& str)
71811be35a1SLionel Sambuc {
71911be35a1SLionel Sambuc     lua_pushstring(_pimpl->lua_state, str.c_str());
72011be35a1SLionel Sambuc }
72111be35a1SLionel Sambuc 
72211be35a1SLionel Sambuc 
72311be35a1SLionel Sambuc /// Wrapper around lua_pushvalue.
72411be35a1SLionel Sambuc ///
72511be35a1SLionel Sambuc /// \param index The second parameter to lua_pushvalue.
72611be35a1SLionel Sambuc void
push_value(const int index)72711be35a1SLionel Sambuc lutok::state::push_value(const int index)
72811be35a1SLionel Sambuc {
72911be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, index);
73011be35a1SLionel Sambuc }
73111be35a1SLionel Sambuc 
73211be35a1SLionel Sambuc 
73311be35a1SLionel Sambuc /// Wrapper around lua_rawget.
73411be35a1SLionel Sambuc ///
73511be35a1SLionel Sambuc /// \param index The second parameter to lua_rawget.
73611be35a1SLionel Sambuc void
raw_get(const int index)73711be35a1SLionel Sambuc lutok::state::raw_get(const int index)
73811be35a1SLionel Sambuc {
73911be35a1SLionel Sambuc     lua_rawget(_pimpl->lua_state, index);
74011be35a1SLionel Sambuc }
74111be35a1SLionel Sambuc 
74211be35a1SLionel Sambuc 
74311be35a1SLionel Sambuc /// Wrapper around lua_rawset.
74411be35a1SLionel Sambuc ///
74511be35a1SLionel Sambuc /// \param index The second parameter to lua_rawset.
74611be35a1SLionel Sambuc ///
74711be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
74811be35a1SLionel Sambuc /// the Lua stack.
74911be35a1SLionel Sambuc void
raw_set(const int index)75011be35a1SLionel Sambuc lutok::state::raw_set(const int index)
75111be35a1SLionel Sambuc {
75211be35a1SLionel Sambuc     lua_rawset(_pimpl->lua_state, index);
75311be35a1SLionel Sambuc }
75411be35a1SLionel Sambuc 
75511be35a1SLionel Sambuc 
75611be35a1SLionel Sambuc /// Wrapper around lua_setglobal.
75711be35a1SLionel Sambuc ///
75811be35a1SLionel Sambuc /// \param name The second parameter to lua_setglobal.
75911be35a1SLionel Sambuc ///
76011be35a1SLionel Sambuc /// \throw api_error If lua_setglobal fails.
76111be35a1SLionel Sambuc ///
76211be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
76311be35a1SLionel Sambuc /// the Lua stack.
76411be35a1SLionel Sambuc void
set_global(const std::string & name)76511be35a1SLionel Sambuc lutok::state::set_global(const std::string& name)
76611be35a1SLionel Sambuc {
76711be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, protected_setglobal);
76811be35a1SLionel Sambuc     lua_pushstring(_pimpl->lua_state, name.c_str());
76911be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, -3);
77011be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0)
77111be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_setglobal");
77211be35a1SLionel Sambuc     lua_pop(_pimpl->lua_state, 1);
77311be35a1SLionel Sambuc }
77411be35a1SLionel Sambuc 
77511be35a1SLionel Sambuc 
77611be35a1SLionel Sambuc /// Wrapper around lua_setmetatable.
77711be35a1SLionel Sambuc ///
77811be35a1SLionel Sambuc /// \param index The second parameter to lua_setmetatable.
77911be35a1SLionel Sambuc void
set_metatable(const int index)78011be35a1SLionel Sambuc lutok::state::set_metatable(const int index)
78111be35a1SLionel Sambuc {
78211be35a1SLionel Sambuc     lua_setmetatable(_pimpl->lua_state, index);
78311be35a1SLionel Sambuc }
78411be35a1SLionel Sambuc 
78511be35a1SLionel Sambuc 
78611be35a1SLionel Sambuc /// Wrapper around lua_settable.
78711be35a1SLionel Sambuc ///
78811be35a1SLionel Sambuc /// \param index The second parameter to lua_settable.
78911be35a1SLionel Sambuc ///
79011be35a1SLionel Sambuc /// \throw api_error If lua_settable fails.
79111be35a1SLionel Sambuc ///
79211be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory to manipulate
79311be35a1SLionel Sambuc /// the Lua stack.
79411be35a1SLionel Sambuc void
set_table(const int index)79511be35a1SLionel Sambuc lutok::state::set_table(const int index)
79611be35a1SLionel Sambuc {
79711be35a1SLionel Sambuc     lua_pushcfunction(_pimpl->lua_state, protected_settable);
79811be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);
79911be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, -4);
80011be35a1SLionel Sambuc     lua_pushvalue(_pimpl->lua_state, -4);
80111be35a1SLionel Sambuc     if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0)
80211be35a1SLionel Sambuc         throw lutok::api_error::from_stack(*this, "lua_settable");
80311be35a1SLionel Sambuc     lua_pop(_pimpl->lua_state, 2);
80411be35a1SLionel Sambuc }
80511be35a1SLionel Sambuc 
80611be35a1SLionel Sambuc 
80711be35a1SLionel Sambuc /// Wrapper around lua_toboolean.
80811be35a1SLionel Sambuc ///
80911be35a1SLionel Sambuc /// \param index The second parameter to lua_toboolean.
81011be35a1SLionel Sambuc ///
81111be35a1SLionel Sambuc /// \return The return value of lua_toboolean.
81211be35a1SLionel Sambuc bool
to_boolean(const int index)81311be35a1SLionel Sambuc lutok::state::to_boolean(const int index)
81411be35a1SLionel Sambuc {
81511be35a1SLionel Sambuc     assert(is_boolean(index));
81611be35a1SLionel Sambuc     return lua_toboolean(_pimpl->lua_state, index);
81711be35a1SLionel Sambuc }
81811be35a1SLionel Sambuc 
81911be35a1SLionel Sambuc 
82011be35a1SLionel Sambuc /// Wrapper around lua_tointeger.
82111be35a1SLionel Sambuc ///
82211be35a1SLionel Sambuc /// \param index The second parameter to lua_tointeger.
82311be35a1SLionel Sambuc ///
82411be35a1SLionel Sambuc /// \return The return value of lua_tointeger.
82511be35a1SLionel Sambuc long
to_integer(const int index)82611be35a1SLionel Sambuc lutok::state::to_integer(const int index)
82711be35a1SLionel Sambuc {
82811be35a1SLionel Sambuc     assert(is_number(index));
82911be35a1SLionel Sambuc     return lua_tointeger(_pimpl->lua_state, index);
83011be35a1SLionel Sambuc }
83111be35a1SLionel Sambuc 
83211be35a1SLionel Sambuc 
83311be35a1SLionel Sambuc /// Wrapper around lua_touserdata.
83411be35a1SLionel Sambuc ///
83511be35a1SLionel Sambuc /// This is internal.  The public type-safe interface of this method should be
83611be35a1SLionel Sambuc /// used instead.
83711be35a1SLionel Sambuc ///
83811be35a1SLionel Sambuc /// \param index The second parameter to lua_touserdata.
83911be35a1SLionel Sambuc ///
84011be35a1SLionel Sambuc /// \return The return value of lua_touserdata.
84111be35a1SLionel Sambuc ///
84211be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
84311be35a1SLionel Sambuc void*
to_userdata_voidp(const int index)84411be35a1SLionel Sambuc lutok::state::to_userdata_voidp(const int index)
84511be35a1SLionel Sambuc {
84611be35a1SLionel Sambuc     return lua_touserdata(_pimpl->lua_state, index);
84711be35a1SLionel Sambuc }
84811be35a1SLionel Sambuc 
84911be35a1SLionel Sambuc 
85011be35a1SLionel Sambuc 
85111be35a1SLionel Sambuc /// Wrapper around lua_tostring.
85211be35a1SLionel Sambuc ///
85311be35a1SLionel Sambuc /// \param index The second parameter to lua_tostring.
85411be35a1SLionel Sambuc ///
85511be35a1SLionel Sambuc /// \return The return value of lua_tostring.
85611be35a1SLionel Sambuc ///
85711be35a1SLionel Sambuc /// \warning Terminates execution if there is not enough memory.
85811be35a1SLionel Sambuc std::string
to_string(const int index)85911be35a1SLionel Sambuc lutok::state::to_string(const int index)
86011be35a1SLionel Sambuc {
86111be35a1SLionel Sambuc     assert(is_string(index));
86211be35a1SLionel Sambuc     const char *raw_string = lua_tostring(_pimpl->lua_state, index);
86311be35a1SLionel Sambuc     // Note that the creation of a string object below (explicit for clarity)
86411be35a1SLionel Sambuc     // implies that the raw string is duplicated and, henceforth, the string is
86511be35a1SLionel Sambuc     // safe even if the corresponding element is popped from the Lua stack.
86611be35a1SLionel Sambuc     return std::string(raw_string);
86711be35a1SLionel Sambuc }
86811be35a1SLionel Sambuc 
86911be35a1SLionel Sambuc 
87011be35a1SLionel Sambuc /// Wrapper around lua_upvalueindex.
87111be35a1SLionel Sambuc ///
87211be35a1SLionel Sambuc /// \param index The first parameter to lua_upvalueindex.
87311be35a1SLionel Sambuc ///
87411be35a1SLionel Sambuc /// \return The return value of lua_upvalueindex.
87511be35a1SLionel Sambuc int
upvalue_index(const int index)87611be35a1SLionel Sambuc lutok::state::upvalue_index(const int index)
87711be35a1SLionel Sambuc {
87811be35a1SLionel Sambuc     return lua_upvalueindex(index);
87911be35a1SLionel Sambuc }
88011be35a1SLionel Sambuc 
88111be35a1SLionel Sambuc 
88211be35a1SLionel Sambuc /// Gets the internal lua_State object.
88311be35a1SLionel Sambuc ///
88411be35a1SLionel Sambuc /// \return The raw Lua state.  This is returned as a void pointer to prevent
88511be35a1SLionel Sambuc /// including the lua.hpp header file from our public interface.  The only way
88611be35a1SLionel Sambuc /// to call this method is by using the c_gate module, and c_gate takes care of
88711be35a1SLionel Sambuc /// casting this object to the appropriate type.
88811be35a1SLionel Sambuc void*
raw_state(void)88911be35a1SLionel Sambuc lutok::state::raw_state(void)
89011be35a1SLionel Sambuc {
89111be35a1SLionel Sambuc     return _pimpl->lua_state;
89211be35a1SLionel Sambuc }
893