static void sglua_copy_userdata(lua_State* src, lua_State* dst);
static void sglua_copy_thread(lua_State* src, lua_State* dst);
-/**
- * @brief Returns the father of a state, i.e. the state that created it.
- * @param L a Lua state
- * @return its father, or NULL if the state was not created by sglua_clone_state()
- */
-static lua_State* sglua_get_father(lua_State* L) {
-
- /* ... */
- lua_pushstring(L, "simgrid.father");
- /* ... "simgrid.father" */
- lua_rawget(L, LUA_REGISTRYINDEX);
- /* ... father */
- lua_State* father = lua_touserdata(L, -1);
- lua_pop(L, 1);
- /* ... */
- return father;
-}
-
/**
* @brief Adds a reference to a maestro table to the list of known maestro
* tables of a state.
/* ... */
lua_pushvalue(L, index);
/* ... table */
- lua_getfield(L, LUA_REGISTRYINDEX, "simgrid.maestro_tables");
+ lua_pushstring(L, "simgrid.maestro_tables");
+ /* ... table "simgrid.maestro_tables" */
+ lua_rawget(L, LUA_REGISTRYINDEX);
/* ... table maestrotbs */
lua_pushvalue(L, -2);
/* ... table maestrotbs table */
void* maestro_table_ptr = NULL;
/* ... */
+ lua_pushvalue(L, index);
+ /* ... table */
lua_pushstring(L, "simgrid.maestro_tables");
- /* ... "simgrid.maestro_tables" */
+ /* ... table "simgrid.maestro_tables" */
lua_rawget(L, LUA_REGISTRYINDEX);
- /* ... maestrotbs */
- lua_pushvalue(L, index);
- /* ... maestrotbs table */
+ /* ... table maestrotbs */
+ lua_pushvalue(L, -2);
+ /* ... table maestrotbs table */
lua_gettable(L, -2);
- /* ... maestrotbs tableptr/nil */
+ /* ... table maestrotbs tableptr/nil */
if (!lua_isnil(L, -1)) {
- /* ... maestrotbs tableptr */
+ /* ... table maestrotbs tableptr */
maestro_table_ptr = (void*) lua_topointer(L, -1);
}
- lua_pop(L, 2);
+ lua_pop(L, 3);
/* ... */
return maestro_table_ptr;
}
/**
* @brief Pops a value from the stack of a source state and pushes it on the
* stack of another state.
- *
* If the value is a table, its content is copied recursively.
*
- * TODO: add support of closures
+ * This function is similar to lua_xmove() but it allows to move a value
+ * between two different global states.
*
* @param src the source state (not necessarily maestro)
* @param dst the destination state
table_ptr = (void*) lua_topointer(src, -1);
if (!sglua_is_maestro(src)) {
- XBT_DEBUG("Using a non-maestro table pointer");
+ XBT_DEBUG("%sMaestro does not know this table",
+ sglua_get_spaces(indent));
}
}
- else if (sglua_is_maestro(src)) {
+
+ 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);
+ xbt_assert(sglua_get_maestro_table_ptr(src, -1) == table_ptr);
}
/* to avoid infinite recursion, see if this table is already known by dst */
/* FIXME: we may have added a table with a non-maestro pointer, is this a
problem? */
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);
* @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 (TODO).
+ * Copying upvalues is not implemented yet.
*
* @param src source state
* @param dst destination state
static void sglua_copy_function(lua_State* src, lua_State* dst) {
if (lua_iscfunction(src, -1)) {
- /* it's a C function: just copy the pointer */
- lua_CFunction f = lua_tocfunction(src, -1);
- lua_pushcfunction(dst, f);
+ /* it's a C function */
+
+ XBT_DEBUG("It's a C function");
+ sglua_stack_dump("src before copying upvalues: ", src);
+
+ /* get the function pointer */
+ int function_index = lua_gettop(src);
+ lua_CFunction f = lua_tocfunction(src, function_index);
+
+ /* copy the upvalues */
+ int i = 0;
+ const char* upvalue_name = NULL;
+ do {
+ i++;
+ upvalue_name = lua_getupvalue(src, function_index, i);
+
+ if (upvalue_name != NULL) {
+ XBT_DEBUG("Upvalue %s", upvalue_name);
+ sglua_move_value(src, dst);
+ }
+ } while (upvalue_name != NULL);
+
+ sglua_stack_dump("src before copying pointer: ", src);
+
+ /* set the function */
+ lua_pushcclosure(dst, f, i - 1);
+ XBT_DEBUG("Function pointer copied");
}
else {
/* it's a Lua function: dump it from src */
lua_rawset(L, LUA_REGISTRYINDEX);
/* -- */
- /* open the standard libs (theoretically, this is not necessary as they can
- * be inherited like any global values, but without a proper support of
- * closures, iterators like ipairs don't work). */
- XBT_DEBUG("Metatable of globals and registry set, opening standard libraries now");
- luaL_openlibs(L);
+ /* opening the standard libs is not necessary as they are
+ * be inherited like any global values */
+ /* luaL_openlibs(L); */
XBT_DEBUG("New state created");