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 29 extern "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 41 namespace { 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. 52 static int 53 protected_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. 69 static int 70 protected_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. 86 static int 87 protected_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. 103 static int 104 protected_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. 120 static int 121 protected_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. 138 static int 139 call_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. 173 static int 174 cxx_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. 202 static int 203 cxx_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 215 const int lutok::registry_index = LUA_REGISTRYINDEX; 216 217 218 /// Internal implementation for lutok::state. 219 struct 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. 242 lutok::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. 257 lutok::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. 268 lutok::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. 283 void 284 lutok::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. 301 void 302 lutok::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. 317 void 318 lutok::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. 340 bool 341 lutok::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. 352 bool 353 lutok::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. 367 void 368 lutok::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. 383 int 384 lutok::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. 393 void 394 lutok::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. 405 bool 406 lutok::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. 417 bool 418 lutok::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. 429 bool 430 lutok::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. 441 bool 442 lutok::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. 453 bool 454 lutok::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. 465 bool 466 lutok::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. 477 bool 478 lutok::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. 492 void 493 lutok::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. 509 void 510 lutok::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. 520 void 521 lutok::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. 537 void* 538 lutok::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. 551 bool 552 lutok::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. 576 void 577 lutok::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. 588 void 589 lutok::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. 602 void 603 lutok::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. 621 void 622 lutok::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. 642 void 643 lutok::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. 653 void 654 lutok::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. 665 void 666 lutok::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. 679 void 680 lutok::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. 695 void 696 lutok::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. 708 void 709 lutok::state::push_integer(const int value) 710 { 711 lua_pushinteger(_pimpl->lua_state, value); 712 } 713 714 715 /// Wrapper around lua_pushnil. 716 void 717 lutok::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. 728 void 729 lutok::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. 738 void 739 lutok::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. 748 void 749 lutok::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. 761 void 762 lutok::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. 776 void 777 lutok::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. 791 void 792 lutok::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. 806 void 807 lutok::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. 824 bool 825 lutok::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. 837 long 838 lutok::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. 855 void* 856 lutok::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. 870 std::string 871 lutok::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. 887 int 888 lutok::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. 900 void* 901 lutok::state::raw_state(void) 902 { 903 return _pimpl->lua_state; 904 } 905