- luaL_register(L, "simgrid", simgrid_functions);
-
- /* register the task methods to lua */
- luaL_openlib(L, TASK_MODULE_NAME, task_functions, 0); // create methods table, add it to the globals
- luaL_newmetatable(L, TASK_MODULE_NAME); // create metatable for Task, add it to the Lua registry
- luaL_openlib(L, 0, task_meta, 0); // fill metatable
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, -3); // dup methods table
- lua_rawset(L, -3); // metatable.__index = methods
- lua_pushliteral(L, "__metatable");
- lua_pushvalue(L, -3); // dup methods table
- lua_rawset(L, -3); // hide metatable:metatable.__metatable = methods
- lua_pop(L, 1); // drop metatable
-
- /* register the hosts methods to lua */
- luaL_openlib(L, HOST_MODULE_NAME, host_functions, 0);
- luaL_newmetatable(L, HOST_MODULE_NAME);
- luaL_openlib(L, 0, host_meta, 0);
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, -3);
- lua_rawset(L, -3);
- lua_pushliteral(L, "__metatable");
- lua_pushvalue(L, -3);
- lua_rawset(L, -3);
- lua_pop(L, 1);
-
- /* register the platform methods to lua */
- luaL_openlib(L, PLATF_MODULE_NAME, platf_functions, 0);
- luaL_newmetatable(L, PLATF_MODULE_NAME);
- lua_pop(L, 1);
+ luaL_newlib(L, simgrid_functions); /* simgrid */
+ lua_pushvalue(L, -1); /* simgrid simgrid */
+ lua_setglobal(L, "simgrid"); /* simgrid */
+
+ /* set a finalizer that cleans simgrid, by adding to the simgrid module a
+ * dummy userdata whose __gc metamethod calls MSG_clean() */
+ lua_newuserdata(L, sizeof(void*)); /* simgrid udata */
+ lua_newtable(L); /* simgrid udata mt */
+ lua_pushcfunction(L, simgrid_gc); /* simgrid udata mt simgrid_gc */
+ lua_setfield(L, -2, "__gc"); /* simgrid udata mt */
+ lua_setmetatable(L, -2); /* simgrid udata */
+ lua_setfield(L, -2, "__simgrid_loaded"); /* simgrid */
+ lua_pop(L, 1); /* -- */
+}
+
+/**
+ * \brief Creates the simgrid module and make it available to Lua.
+ * \param L a Lua world
+ */
+static void sglua_register_c_functions(lua_State *L)
+{
+ sglua_register_core_functions(L);
+ sglua_register_task_functions(L);
+ sglua_register_comm_functions(L);
+ sglua_register_host_functions(L);
+ sglua_register_process_functions(L);
+ sglua_register_platf_functions(L);
+}
+
+/**
+ * \brief Runs a Lua function as a new simulated process.
+ * \param argc number of arguments of the function
+ * \param argv name of the Lua function and array of its arguments
+ * \return result of the function
+ */
+static int run_lua_code(int argc, char **argv)
+{
+ XBT_DEBUG("Run lua code %s", argv[0]);
+
+ /* create a new state, getting globals from maestro */
+ lua_State *L = sglua_clone_maestro();
+ MSG_process_set_data(MSG_process_self(), L);
+
+ /* start the function */
+ lua_getglobal(L, argv[0]);
+ xbt_assert(lua_isfunction(L, -1),
+ "There is no Lua function with name `%s'", argv[0]);
+
+ /* push arguments onto the stack */
+ int i;
+ for (i = 1; i < argc; i++)
+ lua_pushstring(L, argv[i]);
+
+ /* call the function */
+ XBT_ATTRIB_UNUSED int err;
+ err = lua_pcall(L, argc - 1, 1, 0);
+ xbt_assert(err == 0, "Error running function `%s': %s", argv[0],
+ lua_tostring(L, -1));
+
+ /* retrieve result */
+ int res = 1;
+ if (lua_isnumber(L, -1)) {
+ res = lua_tointeger(L, -1);
+ lua_pop(L, 1); /* pop returned value */
+ }
+
+ XBT_DEBUG("Execution of Lua code %s is over", (argv ? argv[0] : "(null)"));
+
+ return res;
+}
+
+/**
+ * \brief Returns a string corresponding to an MSG error code.
+ * \param err an MSG error code
+ * \return a string describing this error
+ */
+const char* sglua_get_msg_error(msg_error_t err) {
+
+ static const char* msg_errors[] = {
+ NULL,
+ "timeout",
+ "transfer failure",
+ "host failure",
+ "task canceled"
+ };
+
+ return msg_errors[err];