From 2ac674735ba38c655be4f2e473b82974c76cf8c9 Mon Sep 17 00:00:00 2001 From: ame Date: Tue, 2 Sep 2025 22:40:57 -0500 Subject: better local copying (wip) --- src/lua.c | 27 +++++++++++++++++++-------- src/lua.h | 7 +++++++ src/net.h | 3 --- src/net/common.h | 1 - src/table.c | 1 - src/thread.c | 56 ++++++++++++++++++++++++++++++++++++++++++++------------ 6 files changed, 70 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/lua.c b/src/lua.c index 4fe9962..6ed46de 100644 --- a/src/lua.c +++ b/src/lua.c @@ -174,7 +174,7 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){ switch(type = lua_type(src, -1)){ case LUA_TNUMBER: n = lua_tonumber(src, -1); - if(n == (uint64_t)n) lua_pushinteger(dest, lua_tonumber(src, -1)); + if(n == (uint64_t)n) lua_pushinteger(dest, (uint64_t)lua_tonumber(src, -1)); else lua_pushnumber(dest, n); break; case LUA_TBOOLEAN: @@ -249,6 +249,7 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){ lua_dump(src, writer, (void*)awa, 0); luaL_loadbuffer(dest, awa->c, awa->len, "fun"); + if(!(flags & SKIP_LOCALS)) lua_assign_upvalues(dest, lua_gettop(dest)); //lua_remove(dest, -2); str_free(awa); break; @@ -387,19 +388,29 @@ void luaI_jointable(lua_State* L){ //copys all variables from state A to B, including locals (stored in _locals) //populates _ENV the same as _G void luaI_copyvars(lua_State* from, lua_State* to){ - lua_getglobal(from, "_G"); - luaI_deepcopy(from, to, SKIP_GC | SKIP__G); - lua_set_global_table(to); + lua_getglobal(from, "_locals"); + int x = lua_gettop(from); - env_table(from, 0); - luaI_deepcopy(from, to, SKIP_GC); + if(lua_isnil(from, x)){ + lua_pop(from, 1); + x = 0; + } + + env_table(from, x != 0); + luaI_deepcopy(from, to, SKIP_GC | SKIP_LOCALS); int idx = lua_gettop(to); lua_pushglobaltable(to); int tidx = lua_gettop(to); luaI_tsetv(to, idx, "_ENV", tidx); - luaI_tsetv(to, tidx, "_locals", idx); + + lua_getglobal(from, "_G"); + luaI_deepcopy(from, to, SKIP_GC | SKIP__G); + lua_set_global_table(to); + + lua_pushvalue(to, idx); + lua_setglobal(to, "_locals"); } /** @@ -452,7 +463,7 @@ int lua_assign_upvalues(lua_State* L, int fidx){ lua_setupvalue(L, fidx, lua_tointeger(L, -2)); } - lua_pushvalue(L, fidx); + lua_settop(L, fidx); return 0; } diff --git a/src/lua.h b/src/lua.h index 2e7aa5e..1d5bea1 100644 --- a/src/lua.h +++ b/src/lua.h @@ -12,6 +12,7 @@ enum deep_copy_flags { SKIP_GC = (1 << 1), IS_META = (1 << 2), SKIP__G = (1 << 3), + SKIP_LOCALS = (1 << 4), }; #endif @@ -38,6 +39,8 @@ typedef int (*stream_free_function)(void**); void luaI_newstream(lua_State* L, stream_read_function, stream_free_function, void*); int luaI_nothing(lua_State*); +int env_table(lua_State* L, int provide_table); +void luaI_jointable(lua_State* L); //generic macro that takes other macros (see below) #define _tset_b(L, Tidx, K, V, F)\ @@ -63,6 +66,10 @@ int luaI_nothing(lua_State*); _tset_b(L, Tidx, K, V, lua_pushcfunction) #define luaI_tsetlud(L, Tidx, K, V)\ _tset_b(L, Tidx, K, V, lua_pushlightuserdata) +#define luaI_tsetnil(L, Tidx, K)\ + lua_pushstring(L, K);\ + lua_pushnil(L);\ + lua_settable(L, Tidx); #define luaI_treplk(L, Tidx, K, nK){\ lua_pushstring(L, K);\ diff --git a/src/net.h b/src/net.h index f7e5d64..9f0fe42 100644 --- a/src/net.h +++ b/src/net.h @@ -38,9 +38,6 @@ void* handle_client(void *_arg); int start_serv(lua_State* L, int port); -// -static char* http_codes[600] = {0}; - int clean_lullaby_net(lua_State* L); static const luaL_Reg net_function_list [] = { diff --git a/src/net/common.h b/src/net/common.h index 947eee7..fbafb58 100644 --- a/src/net/common.h +++ b/src/net/common.h @@ -5,7 +5,6 @@ #include #include #include -#define _GNU_SOURCE #include #include #include diff --git a/src/table.c b/src/table.c index 9caca0b..418da3a 100644 --- a/src/table.c +++ b/src/table.c @@ -1,6 +1,5 @@ #include "table.h" #include -#define _GNU_SOURCE #include #include diff --git a/src/thread.c b/src/thread.c index 5aed694..bb412ba 100644 --- a/src/thread.c +++ b/src/thread.c @@ -207,12 +207,28 @@ int _thread_await(lua_State* L){ if(!info->done) pthread_mutex_lock(&*info->lock); info->done = 1; + env_table(info->L, 0); + luaI_deepcopy(info->L, L, SKIP_LOCALS); + lua_pop(info->L, 1); + env_table(L, 0); + luaI_jointable(L); + + lua_setglobal(L, "_locals"); + for(int i = 0; i != info->return_count; i++){ int ot = lua_gettop(info->L); lua_pushvalue(info->L, ot - info->return_count + i); + luaI_deepcopy(info->L, L, 0); - + + int type = lua_type(info->L, ot - info->return_count + i); + if(type == LUA_TTABLE || type == LUA_TUSERDATA){ + lua_getmetatable(info->L, ot - info->return_count + i); + int idx = lua_gettop(info->L); + luaI_tsetnil(info->L, idx, "__gc"); + } + lua_settop(info->L, ot); } @@ -224,18 +240,19 @@ int _thread_clean(lua_State* L){ lua_gettable(L, 1); struct thread_info* info = lua_touserdata(L, -1); if(info != NULL && info->L != NULL){ - + luaI_tsetnil(L, 1, "_"); + //lua_gc(info->L, LUA_GCRESTART); lua_gc(info->L, LUA_GCCOLLECT); + lua_close(info->L); + info->L = NULL; pthread_mutex_destroy(&*info->lock); free(info->lock); pthread_cancel(info->tid); free(info); - - luaI_tsetlud(L, 1, "_", NULL); } return 0; } @@ -295,7 +312,7 @@ struct thread_buffer { int _buffer_get(lua_State* L){ struct thread_buffer *buffer = lua_touserdata(L, 1); pthread_mutex_lock(&*buffer->lock); - luaI_deepcopy(buffer->L, L, SKIP_GC); + luaI_deepcopy(buffer->L, L, SKIP_GC | SKIP_LOCALS); pthread_mutex_unlock(&*buffer->lock); return 1; } @@ -304,8 +321,13 @@ int _buffer_set(lua_State* L){ struct thread_buffer *buffer = lua_touserdata(L, 1); pthread_mutex_lock(&*buffer->lock); lua_settop(buffer->L, 0); - luaI_deepcopy(L, buffer->L, SKIP_GC); + luaI_deepcopy(L, buffer->L, SKIP_LOCALS); pthread_mutex_unlock(&*buffer->lock); + + lua_getmetatable(L, 2); + int idx = lua_gettop(L); + luaI_tsetnil(L, idx, "__gc"); + return 1; } @@ -319,15 +341,20 @@ int _buffer_mod(lua_State* L){ assert(used == 0); used = 1; - luaI_deepcopy(buffer->L, L, SKIP_GC); + luaI_deepcopy(buffer->L, L, SKIP_GC | SKIP_LOCALS); int item = lua_gettop(L); lua_pushvalue(L, 2); lua_pushvalue(L, item); lua_call(L, 1, 1); if(lua_type(L, -1) != LUA_TNIL){ + int idx = lua_gettop(L); lua_settop(buffer->L, 0); - luaI_deepcopy(L, buffer->L, SKIP_GC); + luaI_deepcopy(L, buffer->L, SKIP_LOCALS); + + lua_getmetatable(L, idx); + idx = lua_gettop(L); + luaI_tsetnil(L, idx, "__gc"); } used = 0; @@ -362,7 +389,7 @@ int l_buffer_index(lua_State* L){ return 1; } - luaI_deepcopy(buffer->L, L, SKIP_GC); + luaI_deepcopy(buffer->L, L, SKIP_GC | SKIP_LOCALS); lua_pop(buffer->L, 1); break; } @@ -389,12 +416,12 @@ int meta_proxy(lua_State* L){ for(int i = 4; i <= argc; i++){ count++; lua_pushvalue(L, i); - luaI_deepcopy(L, buffer->L, SKIP_GC); + luaI_deepcopy(L, buffer->L, SKIP_GC | SKIP_LOCALS); } //printf("%i\n",count); lua_call(buffer->L, count + 1, 1); - luaI_deepcopy(buffer->L, L, 0); + luaI_deepcopy(buffer->L, L, SKIP_LOCALS); lua_pushnil(buffer->L); lua_setmetatable(buffer->L, -2); @@ -453,10 +480,11 @@ int l_buffer(lua_State* L){ int buffer_idx = lua_gettop(L); buffer->L = luaL_newstate(); + lua_gc(buffer->L, LUA_GCSTOP); buffer->lock = malloc(sizeof * buffer->lock); if(pthread_mutex_init(&*buffer->lock, NULL) != 0) p_fatal("pthread_mutex_init failed"); lua_pushvalue(L, 1); - luaI_deepcopy(L, buffer->L, SKIP_GC); + luaI_deepcopy(L, buffer->L, SKIP_LOCALS); lua_newtable(L); int meta_idx = lua_gettop(L); @@ -464,6 +492,10 @@ int l_buffer(lua_State* L){ luaI_tsetcf(L, meta_idx, "__index", l_buffer_index); luaI_tsetcf(L, meta_idx, "__gc", l_buffer_gc); + lua_getmetatable(L, 1); + int idx = lua_gettop(L); + luaI_tsetnil(L, idx, "__gc"); + lua_pushvalue(L, meta_idx); lua_setmetatable(L, buffer_idx); lua_pushvalue(L, buffer_idx); -- cgit v1.2.3