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