From 237fcfbd61a9895326538a274f025d9ed57a3903 Mon Sep 17 00:00:00 2001 From: ame Date: Sat, 25 May 2024 04:08:59 -0500 Subject: fixed deepcopy --- src/io.c | 2 +- src/lua.c | 108 ++++++++++++++++++++++++++--------------------------------- src/lua.h | 2 +- src/net.c | 2 +- src/thread.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++--- src/thread.h | 4 +++ 6 files changed, 148 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/io.c b/src/io.c index 06fa535..d86283d 100644 --- a/src/io.c +++ b/src/io.c @@ -137,7 +137,7 @@ void i_pprint(lua_State* L, int indent, int skip_indent){ break; case LUA_TFUNCTION: if(!skip_indent) print_indentation(indent); - printf(color_yellow"(%p)"color_reset, lua_topointer(L, -1)); + printf(color_yellow"(fn,%p)"color_reset, lua_topointer(L, -1)); break; case LUA_TUSERDATA: if(!skip_indent) print_indentation(indent); diff --git a/src/lua.c b/src/lua.c index 868d253..05489e1 100644 --- a/src/lua.c +++ b/src/lua.c @@ -40,8 +40,9 @@ int writer(lua_State *L, const void* p, size_t sz, void* ud){ * @param {lua_State*} source * @param {lua_State*} dest * @param {void*} items already visited, use NULL + * @param {int} whether or not to skip meta data */ -void i_dcopy(lua_State* src, lua_State* dest, void* _seen){ +void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){ parray_t* seen = (parray_t*)_seen; int wnull = seen == NULL; if(wnull) seen = parray_init(); @@ -54,7 +55,8 @@ void i_dcopy(lua_State* src, lua_State* dest, void* _seen){ void* whar; double n; int old_top = lua_gettop(src); - //printf("%i\n",ii++); + int modi = 0; + switch(lua_type(src, -1)){ case LUA_TNUMBER: n = luaL_checknumber(src, -1); @@ -66,96 +68,82 @@ void i_dcopy(lua_State* src, lua_State* dest, void* _seen){ lua_pushlstring(dest, s, len); break; case LUA_TTABLE: + modi = 1; lua_newtable(dest); at = lua_gettop(dest); at2 = lua_gettop(src); char aauwu[50] = {0}; sprintf(aauwu, "%p", lua_topointer(src, at2)); - //int* sp = malloc(1); whar = parray_get(seen, aauwu); - if( whar != NULL){ - //printf("%s\n",lua_tostring(src, at2 - 1)); - //printf("WHAR\n"); + if(whar != NULL){ lua_pop(dest, 1); lua_rawgeti(dest, LUA_REGISTRYINDEX, *(int*)whar); - - return; } int *sp = malloc(sizeof * sp); - //lua_pushinteger(dest, 55); int r = luaL_ref(dest, LUA_REGISTRYINDEX); lua_rawgeti(dest, LUA_REGISTRYINDEX, r); *sp = r; parray_set(seen, aauwu, sp); - //printf("saved %i\n", *sp); - //for(int i = 0; i != seen->len; i++){ - // printf("%i ", *(int*)seen->P[i].value); - //} lua_pushnil(src); for(;lua_next(src, at2) != 0;){ - lua_pushvalue(src, -2); - int a = lua_gettop(src); - //l_pprint(src); - lua_settop(src, a); - i_dcopy(src, dest, seen); - - lua_pushvalue(src, -2); - i_dcopy(src, dest, seen); - + int first, second = first = lua_gettop(src); + first -= 1; + lua_pushvalue(src, first); + luaI_deepcopy(src, dest, seen, 0); + + lua_pushvalue(src, second); + luaI_deepcopy(src, dest, seen, 0); lua_settable(dest, at); + lua_pop(src, 3); } - //printf("done\n"); - //lua_settop(dest, at); break; case LUA_TFUNCTION: - if(lua_iscfunction(src, old_top)){ - //kinda silly - lua_pushcfunction(dest, lua_tocfunction(src, -1)); - break; - } + if(lua_iscfunction(src, old_top)){ + //kinda silly + lua_pushcfunction(dest, lua_tocfunction(src, -1)); + break; + } - str* awa = str_init(""); - lua_dump(src, writer, (void*)awa, 0); - lua_pushlstring(dest, awa->c, awa->len); + str* awa = str_init(""); + lua_dump(src, writer, (void*)awa, 0); + lua_pushlstring(dest, awa->c, awa->len); - luaL_loadbuffer(dest, awa->c, awa->len, awa->c); - lua_remove(dest, -2); - str_free(awa); - //lua_pushvalue(dest, -1); - break; + luaL_loadbuffer(dest, awa->c, awa->len, awa->c); + lua_remove(dest, -2); + str_free(awa); + break; case LUA_TUSERDATA: + modi = 1; + size_t raw_len = lua_rawlen(src, -1); + void* ud = lua_newuserdata(dest, raw_len); + memcpy(ud, lua_touserdata(src, -1), raw_len); + break; case LUA_TLIGHTUSERDATA: - lua_pushlightuserdata(dest, lua_touserdata(src, -1)); - int tidx = lua_gettop(dest); - - if(lua_getmetatable(src, -1)){ - //int a = lua_gettop(src); - //l_pprint(src); - //lua_settop(src, a); - //printf("**--**\n"); - i_dcopy(src, dest, seen); - //int a = lua_gettop(dest); - //l_pprint(dest); - //lua_settop(dest, a); - lua_setmetatable(dest, tidx); - lua_pop(src, 1); - } - lua_settop(dest, tidx); - //printf("aww\n"); - //lua_pushnumber(dest, 8); - break; + modi = 1; + lua_pushlightuserdata(dest, lua_touserdata(src, -1)); + break; default: - printf("%i\n",lua_type(src, -1)); - lua_pushnil(dest); - break; + printf("unknown type %i\n",lua_type(src, -1)); + lua_pushnil(dest); + break; } + int tidx = lua_gettop(dest); + int aa = lua_gettop(src); + + if(modi&&!skip_meta&&lua_getmetatable(src, -1)){ + luaI_deepcopy(src, dest, seen, 1); + lua_setmetatable(dest, tidx); + + lua_settop(dest, tidx); + } + lua_settop(src, aa); + if(wnull) parray_clear(seen, FREE); - //lua_settop(src, old_top); _seen = seen; } diff --git a/src/lua.h b/src/lua.h index bd0da87..6cb28a7 100644 --- a/src/lua.h +++ b/src/lua.h @@ -6,7 +6,7 @@ void* __malloc_(size_t); void __free_(void*); -void i_dcopy(lua_State* src, lua_State* dest, void*); +void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int); void lua_set_global_table(lua_State*); //generic macro that takes other macros (see below) diff --git a/src/net.c b/src/net.c index 486f44a..36deb0f 100644 --- a/src/net.c +++ b/src/net.c @@ -754,7 +754,7 @@ void* handle_client(void *_arg){ lua_getglobal(args->L, "_G"); //time_start(copy) - i_dcopy(args->L, L, NULL); + luaI_deepcopy(args->L, L, NULL, 0); //time_end("copy", copy) lua_settop(args->L, old_top); diff --git a/src/thread.c b/src/thread.c index dd4052a..dec9ceb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -9,6 +9,7 @@ #include "util.h" #include "types/larray.h" +#include "hash/fnv.h" struct thread_info { str* function; @@ -96,7 +97,7 @@ int l_res(lua_State* L){ int ot = lua_gettop(L); lua_pushvalue(L, 2 + i); - i_dcopy(L, info->L, NULL); + luaI_deepcopy(L, info->L, NULL, 0); lua_settop(L, ot); } @@ -148,7 +149,7 @@ int l_await(lua_State* L){ int ot = lua_gettop(info->L); lua_pushvalue(info->L, ot - info->return_count + i); - i_dcopy(info->L, L, NULL); + luaI_deepcopy(info->L, L, NULL, 0); lua_settop(info->L, ot); } @@ -177,10 +178,10 @@ int l_clean(lua_State* L){ int l_async(lua_State* oL){ lua_State* L = luaL_newstate(); - luaL_openlibs(L); + //luaL_openlibs(L); lua_getglobal(oL, "_G"); - i_dcopy(oL, L, NULL); + luaI_deepcopy(oL, L, NULL, 0); lua_set_global_table(L); struct thread_info* args = calloc(1, sizeof * args); @@ -211,3 +212,91 @@ int l_async(lua_State* oL){ lua_pushvalue(oL, res_idx); return 1; } + +struct thread_buffer { + lua_State* L; + pthread_mutex_t lock; +}; + +int _buffer_get(lua_State* L){ + struct thread_buffer *buffer = lua_touserdata(L, 1); + pthread_mutex_lock(&buffer->lock); + luaI_deepcopy(buffer->L, L, NULL, 0); + pthread_mutex_unlock(&buffer->lock); + return 1; +} + +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, NULL, 0); + pthread_mutex_unlock(&buffer->lock); + return 1; +} + +int _buffer_mod(lua_State* L){ + struct thread_buffer *buffer = lua_touserdata(L, 1); + pthread_mutex_lock(&buffer->lock); + luaI_deepcopy(buffer->L, L, NULL, 0); + 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){ + lua_settop(buffer->L, 0); + luaI_deepcopy(L, buffer->L, NULL, 0); + } + pthread_mutex_unlock(&buffer->lock); + return 1; +} + + +int l_buffer_index(lua_State* L){ + uint64_t len, hash; + const char* str = luaL_tolstring(L, 2, &len); + + hash = fnv_1((uint8_t*)str, len, v_1); + + switch(hash){ + case 0xd8c8ad186b9ed323: //get + lua_pushcfunction(L, _buffer_get); + break; + case 0xd89f9d186b7bb367: //set + lua_pushcfunction(L, _buffer_set); + break; + case 0xd8b3c7186b8ca31f: //mod + lua_pushcfunction(L, _buffer_mod); + break; + default: + lua_pushnil(L); + break; + } + return 1; +} + +int l_buffer(lua_State* L){ + struct thread_buffer *buffer = malloc(sizeof * buffer); + buffer->L = luaL_newstate(); + pthread_mutex_init(&buffer->lock, NULL); + luaI_deepcopy(L, buffer->L, NULL, 0); + + lua_newtable(L); + int meta_idx = lua_gettop(L); + luaI_tsetcf(L, meta_idx, "__index", l_buffer_index); + + lua_pushlightuserdata(L, buffer); + lua_pushvalue(L, meta_idx); + lua_setmetatable(L, -2); + + return 1; +} + +int l_testcopy(lua_State* L){ + lua_State* temp = luaL_newstate(); + luaI_deepcopy(L, temp, NULL, 0); + luaI_deepcopy(temp, L, NULL, 0); + + return 1; +} diff --git a/src/thread.h b/src/thread.h index 9dab9b1..b83db4c 100644 --- a/src/thread.h +++ b/src/thread.h @@ -3,6 +3,8 @@ int l_async(lua_State*); int l_tlock(lua_State*); int l_tunlock(lua_State*); +int l_buffer(lua_State*); +int l_testcopy(lua_State*); void lib_thread_clean(); @@ -10,5 +12,7 @@ static const luaL_Reg thread_function_list [] = { {"async",l_async}, {"lock",l_tlock}, {"unlock",l_tunlock}, + {"buffer",l_buffer}, + {"testcopy",l_testcopy}, {NULL,NULL} }; -- cgit v1.2.3