aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorame <[email protected]>2025-09-02 22:40:57 -0500
committerame <[email protected]>2025-09-02 22:40:57 -0500
commit2ac674735ba38c655be4f2e473b82974c76cf8c9 (patch)
treef4a83ca32e1a59367c4d41fc4ba8216f62bb82ec
parent6077a4fd2c280de03d8489a93080f24aa49d56a9 (diff)
better local copying (wip)
-rw-r--r--src/lua.c27
-rw-r--r--src/lua.h7
-rw-r--r--src/net.h3
-rw-r--r--src/net/common.h1
-rw-r--r--src/table.c1
-rw-r--r--src/thread.c56
6 files changed, 70 insertions, 25 deletions
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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>
-#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
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 <stdlib.h>
-#define _GNU_SOURCE
#include <string.h>
#include <stdint.h>
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);