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)-1); 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) == 0) 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 luaopen_base. 572/// 573/// \throw api_error If luaopen_base fails. 574/// 575/// \warning Terminates execution if there is not enough memory. 576void 577lutok::state::open_base(void) 578{ 579 lua_pushcfunction(_pimpl->lua_state, luaopen_base); 580 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 581 throw lutok::api_error::from_stack(*this, "luaopen_base"); 582} 583 584 585/// Wrapper around luaopen_string. 586/// 587/// \throw api_error If luaopen_string fails. 588/// 589/// \warning Terminates execution if there is not enough memory. 590void 591lutok::state::open_string(void) 592{ 593#if LUA_VERSION_NUM >= 502 594 luaL_requiref(_pimpl->lua_state, LUA_STRLIBNAME, luaopen_string, 1); 595 lua_pop(_pimpl->lua_state, 1); 596#else 597 lua_pushcfunction(_pimpl->lua_state, luaopen_string); 598 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 599 throw lutok::api_error::from_stack(*this, "luaopen_string"); 600#endif 601} 602 603 604/// Wrapper around luaopen_table. 605/// 606/// \throw api_error If luaopen_table fails. 607/// 608/// \warning Terminates execution if there is not enough memory. 609void 610lutok::state::open_table(void) 611{ 612#if LUA_VERSION_NUM >= 502 613 luaL_requiref(_pimpl->lua_state, LUA_TABLIBNAME, luaopen_table, 1); 614 lua_pop(_pimpl->lua_state, 1); 615#else 616 lua_pushcfunction(_pimpl->lua_state, luaopen_table); 617 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 618 throw lutok::api_error::from_stack(*this, "luaopen_table"); 619#endif 620} 621 622 623/// Wrapper around lua_pcall. 624/// 625/// \param nargs The second parameter to lua_pcall. 626/// \param nresults The third parameter to lua_pcall. 627/// \param errfunc The fourth parameter to lua_pcall. 628/// 629/// \throw api_error If lua_pcall returns an error. 630void 631lutok::state::pcall(const int nargs, const int nresults, const int errfunc) 632{ 633 if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0) 634 throw lutok::api_error::from_stack(*this, "lua_pcall"); 635} 636 637 638/// Wrapper around lua_pop. 639/// 640/// \param count The second parameter to lua_pop. 641void 642lutok::state::pop(const int count) 643{ 644 assert(count <= lua_gettop(_pimpl->lua_state)); 645 lua_pop(_pimpl->lua_state, count); 646 assert(lua_gettop(_pimpl->lua_state) >= 0); 647} 648 649 650/// Wrapper around lua_pushboolean. 651/// 652/// \param value The second parameter to lua_pushboolean. 653void 654lutok::state::push_boolean(const bool value) 655{ 656 lua_pushboolean(_pimpl->lua_state, value ? 1 : 0); 657} 658 659 660/// Wrapper around lua_pushcclosure. 661/// 662/// This is not a pure wrapper around lua_pushcclosure because this has to do 663/// extra magic to allow passing C++ functions instead of plain C functions. 664/// 665/// \param function The C++ function to be pushed as a closure. 666/// \param nvalues The number of upvalues that the function receives. 667void 668lutok::state::push_cxx_closure(cxx_function function, const int nvalues) 669{ 670 cxx_function *data = static_cast< cxx_function* >( 671 lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function))); 672 *data = function; 673 lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1); 674} 675 676 677/// Wrapper around lua_pushcfunction. 678/// 679/// This is not a pure wrapper around lua_pushcfunction because this has to do 680/// extra magic to allow passing C++ functions instead of plain C functions. 681/// 682/// \param function The C++ function to be pushed. 683void 684lutok::state::push_cxx_function(cxx_function function) 685{ 686 cxx_function *data = static_cast< cxx_function* >( 687 lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function))); 688 *data = function; 689 lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1); 690} 691 692 693/// Wrapper around lua_pushinteger. 694/// 695/// \param value The second parameter to lua_pushinteger. 696void 697lutok::state::push_integer(const int value) 698{ 699 lua_pushinteger(_pimpl->lua_state, value); 700} 701 702 703/// Wrapper around lua_pushnil. 704void 705lutok::state::push_nil(void) 706{ 707 lua_pushnil(_pimpl->lua_state); 708} 709 710 711/// Wrapper around lua_pushstring. 712/// 713/// \param str The second parameter to lua_pushstring. 714/// 715/// \warning Terminates execution if there is not enough memory. 716void 717lutok::state::push_string(const std::string& str) 718{ 719 lua_pushstring(_pimpl->lua_state, str.c_str()); 720} 721 722 723/// Wrapper around lua_pushvalue. 724/// 725/// \param index The second parameter to lua_pushvalue. 726void 727lutok::state::push_value(const int index) 728{ 729 lua_pushvalue(_pimpl->lua_state, index); 730} 731 732 733/// Wrapper around lua_rawget. 734/// 735/// \param index The second parameter to lua_rawget. 736void 737lutok::state::raw_get(const int index) 738{ 739 lua_rawget(_pimpl->lua_state, index); 740} 741 742 743/// Wrapper around lua_rawset. 744/// 745/// \param index The second parameter to lua_rawset. 746/// 747/// \warning Terminates execution if there is not enough memory to manipulate 748/// the Lua stack. 749void 750lutok::state::raw_set(const int index) 751{ 752 lua_rawset(_pimpl->lua_state, index); 753} 754 755 756/// Wrapper around lua_setglobal. 757/// 758/// \param name The second parameter to lua_setglobal. 759/// 760/// \throw api_error If lua_setglobal fails. 761/// 762/// \warning Terminates execution if there is not enough memory to manipulate 763/// the Lua stack. 764void 765lutok::state::set_global(const std::string& name) 766{ 767 lua_pushcfunction(_pimpl->lua_state, protected_setglobal); 768 lua_pushstring(_pimpl->lua_state, name.c_str()); 769 lua_pushvalue(_pimpl->lua_state, -3); 770 if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0) 771 throw lutok::api_error::from_stack(*this, "lua_setglobal"); 772 lua_pop(_pimpl->lua_state, 1); 773} 774 775 776/// Wrapper around lua_setmetatable. 777/// 778/// \param index The second parameter to lua_setmetatable. 779void 780lutok::state::set_metatable(const int index) 781{ 782 lua_setmetatable(_pimpl->lua_state, index); 783} 784 785 786/// Wrapper around lua_settable. 787/// 788/// \param index The second parameter to lua_settable. 789/// 790/// \throw api_error If lua_settable fails. 791/// 792/// \warning Terminates execution if there is not enough memory to manipulate 793/// the Lua stack. 794void 795lutok::state::set_table(const int index) 796{ 797 lua_pushcfunction(_pimpl->lua_state, protected_settable); 798 lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index); 799 lua_pushvalue(_pimpl->lua_state, -4); 800 lua_pushvalue(_pimpl->lua_state, -4); 801 if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0) 802 throw lutok::api_error::from_stack(*this, "lua_settable"); 803 lua_pop(_pimpl->lua_state, 2); 804} 805 806 807/// Wrapper around lua_toboolean. 808/// 809/// \param index The second parameter to lua_toboolean. 810/// 811/// \return The return value of lua_toboolean. 812bool 813lutok::state::to_boolean(const int index) 814{ 815 assert(is_boolean(index)); 816 return lua_toboolean(_pimpl->lua_state, index); 817} 818 819 820/// Wrapper around lua_tointeger. 821/// 822/// \param index The second parameter to lua_tointeger. 823/// 824/// \return The return value of lua_tointeger. 825long 826lutok::state::to_integer(const int index) 827{ 828 assert(is_number(index)); 829 return lua_tointeger(_pimpl->lua_state, index); 830} 831 832 833/// Wrapper around lua_touserdata. 834/// 835/// This is internal. The public type-safe interface of this method should be 836/// used instead. 837/// 838/// \param index The second parameter to lua_touserdata. 839/// 840/// \return The return value of lua_touserdata. 841/// 842/// \warning Terminates execution if there is not enough memory. 843void* 844lutok::state::to_userdata_voidp(const int index) 845{ 846 return lua_touserdata(_pimpl->lua_state, index); 847} 848 849 850 851/// Wrapper around lua_tostring. 852/// 853/// \param index The second parameter to lua_tostring. 854/// 855/// \return The return value of lua_tostring. 856/// 857/// \warning Terminates execution if there is not enough memory. 858std::string 859lutok::state::to_string(const int index) 860{ 861 assert(is_string(index)); 862 const char *raw_string = lua_tostring(_pimpl->lua_state, index); 863 // Note that the creation of a string object below (explicit for clarity) 864 // implies that the raw string is duplicated and, henceforth, the string is 865 // safe even if the corresponding element is popped from the Lua stack. 866 return std::string(raw_string); 867} 868 869 870/// Wrapper around lua_upvalueindex. 871/// 872/// \param index The first parameter to lua_upvalueindex. 873/// 874/// \return The return value of lua_upvalueindex. 875int 876lutok::state::upvalue_index(const int index) 877{ 878 return lua_upvalueindex(index); 879} 880 881 882/// Gets the internal lua_State object. 883/// 884/// \return The raw Lua state. This is returned as a void pointer to prevent 885/// including the lua.hpp header file from our public interface. The only way 886/// to call this method is by using the c_gate module, and c_gate takes care of 887/// casting this object to the appropriate type. 888void* 889lutok::state::raw_state(void) 890{ 891 return _pimpl->lua_state; 892} 893