aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/io.c2
-rw-r--r--src/lua.c108
-rw-r--r--src/lua.h2
-rw-r--r--src/net.c2
-rw-r--r--src/thread.c97
-rw-r--r--src/thread.h4
6 files changed, 148 insertions, 67 deletions
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}
};