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)-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. 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) == 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. 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 luaopen_base. 572 /// 573 /// \throw api_error If luaopen_base fails. 574 /// 575 /// \warning Terminates execution if there is not enough memory. 576 void 577 lutok::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. 590 void 591 lutok::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. 609 void 610 lutok::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. 630 void 631 lutok::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. 641 void 642 lutok::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. 653 void 654 lutok::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. 667 void 668 lutok::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. 683 void 684 lutok::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. 696 void 697 lutok::state::push_integer(const int value) 698 { 699 lua_pushinteger(_pimpl->lua_state, value); 700 } 701 702 703 /// Wrapper around lua_pushnil. 704 void 705 lutok::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. 716 void 717 lutok::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. 726 void 727 lutok::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. 736 void 737 lutok::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. 749 void 750 lutok::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. 764 void 765 lutok::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. 779 void 780 lutok::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. 794 void 795 lutok::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. 812 bool 813 lutok::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. 825 long 826 lutok::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. 843 void* 844 lutok::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. 858 std::string 859 lutok::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. 875 int 876 lutok::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. 888 void* 889 lutok::state::raw_state(void) 890 { 891 return _pimpl->lua_state; 892 } 893