// Copyright 2011 Google Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above copyright10// notice, this list of conditions and the following disclaimer in the11// documentation and/or other materials provided with the distribution.12// * Neither the name of Google Inc. nor the names of its contributors13// may be used to endorse or promote products derived from this software14// without specific prior written permission.15//16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2728extern "C" {29#include <unistd.h>30}3132#include <cassert>33#include <cstring>3435#include "c_gate.hpp"36#include "exceptions.hpp"37#include "state.ipp"383940namespace {414243/// Wrapper around lua_getglobal to run in a protected environment.44///45/// \pre stack(-1) is the name of the global to get.46/// \post stack(-1) is the value of the global.47///48/// \param state The Lua C API state.49///50/// \return The number of return values pushed onto the stack.51static int52protected_getglobal(lua_State* state)53{54lua_getglobal(state, lua_tostring(state, -1));55return 1;56}575859/// Wrapper around lua_gettable to run in a protected environment.60///61/// \pre stack(-2) is the table to get the element from.62/// \pre stack(-1) is the table index.63/// \post stack(-1) is the value of stack(-2)[stack(-1)].64///65/// \param state The Lua C API state.66///67/// \return The number of return values pushed onto the stack.68static int69protected_gettable(lua_State* state)70{71lua_gettable(state, -2);72return 1;73}747576/// Wrapper around lua_next to run in a protected environment.77///78/// \pre stack(-2) is the table to get the next element from.79/// \pre stack(-1) is the last processed key.80/// \post stack(-1) is the value of next(stack(-2), stack(-1)).81///82/// \param state The Lua C API state.83///84/// \return The number of return values pushed onto the stack.85static int86protected_next(lua_State* state)87{88const int more = lua_next(state, -2) != 0;89lua_pushboolean(state, more);90return more ? 3 : 1;91}929394/// Wrapper around lua_setglobal to run in a protected environment.95///96/// \pre stack(-2) is the name of the global to set.97/// \pre stack(-1) is the value to set the global to.98///99/// \param state The Lua C API state.100///101/// \return The number of return values pushed onto the stack.102static int103protected_setglobal(lua_State* state)104{105lua_setglobal(state, lua_tostring(state, -2));106return 0;107}108109110/// Wrapper around lua_settable to run in a protected environment.111///112/// \pre stack(-3) is the table to set the element into.113/// \pre stack(-2) is the table index.114/// \pre stack(-1) is the value to set.115///116/// \param state The Lua C API state.117///118/// \return The number of return values pushed onto the stack.119static int120protected_settable(lua_State* state)121{122lua_settable(state, -3);123return 0;124}125126127/// Calls a C++ Lua function from a C calling environment.128///129/// Any errors reported by the C++ function are caught and reported to the130/// caller as Lua errors.131///132/// \param function The C++ function to call.133/// \param raw_state The raw Lua state.134///135/// \return The number of return values pushed onto the Lua stack by the136/// function.137static int138call_cxx_function_from_c(lutok::cxx_function function,139lua_State* raw_state) throw()140{141char error_buf[1024];142143try {144lutok::state state = lutok::state_c_gate::connect(raw_state);145return function(state);146} catch (const std::exception& e) {147std::strncpy(error_buf, e.what(), sizeof(error_buf));148} catch (...) {149std::strncpy(error_buf, "Unhandled exception in Lua C++ hook",150sizeof(error_buf));151}152error_buf[sizeof(error_buf) - 1] = '\0';153// We raise the Lua error from outside the try/catch context and we use154// a stack-based buffer to hold the message to ensure that we do not leak155// any C++ objects (and, as a likely result, memory) when Lua performs its156// longjmp.157return luaL_error(raw_state, "%s", error_buf);158}159160161/// Lua glue to call a C++ closure.162///163/// This Lua binding is actually a closure that we have constructed from the164/// state.push_cxx_closure() method. The closure contains the same upvalues165/// provided by the user plus an extra upvalue that contains the address of the166/// C++ function we have to call. All we do here is safely delegate the167/// execution to the wrapped C++ closure.168///169/// \param raw_state The Lua C API state.170///171/// \return The number of return values of the called closure.172static int173cxx_closure_trampoline(lua_State* raw_state)174{175lutok::state state = lutok::state_c_gate::connect(raw_state);176177int nupvalues;178{179lua_Debug debug;180lua_getstack(raw_state, 0, &debug);181lua_getinfo(raw_state, "u", &debug);182nupvalues = debug.nups;183}184185lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(186state.upvalue_index(nupvalues));187return call_cxx_function_from_c(*function, raw_state);188}189190191/// Lua glue to call a C++ function.192///193/// This Lua binding is actually a closure that we have constructed from the194/// state.push_cxx_function() method. The closure has a single upvalue that195/// contains the address of the C++ function we have to call. All we do here is196/// safely delegate the execution to the wrapped C++ function.197///198/// \param raw_state The Lua C API state.199///200/// \return The number of return values of the called function.201static int202cxx_function_trampoline(lua_State* raw_state)203{204lutok::state state = lutok::state_c_gate::connect(raw_state);205lutok::cxx_function* function = state.to_userdata< lutok::cxx_function >(206state.upvalue_index(1));207return call_cxx_function_from_c(*function, raw_state);208}209210211} // anonymous namespace212213214const int lutok::registry_index = LUA_REGISTRYINDEX;215216217/// Internal implementation for lutok::state.218struct lutok::state::impl {219/// The Lua internal state.220lua_State* lua_state;221222/// Whether we own the state or not (to decide if we close it).223bool owned;224225/// Constructor.226///227/// \param lua_ The Lua internal state.228/// \param owned_ Whether we own the state or not.229impl(lua_State* lua_, bool owned_) :230lua_state(lua_),231owned(owned_)232{233}234};235236237/// Initializes the Lua state.238///239/// You must share the same state object alongside the lifetime of your Lua240/// session. As soon as the object is destroyed, the session is terminated.241lutok::state::state(void)242{243lua_State* lua = luaL_newstate();244if (lua == NULL)245throw lutok::error("lua open failed");246_pimpl.reset(new impl(lua, true));247}248249250/// Initializes the Lua state from an existing raw state.251///252/// Instances constructed using this method do NOT own the raw state. This253/// means that, on exit, the state will not be destroyed.254///255/// \param raw_state_ The raw Lua state to wrap.256lutok::state::state(void* raw_state_) :257_pimpl(new impl(reinterpret_cast< lua_State* >(raw_state_), false))258{259}260261262/// Destructor for the Lua state.263///264/// Closes the session unless it has already been closed by calling the265/// close() method. It is recommended to explicitly close the session in the266/// code.267lutok::state::~state(void)268{269if (_pimpl->owned && _pimpl->lua_state != NULL)270close();271}272273274/// Terminates this Lua session.275///276/// It is recommended to call this instead of relying on the destructor to do277/// the cleanup, but it is not a requirement to use close().278///279/// \pre close() has not yet been called.280/// \pre The Lua stack is empty. This is not truly necessary but ensures that281/// our code is consistent and clears the stack explicitly.282void283lutok::state::close(void)284{285assert(_pimpl->lua_state != NULL);286assert(lua_gettop(_pimpl->lua_state) == 0);287lua_close(_pimpl->lua_state);288_pimpl->lua_state = NULL;289}290291292/// Wrapper around lua_getglobal.293///294/// \param name The second parameter to lua_getglobal.295///296/// \throw api_error If lua_getglobal fails.297///298/// \warning Terminates execution if there is not enough memory to manipulate299/// the Lua stack.300void301lutok::state::get_global(const std::string& name)302{303lua_pushcfunction(_pimpl->lua_state, protected_getglobal);304lua_pushstring(_pimpl->lua_state, name.c_str());305if (lua_pcall(_pimpl->lua_state, 1, 1, 0) != 0)306throw lutok::api_error::from_stack(*this, "lua_getglobal");307}308309310/// Pushes a reference to the global table onto the stack.311///312/// This is a wrapper around the incompatible differences between Lua 5.1 and313/// 5.2 to access to the globals table.314///315/// \post state(-1) Contains the reference to the globals table.316void317lutok::state::get_global_table(void)318{319#if LUA_VERSION_NUM >= 502320lua_pushvalue(_pimpl->lua_state, registry_index);321lua_pushinteger(_pimpl->lua_state, LUA_RIDX_GLOBALS);322lua_gettable(_pimpl->lua_state, -2);323lua_remove(_pimpl->lua_state, -2);324#else325lua_pushvalue(_pimpl->lua_state, LUA_GLOBALSINDEX);326#endif327}328329330/// Wrapper around luaL_getmetafield.331///332/// \param index The second parameter to luaL_getmetafield.333/// \param name The third parameter to luaL_getmetafield.334///335/// \return The return value of luaL_getmetafield.336///337/// \warning Terminates execution if there is not enough memory to manipulate338/// the Lua stack.339bool340lutok::state::get_metafield(const int index, const std::string& name)341{342return luaL_getmetafield(_pimpl->lua_state, index, name.c_str()) != 0;343}344345346/// Wrapper around lua_getmetatable.347///348/// \param index The second parameter to lua_getmetatable.349///350/// \return The return value of lua_getmetatable.351bool352lutok::state::get_metatable(const int index)353{354return lua_getmetatable(_pimpl->lua_state, index) != 0;355}356357358/// Wrapper around lua_gettable.359///360/// \param index The second parameter to lua_gettable.361///362/// \throw api_error If lua_gettable fails.363///364/// \warning Terminates execution if there is not enough memory to manipulate365/// the Lua stack.366void367lutok::state::get_table(const int index)368{369assert(lua_gettop(_pimpl->lua_state) >= 2);370lua_pushcfunction(_pimpl->lua_state, protected_gettable);371lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);372lua_pushvalue(_pimpl->lua_state, -3);373if (lua_pcall(_pimpl->lua_state, 2, 1, 0) != 0)374throw lutok::api_error::from_stack(*this, "lua_gettable");375lua_remove(_pimpl->lua_state, -2);376}377378379/// Wrapper around lua_gettop.380///381/// \return The return value of lua_gettop.382int383lutok::state::get_top(void)384{385return lua_gettop(_pimpl->lua_state);386}387388389/// Wrapper around lua_insert.390///391/// \param index The second parameter to lua_insert.392void393lutok::state::insert(const int index)394{395lua_insert(_pimpl->lua_state, index);396}397398399/// Wrapper around lua_isboolean.400///401/// \param index The second parameter to lua_isboolean.402///403/// \return The return value of lua_isboolean.404bool405lutok::state::is_boolean(const int index)406{407return lua_isboolean(_pimpl->lua_state, index);408}409410411/// Wrapper around lua_isfunction.412///413/// \param index The second parameter to lua_isfunction.414///415/// \return The return value of lua_isfunction.416bool417lutok::state::is_function(const int index)418{419return lua_isfunction(_pimpl->lua_state, index);420}421422423/// Wrapper around lua_isnil.424///425/// \param index The second parameter to lua_isnil.426///427/// \return The return value of lua_isnil.428bool429lutok::state::is_nil(const int index)430{431return lua_isnil(_pimpl->lua_state, index);432}433434435/// Wrapper around lua_isnumber.436///437/// \param index The second parameter to lua_isnumber.438///439/// \return The return value of lua_isnumber.440bool441lutok::state::is_number(const int index)442{443return lua_isnumber(_pimpl->lua_state, index);444}445446447/// Wrapper around lua_isstring.448///449/// \param index The second parameter to lua_isstring.450///451/// \return The return value of lua_isstring.452bool453lutok::state::is_string(const int index)454{455return lua_isstring(_pimpl->lua_state, index);456}457458459/// Wrapper around lua_istable.460///461/// \param index The second parameter to lua_istable.462///463/// \return The return value of lua_istable.464bool465lutok::state::is_table(const int index)466{467return lua_istable(_pimpl->lua_state, index);468}469470471/// Wrapper around lua_isuserdata.472///473/// \param index The second parameter to lua_isuserdata.474///475/// \return The return value of lua_isuserdata.476bool477lutok::state::is_userdata(const int index)478{479return lua_isuserdata(_pimpl->lua_state, index);480}481482483/// Wrapper around luaL_loadfile.484///485/// \param file The second parameter to luaL_loadfile.486///487/// \throw api_error If luaL_loadfile returns an error.488/// \throw file_not_found_error If the file cannot be accessed.489///490/// \warning Terminates execution if there is not enough memory.491void492lutok::state::load_file(const std::string& file)493{494if (::access(file.c_str(), R_OK) == -1)495throw lutok::file_not_found_error(file);496if (luaL_loadfile(_pimpl->lua_state, file.c_str()) != 0)497throw lutok::api_error::from_stack(*this, "luaL_loadfile");498}499500501/// Wrapper around luaL_loadstring.502///503/// \param str The second parameter to luaL_loadstring.504///505/// \throw api_error If luaL_loadstring returns an error.506///507/// \warning Terminates execution if there is not enough memory.508void509lutok::state::load_string(const std::string& str)510{511if (luaL_loadstring(_pimpl->lua_state, str.c_str()) != 0)512throw lutok::api_error::from_stack(*this, "luaL_loadstring");513}514515516/// Wrapper around lua_newtable.517///518/// \warning Terminates execution if there is not enough memory.519void520lutok::state::new_table(void)521{522lua_newtable(_pimpl->lua_state);523}524525526/// Wrapper around lua_newuserdata.527///528/// This is internal. The public type-safe interface of this method should be529/// used instead.530///531/// \param size The second parameter to lua_newuserdata.532///533/// \return The return value of lua_newuserdata.534///535/// \warning Terminates execution if there is not enough memory.536void*537lutok::state::new_userdata_voidp(const size_t size)538{539return lua_newuserdata(_pimpl->lua_state, size);540}541542543/// Wrapper around lua_next.544///545/// \param index The second parameter to lua_next.546///547/// \return True if there are more elements to process; false otherwise.548///549/// \warning Terminates execution if there is not enough memory.550bool551lutok::state::next(const int index)552{553assert(lua_istable(_pimpl->lua_state, index));554assert(lua_gettop(_pimpl->lua_state) >= 1);555lua_pushcfunction(_pimpl->lua_state, protected_next);556lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);557lua_pushvalue(_pimpl->lua_state, -3);558if (lua_pcall(_pimpl->lua_state, 2, LUA_MULTRET, 0) != 0)559throw lutok::api_error::from_stack(*this, "lua_next");560const bool more = lua_toboolean(_pimpl->lua_state, -1);561lua_pop(_pimpl->lua_state, 1);562if (more)563lua_remove(_pimpl->lua_state, -3);564else565lua_pop(_pimpl->lua_state, 1);566return more;567}568569570/// Wrapper around luaL_openlibs.571///572/// \throw api_error If luaL_openlibs fails.573///574/// \warning Terminates execution if there is not enough memory.575void576lutok::state::open_all(void)577{578luaL_openlibs(_pimpl->lua_state);579}580581582/// Wrapper around luaopen_base.583///584/// \throw api_error If luaopen_base fails.585///586/// \warning Terminates execution if there is not enough memory.587void588lutok::state::open_base(void)589{590lua_pushcfunction(_pimpl->lua_state, luaopen_base);591if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)592throw lutok::api_error::from_stack(*this, "luaopen_base");593}594595596/// Wrapper around luaopen_string.597///598/// \throw api_error If luaopen_string fails.599///600/// \warning Terminates execution if there is not enough memory.601void602lutok::state::open_string(void)603{604#if LUA_VERSION_NUM >= 502605luaL_requiref(_pimpl->lua_state, LUA_STRLIBNAME, luaopen_string, 1);606lua_pop(_pimpl->lua_state, 1);607#else608lua_pushcfunction(_pimpl->lua_state, luaopen_string);609if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)610throw lutok::api_error::from_stack(*this, "luaopen_string");611#endif612}613614615/// Wrapper around luaopen_table.616///617/// \throw api_error If luaopen_table fails.618///619/// \warning Terminates execution if there is not enough memory.620void621lutok::state::open_table(void)622{623#if LUA_VERSION_NUM >= 502624luaL_requiref(_pimpl->lua_state, LUA_TABLIBNAME, luaopen_table, 1);625lua_pop(_pimpl->lua_state, 1);626#else627lua_pushcfunction(_pimpl->lua_state, luaopen_table);628if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0)629throw lutok::api_error::from_stack(*this, "luaopen_table");630#endif631}632633634/// Wrapper around lua_pcall.635///636/// \param nargs The second parameter to lua_pcall.637/// \param nresults The third parameter to lua_pcall.638/// \param errfunc The fourth parameter to lua_pcall.639///640/// \throw api_error If lua_pcall returns an error.641void642lutok::state::pcall(const int nargs, const int nresults, const int errfunc)643{644if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0)645throw lutok::api_error::from_stack(*this, "lua_pcall");646}647648649/// Wrapper around lua_pop.650///651/// \param count The second parameter to lua_pop.652void653lutok::state::pop(const int count)654{655assert(count <= lua_gettop(_pimpl->lua_state));656lua_pop(_pimpl->lua_state, count);657assert(lua_gettop(_pimpl->lua_state) >= 0);658}659660661/// Wrapper around lua_pushboolean.662///663/// \param value The second parameter to lua_pushboolean.664void665lutok::state::push_boolean(const bool value)666{667lua_pushboolean(_pimpl->lua_state, value ? 1 : 0);668}669670671/// Wrapper around lua_pushcclosure.672///673/// This is not a pure wrapper around lua_pushcclosure because this has to do674/// extra magic to allow passing C++ functions instead of plain C functions.675///676/// \param function The C++ function to be pushed as a closure.677/// \param nvalues The number of upvalues that the function receives.678void679lutok::state::push_cxx_closure(cxx_function function, const int nvalues)680{681cxx_function *data = static_cast< cxx_function* >(682lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));683*data = function;684lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1);685}686687688/// Wrapper around lua_pushcfunction.689///690/// This is not a pure wrapper around lua_pushcfunction because this has to do691/// extra magic to allow passing C++ functions instead of plain C functions.692///693/// \param function The C++ function to be pushed.694void695lutok::state::push_cxx_function(cxx_function function)696{697cxx_function *data = static_cast< cxx_function* >(698lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function)));699*data = function;700lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1);701}702703704/// Wrapper around lua_pushinteger.705///706/// \param value The second parameter to lua_pushinteger.707void708lutok::state::push_integer(const int value)709{710lua_pushinteger(_pimpl->lua_state, value);711}712713714/// Wrapper around lua_pushnil.715void716lutok::state::push_nil(void)717{718lua_pushnil(_pimpl->lua_state);719}720721722/// Wrapper around lua_pushstring.723///724/// \param str The second parameter to lua_pushstring.725///726/// \warning Terminates execution if there is not enough memory.727void728lutok::state::push_string(const std::string& str)729{730lua_pushstring(_pimpl->lua_state, str.c_str());731}732733734/// Wrapper around lua_pushvalue.735///736/// \param index The second parameter to lua_pushvalue.737void738lutok::state::push_value(const int index)739{740lua_pushvalue(_pimpl->lua_state, index);741}742743744/// Wrapper around lua_rawget.745///746/// \param index The second parameter to lua_rawget.747void748lutok::state::raw_get(const int index)749{750lua_rawget(_pimpl->lua_state, index);751}752753754/// Wrapper around lua_rawset.755///756/// \param index The second parameter to lua_rawset.757///758/// \warning Terminates execution if there is not enough memory to manipulate759/// the Lua stack.760void761lutok::state::raw_set(const int index)762{763lua_rawset(_pimpl->lua_state, index);764}765766767/// Wrapper around lua_setglobal.768///769/// \param name The second parameter to lua_setglobal.770///771/// \throw api_error If lua_setglobal fails.772///773/// \warning Terminates execution if there is not enough memory to manipulate774/// the Lua stack.775void776lutok::state::set_global(const std::string& name)777{778lua_pushcfunction(_pimpl->lua_state, protected_setglobal);779lua_pushstring(_pimpl->lua_state, name.c_str());780lua_pushvalue(_pimpl->lua_state, -3);781if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0)782throw lutok::api_error::from_stack(*this, "lua_setglobal");783lua_pop(_pimpl->lua_state, 1);784}785786787/// Wrapper around lua_setmetatable.788///789/// \param index The second parameter to lua_setmetatable.790void791lutok::state::set_metatable(const int index)792{793lua_setmetatable(_pimpl->lua_state, index);794}795796797/// Wrapper around lua_settable.798///799/// \param index The second parameter to lua_settable.800///801/// \throw api_error If lua_settable fails.802///803/// \warning Terminates execution if there is not enough memory to manipulate804/// the Lua stack.805void806lutok::state::set_table(const int index)807{808lua_pushcfunction(_pimpl->lua_state, protected_settable);809lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index);810lua_pushvalue(_pimpl->lua_state, -4);811lua_pushvalue(_pimpl->lua_state, -4);812if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0)813throw lutok::api_error::from_stack(*this, "lua_settable");814lua_pop(_pimpl->lua_state, 2);815}816817818/// Wrapper around lua_toboolean.819///820/// \param index The second parameter to lua_toboolean.821///822/// \return The return value of lua_toboolean.823bool824lutok::state::to_boolean(const int index)825{826assert(is_boolean(index));827return lua_toboolean(_pimpl->lua_state, index);828}829830831/// Wrapper around lua_tointeger.832///833/// \param index The second parameter to lua_tointeger.834///835/// \return The return value of lua_tointeger.836long837lutok::state::to_integer(const int index)838{839assert(is_number(index));840return lua_tointeger(_pimpl->lua_state, index);841}842843844/// Wrapper around lua_touserdata.845///846/// This is internal. The public type-safe interface of this method should be847/// used instead.848///849/// \param index The second parameter to lua_touserdata.850///851/// \return The return value of lua_touserdata.852///853/// \warning Terminates execution if there is not enough memory.854void*855lutok::state::to_userdata_voidp(const int index)856{857return lua_touserdata(_pimpl->lua_state, index);858}859860861862/// Wrapper around lua_tostring.863///864/// \param index The second parameter to lua_tostring.865///866/// \return The return value of lua_tostring.867///868/// \warning Terminates execution if there is not enough memory.869std::string870lutok::state::to_string(const int index)871{872assert(is_string(index));873const char *raw_string = lua_tostring(_pimpl->lua_state, index);874// Note that the creation of a string object below (explicit for clarity)875// implies that the raw string is duplicated and, henceforth, the string is876// safe even if the corresponding element is popped from the Lua stack.877return std::string(raw_string);878}879880881/// Wrapper around lua_upvalueindex.882///883/// \param index The first parameter to lua_upvalueindex.884///885/// \return The return value of lua_upvalueindex.886int887lutok::state::upvalue_index(const int index)888{889return lua_upvalueindex(index);890}891892893/// Gets the internal lua_State object.894///895/// \return The raw Lua state. This is returned as a void pointer to prevent896/// including the lua.hpp header file from our public interface. The only way897/// to call this method is by using the c_gate module, and c_gate takes care of898/// casting this object to the appropriate type.899void*900lutok::state::raw_state(void)901{902return _pimpl->lua_state;903}904905906