+ {
+ /* copy the data */
+ /* src: ... udata
+ dst: visited ... */
+ size_t size = lua_objlen(src, -1);
+ void* src_block = lua_touserdata(src, -1);
+ void* dst_block = lua_newuserdata(dst, size);
+ /* dst: visited ... udata */
+ memcpy(dst_block, src_block, size);
+
+ /* copy the metatable if any */
+ int has_meta_table = lua_getmetatable(src, -1);
+ /* src: ... udata mt? */
+ if (has_meta_table) {
+ XBT_DEBUG("%sCopying metatable of userdata (%p)", get_spaces(indent),
+ lua_topointer(src, -1));
+ /* src: ... udata mt */
+ lua_State* father = get_father(dst);
+
+ if (father != NULL) {
+ XBT_DEBUG("%sGet the metatable from my father", get_spaces(indent));
+ /* find the same metatable in the father state */
+ /* TODO find in visited_tables of src the pointer to the same
+ * metatable in the father world, then copy the metatable from the
+ * father world into dst
+ */
+ lua_pushstring(father, "simgrid.visited_tables");
+ /* father: ... "simgrid.visited_tables" */
+ lua_rawget(father, LUA_REGISTRYINDEX);
+ /* father: ... visited */
+ lua_pushlightuserdata(father, (void*) lua_topointer(src, -1));
+ /* father: ... visited pfathermt */
+ lua_gettable(father, -2);
+ /* father: ... visited mt */
+ move_value_impl(father, dst, "(father metatable)");
+ /* father: ... visited
+ dst: visited ... udata mt */
+ lua_pop(father, 1);
+ /* father: ... */
+ }
+ else {
+ XBT_DEBUG("%sI have no father", get_spaces(indent));
+ move_value_impl(src, dst, "metatable");
+ /* src: ... udata
+ dst: visited ... udata mt */
+ }
+ lua_setmetatable(dst, -2);
+ /* dst: visited ... udata */
+
+ XBT_DEBUG("%sMetatable of userdata copied", get_spaces(indent));
+ }
+ else {
+ XBT_DEBUG("%sNo metatable for this userdata", get_spaces(indent));
+ /* src: ... udata */
+ }
+ }
+ break;