From: Christophe ThiƩry Date: Thu, 6 Oct 2011 14:26:52 +0000 (+0200) Subject: Lua: add support of closures to the state cloner X-Git-Tag: exp_20120216~558^2~15^2~1 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/9c13b98a571f44f7f2faf7193a60ce7e94a82094?hp=39f91e9db08a54b8c87c8f835079427725518fe7 Lua: add support of closures to the state cloner --- diff --git a/examples/lua/masterslave/slave.lua b/examples/lua/masterslave/slave.lua index 9c257c479b..9ecddc6a3e 100644 --- a/examples/lua/masterslave/slave.lua +++ b/examples/lua/masterslave/slave.lua @@ -6,6 +6,7 @@ function Slave(...) local my_mailbox="slave "..arg[1] simgrid.info("Hello from lua, I'm a poor slave with mbox: "..my_mailbox) + while true do local tk = simgrid.Task.recv(my_mailbox); diff --git a/src/bindings/lua/lua_state_cloner.c b/src/bindings/lua/lua_state_cloner.c index e5789ec625..4e35f184dd 100644 --- a/src/bindings/lua/lua_state_cloner.c +++ b/src/bindings/lua/lua_state_cloner.c @@ -126,10 +126,10 @@ static void sglua_get_table_by_ptr(lua_State* L, void* 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 @@ -377,9 +377,33 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) { 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 */ @@ -584,11 +608,9 @@ lua_State* sglua_clone_maestro(void) { 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"); diff --git a/src/bindings/lua/simgrid_lua.c b/src/bindings/lua/simgrid_lua.c index 611b475420..5fdd7c1618 100644 --- a/src/bindings/lua/simgrid_lua.c +++ b/src/bindings/lua/simgrid_lua.c @@ -8,6 +8,7 @@ #include "simgrid_lua.h" #include "lua_state_cloner.h" +#include "lua_utils.h" XBT_LOG_NEW_DEFAULT_CATEGORY(lua, "Lua Bindings"); @@ -23,24 +24,26 @@ static lua_State *lua_maestro_state; static void register_c_functions(lua_State *L); -/* static void *my_checkudata (lua_State *L, int ud, const char *tname) { + + XBT_DEBUG("Checking the task: ud = %d", ud); + sglua_stack_dump("my_checkudata: ", L); void *p = lua_touserdata(L, ud); lua_getfield(L, LUA_REGISTRYINDEX, tname); const void* correct_mt = lua_topointer(L, -1); int has_mt = lua_getmetatable(L, ud); + XBT_DEBUG("Checking the task: has metatable ? %d", has_mt); const void* actual_mt = NULL; if (has_mt) { actual_mt = lua_topointer(L, -1); lua_pop(L, 1); } XBT_DEBUG("Checking the task's metatable: expected %p, found %p", correct_mt, actual_mt); - stack_dump("my_checkudata: ", L); + sglua_stack_dump("my_checkudata: ", L); if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2)) luaL_typerror(L, ud, tname); lua_pop(L, 2); return p; } -*/ /** * @brief Ensures that a userdata on the stack is a task @@ -52,6 +55,7 @@ static void *my_checkudata (lua_State *L, int ud, const char *tname) { static m_task_t checkTask(lua_State * L, int index) { m_task_t *pi, tk; + XBT_DEBUG("Lua task: %s", sglua_tostring(L, index)); luaL_checktype(L, index, LUA_TTABLE); lua_getfield(L, index, "__simgrid_task");