Ejemplo n.º 1
0
/**
 * @brief Dumps a lua table with XBT_DEBUG
 *
 * This function can be called from within lua via "simgrid.dump(table)". It will
 * then dump the table via XBT_DEBUG
 */
static int dump(lua_State* L) {
  int argc = lua_gettop(L);

  for (int i = 1; i <= argc; i++) {
    if (lua_istable(L, i)) {
      lua_pushnil(L); /* table nil */

      //lua_next pops the topmost element from the stack and
      //gets the next pair from the table at the specified index
      while (lua_next(L, i)) { /* table key val  */
        // we need to copy here, as a cast from "Number" to "String"
        // could happen in Lua.
        // see remark in the lua manual, function "lua_tolstring"
        // http://www.lua.org/manual/5.3/manual.html#lua_tolstring

        lua_pushvalue(L, -2); /* table key val key */

        XBT_DEBUG("%s", sglua_keyvalue_tostring(L, -1, -2));
      }

      lua_settop(L, argc); // Remove everything except the initial arguments
    }
  }

  return 0;
}
Ejemplo n.º 2
0
/**
 * @brief Copies the table value on top of src to the top of dst.
 *
 * A deep copy of the table is made. If the table has a metatable, the
 * metatable is also copied.
 * If the table comes from maestro and is already known by the destination
 * state, it is not copied again.
 *
 * @param src source state
 * @param dst destination state
 */
static void sglua_copy_table(lua_State* src, lua_State* dst) {

                                  /* src: ... table
                                     dst: ... */
  int indent = lua_gettop(dst) * 6  + 2;

  /* get from maestro the pointer that identifies this table */
  void* table_ptr = sglua_get_maestro_table_ptr(src, -1);
  int known_by_maestro = (table_ptr != NULL);

  if (!known_by_maestro) {
    /* the table didn't come from maestro: nevermind, use the pointer of src */
    table_ptr = (void*) lua_topointer(src, -1);
    XBT_DEBUG("%sMaestro does not know this table",
        sglua_get_spaces(indent));
  }

  if (sglua_is_maestro(src)) {
    /* register the table in maestro itself */
    XBT_DEBUG("%sKeeping track of this table in maestro itself",
        sglua_get_spaces(indent));
    sglua_add_maestro_table(src, -1, table_ptr);
    known_by_maestro = 1;
    xbt_assert(sglua_get_maestro_table_ptr(src, -1) == table_ptr);
  }

  /* to avoid infinite recursion, see if this table is already known by dst */
  sglua_get_table_by_ptr(dst, table_ptr);
                                  /* dst: ... table/nil */
  if (!lua_isnil(dst, -1)) {
    XBT_DEBUG("%sNothing to do: table already known (%p)",
        sglua_get_spaces(indent), table_ptr);
                                  /* dst: ... table */
  }
  else {
    XBT_DEBUG("%sFirst visit of this table (%p)", sglua_get_spaces(indent),
        table_ptr);
                                  /* dst: ... nil */
    lua_pop(dst, 1);
                                  /* dst: ... */

    /* first visit: create the new table in dst */
    lua_newtable(dst);
                                  /* dst: ... table */

    /* mark the table as known right now to avoid infinite recursion */
    sglua_add_maestro_table(dst, -1, table_ptr);
    /* we may have added a table with a non-maestro pointer, but if it was the
     * case, we will remove it later */
    XBT_DEBUG("%sTable marked as known", sglua_get_spaces(indent));
    xbt_assert(sglua_get_maestro_table_ptr(dst, -1) == table_ptr);

    sglua_stack_dump("dst after marking the table as known (should be ... table): ", dst);

    /* copy the metatable if any */
    int has_meta_table = lua_getmetatable(src, -1);
                                  /* src: ... table mt? */
    if (has_meta_table) {
      XBT_DEBUG("%sCopying the metatable", sglua_get_spaces(indent));
                                  /* src: ... table mt */
      sglua_copy_table(src, dst);
                                  /* dst: ... table mt */
      lua_pop(src, 1);
                                  /* src: ... table */
      lua_setmetatable(dst, -2);
                                  /* dst: ... table */
    }
    else {
                                  /* src: ... table */
      XBT_DEBUG("%sNo metatable", sglua_get_spaces(indent));
    }

    sglua_stack_dump("src before traversing the table (should be ... table): ", src);
    sglua_stack_dump("dst before traversing the table (should be ... table): ", dst);

    /* traverse the table of src and copy each element */
    lua_pushnil(src);
                                  /* src: ... table nil */
    while (lua_next(src, -2) != 0) {
                                  /* src: ... table key value */

      XBT_DEBUG("%sCopying table element %s", sglua_get_spaces(indent),
          sglua_keyvalue_tostring(src, -2, -1));

      sglua_stack_dump("src before copying table element (should be ... table key value): ", src);
      sglua_stack_dump("dst before copying table element (should be ... table): ", dst);

      /* copy the key */
      lua_pushvalue(src, -2);
                                  /* src: ... table key value key */
      indent += 2;
      XBT_DEBUG("%sCopying the key part of the table element",
          sglua_get_spaces(indent));
      sglua_move_value(src, dst);
                                  /* src: ... table key value
                                     dst: ... table key */
      XBT_DEBUG("%sCopied the key part of the table element",
          sglua_get_spaces(indent));

      /* copy the value */
      XBT_DEBUG("%sCopying the value part of the table element",
          sglua_get_spaces(indent));
      sglua_move_value(src, dst);
                                  /* src: ... table key
                                     dst: ... table key value */
      XBT_DEBUG("%sCopied the value part of the table element",
          sglua_get_spaces(indent));
      indent -= 2;

      /* set the table element */
      lua_settable(dst, -3);
                                  /* dst: ... table */

      /* the key stays on top of src for next iteration */
      sglua_stack_dump("src before next iteration (should be ... table key): ", src);
      sglua_stack_dump("dst before next iteration (should be ... table): ", dst);

      XBT_DEBUG("%sTable element copied", sglua_get_spaces(indent));
    }
    XBT_DEBUG("%sFinished traversing the table", sglua_get_spaces(indent));
  }

  if (!known_by_maestro) {
    /* actually,it was not a maestro table: forget the pointer */
    sglua_remove_maestro_table(dst, -1, table_ptr);
  }
}