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::globals_index = LUA_GLOBALSINDEX; 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 = lua_open(); 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 /// Wrapper around luaL_getmetafield. 312 /// 313 /// \param index The second parameter to luaL_getmetafield. 314 /// \param name The third parameter to luaL_getmetafield. 315 /// 316 /// \return The return value of luaL_getmetafield. 317 /// 318 /// \warning Terminates execution if there is not enough memory to manipulate 319 /// the Lua stack. 320 bool 321 lutok::state::get_metafield(const int index, const std::string& name) 322 { 323 return luaL_getmetafield(_pimpl->lua_state, index, name.c_str()) != 0; 324 } 325 326 327 /// Wrapper around lua_getmetatable. 328 /// 329 /// \param index The second parameter to lua_getmetatable. 330 /// 331 /// \return The return value of lua_getmetatable. 332 bool 333 lutok::state::get_metatable(const int index) 334 { 335 return lua_getmetatable(_pimpl->lua_state, index) != 0; 336 } 337 338 339 /// Wrapper around lua_gettable. 340 /// 341 /// \param index The second parameter to lua_gettable. 342 /// 343 /// \throw api_error If lua_gettable fails. 344 /// 345 /// \warning Terminates execution if there is not enough memory to manipulate 346 /// the Lua stack. 347 void 348 lutok::state::get_table(const int index) 349 { 350 assert(lua_gettop(_pimpl->lua_state) >= 2); 351 lua_pushcfunction(_pimpl->lua_state, protected_gettable); 352 lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index); 353 lua_pushvalue(_pimpl->lua_state, -3); 354 if (lua_pcall(_pimpl->lua_state, 2, 1, 0) != 0) 355 throw lutok::api_error::from_stack(*this, "lua_gettable"); 356 lua_remove(_pimpl->lua_state, -2); 357 } 358 359 360 /// Wrapper around lua_gettop. 361 /// 362 /// \return The return value of lua_gettop. 363 int 364 lutok::state::get_top(void) 365 { 366 return lua_gettop(_pimpl->lua_state); 367 } 368 369 370 /// Wrapper around lua_insert. 371 /// 372 /// \param index The second parameter to lua_insert. 373 void 374 lutok::state::insert(const int index) 375 { 376 lua_insert(_pimpl->lua_state, index); 377 } 378 379 380 /// Wrapper around lua_isboolean. 381 /// 382 /// \param index The second parameter to lua_isboolean. 383 /// 384 /// \return The return value of lua_isboolean. 385 bool 386 lutok::state::is_boolean(const int index) 387 { 388 return lua_isboolean(_pimpl->lua_state, index); 389 } 390 391 392 /// Wrapper around lua_isfunction. 393 /// 394 /// \param index The second parameter to lua_isfunction. 395 /// 396 /// \return The return value of lua_isfunction. 397 bool 398 lutok::state::is_function(const int index) 399 { 400 return lua_isfunction(_pimpl->lua_state, index); 401 } 402 403 404 /// Wrapper around lua_isnil. 405 /// 406 /// \param index The second parameter to lua_isnil. 407 /// 408 /// \return The return value of lua_isnil. 409 bool 410 lutok::state::is_nil(const int index) 411 { 412 return lua_isnil(_pimpl->lua_state, index); 413 } 414 415 416 /// Wrapper around lua_isnumber. 417 /// 418 /// \param index The second parameter to lua_isnumber. 419 /// 420 /// \return The return value of lua_isnumber. 421 bool 422 lutok::state::is_number(const int index) 423 { 424 return lua_isnumber(_pimpl->lua_state, index); 425 } 426 427 428 /// Wrapper around lua_isstring. 429 /// 430 /// \param index The second parameter to lua_isstring. 431 /// 432 /// \return The return value of lua_isstring. 433 bool 434 lutok::state::is_string(const int index) 435 { 436 return lua_isstring(_pimpl->lua_state, index); 437 } 438 439 440 /// Wrapper around lua_istable. 441 /// 442 /// \param index The second parameter to lua_istable. 443 /// 444 /// \return The return value of lua_istable. 445 bool 446 lutok::state::is_table(const int index) 447 { 448 return lua_istable(_pimpl->lua_state, index); 449 } 450 451 452 /// Wrapper around lua_isuserdata. 453 /// 454 /// \param index The second parameter to lua_isuserdata. 455 /// 456 /// \return The return value of lua_isuserdata. 457 bool 458 lutok::state::is_userdata(const int index) 459 { 460 return lua_isuserdata(_pimpl->lua_state, index); 461 } 462 463 464 /// Wrapper around luaL_loadfile. 465 /// 466 /// \param file The second parameter to luaL_loadfile. 467 /// 468 /// \throw api_error If luaL_loadfile returns an error. 469 /// \throw file_not_found_error If the file cannot be accessed. 470 /// 471 /// \warning Terminates execution if there is not enough memory. 472 void 473 lutok::state::load_file(const std::string& file) 474 { 475 if (!::access(file.c_str(), R_OK) == 0) 476 throw lutok::file_not_found_error(file); 477 if (luaL_loadfile(_pimpl->lua_state, file.c_str()) != 0) 478 throw lutok::api_error::from_stack(*this, "luaL_loadfile"); 479 } 480 481 482 /// Wrapper around luaL_loadstring. 483 /// 484 /// \param str The second parameter to luaL_loadstring. 485 /// 486 /// \throw api_error If luaL_loadstring returns an error. 487 /// 488 /// \warning Terminates execution if there is not enough memory. 489 void 490 lutok::state::load_string(const std::string& str) 491 { 492 if (luaL_loadstring(_pimpl->lua_state, str.c_str()) != 0) 493 throw lutok::api_error::from_stack(*this, "luaL_loadstring"); 494 } 495 496 497 /// Wrapper around lua_newtable. 498 /// 499 /// \warning Terminates execution if there is not enough memory. 500 void 501 lutok::state::new_table(void) 502 { 503 lua_newtable(_pimpl->lua_state); 504 } 505 506 507 /// Wrapper around lua_newuserdata. 508 /// 509 /// This is internal. The public type-safe interface of this method should be 510 /// used instead. 511 /// 512 /// \param size The second parameter to lua_newuserdata. 513 /// 514 /// \return The return value of lua_newuserdata. 515 /// 516 /// \warning Terminates execution if there is not enough memory. 517 void* 518 lutok::state::new_userdata_voidp(const size_t size) 519 { 520 return lua_newuserdata(_pimpl->lua_state, size); 521 } 522 523 524 /// Wrapper around lua_next. 525 /// 526 /// \param index The second parameter to lua_next. 527 /// 528 /// \return True if there are more elements to process; false otherwise. 529 /// 530 /// \warning Terminates execution if there is not enough memory. 531 bool 532 lutok::state::next(const int index) 533 { 534 assert(lua_istable(_pimpl->lua_state, index)); 535 assert(lua_gettop(_pimpl->lua_state) >= 1); 536 lua_pushcfunction(_pimpl->lua_state, protected_next); 537 lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index); 538 lua_pushvalue(_pimpl->lua_state, -3); 539 if (lua_pcall(_pimpl->lua_state, 2, LUA_MULTRET, 0) != 0) 540 throw lutok::api_error::from_stack(*this, "lua_next"); 541 const bool more = lua_toboolean(_pimpl->lua_state, -1); 542 lua_pop(_pimpl->lua_state, 1); 543 if (more) 544 lua_remove(_pimpl->lua_state, -3); 545 else 546 lua_pop(_pimpl->lua_state, 1); 547 return more; 548 } 549 550 551 /// Wrapper around luaopen_base. 552 /// 553 /// \throw api_error If luaopen_base fails. 554 /// 555 /// \warning Terminates execution if there is not enough memory. 556 void 557 lutok::state::open_base(void) 558 { 559 lua_pushcfunction(_pimpl->lua_state, luaopen_base); 560 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 561 throw lutok::api_error::from_stack(*this, "luaopen_base"); 562 } 563 564 565 /// Wrapper around luaopen_string. 566 /// 567 /// \throw api_error If luaopen_string fails. 568 /// 569 /// \warning Terminates execution if there is not enough memory. 570 void 571 lutok::state::open_string(void) 572 { 573 lua_pushcfunction(_pimpl->lua_state, luaopen_string); 574 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 575 throw lutok::api_error::from_stack(*this, "luaopen_string"); 576 } 577 578 579 /// Wrapper around luaopen_table. 580 /// 581 /// \throw api_error If luaopen_table fails. 582 /// 583 /// \warning Terminates execution if there is not enough memory. 584 void 585 lutok::state::open_table(void) 586 { 587 lua_pushcfunction(_pimpl->lua_state, luaopen_table); 588 if (lua_pcall(_pimpl->lua_state, 0, 0, 0) != 0) 589 throw lutok::api_error::from_stack(*this, "luaopen_table"); 590 } 591 592 593 /// Wrapper around lua_pcall. 594 /// 595 /// \param nargs The second parameter to lua_pcall. 596 /// \param nresults The third parameter to lua_pcall. 597 /// \param errfunc The fourth parameter to lua_pcall. 598 /// 599 /// \throw api_error If lua_pcall returns an error. 600 void 601 lutok::state::pcall(const int nargs, const int nresults, const int errfunc) 602 { 603 if (lua_pcall(_pimpl->lua_state, nargs, nresults, errfunc) != 0) 604 throw lutok::api_error::from_stack(*this, "lua_pcall"); 605 } 606 607 608 /// Wrapper around lua_pop. 609 /// 610 /// \param count The second parameter to lua_pop. 611 void 612 lutok::state::pop(const int count) 613 { 614 assert(count <= lua_gettop(_pimpl->lua_state)); 615 lua_pop(_pimpl->lua_state, count); 616 assert(lua_gettop(_pimpl->lua_state) >= 0); 617 } 618 619 620 /// Wrapper around lua_pushboolean. 621 /// 622 /// \param value The second parameter to lua_pushboolean. 623 void 624 lutok::state::push_boolean(const bool value) 625 { 626 lua_pushboolean(_pimpl->lua_state, value ? 1 : 0); 627 } 628 629 630 /// Wrapper around lua_pushcclosure. 631 /// 632 /// This is not a pure wrapper around lua_pushcclosure because this has to do 633 /// extra magic to allow passing C++ functions instead of plain C functions. 634 /// 635 /// \param function The C++ function to be pushed as a closure. 636 /// \param nvalues The number of upvalues that the function receives. 637 void 638 lutok::state::push_cxx_closure(cxx_function function, const int nvalues) 639 { 640 cxx_function *data = static_cast< cxx_function* >( 641 lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function))); 642 *data = function; 643 lua_pushcclosure(_pimpl->lua_state, cxx_closure_trampoline, nvalues + 1); 644 } 645 646 647 /// Wrapper around lua_pushcfunction. 648 /// 649 /// This is not a pure wrapper around lua_pushcfunction because this has to do 650 /// extra magic to allow passing C++ functions instead of plain C functions. 651 /// 652 /// \param function The C++ function to be pushed. 653 void 654 lutok::state::push_cxx_function(cxx_function function) 655 { 656 cxx_function *data = static_cast< cxx_function* >( 657 lua_newuserdata(_pimpl->lua_state, sizeof(cxx_function))); 658 *data = function; 659 lua_pushcclosure(_pimpl->lua_state, cxx_function_trampoline, 1); 660 } 661 662 663 /// Wrapper around lua_pushinteger. 664 /// 665 /// \param value The second parameter to lua_pushinteger. 666 void 667 lutok::state::push_integer(const int value) 668 { 669 lua_pushinteger(_pimpl->lua_state, value); 670 } 671 672 673 /// Wrapper around lua_pushnil. 674 void 675 lutok::state::push_nil(void) 676 { 677 lua_pushnil(_pimpl->lua_state); 678 } 679 680 681 /// Wrapper around lua_pushstring. 682 /// 683 /// \param str The second parameter to lua_pushstring. 684 /// 685 /// \warning Terminates execution if there is not enough memory. 686 void 687 lutok::state::push_string(const std::string& str) 688 { 689 lua_pushstring(_pimpl->lua_state, str.c_str()); 690 } 691 692 693 /// Wrapper around lua_pushvalue. 694 /// 695 /// \param index The second parameter to lua_pushvalue. 696 void 697 lutok::state::push_value(const int index) 698 { 699 lua_pushvalue(_pimpl->lua_state, index); 700 } 701 702 703 /// Wrapper around lua_rawget. 704 /// 705 /// \param index The second parameter to lua_rawget. 706 void 707 lutok::state::raw_get(const int index) 708 { 709 lua_rawget(_pimpl->lua_state, index); 710 } 711 712 713 /// Wrapper around lua_rawset. 714 /// 715 /// \param index The second parameter to lua_rawset. 716 /// 717 /// \warning Terminates execution if there is not enough memory to manipulate 718 /// the Lua stack. 719 void 720 lutok::state::raw_set(const int index) 721 { 722 lua_rawset(_pimpl->lua_state, index); 723 } 724 725 726 /// Wrapper around lua_setglobal. 727 /// 728 /// \param name The second parameter to lua_setglobal. 729 /// 730 /// \throw api_error If lua_setglobal fails. 731 /// 732 /// \warning Terminates execution if there is not enough memory to manipulate 733 /// the Lua stack. 734 void 735 lutok::state::set_global(const std::string& name) 736 { 737 lua_pushcfunction(_pimpl->lua_state, protected_setglobal); 738 lua_pushstring(_pimpl->lua_state, name.c_str()); 739 lua_pushvalue(_pimpl->lua_state, -3); 740 if (lua_pcall(_pimpl->lua_state, 2, 0, 0) != 0) 741 throw lutok::api_error::from_stack(*this, "lua_setglobal"); 742 lua_pop(_pimpl->lua_state, 1); 743 } 744 745 746 /// Wrapper around lua_setmetatable. 747 /// 748 /// \param index The second parameter to lua_setmetatable. 749 void 750 lutok::state::set_metatable(const int index) 751 { 752 lua_setmetatable(_pimpl->lua_state, index); 753 } 754 755 756 /// Wrapper around lua_settable. 757 /// 758 /// \param index The second parameter to lua_settable. 759 /// 760 /// \throw api_error If lua_settable fails. 761 /// 762 /// \warning Terminates execution if there is not enough memory to manipulate 763 /// the Lua stack. 764 void 765 lutok::state::set_table(const int index) 766 { 767 lua_pushcfunction(_pimpl->lua_state, protected_settable); 768 lua_pushvalue(_pimpl->lua_state, index < 0 ? index - 1 : index); 769 lua_pushvalue(_pimpl->lua_state, -4); 770 lua_pushvalue(_pimpl->lua_state, -4); 771 if (lua_pcall(_pimpl->lua_state, 3, 0, 0) != 0) 772 throw lutok::api_error::from_stack(*this, "lua_settable"); 773 lua_pop(_pimpl->lua_state, 2); 774 } 775 776 777 /// Wrapper around lua_toboolean. 778 /// 779 /// \param index The second parameter to lua_toboolean. 780 /// 781 /// \return The return value of lua_toboolean. 782 bool 783 lutok::state::to_boolean(const int index) 784 { 785 assert(is_boolean(index)); 786 return lua_toboolean(_pimpl->lua_state, index); 787 } 788 789 790 /// Wrapper around lua_tointeger. 791 /// 792 /// \param index The second parameter to lua_tointeger. 793 /// 794 /// \return The return value of lua_tointeger. 795 long 796 lutok::state::to_integer(const int index) 797 { 798 assert(is_number(index)); 799 return lua_tointeger(_pimpl->lua_state, index); 800 } 801 802 803 /// Wrapper around lua_touserdata. 804 /// 805 /// This is internal. The public type-safe interface of this method should be 806 /// used instead. 807 /// 808 /// \param index The second parameter to lua_touserdata. 809 /// 810 /// \return The return value of lua_touserdata. 811 /// 812 /// \warning Terminates execution if there is not enough memory. 813 void* 814 lutok::state::to_userdata_voidp(const int index) 815 { 816 return lua_touserdata(_pimpl->lua_state, index); 817 } 818 819 820 821 /// Wrapper around lua_tostring. 822 /// 823 /// \param index The second parameter to lua_tostring. 824 /// 825 /// \return The return value of lua_tostring. 826 /// 827 /// \warning Terminates execution if there is not enough memory. 828 std::string 829 lutok::state::to_string(const int index) 830 { 831 assert(is_string(index)); 832 const char *raw_string = lua_tostring(_pimpl->lua_state, index); 833 // Note that the creation of a string object below (explicit for clarity) 834 // implies that the raw string is duplicated and, henceforth, the string is 835 // safe even if the corresponding element is popped from the Lua stack. 836 return std::string(raw_string); 837 } 838 839 840 /// Wrapper around lua_upvalueindex. 841 /// 842 /// \param index The first parameter to lua_upvalueindex. 843 /// 844 /// \return The return value of lua_upvalueindex. 845 int 846 lutok::state::upvalue_index(const int index) 847 { 848 return lua_upvalueindex(index); 849 } 850 851 852 /// Gets the internal lua_State object. 853 /// 854 /// \return The raw Lua state. This is returned as a void pointer to prevent 855 /// including the lua.hpp header file from our public interface. The only way 856 /// to call this method is by using the c_gate module, and c_gate takes care of 857 /// casting this object to the appropriate type. 858 void* 859 lutok::state::raw_state(void) 860 { 861 return _pimpl->lua_state; 862 } 863