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