Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added new case to lua_state_cloner.c: LUA_TNONE
[simgrid.git] / src / bindings / lua / lua_state_cloner.c
index 27a79d6..64a4f8d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010. The SimGrid Team.
+/* Copyright (c) 2010-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -16,6 +16,7 @@
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(lua_state_cloner, bindings, "Lua state management");
 
 static void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr);
+static void sglua_remove_maestro_table(lua_State* L, int index, void* maestro_table_ptr);
 static void* sglua_get_maestro_table_ptr(lua_State* L, int index);
 static void sglua_get_table_by_ptr(lua_State* L, void* table_ptr);
 static int l_get_from_maestro(lua_State* L);
@@ -41,7 +42,7 @@ static void sglua_copy_thread(lua_State* src, lua_State* dst);
  * @param index index of the copy of the maestro table in the stack of L
  * @param maestro_table_ptr pointer to the original table in maestro's world
  */
-void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) {
+static void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) {
 
   /* we will set both [ptr] -> table and [table] -> ptr */
 
@@ -68,6 +69,41 @@ void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) {
                                   /* ... */
 }
 
+/**
+ * @brief Removes a reference to a maestro table to the list of known maestro
+ * tables of a state.
+ *
+ * @param L a state (can be maestro itself)
+ * @param index index of the copy of the maestro table in the stack of L
+ * @param maestro_table_ptr pointer to the original table in maestro's world
+ */
+static void sglua_remove_maestro_table(lua_State* L, int index, void* maestro_table_ptr) {
+
+  /* we will unset both [ptr] -> table and [table] -> ptr */
+
+                                  /* ... */
+  lua_pushvalue(L, index);
+                                  /* ... table */
+  lua_pushstring(L, "simgrid.maestro_tables");
+                                  /* ... table "simgrid.maestro_tables" */
+  lua_rawget(L, LUA_REGISTRYINDEX);
+                                  /* ... table maestrotbs */
+  lua_pushvalue(L, -2);
+                                  /* ... table maestrotbs table */
+  lua_pushnil(L);
+                                  /* ... table maestrotbs table nil */
+  lua_pushlightuserdata(L, maestro_table_ptr);
+                                  /* ... table maestrotbs table nil tableptr */
+  lua_pushnil(L);
+                                  /* ... table maestrotbs table nil tableptr nil*/
+  lua_settable(L, -5);
+                                  /* ... table maestrotbs table nil */
+  lua_settable(L, -3);
+                                  /* ... table maestrotbs */
+  lua_pop(L, 2);
+                                  /* ... */
+}
+
 /**
  * @brief For a table in the stack of L, returns a pointer that identifies the
  * same table in in maestro's world.
@@ -196,9 +232,12 @@ void sglua_copy_value(lua_State* src, lua_State* dst) {
     case LUA_TTHREAD:
       sglua_copy_thread(src, dst);
       break;
+
+    case LUA_TNONE:
+        XBT_ERROR("This index is acceptable but non-valid");
+      break;
   }
 
-  indent -= 2;
   XBT_DEBUG("%sData copied", sglua_get_spaces(indent));
 
   sglua_stack_dump("src after copying a value (should be ... value): ", src);
@@ -244,12 +283,12 @@ static void sglua_copy_string(lua_State* src, lua_State* dst) {
 }
 
 /**
- * @brief Copies the table value on the top of src to the top of dst.
+ * @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 is already known by the destination state, it is not copied
- * again.
+ * 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
@@ -262,14 +301,13 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) {
 
   /* get from maestro the pointer that identifies this table */
   void* table_ptr = sglua_get_maestro_table_ptr(src, -1);
-  if (table_ptr == NULL) {
+  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);
-
-    if (!sglua_is_maestro(src)) {
-      XBT_DEBUG("%sMaestro does not know this table",
-          sglua_get_spaces(indent));
-    }
+    XBT_DEBUG("%sMaestro does not know this table",
+        sglua_get_spaces(indent));
   }
 
   if (sglua_is_maestro(src)) {
@@ -277,6 +315,7 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) {
     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);
   }
 
@@ -301,8 +340,8 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) {
 
     /* mark the table as known right now to avoid infinite recursion */
     sglua_add_maestro_table(dst, -1, table_ptr);
-    /* FIXME: we may have added a table with a non-maestro pointer, is this a
-       problem? */
+    /* 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);
 
@@ -375,13 +414,17 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) {
     }
     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);
+  }
 }
 
 /**
  * @brief Copies the function on the top of src to the top of dst.
  *
  * It can be a Lua function or a C function.
- * Copying upvalues is not implemented yet.
  *
  * @param src source state
  * @param dst destination state
@@ -425,8 +468,12 @@ static void sglua_copy_function(lua_State* src, lua_State* dst) {
     buffer.size = 0;
     buffer.data = xbt_new(char, buffer.capacity);
 
-    /* copy the binary chunk from src into a buffer */
-    _XBT_GNUC_UNUSED int error = lua_dump(src, sglua_memory_writer, &buffer);
+    /* copy the binary chunk from src into a buffer
+     * c.heinrich: Added parameter TRUE for Lua 5.3 - this strips all debug
+     * information from the function.
+     */
+    // Was before merge: XBT_GNUC_UNUSED and was replaced with XBT_ATTRIB_UNUSED
+    XBT_ATTRIB_UNUSED int error = lua_dump(src, sglua_memory_writer, &buffer, TRUE);
     xbt_assert(!error, "Failed to dump the function from the source state: error %d",
         error);
     XBT_DEBUG("Fonction dumped: %zu bytes", buffer.size);
@@ -467,7 +514,7 @@ static void sglua_copy_userdata(lua_State* src, lua_State* dst) {
   /* copy the data */
                                   /* src: ... udata
                                      dst: ... */
-  size_t size = lua_objlen(src, -1);
+  size_t size = lua_rawlen(src, -1);
   void* src_block = lua_touserdata(src, -1);
   void* dst_block = lua_newuserdata(dst, size);
                                   /* dst: ... udata */
@@ -537,14 +584,14 @@ static int l_get_from_maestro(lua_State *L) {
 
   /* want a global or a registry value? */
   int pseudo_index;
-  if (lua_equal(L, 1, LUA_REGISTRYINDEX)) {
+  if (lua_compare(L, 1, LUA_REGISTRYINDEX, LUA_OPEQ)) {
     /* registry */
     pseudo_index = LUA_REGISTRYINDEX;
     XBT_DEBUG("Will get the value from the registry of maestro");
   }
   else {
     /* global */
-    pseudo_index = LUA_GLOBALSINDEX;
+    pseudo_index = lua_getfield(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
     XBT_DEBUG("Will get the value from the globals of maestro");
   }
 
@@ -616,7 +663,8 @@ lua_State* sglua_clone_maestro(void) {
   lua_setmetatable(L, -2);                  /* thread newenv mt reg */
   lua_pop(L, 1);                            /* thread newenv mt */
   lua_setmetatable(L, -2);                  /* thread newenv */
-  lua_setfenv(L, -2);                       /* thread */
+  // TODO c.heinrich This needs to be re-implemented
+  /*lua_setfenv(L, -2);                       [> thread <]*/
   lua_pop(L, 1);                            /* -- */
 
   /* create the table of known tables from maestro */