Fawkes API  Fawkes Development Version
context.cpp
1 
2 /***************************************************************************
3  * context.cpp - Fawkes Lua Context
4  *
5  * Created: Fri May 23 15:53:54 2008
6  * Copyright 2006-2009 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include <lua/context.h>
24 #include <lua/context_watcher.h>
25 #include <core/threading/mutex.h>
26 #include <core/threading/mutex_locker.h>
27 #include <core/exceptions/system.h>
28 #include <core/exceptions/software.h>
29 #include <logging/liblogger.h>
30 
31 #include <algorithm>
32 #include <tolua++.h>
33 #include <cstdlib>
34 #include <cstring>
35 #include <unistd.h>
36 
37 namespace fawkes {
38 #if 0 /* just to make Emacs auto-indent happy */
39 }
40 #endif
41 
42 /** @class LuaContext <lua/context.h>
43  * Lua C++ wrapper.
44  * This thin wrapper allows for easy integration of Fawkes into other
45  * applications. It provides convenience methods to some Lua and
46  * tolua++ features like setting global variables or pushing/popping
47  * values.
48  *
49  * It allows raw access to the Lua state since this class does not and
50  * should not provide all the features Lua provides. If you use this
51  * make sure that you lock the Lua context to avoid multi-threading
52  * problems (if that is a possible concern in your application).
53  *
54  * LuaContext can use a FileAlterationMonitor on all added package and
55  * C package directories. If anything changes in these directories the
56  * Lua instance is then automatically restarted (closed, re-opened and
57  * re-initialized).
58  *
59  * @author Tim Niemueller
60  */
61 
62 /** Constructor.
63  * @param enable_tracebacks if true an error function is installed at the top
64  * of the stackand used for pcalls where errfunc is 0.
65  */
66 LuaContext::LuaContext(bool enable_tracebacks)
67 {
68  __owns_L = true;
69  __enable_tracebacks = enable_tracebacks;
70  __fam = NULL;
71  __fam_thread = NULL;
72 
73  __lua_mutex = new Mutex();
74 
75  __start_script = NULL;
76  __L = init_state();
77 }
78 
79 /** Wrapper contstructor.
80  * This wraps around an existing Lua state. It does not initialize the state in
81  * the sense that it would add variables etc. It only provides convenient access
82  * to the state methods via a C++ interface. It's mainly intended to be used to
83  * create a LuaContext to be passed to LuaContextWatcher::lua_restarted(). The
84  * state is not closed on destruction as is done when using the other ctor.
85  * @param L Lua state to wrap
86  */
88 {
89  __owns_L = false;
90  __L = L;
91  __lua_mutex = new Mutex();
92  __start_script = NULL;
93  __fam = NULL;
94  __fam_thread = NULL;
95 }
96 
97 /** Destructor. */
99 {
100  __lua_mutex->lock();
101 
102  if (! __finalize_call.empty())
103  do_string(__L, "%s", __finalize_call.c_str());
104 
105  if (__fam_thread) {
106  __fam_thread->cancel();
107  __fam_thread->join();
108  delete __fam_thread;
109  }
110  delete __lua_mutex;
111  if ( __start_script ) free(__start_script);
112  if ( __owns_L) {
113  lua_close(__L);
114  }
115 }
116 
117 
118 /** Setup file alteration monitor.
119  * Setup an internal file alteration monitor that can react to changes
120  * on Lua files and packages.
121  * @param auto_restart automatically restart the Lua context in case
122  * of an event
123  * @param conc_thread true to run a concurrent thread for event
124  * processing. If and only if you set this to false, ensure that
125  * process_fam_events() periodically.
126  */
127 void
128 LuaContext::setup_fam(bool auto_restart, bool conc_thread)
129 {
130  __fam = new FileAlterationMonitor();
131  __fam->add_filter("^[^.].*\\.lua$");
132  if (auto_restart) {
133  __fam->add_listener(this);
134  }
135  if (conc_thread) {
136  __fam_thread = new FamThread(__fam);
137  __fam_thread->start();
138  }
139 }
140 
141 
142 /** Get file alteration monitor.
143  * @return reference counted pointer to file alteration monitor. Note
144  * that the pointer might be invalid if setup_fam() has not been called.
145  */
148 {
149  return __fam;
150 }
151 
152 
153 /** Initialize Lua state.
154  * Initializes the state and makes all necessary initializations.
155  * @return fresh initialized Lua state
156  */
157 lua_State *
158 LuaContext::init_state()
159 {
160  lua_State *L = luaL_newstate();
161  luaL_openlibs(L);
162 
163  if (__enable_tracebacks) {
164  lua_getglobal(L, "debug");
165  lua_getfield(L, -1, "traceback");
166  lua_remove(L, -2);
167  }
168 
169  // Add package paths
170  for (__slit = __package_dirs.begin(); __slit != __package_dirs.end(); ++__slit) {
171  do_string(L, "package.path = package.path .. \";%s/?.lua;%s/?/init.lua\"", __slit->c_str(), __slit->c_str());
172  }
173 
174  for (__slit = __cpackage_dirs.begin(); __slit != __cpackage_dirs.end(); ++__slit) {
175  do_string(L, "package.cpath = package.cpath .. \";%s/?.so\"", __slit->c_str());
176  }
177 
178  // load base packages
179  for (__slit = __packages.begin(); __slit != __packages.end(); ++__slit) {
180  do_string(L, "require(\"%s\")", __slit->c_str());
181  }
182 
183  for ( __utit = __usertypes.begin(); __utit != __usertypes.end(); ++__utit) {
184  tolua_pushusertype(L, __utit->second.first, __utit->second.second.c_str());
185  lua_setglobal(L, __utit->first.c_str());
186  }
187 
188  for ( __strings_it = __strings.begin(); __strings_it != __strings.end(); ++__strings_it) {
189  lua_pushstring(L, __strings_it->second.c_str());
190  lua_setglobal(L, __strings_it->first.c_str());
191  }
192 
193  for ( __booleans_it = __booleans.begin(); __booleans_it != __booleans.end(); ++__booleans_it) {
194  lua_pushboolean(L, __booleans_it->second);
195  lua_setglobal(L, __booleans_it->first.c_str());
196  }
197 
198  for ( __numbers_it = __numbers.begin(); __numbers_it != __numbers.end(); ++__numbers_it) {
199  lua_pushnumber(L, __numbers_it->second);
200  lua_setglobal(L, __numbers_it->first.c_str());
201  }
202 
203  for ( __integers_it = __integers.begin(); __integers_it != __integers.end(); ++__integers_it) {
204  lua_pushinteger(L, __integers_it->second);
205  lua_setglobal(L, __integers_it->first.c_str());
206  }
207 
208  for ( __cfuncs_it = __cfuncs.begin(); __cfuncs_it != __cfuncs.end(); ++__cfuncs_it)
209  {
210  lua_pushcfunction(L, __cfuncs_it->second);
211  lua_setglobal(L, __cfuncs_it->first.c_str());
212  }
213 
214  LuaContext *tmpctx = new LuaContext(L);
215 
216  MutexLocker(__watchers.mutex());
218  for (i = __watchers.begin(); i != __watchers.end(); ++i) {
219  try {
220  (*i)->lua_restarted(tmpctx);
221  } catch (...) {
222  try {
223  if (! __finalize_call.empty())
224  do_string(L, "%s", __finalize_call.c_str());
225  } catch (Exception &e) {} // ignored
226 
227  delete tmpctx;
228  lua_close(L);
229  throw;
230  }
231  }
232  delete tmpctx;
233 
234  try {
235  if ( __start_script ) {
236  if (access(__start_script, R_OK) == 0) {
237  // it's a file and we can access it, execute it!
238  do_file(L, __start_script);
239  } else {
240  do_string(L, "require(\"%s\")", __start_script);
241  }
242  }
243  } catch (...) {
244  if (! __finalize_call.empty())
245  do_string(L, "%s", __finalize_call.c_str());
246  lua_close(L);
247  throw;
248  }
249 
250  return L;
251 }
252 
253 
254 /** Set start script.
255  * The script will be executed once immediately in this method, make
256  * sure you call this after all other init-relevant routines like
257  * add_* if you need to access these in the start script!
258  * @param start_script script to execute now and on restart(). If the
259  * string is the path and name of an accessible file it is loaded via
260  * do_file(), otherwise it is considered to be the name of a module and
261  * loaded via Lua's require(). Note however, that if you use a module,
262  * special care has to be taken to correctly modify the global
263  * environment!
264  */
265 void
266 LuaContext::set_start_script(const char *start_script)
267 {
268  if ( __start_script ) free(__start_script);
269  if ( start_script ) {
270  __start_script = strdup(start_script);
271  if (access(__start_script, R_OK) == 0) {
272  // it's a file and we can access it, execute it!
273  do_file(__start_script);
274  } else {
275  do_string("require(\"%s\")", __start_script);
276  }
277  } else {
278  __start_script = NULL;
279  }
280 }
281 
282 
283 /** Restart Lua.
284  * Creates a new Lua state, initializes it, anf if this went well the
285  * current state is swapped with the new state.
286  */
287 void
289 {
290  MutexLocker lock(__lua_mutex);
291  try {
292  if (! __finalize_prepare_call.empty())
293  do_string(__L, "%s", __finalize_prepare_call.c_str());
294 
295  lock.unlock();
296  lua_State *L = init_state();
297  lock.relock();
298  lua_State *tL = __L;
299 
300  try {
301  if (! __finalize_call.empty())
302  do_string(__L, "%s", __finalize_call.c_str());
303  } catch (Exception &e) {
304  LibLogger::log_warn("LuaContext", "Finalization call on old context failed, "
305  "exception follows, ignoring.");
306  LibLogger::log_warn("LuaContext", e);
307  }
308 
309  __L = L;
310  if (__owns_L) lua_close(tL);
311  __owns_L = true;
312 
313  } catch (Exception &e) {
314  LibLogger::log_error("LuaContext", "Could not restart Lua instance, an error "
315  "occured while initializing new state. Keeping old state.");
316  LibLogger::log_error("LuaContext", e);
317  if (! __finalize_cancel_call.empty())
318  do_string(__L, "%s", __finalize_cancel_call.c_str());
319  }
320 }
321 
322 
323 /** Add a Lua package directory.
324  * The directory is added to the search path for lua packages. Files with
325  * a .lua suffix will be considered as Lua modules.
326  * @param path path to add
327  * @param prefix if true, insert path at the beginning of the search path,
328  * append to end otherwise
329  */
330 void
331 LuaContext::add_package_dir(const char *path, bool prefix)
332 {
333  MutexLocker lock(__lua_mutex);
334 
335  if (prefix) {
336  do_string(__L,
337  "package.path = \"%s/?.lua;%s/?/init.lua;\""
338  ".. package.path", path, path);
339 
340  __package_dirs.push_front(path);
341  } else {
342  do_string(__L,
343  "package.path = package.path .. "
344  "\";%s/?.lua;%s/?/init.lua\"", path, path);
345 
346  __package_dirs.push_back(path);
347  }
348  if ( __fam ) __fam->watch_dir(path);
349 }
350 
351 
352 /** Add a Lua C package directory.
353  * The directory is added to the search path for lua C packages. Files
354  * with a .so suffix will be considered as Lua modules.
355  * @param path path to add
356  * @param prefix if true, insert path at the beginning of the search path,
357  * append to end otherwise
358  */
359 void
360 LuaContext::add_cpackage_dir(const char *path, bool prefix)
361 {
362  MutexLocker lock(__lua_mutex);
363 
364  if (prefix) {
365  do_string(__L, "package.cpath = \"%s/?.so;\" .. package.cpath", path);
366 
367  __cpackage_dirs.push_front(path);
368  } else {
369  do_string(__L, "package.cpath = package.cpath .. \";%s/?.so\"", path);
370 
371  __cpackage_dirs.push_back(path);
372  }
373  if ( __fam ) __fam->watch_dir(path);
374 }
375 
376 
377 /** Add a default package.
378  * Packages that are added this way are automatically loaded now and
379  * on restart().
380  * @param package package to add
381  */
382 void
383 LuaContext::add_package(const char *package)
384 {
385  MutexLocker lock(__lua_mutex);
386  if (find(__packages.begin(), __packages.end(), package) == __packages.end()) {
387  do_string(__L, "require(\"%s\")", package);
388 
389  __packages.push_back(package);
390  }
391 }
392 
393 
394 /** Get Lua state.
395  * Allows for raw modification of the used Lua state. Remember proper
396  * locking!
397  * @return Currently used Lua state
398  */
399 lua_State *
401 {
402  return __L;
403 }
404 
405 
406 /** Lock Lua state. */
407 void
409 {
410  __lua_mutex->lock();
411 }
412 
413 
414 /** Try to lock the Lua state.
415  * @return true if the state has been locked, false otherwise.
416  */
417 bool
419 {
420  return __lua_mutex->try_lock();
421 }
422 
423 
424 /** Unlock Lua state. */
425 void
427 {
428  __lua_mutex->unlock();
429 }
430 
431 
432 /** Execute file.
433  * @param filename filet to load and excute.
434  */
435 void
436 LuaContext::do_file(const char *filename)
437 {
438  MutexLocker lock(__lua_mutex);
439  do_file(__L, filename);
440 }
441 
442 
443 /** Execute file on a specific Lua state.
444  * @param L Lua state to execute the file in.
445  * @param filename filet to load and excute.
446  */
447 void
448 LuaContext::do_file(lua_State *L, const char *filename)
449 {
450  // Load initialization code
451  int err = 0;
452  std::string errmsg;
453  if ( (err = luaL_loadfile(L, filename)) != 0) {
454  errmsg = lua_tostring(L, -1);
455  lua_pop(L, 1);
456  switch (err) {
457  case LUA_ERRSYNTAX:
458  throw SyntaxErrorException("Lua syntax error in file %s: %s", filename, errmsg.c_str());
459 
460  case LUA_ERRMEM:
461  throw OutOfMemoryException("Could not load Lua file %s", filename);
462 
463  case LUA_ERRFILE:
464  throw CouldNotOpenFileException(filename, errmsg.c_str());
465  }
466  }
467 
468  int errfunc = __enable_tracebacks ? 1 : 0;
469  if ( (err = lua_pcall(L, 0, LUA_MULTRET, errfunc)) != 0 ) {
470  // There was an error while executing the initialization file
471  errmsg = lua_tostring(L, -1);
472  lua_pop(L, 1);
473  switch (err) {
474  case LUA_ERRRUN:
475  throw LuaRuntimeException("do_file", errmsg.c_str());
476 
477  case LUA_ERRMEM:
478  throw OutOfMemoryException("Could not execute Lua file %s", filename);
479 
480  case LUA_ERRERR:
481  throw LuaErrorException("do_file", errmsg.c_str());
482 
483  default:
484  throw LuaErrorException("do_file/unknown error", errmsg.c_str());
485  }
486  }
487 
488 }
489 
490 
491 /** Execute string on a specific Lua state.
492  * @param L Lua state to execute the string in
493  * @param format format of string to execute, arguments can be the same as
494  * for vasprintf.
495  */
496 void
497 LuaContext::do_string(lua_State *L, const char *format, ...)
498 {
499  va_list arg;
500  va_start(arg, format);
501  char *s;
502  if (vasprintf(&s, format, arg) == -1) {
503  throw Exception("LuaContext::do_string: Could not form string");
504  }
505  std::string ss(s);
506  free(s);
507  va_end(arg);
508 
509  int err = 0;
510  std::string errmsg;
511  if ( (err = luaL_loadstring(L, ss.c_str())) != 0) {
512  errmsg = lua_tostring(L, -1);
513  lua_pop(L, 1);
514  switch (err) {
515  case LUA_ERRSYNTAX:
516  throw SyntaxErrorException("Lua syntax error in string %s: %s", ss.c_str(), errmsg.c_str());
517 
518  case LUA_ERRMEM:
519  throw OutOfMemoryException("Could not load Lua string %s", ss.c_str());
520  }
521  }
522 
523  int errfunc = __enable_tracebacks ? 1 : 0;
524  err = lua_pcall(L, 0, LUA_MULTRET, errfunc);
525 
526  if (err != 0) {
527  std::string errmsg = lua_tostring(L, -1);
528  lua_pop(L, 1);
529  switch (err) {
530  case LUA_ERRRUN:
531  throw LuaRuntimeException("do_string", errmsg.c_str());
532 
533  case LUA_ERRMEM:
534  throw OutOfMemoryException("Could not execute Lua chunk via pcall");
535 
536  case LUA_ERRERR:
537  throw LuaErrorException("do_string", errmsg.c_str());
538  }
539  }
540 }
541 
542 
543 /** Execute string.
544  * @param format format of string to execute, arguments can be the same as
545  * for vasprintf.
546  */
547 void
548 LuaContext::do_string(const char *format, ...)
549 {
550  MutexLocker lock(__lua_mutex);
551 
552  va_list arg;
553  va_start(arg, format);
554  char *s;
555  if (vasprintf(&s, format, arg) == -1) {
556  throw Exception("LuaContext::do_string: Could not form string");
557  }
558  std::string ss(s);
559  free(s);
560  va_end(arg);
561 
562  int err = 0;
563  std::string errmsg;
564  if ( (err = luaL_loadstring(__L, ss.c_str())) != 0) {
565  errmsg = lua_tostring(__L, -1);
566  lua_pop(__L, 1);
567  switch (err) {
568  case LUA_ERRSYNTAX:
569  throw SyntaxErrorException("Lua syntax error in string %s: %s", ss.c_str(), errmsg.c_str());
570 
571  case LUA_ERRMEM:
572  throw OutOfMemoryException("Could not load Lua string %s", ss.c_str());
573  }
574  }
575 
576  int errfunc = __enable_tracebacks ? 1 : 0;
577  err = lua_pcall(__L, 0, LUA_MULTRET, errfunc);
578 
579  if (err != 0) {
580  std::string errmsg = lua_tostring(__L, -1);
581  lua_pop(__L, 1);
582  switch (err) {
583  case LUA_ERRRUN:
584  throw LuaRuntimeException("do_string", errmsg.c_str());
585 
586  case LUA_ERRMEM:
587  throw OutOfMemoryException("Could not execute Lua chunk via pcall");
588 
589  case LUA_ERRERR:
590  throw LuaErrorException("do_string", errmsg.c_str());
591  }
592  }
593 }
594 
595 
596 /** Load Lua string.
597  * Loads the Lua string and places it as a function on top of the stack.
598  * @param s string to load
599  */
600 void
602 {
603  int err;
604  if ( (err = luaL_loadstring(__L, s)) != 0 ) {
605  std::string errmsg = lua_tostring(__L, -1);
606  lua_pop(__L, 1);
607  switch (err) {
608  case LUA_ERRSYNTAX:
609  throw SyntaxErrorException("Lua syntax error in string '%s': %s",
610  s, errmsg.c_str());
611 
612  case LUA_ERRMEM:
613  throw OutOfMemoryException("Could not load Lua string '%s'", s);
614  }
615  }
616 }
617 
618 
619 /** Protected call.
620  * Calls the function on top of the stack. Errors are handled gracefully.
621  * @param nargs number of arguments
622  * @param nresults number of results
623  * @param errfunc stack index of an error handling function
624  * @exception Exception thrown for generic runtime error or if the
625  * error function could not be executed.
626  * @exception OutOfMemoryException thrown if not enough memory was available
627  */
628 void
629 LuaContext::pcall(int nargs, int nresults, int errfunc)
630 {
631  int err = 0;
632  if ( ! errfunc && __enable_tracebacks ) errfunc = 1;
633  if ( (err = lua_pcall(__L, nargs, nresults, errfunc)) != 0 ) {
634  std::string errmsg = lua_tostring(__L, -1);
635  lua_pop(__L, 1);
636  switch (err) {
637  case LUA_ERRRUN:
638  throw LuaRuntimeException("pcall", errmsg.c_str());
639 
640  case LUA_ERRMEM:
641  throw OutOfMemoryException("Could not execute Lua chunk via pcall");
642 
643  case LUA_ERRERR:
644  throw LuaErrorException("pcall", errmsg.c_str());
645  }
646  }
647 }
648 
649 
650 /** Assert that the name is unique.
651  * Checks the internal context structures if the name has been used
652  * already. It will accept a value that has already been set that is of the same
653  * type as the one supplied. Pass the empty string to avoid this.
654  * @param name name to check
655  * @param type type of value
656  * @exception Exception thrown if name is not unique
657  */
658 void
659 LuaContext::assert_unique_name(const char *name, std::string type)
660 {
661  if ( (type == "usertype") && (__usertypes.find(name) != __usertypes.end()) ) {
662  throw Exception("User type entry already exists for name %s", name);
663  }
664  if ( (type == "string") && (__strings.find(name) != __strings.end()) ) {
665  throw Exception("String entry already exists for name %s", name);
666  }
667  if ( (type == "boolean") && (__booleans.find(name) != __booleans.end()) ) {
668  throw Exception("Boolean entry already exists for name %s", name);
669  }
670  if ( (type == "number") && (__numbers.find(name) != __numbers.end()) ) {
671  throw Exception("Number entry already exists for name %s", name);
672  }
673  if ( (type == "integer") && (__integers.find(name) != __integers.end()) ) {
674  throw Exception("Integer entry already exists for name %s", name);
675  }
676  if ( (type == "cfunction") && (__cfuncs.find(name) != __cfuncs.end()) ) {
677  throw Exception("C function entry already exists for name %s", name);
678  }
679 }
680 
681 
682 /** Assign usertype to global variable.
683  * @param name name of global variable to assign the value to
684  * @param data usertype data
685  * @param type_name type name of the data
686  * @param name_space C++ namespace of type, prepended to type_name
687  */
688 void
689 LuaContext::set_usertype(const char *name, void *data,
690  const char *type_name, const char *name_space)
691 {
692  MutexLocker lock(__lua_mutex);
693 
694  std::string type_n = type_name;
695  if ( name_space ) {
696  type_n = std::string(name_space) + "::" + type_name;
697  }
698 
699  assert_unique_name(name, "usertype");
700 
701  __usertypes[name] = std::make_pair(data, type_n);
702 
703  tolua_pushusertype(__L, data, type_n.c_str());
704  lua_setglobal(__L, name);
705 }
706 
707 
708 /** Assign string to global variable.
709  * @param name name of global variable to assign the value to
710  * @param value value to assign
711  */
712 void
713 LuaContext::set_string(const char *name, const char *value)
714 {
715  MutexLocker lock(__lua_mutex);
716  assert_unique_name(name, "string");
717 
718  __strings[name] = value;
719 
720  lua_pushstring(__L, value);
721  lua_setglobal(__L, name);
722 }
723 
724 
725 /** Assign boolean to global variable.
726  * @param name name of global variable to assign the value to
727  * @param value value to assign
728  */
729 void
730 LuaContext::set_boolean(const char *name, bool value)
731 {
732  MutexLocker lock(__lua_mutex);
733  assert_unique_name(name, "boolean");
734 
735  __booleans[name] = value;
736 
737  lua_pushboolean(__L, value ? 1 : 0);
738  lua_setglobal(__L, name);
739 }
740 
741 
742 /** Assign number to global variable.
743  * @param name name of global variable to assign the value to
744  * @param value value to assign
745  */
746 void
747 LuaContext::set_number(const char *name, lua_Number value)
748 {
749  MutexLocker lock(__lua_mutex);
750  assert_unique_name(name, "number");
751 
752  __numbers[name] = value;
753 
754  lua_pushnumber(__L, value);
755  lua_setglobal(__L, name);
756 }
757 
758 
759 /** Assign integer to global variable.
760  * @param name name of global variable to assign the value to
761  * @param value value to assign
762  */
763 void
764 LuaContext::set_integer(const char *name, lua_Integer value)
765 {
766  MutexLocker lock(__lua_mutex);
767  assert_unique_name(name, "integer");
768 
769  __integers[name] = value;
770 
771  lua_pushinteger(__L, value);
772  lua_setglobal(__L, name);
773 }
774 
775 
776 /** Assign cfunction to global variable.
777  * @param name name of global variable to assign the value to
778  * @param f function
779  */
780 void
781 LuaContext::set_cfunction(const char *name, lua_CFunction f)
782 {
783  MutexLocker lock(__lua_mutex);
784  assert_unique_name(name, "cfunction");
785 
786  __cfuncs[name] = f;
787 
788  lua_pushcfunction(__L, f);
789  lua_setglobal(__L, name);
790 }
791 
792 
793 /** Push boolean on top of stack.
794  * @param value value to push
795  */
796 void
798 {
799  MutexLocker lock(__lua_mutex);
800  lua_pushboolean(__L, value ? 1 : 0);
801 }
802 
803 
804 /** Push formatted string on top of stack.
805  * @param format string format
806  * @see man 3 sprintf
807  */
808 void
809 LuaContext::push_fstring(const char *format, ...)
810 {
811  MutexLocker lock(__lua_mutex);
812  va_list arg;
813  va_start(arg, format);
814  lua_pushvfstring(__L, format, arg);
815  va_end(arg);
816 }
817 
818 
819 /** Push integer on top of stack.
820  * @param value value to push
821  */
822 void
823 LuaContext::push_integer(lua_Integer value)
824 {
825  MutexLocker lock(__lua_mutex);
826  lua_pushinteger(__L, value);
827 }
828 
829 
830 /** Push light user data on top of stack.
831  * @param p pointer to light user data to push
832  */
833 void
835 {
836  MutexLocker lock(__lua_mutex);
837  lua_pushlightuserdata(__L, p);
838 }
839 
840 
841 /** Push substring on top of stack.
842  * @param s string to push
843  * @param len length of string to push
844  */
845 void
846 LuaContext::push_lstring(const char *s, size_t len)
847 {
848  MutexLocker lock(__lua_mutex);
849  lua_pushlstring(__L, s, len);
850 }
851 
852 
853 /** Push nil on top of stack.
854  */
855 void
857 {
858  MutexLocker lock(__lua_mutex);
859  lua_pushnil(__L);
860 }
861 
862 
863 /** Push number on top of stack.
864  * @param value value to push
865  */
866 void
867 LuaContext::push_number(lua_Number value)
868 {
869  MutexLocker lock(__lua_mutex);
870  lua_pushnumber(__L, value);
871 }
872 
873 
874 /** Push string on top of stack.
875  * @param value value to push
876  */
877 void
878 LuaContext::push_string(const char *value)
879 {
880  MutexLocker lock(__lua_mutex);
881  lua_pushstring(__L, value);
882 }
883 
884 
885 /** Push thread on top of stack.
886  */
887 void
889 {
890  MutexLocker lock(__lua_mutex);
891  lua_pushthread(__L);
892 }
893 
894 
895 /** Push a copy of the element at the given index on top of the stack.
896  * @param idx index of the value to copy
897  */
898 void
900 {
901  MutexLocker lock(__lua_mutex);
902  lua_pushvalue(__L, idx);
903 }
904 
905 
906 /** Push formatted string on top of stack.
907  * @param format string format
908  * @param arg variadic argument list
909  * @see man 3 sprintf
910  */
911 void
912 LuaContext::push_vfstring(const char *format, va_list arg)
913 {
914  MutexLocker lock(__lua_mutex);
915  lua_pushvfstring(__L, format, arg);
916 }
917 
918 
919 /** Push usertype on top of stack.
920  * @param data usertype data
921  * @param type_name type name of the data
922  * @param name_space C++ namespace of type, prepended to type_name
923  */
924 void
925 LuaContext::push_usertype(void *data, const char *type_name,
926  const char *name_space)
927 {
928  MutexLocker lock(__lua_mutex);
929 
930  std::string type_n = type_name;
931  if ( name_space ) {
932  type_n = std::string(name_space) + "::" + type_name;
933  }
934 
935  tolua_pushusertype(__L, data, type_n.c_str());
936 }
937 
938 
939 /** Push C function on top of stack.
940  * @param f C Function to push
941  */
942 void
944 {
945  MutexLocker lock(__lua_mutex);
946  lua_pushcfunction(__L, f);
947 }
948 
949 
950 /** Get name of type of value at a given index.
951  * @param idx index of value to get type for
952  * @return name of type of the value at the given index
953  */
954 std::string
956 {
957  return lua_typename(__L, lua_type(__L, idx));
958 }
959 
960 /** Pop value(s) from stack.
961  * @param n number of values to pop
962  */
963 void
965 {
966  MutexLocker lock(__lua_mutex);
967  if (__enable_tracebacks && (n >= stack_size())) {
968  throw LuaRuntimeException("pop", "Cannot pop traceback function, invalid n");
969  }
970  lua_pop(__L, n);
971 }
972 
973 /** Remove value from stack.
974  * @param idx index of element to remove
975  */
976 void
978 {
979  MutexLocker lock(__lua_mutex);
980  if (__enable_tracebacks && ((idx == 1) || (idx == -stack_size()))) {
981  throw LuaRuntimeException("pop", "Cannot remove traceback function");
982  }
983  lua_remove(__L, idx);
984 }
985 
986 
987 /** Get size of stack.
988  * @return number of elements on the stack
989  */
990 int
992 {
993  return lua_gettop(__L);
994 }
995 
996 
997 /** Create a table on top of the stack.
998  * @param narr number of array elements
999  * @param nrec number of non-array elements
1000  */
1001 void
1002 LuaContext::create_table(int narr, int nrec)
1003 {
1004  lua_createtable(__L, narr, nrec);
1005 }
1006 
1007 
1008 /** Set value of a table.
1009  * Sets value t[k] = v. t is the table at the given index, by default it is the
1010  * third-last entry (index is -3). v is the value at the top of the stack, k
1011  * is the element just below the top.
1012  * @param t_index index of the table on the stack
1013  */
1014 void
1016 {
1017  lua_settable(__L, t_index);
1018 }
1019 
1020 
1021 /** Set field of a table. Does the equivalent to t[k] = v, where t is
1022  * the value at the given valid index and v is the value at the top of
1023  * the stack. This function pops the value from the stack. As in Lua,
1024  * this function may trigger a metamethod for the "newindex" event.
1025  * @param key key of the field to set @param t_index index of the
1026  * table on the stack, defaults to the element just below the value to
1027  * set (-2, second last element on the stack).
1028  */
1029 void
1030 LuaContext::set_field(const char *key, int t_index)
1031 {
1032  lua_setfield(__L, t_index, key);
1033 }
1034 
1035 
1036 /** Set a global value.
1037  * Sets the global variable with the given name to the value currently on top
1038  * of the stack. No check whatsoever regarding the name is done.
1039  * @param name name of the variable to assign
1040  */
1041 void
1042 LuaContext::set_global(const char *name)
1043 {
1044  lua_setglobal(__L, name);
1045 }
1046 
1047 
1048 /** Get value from table.
1049  * Assumes that an index k is at the top of the stack. Then t[k] is retrieved,
1050  * where t is a table at the given index idx. The resulting value is pushed
1051  * onto the stack, while the key k is popped from the stack, thus the value
1052  * replaces the key.
1053  * @param idx index of the table on the stack
1054  */
1055 void
1057 {
1058  lua_gettable(__L, idx);
1059 }
1060 
1061 
1062 /** Get named value from table.
1063  * Retrieves the t[k], where k is the given key and t is a table at the given
1064  * index idx. The value is pushed onto the stack.
1065  * @param idx index of the table
1066  * @param k key of the table entry
1067  */
1068 void
1069 LuaContext::get_field(int idx, const char *k)
1070 {
1071  lua_getfield(__L, idx, k);
1072 }
1073 
1074 
1075 /** Set value without invoking meta methods.
1076  * Similar to set_table(), but does raw access, i.e. without invoking meta-methods.
1077  * @param idx index of the table
1078  */
1079 void
1081 {
1082  lua_rawset(__L, idx);
1083 }
1084 
1085 
1086 /** Set indexed value without invoking meta methods.
1087  * Sets t[n]=v, where t is a table at index idx and v is the value at the
1088  * top of the stack.
1089  * @param idx index of the table
1090  * @param n index in the table
1091  */
1092 void
1093 LuaContext::raw_seti(int idx, int n)
1094 {
1095  lua_rawseti(__L, idx, n);
1096 }
1097 
1098 
1099 /** Get value without invoking meta methods.
1100  * Similar to get_table(), but does raw access, i.e. without invoking meta-methods.
1101  * @param idx index of the table
1102  */
1103 void
1105 {
1106  lua_rawget(__L, idx);
1107 }
1108 
1109 
1110 /** Get indexed value without invoking meta methods.
1111  * Pushes t[n] onto the stack, where t is a table at index idx.
1112  * @param idx index of the table
1113  * @param n index in the table
1114  */
1115 void
1116 LuaContext::raw_geti(int idx, int n)
1117 {
1118  lua_rawgeti(__L, idx, n);
1119 }
1120 
1121 
1122 /** Get global variable.
1123  * @param name name of the global variable
1124  */
1125 void
1126 LuaContext::get_global(const char *name)
1127 {
1128  lua_getglobal(__L, name);
1129 }
1130 
1131 
1132 /** Remove global variable.
1133  * Assigns nil to the given variable and removes it from internal
1134  * assignment maps.
1135  * @param name name of value to remove
1136  */
1137 void
1138 LuaContext::remove_global(const char *name)
1139 {
1140  MutexLocker lock(__lua_mutex);
1141 
1142  __usertypes.erase(name);
1143  __strings.erase(name);
1144  __booleans.erase(name);
1145  __numbers.erase(name);
1146  __integers.erase(name);
1147  __cfuncs.erase(name);
1148 
1149  lua_pushnil(__L);
1150  lua_setglobal(__L, name);
1151 }
1152 
1153 
1154 /** Iterate to next entry of table.
1155  * @param idx stack index of table
1156  * @return true if there was another iterable value in the table,
1157  * false otherwise
1158  */
1159 bool
1161 {
1162  return lua_next(__L, idx) != 0;
1163 }
1164 
1165 
1166 /** Retrieve stack value as number.
1167  * @param idx stack index of value
1168  * @return value as number
1169  */
1170 lua_Number
1172 {
1173  return lua_tonumber(__L, idx);
1174 }
1175 
1176 
1177 /** Retrieve stack value as integer.
1178  * @param idx stack index of value
1179  * @return value as integer
1180  */
1181 lua_Integer
1183 {
1184  return lua_tointeger(__L, idx);
1185 }
1186 
1187 
1188 /** Retrieve stack value as boolean.
1189  * @param idx stack index of value
1190  * @return value as boolean
1191  */
1192 bool
1194 {
1195  return lua_toboolean(__L, idx);
1196 }
1197 
1198 
1199 /** Retrieve stack value as string.
1200  * @param idx stack index of value
1201  * @return value as string
1202  */
1203 const char *
1205 {
1206  return lua_tostring(__L, idx);
1207 }
1208 
1209 /** Retrieve stack value as userdata.
1210  * @param idx stack index of value
1211  * @return value as userdata, maybe NULL
1212  */
1213 void *
1215 {
1216  return lua_touserdata(__L, idx);
1217 }
1218 
1219 
1220 /** Retrieve stack value as pointer.
1221  * @param idx stack index of value
1222  * @return value as pointer, maybe NULL
1223  */
1224 void *
1226 {
1227  return (void *)lua_topointer(__L, idx);
1228 }
1229 
1230 
1231 /** Retrieve stack value as a tolua++ user type.
1232  * @param idx stack index of value
1233  * @return value as pointer, maybe NULL
1234  */
1235 void *
1237 {
1238  return tolua_tousertype(__L, idx, 0);
1239 }
1240 
1241 
1242 /** Check if stack value is a boolean.
1243  * @param idx stack index of value
1244  * @return true if value is a boolean, false otherwise
1245  */
1246 bool
1248 {
1249  return lua_isboolean(__L, idx);
1250 }
1251 
1252 
1253 /** Check if stack value is a C function.
1254  * @param idx stack index of value
1255  * @return true if value is a C function, false otherwise
1256  */
1257 bool
1259 {
1260  return lua_iscfunction(__L, idx);
1261 }
1262 
1263 
1264 /** Check if stack value is a function.
1265  * @param idx stack index of value
1266  * @return true if value is a function, false otherwise
1267  */
1268 bool
1270 {
1271  return lua_isfunction(__L, idx);
1272 }
1273 
1274 
1275 /** Check if stack value is light user data.
1276  * @param idx stack index of value
1277  * @return true if value is light user data , false otherwise
1278  */
1279 bool
1281 {
1282  return lua_islightuserdata(__L, idx);
1283 }
1284 
1285 
1286 /** Check if stack value is nil.
1287  * @param idx stack index of value
1288  * @return true if value is nil, false otherwise
1289  */
1290 bool
1292 {
1293  return lua_isnil(__L, idx);
1294 }
1295 
1296 
1297 /** Check if stack value is a number.
1298  * @param idx stack index of value
1299  * @return true if value is a number, false otherwise
1300  */
1301 bool
1303 {
1304  return lua_isnumber(__L, idx);
1305 }
1306 
1307 
1308 /** Check if stack value is a string.
1309  * @param idx stack index of value
1310  * @return true if value is a string, false otherwise
1311  */
1312 bool
1314 {
1315  return lua_isstring(__L, idx);
1316 }
1317 
1318 
1319 /** Check if stack value is a table.
1320  * @param idx stack index of value
1321  * @return true if value is a table, false otherwise
1322  */
1323 bool
1325 {
1326  return lua_istable(__L, idx);
1327 }
1328 
1329 
1330 /** Check if stack value is a thread.
1331  * @param idx stack index of value
1332  * @return true if value is a thread, false otherwise
1333  */
1334 bool
1336 {
1337  return lua_isthread(__L, idx);
1338 }
1339 
1340 
1341 /** Get object length
1342  * @param idx stack index of value
1343  * @return size of object
1344  */
1345 size_t
1347 {
1348  return lua_objlen(__L, idx);
1349 }
1350 
1351 
1352 /** Set function environment.
1353  * Sets the table on top of the stack as environment of the function
1354  * at the given stack index.
1355  * @param idx stack index of function
1356  */
1357 void
1359 {
1360 #if LUA_VERSION_NUM > 501
1361  // stack: ... func@idx ... env
1362  // find _ENV
1363  int n = 0;
1364  const char *val_name;
1365  while ((val_name = lua_getupvalue(__L, idx, ++n)) != NULL) { // ... env upval
1366  if (strcmp(val_name, "_ENV") == 0) {
1367  // found environment
1368  break;
1369  } else {
1370  // we're not interested, remove value from stack
1371  lua_pop(__L, 1); // ... env
1372  }
1373  }
1374 
1375  // found an environment
1376  if (val_name != NULL) { // ... env upval
1377  // create a new simple up value
1378  luaL_loadstring(__L, ""); // ... env upval chunk
1379  lua_pushvalue(__L, -3); // ... env upval chunk env
1380  lua_setupvalue(__L, -2, 1); // ... env upval func
1381  int act_idx = idx > 0 ? idx : idx - 2;
1382  lua_upvaluejoin(__L, act_idx, n, -1, 1); // ... env upval chunk
1383  lua_pop(__L, 3); // ...
1384  } else {
1385  throw Exception("No environment found");
1386  }
1387 #else
1388  lua_setfenv(__L, idx);
1389 #endif
1390 }
1391 
1392 /** Add a context watcher.
1393  * @param watcher watcher to add
1394  */
1395 void
1397 {
1398  __watchers.push_back_locked(watcher);
1399 }
1400 
1401 
1402 /** Remove a context watcher.
1403  * @param watcher watcher to remove
1404  */
1405 void
1407 {
1408  __watchers.remove_locked(watcher);
1409 }
1410 
1411 
1412 /** Set code to execute during finalization.
1413  * @param finalize code string to execute (via do_string()) when eventually
1414  * finalizing a context
1415  * @param finalize_prepare code string to execute (via do_string()) before
1416  * finalization is performed, for example during a context restart before the
1417  * new context is initialized
1418  * @param finalize_cancel code string to execute (via do_string()) if,
1419  * during a restart, the initialization of the new context failed and therefore
1420  * the previously prepared finalization must be cancelled
1421  */
1422 void
1423 LuaContext::set_finalization_calls(std::string finalize, std::string finalize_prepare,
1424  std::string finalize_cancel)
1425 {
1426  __finalize_call = finalize;
1427  __finalize_prepare_call = finalize_prepare;
1428  __finalize_cancel_call = finalize_cancel;
1429 }
1430 
1431 
1432 
1433 
1434 /** Process FAM events. */
1435 void
1437 {
1438  if ( __fam) __fam->process_events();
1439 }
1440 
1441 
1442 void
1443 LuaContext::fam_event(const char *filename, unsigned int mask)
1444 {
1445  restart();
1446 }
1447 
1448 
1449 } // end of namespace fawkes
void restart()
Restart Lua.
Definition: context.cpp:288
void push_thread()
Push thread on top of stack.
Definition: context.cpp:888
File could not be opened.
Definition: system.h:53
void push_light_user_data(void *p)
Push light user data on top of stack.
Definition: context.cpp:834
void setup_fam(bool auto_restart, bool conc_thread)
Setup file alteration monitor.
Definition: context.cpp:128
void push_vfstring(const char *format, va_list arg)
Push formatted string on top of stack.
Definition: context.cpp:912
bool is_light_user_data(int idx)
Check if stack value is light user data.
Definition: context.cpp:1280
Lua context watcher.
bool is_number(int idx)
Check if stack value is a number.
Definition: context.cpp:1302
void push_integer(lua_Integer value)
Push integer on top of stack.
Definition: context.cpp:823
void raw_geti(int idx, int n)
Get indexed value without invoking meta methods.
Definition: context.cpp:1116
Fawkes library namespace.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
bool is_thread(int idx)
Check if stack value is a thread.
Definition: context.cpp:1335
Mutex locking helper.
Definition: mutex_locker.h:33
void pop(int n)
Pop value(s) from stack.
Definition: context.cpp:964
void push_lstring(const char *s, size_t len)
Push substring on top of stack.
Definition: context.cpp:846
void remove(int idx)
Remove value from stack.
Definition: context.cpp:977
void set_cfunction(const char *name, lua_CFunction f)
Assign cfunction to global variable.
Definition: context.cpp:781
void raw_seti(int idx, int n)
Set indexed value without invoking meta methods.
Definition: context.cpp:1093
virtual void fam_event(const char *filename, unsigned int mask)
Event has been raised.
Definition: context.cpp:1443
void load_string(const char *s)
Load Lua string.
Definition: context.cpp:601
void add_package_dir(const char *path, bool prefix=false)
Add a Lua package directory.
Definition: context.cpp:331
void remove_watcher(LuaContextWatcher *watcher)
Remove a context watcher.
Definition: context.cpp:1406
bool is_cfunction(int idx)
Check if stack value is a C function.
Definition: context.cpp:1258
bool try_lock()
Try to lock the Lua state.
Definition: context.cpp:418
void set_field(const char *key, int t_index=-2)
Set field of a table.
Definition: context.cpp:1030
void set_table(int t_index=-3)
Set value of a table.
Definition: context.cpp:1015
void add_package(const char *package)
Add a default package.
Definition: context.cpp:383
void unlock()
Unlock the mutex.
void unlock()
Unlock Lua state.
Definition: context.cpp:426
static void log_error(const char *component, const char *format,...)
Log error message.
Definition: liblogger.cpp:180
void push_value(int idx)
Push a copy of the element at the given index on top of the stack.
Definition: context.cpp:899
void push_nil()
Push nil on top of stack.
Definition: context.cpp:856
int stack_size()
Get size of stack.
Definition: context.cpp:991
void pcall(int nargs=0, int nresults=0, int errfunc=0)
Protected call.
Definition: context.cpp:629
bool is_nil(int idx)
Check if stack value is nil.
Definition: context.cpp:1291
Base class for exceptions in Fawkes.
Definition: exception.h:36
lua_Number to_number(int idx)
Retrieve stack value as number.
Definition: context.cpp:1171
void push_cfunction(lua_CFunction f)
Push C function on top of stack.
Definition: context.cpp:943
void do_string(const char *format,...)
Execute string.
Definition: context.cpp:548
void do_file(const char *filename)
Execute file.
Definition: context.cpp:436
void set_number(const char *name, lua_Number value)
Assign number to global variable.
Definition: context.cpp:747
LuaContext(bool enable_tracebacks=true)
Constructor.
Definition: context.cpp:66
void setfenv(int idx=-2)
Set function environment.
Definition: context.cpp:1358
List with a lock.
Definition: thread.h:40
Lua C++ wrapper.
Definition: context.h:47
void get_field(int idx, const char *k)
Get named value from table.
Definition: context.cpp:1069
void relock()
Lock this mutex, again.
void set_integer(const char *name, lua_Integer value)
Assign integer to global variable.
Definition: context.cpp:764
Monitors files for changes.
Definition: fam.h:71
lua_Integer to_integer(int idx)
Retrieve stack value as integer.
Definition: context.cpp:1182
void set_usertype(const char *name, void *data, const char *type_name, const char *name_space=0)
Assign usertype to global variable.
Definition: context.cpp:689
void push_usertype(void *data, const char *type_name, const char *name_space=0)
Push usertype on top of stack.
Definition: context.cpp:925
static void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: liblogger.cpp:162
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:120
void set_string(const char *name, const char *value)
Assign string to global variable.
Definition: context.cpp:713
void push_string(const char *value)
Push string on top of stack.
Definition: context.cpp:878
bool is_table(int idx)
Check if stack value is a table.
Definition: context.cpp:1324
void cancel()
Cancel a thread.
Definition: thread.cpp:651
void set_finalization_calls(std::string finalize, std::string finalize_prepare, std::string finalize_cancel)
Set code to execute during finalization.
Definition: context.cpp:1423
void process_fam_events()
Process FAM events.
Definition: context.cpp:1436
void set_boolean(const char *name, bool value)
Assign boolean to global variable.
Definition: context.cpp:730
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:49
bool is_string(int idx)
Check if stack value is a string.
Definition: context.cpp:1313
void get_global(const char *name)
Get global variable.
Definition: context.cpp:1126
void push_boolean(bool value)
Push boolean on top of stack.
Definition: context.cpp:797
void add_cpackage_dir(const char *path, bool prefix=false)
Add a Lua C package directory.
Definition: context.cpp:360
void set_start_script(const char *start_script)
Set start script.
Definition: context.cpp:266
bool is_function(int idx)
Check if stack value is a function.
Definition: context.cpp:1269
bool to_boolean(int idx)
Retrieve stack value as boolean.
Definition: context.cpp:1193
bool table_next(int idx)
Iterate to next entry of table.
Definition: context.cpp:1160
lua_State * get_lua_state()
Get Lua state.
Definition: context.cpp:400
void join()
Join the thread.
Definition: thread.cpp:610
Lua runtime exception.
Definition: exceptions.h:30
void get_table(int idx)
Get value from table.
Definition: context.cpp:1056
Lua error exception.
Definition: exceptions.h:36
FileAlterationMonitor thread wrapper.
Definition: fam_thread.h:35
void lock()
Lock this mutex.
Definition: mutex.cpp:89
~LuaContext()
Destructor.
Definition: context.cpp:98
void lock()
Lock Lua state.
Definition: context.cpp:408
void remove_global(const char *name)
Remove global variable.
Definition: context.cpp:1138
Mutex mutual exclusion lock.
Definition: mutex.h:32
void set_global(const char *name)
Set a global value.
Definition: context.cpp:1042
void * to_pointer(int idx)
Retrieve stack value as pointer.
Definition: context.cpp:1225
void create_table(int narr=0, int nrec=0)
Create a table on top of the stack.
Definition: context.cpp:1002
void push_number(lua_Number value)
Push number on top of stack.
Definition: context.cpp:867
void * to_userdata(int idx)
Retrieve stack value as userdata.
Definition: context.cpp:1214
void * to_usertype(int idx)
Retrieve stack value as a tolua++ user type.
Definition: context.cpp:1236
const char * to_string(int idx)
Retrieve stack value as string.
Definition: context.cpp:1204
void raw_get(int idx)
Get value without invoking meta methods.
Definition: context.cpp:1104
size_t objlen(int idx)
Get object length.
Definition: context.cpp:1346
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:511
std::string type_name(int idx)
Get name of type of value at a given index.
Definition: context.cpp:955
RefPtr< FileAlterationMonitor > get_fam() const
Get file alteration monitor.
Definition: context.cpp:147
void add_watcher(LuaContextWatcher *watcher)
Add a context watcher.
Definition: context.cpp:1396
bool is_boolean(int idx)
Check if stack value is a boolean.
Definition: context.cpp:1247
void push_fstring(const char *format,...)
Push formatted string on top of stack.
Definition: context.cpp:809
void raw_set(int idx)
Set value without invoking meta methods.
Definition: context.cpp:1080