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
protected_getglobal(lua_State * state)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
protected_gettable(lua_State * state)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
protected_next(lua_State * state)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
protected_setglobal(lua_State * state)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
protected_settable(lua_State * state)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
call_cxx_function_from_c(lutok::cxx_function function,lua_State * raw_state)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
cxx_closure_trampoline(lua_State * raw_state)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
cxx_function_trampoline(lua_State * raw_state)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.
impllutok::state::impl230 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.
state(void)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.
state(void * raw_state_)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.
~state(void)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
close(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
get_global(const std::string & name)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
get_global_table(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
get_metafield(const int index,const std::string & name)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
get_metatable(const int index)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
get_table(const int index)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
get_top(void)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
insert(const int index)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
is_boolean(const int index)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
is_function(const int index)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
is_nil(const int index)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
is_number(const int index)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
is_string(const int index)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
is_table(const int index)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
is_userdata(const int index)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
load_file(const std::string & file)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
load_string(const std::string & str)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
new_table(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*
new_userdata_voidp(const size_t size)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
next(const int index)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
open_all(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
open_base(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
open_string(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
open_table(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
pcall(const int nargs,const int nresults,const int errfunc)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
pop(const int count)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
push_boolean(const bool value)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
push_cxx_closure(cxx_function function,const int nvalues)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
push_cxx_function(cxx_function function)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
push_integer(const int value)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
push_nil(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
push_string(const std::string & str)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
push_value(const int index)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
raw_get(const int index)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
raw_set(const int index)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
set_global(const std::string & name)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
set_metatable(const int index)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
set_table(const int index)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
to_boolean(const int index)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
to_integer(const int index)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*
to_userdata_voidp(const int index)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
to_string(const int index)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
upvalue_index(const int index)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*
raw_state(void)901 lutok::state::raw_state(void)
902 {
903 return _pimpl->lua_state;
904 }
905