Example #1
0
/**
 * @brief Returns a string representation of a key-value pair.
 *
 * It always returns the same pointer.
 *
 * @param L the Lua state
 * @param key_index index of the key (in the lua stack)
 * @param value_index index of the value (in the lua stack)
 * @return a string representation of the key-value pair
 */
const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index) {

  static char buff[64];
  /* value_tostring also always returns the same pointer */
  int len = snprintf(buff, 63, "[%s] -> ", sglua_tostring(L, key_index));
  snprintf(buff + len, 63 - len, "%s", sglua_tostring(L, value_index));
  return buff;
}
Example #2
0
/**
 * @brief Pushes onto the stack a copy of the value on top another stack.
 * If the value is a table, its content is copied recursively.
 *
 * This function allows to move a value between two different global states.
 *
 * @param src the source state (not necessarily maestro)
 * @param dst the destination state
 */
void sglua_copy_value(lua_State* src, lua_State* dst) {

  luaL_checkany(src, -1);                  /* check the value to copy */

  int indent = (lua_gettop(dst) - 1) * 6;
  XBT_DEBUG("%sCopying data %s", sglua_get_spaces(indent), sglua_tostring(src, -1));

  sglua_stack_dump("src before copying a value (should be ... value): ", src);
  sglua_stack_dump("dst before copying a value (should be ...): ", dst);

  switch (lua_type(src, -1)) {

    case LUA_TNIL:
      sglua_copy_nil(src, dst);
      break;

    case LUA_TNUMBER:
      sglua_copy_number(src, dst);
      break;

    case LUA_TBOOLEAN:
      sglua_copy_boolean(src, dst);
      break;

    case LUA_TSTRING:
      sglua_copy_string(src, dst);
      break;

    case LUA_TFUNCTION:
      sglua_copy_function(src, dst);
      break;

    case LUA_TTABLE:
      sglua_copy_table(src, dst);
      break;

    case LUA_TLIGHTUSERDATA:
      sglua_copy_lightuserdata(src, dst);
      break;

    case LUA_TUSERDATA:
      sglua_copy_userdata(src, dst);
      break;

    case LUA_TTHREAD:
      sglua_copy_thread(src, dst);
      break;
  }

  XBT_DEBUG("%sData copied", sglua_get_spaces(indent));

  sglua_stack_dump("src after copying a value (should be ... value): ", src);
  sglua_stack_dump("dst after copying a value (should be ... value): ", dst);
}
Example #3
0
/**
 * @brief Copies a global value or a registry value from the maestro state.
 *
 * The state L must have been created by sglua_clone_maestro_state().
 * This function is meant to be an __index metamethod.
 * Consequently, it assumes that the stack has two elements:
 * a table (either the environment or the registry of L) and the string key of
 * a value that does not exist yet in this table. It copies the corresponding
 * value from maestro and pushes it on the stack of L.
 * If the value does not exist in maestro state either, nil is pushed.
 *
 * TODO: make this function thread safe. If the simulation runs in parallel,
 * several simulated processes may trigger this __index metamethod at the same
 * time and get globals from maestro.
 *
 * @param L the current state
 * @return number of return values pushed (always 1)
 */
static int l_get_from_maestro(lua_State *L) {

  /* check the arguments */
  luaL_checktype(L, 1, LUA_TTABLE);
  const char* key = luaL_checkstring(L, 2);
                                  /* L:      table key */
  XBT_DEBUG("__index of '%s' begins", key);

  /* want a global or a registry value? */
  int pseudo_index;
  if (lua_equal(L, 1, LUA_REGISTRYINDEX)) {
    /* registry */
    pseudo_index = LUA_REGISTRYINDEX;
    XBT_DEBUG("Will get the value from the registry of maestro");
  }
  else {
    /* global */
    pseudo_index = LUA_GLOBALSINDEX;
    XBT_DEBUG("Will get the value from the globals of maestro");
  }

  /* get the father */
  lua_State* maestro = sglua_get_maestro();

                                  /* L:      table key */

  /* get the value from maestro */
  lua_getfield(maestro, pseudo_index, key);
                                  /* maestro: ... value */

  /* push the value onto the stack of L */
  sglua_move_value(maestro, L);
                                  /* maestro: ...
                                     L:      table key value */

  /* prepare the return value of __index */
  lua_pushvalue(L, -1);
                                  /* L:      table key value value */
  lua_insert(L, 1);
                                  /* L:      value table key value */

  /* save the copied value in the table for subsequent accesses */
  lua_settable(L, -3);
                                  /* L:      value table */
  lua_settop(L, 1);
                                  /* L:      value */

  XBT_DEBUG("__index of '%s' returns %s", key, sglua_tostring(L, -1));

  return 1;
}
Example #4
0
/**
 * @brief Dumps the Lua stack if debug logs are enabled.
 * @param msg a message to print
 * @param L a Lua state
 */
void sglua_stack_dump(lua_State* L, const char* msg)
{
  if (XBT_LOG_ISENABLED(lua_debug, xbt_log_priority_debug)) {
    char buff[2048];
    char* p = buff;
    int top = lua_gettop(L);

    fflush(stdout);

    p[0] = '\0';
    for (int i = 1; i <= top; i++) {  /* repeat for each level */
      p += snprintf(p, 2048-(p-buff), "%s ", sglua_tostring(L, i));
    }

    XBT_DEBUG("%s%s", msg, buff);
  }
}