From 98d81e701a3e6c75b932ac75c872ae0e3f4d84f4 Mon Sep 17 00:00:00 2001 From: amelia squires Date: Mon, 14 Apr 2025 14:03:08 -0500 Subject: config change, local support, overall fixes --- src/config.c | 115 ++++++++++++++++++++++++++++++++++++++++------------------ src/config.h | 52 +++++++++++++-------------- src/crypto.h | 7 +++- src/io.c | 10 +++++- src/io.h | 20 +++++++++++ src/lua.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/lua.h | 8 ++++- src/math.h | 5 +++ src/net.c | 6 ++-- src/net.h | 5 +++ src/reg.c | 9 +++-- src/table.h | 5 +++ src/test.c | 12 +++++-- src/test.h | 9 ++++- src/thread.c | 9 +++-- src/thread.h | 5 +++ 16 files changed, 316 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/config.c b/src/config.c index bbbfa19..ad21b0c 100644 --- a/src/config.c +++ b/src/config.c @@ -2,42 +2,89 @@ #include "io.h" #include -int _print_type = 0; -int _max_depth = 2; -int _start_nl_at = 3; -int _collapse_all = 0; -int _collapse_to_memory = 1; -int _print_meta = 0; - -int _file_malloc_chunk = 512; - -int get_config_map(const char* key){ - for(int i = 0; config_map[i].key != NULL; i++){ - if(strcmp(config_map[i].key,key) == 0) return i; +int m_config_index(lua_State* L){ + lua_pushstring(L, "_config"); + lua_gettable(L, 1); + struct config* conf = lua_touserdata(L, -1); + int at = 0; + struct config cc; + + for(;;at++){ + cc = conf[at]; + + if(cc.type == c_none){ + lua_pushnil(L); + return 1; + } + + if(strcmp(cc.name, lua_tostring(L, 2)) == 0) { + break; + } } - return -1; + + switch(cc.type){ + case c_int: + lua_pushinteger(L, *cc.value.c_int); + break; + case c_string: + lua_pushlstring(L, *cc.value.c_string, *cc.value.len); + break; + case c_number: + lua_pushnumber(L, *cc.value.c_number); + break; + case c_none:; + } + + return 1; } -int l_set(lua_State* L) { - luaL_checktype(L, 1, LUA_TTABLE); - get_config_map("print_type"); - lua_pushnil(L); - for(;lua_next(L,1) != 0;){ - int ind = get_config_map(lua_tostring(L,-2)); - - if(ind != -1) { - int key; - if(lua_isboolean(L, -1)){ - key = lua_toboolean(L, -1); - } else { - key = lua_tonumber(L, -1); - } - *config_map[ind].value = key; - //lua_pushnumber(L, 1); - //return 1; - } - lua_pop(L,1); +int m_config_newindex(lua_State* L){ + lua_pushstring(L, "_config"); + lua_gettable(L, 1); + struct config* conf = lua_touserdata(L, -1); + int at = 0; + struct config cc; + + for(;;at++){ + cc = conf[at]; + + if(cc.type == c_none){ + lua_pushnil(L); + return 1; } - lua_pushnumber(L, 0); - return 1; + + if(strcmp(cc.name, lua_tostring(L, 2)) == 0) { + break; + } + } + + switch(cc.type){ + case c_int: + *cc.value.c_int = lua_tointeger(L, 3); + break; + case c_string: + *cc.value.c_string = (char*)luaL_tolstring(L, 3, cc.value.len); + break; + case c_number: + *cc.value.c_number = lua_tonumber(L, 3); + break; + case c_none:; + } + + return 1; +}; + +int i_config_metatable(lua_State* L, struct config* conf){ + int idx = lua_gettop(L); + luaI_tsetlud(L, idx, "_config", conf); + + lua_newtable(L); + int meta_idx = lua_gettop(L); + luaI_tsetcf(L, meta_idx, "__index", m_config_index); + luaI_tsetcf(L, meta_idx, "__newindex", m_config_newindex); + + lua_pushvalue(L, meta_idx); + lua_setmetatable(L, idx); + + return 1; } diff --git a/src/config.h b/src/config.h index 74efc15..f09af91 100644 --- a/src/config.h +++ b/src/config.h @@ -1,34 +1,34 @@ #include "lua.h" +#ifndef _config_h +#define _config_h -extern int _print_type; -extern int _max_depth; -extern int _start_nl_at; -extern int _collapse_all; -extern int _collapse_to_memory; -extern int _print_meta; - -extern int _file_malloc_chunk; - -struct str_to_int { - const char* key; - int* value; +enum config_type { + c_none, + c_string, + c_int, + c_number, + //c_function, + //c_table }; -static struct str_to_int config_map[] = { - {"file_chunksize", &_file_malloc_chunk}, - {"print_type", &_print_type}, - {"max_depth", &_max_depth}, - {"collapse_all", &_collapse_all}, - {"start_nl_at", &_start_nl_at}, - {"collapse_to_memory", &_collapse_to_memory}, - {"print_meta", &_print_meta}, - {NULL,NULL} +struct config { + const char* name; + enum config_type type; + + //a single value will be valid, all other are undefined (except len which will be valid for c_string and c_function) + struct value { + char** c_string; + int* c_int; + float* c_number; + char** c_function; + //location of table in lua registery + int* c_table_idx; + //length used for c_string or c_function + size_t* len; + } value; }; -int l_set(lua_State*); +int i_config_metatable(lua_State*, struct config[]); -static const luaL_Reg config_function_list [] = { - {"set",l_set}, - {NULL,NULL} -}; +#endif diff --git a/src/crypto.h b/src/crypto.h index bfc3b57..b7f342e 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -32,6 +32,8 @@ #include "encode/base64.h" #include "encode/baseN.h" +#include "config.h" + uint8_t rotl8(uint8_t, uint8_t); uint16_t rotl16(uint16_t, uint16_t); unsigned rotl32(unsigned, unsigned); @@ -93,7 +95,7 @@ int _##luaname##_common_hash(lua_State* L){\ *a = initf;\ int ini = lua_gettop(L);\ lua_newtable(L);\ - luaI_tsetlud(L, LUA_REGISTRYINDEX, "__", lua_topointer(L, ud));\ + luaI_tsetlud(L, LUA_REGISTRYINDEX, "__", (void*)lua_topointer(L, ud));\ int i;\ for(i = ud; i != ini; i++) luaI_tsetv(L, ini + 1, lua_topointer(L, i), i);\ lua_common_hash_meta_def(luaname);\ @@ -176,3 +178,6 @@ static const luaL_Reg crypto_function_list [] = { {NULL,NULL} }; +static struct config crypto_config[] = { + {.type = c_none} +}; diff --git a/src/io.c b/src/io.c index 97c7e33..6cc9e50 100644 --- a/src/io.c +++ b/src/io.c @@ -4,10 +4,18 @@ #include "io.h" #include "stdlib.h" #include "stdio.h" -#include "config.h" #include "stdint.h" #include "table.h" +int _print_type = 0; +int _max_depth = 2; +int _start_nl_at = 3; +int _collapse_all = 0; +int _collapse_to_memory = 1; +int _print_meta = 0; + +int _file_malloc_chunk = 512; + int l_readfile(lua_State* L){ size_t len; char* a = (char*)luaL_checklstring(L, 1, &len); diff --git a/src/io.h b/src/io.h index 21e14d0..36702f9 100644 --- a/src/io.h +++ b/src/io.h @@ -1,4 +1,5 @@ #include "lua.h" +#include "config.h" #define color_black "\e[30m" #define color_red "\e[31m" @@ -28,6 +29,25 @@ int l_arg_handle(lua_State*); int l_json_parse(lua_State*); +extern int _file_malloc_chunk; +extern int _print_type; +extern int _max_depth; +extern int _start_nl_at; +extern int _collapse_all; +extern int _collapse_to_memory; +extern int _print_meta; + +static struct config io_config[] = { + {.name = "filechunksize", .type = c_int, .value = {.c_int = &_file_malloc_chunk}}, + {.name = "print_type", .type = c_int, .value = {.c_int = &_print_type}}, + {.name = "max_depth", .type = c_int, .value = {.c_int = &_max_depth}}, + {.name = "start_nl_at", .type = c_int, .value = {.c_int = &_start_nl_at}}, + {.name = "collapse_all", .type = c_int, .value = {.c_int = &_collapse_all}}, + {.name = "collapse_to_memory", .type = c_int, .value = {.c_int = &_collapse_to_memory}}, + {.name = "print_meta", .type = c_int, .value = {.c_int = &_print_meta}}, + {.type = c_none} +}; + static const luaL_Reg io_function_list [] = { {"readfile",l_readfile}, {"debug",l_debug}, diff --git a/src/lua.c b/src/lua.c index d41ee91..b87682d 100644 --- a/src/lua.c +++ b/src/lua.c @@ -97,8 +97,12 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){ for(;lua_next(src, at2) != 0;){ int first, second = first = lua_gettop(src); first -= 1; - if((flags & SKIP_GC) && lua_type(src, first) == LUA_TSTRING - && strcmp("__gc", lua_tostring(src, first)) == 0){ + //this is a mess, skip if key is __gc (when SKIP_GC) + //and skip _G (when SKIP__G) + if(((flags & SKIP__G) && lua_type(src, first) == LUA_TSTRING + && strcmp("_G", lua_tostring(src, first)) == 0) + || ((flags & SKIP_GC) && lua_type(src, first) == LUA_TSTRING + && strcmp("__gc", lua_tostring(src, first)) == 0)){ //printf("found %s\n", lua_tostring(src, first)); lua_pop(src, 1); continue; @@ -215,6 +219,71 @@ void luaI_deepcopy2(lua_State* src, lua_State* dest){ } } +int env_table(lua_State* L, int provide_table){ + if(provide_table == 0){ + lua_newtable(L); + } + int tidx = lua_gettop(L); + + lua_Debug debug; + for(int i = 0;; i++){ + if(lua_getstack(L, i, &debug) == 0) break; + for(int idx = 1;; idx++){ + const char* name = lua_getlocal(L, &debug, idx); + int val = lua_gettop(L); + if(name == NULL) break; + + lua_pushstring(L, name); + lua_gettable(L, tidx); + //all temporary (non-local variables) should start with '(' + if(!lua_isnil(L, -1) || name[0] == '('){ + lua_pop(L, 2); + continue; + } + + luaI_tsetv(L, tidx, name, val); + lua_pop(L, 2); + } + } + + //luaI_tseti(L, tidx, "hii", 234); + + return 1; +} + +//top table is prioritized +void luaI_jointable(lua_State* L){ + int idx = lua_gettop(L) - 1; + + lua_pushnil(L); + for(;lua_next(L, -2) != 0;){ + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_settable(L, idx); + lua_pop(L, 1); + } + + lua_pushvalue(L, idx); +} + +//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); + + env_table(from, 0); + luaI_deepcopy(from, to, SKIP_GC); + 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); +} + /** * @brief extracts a table to be global * @@ -223,7 +292,50 @@ void luaI_deepcopy2(lua_State* src, lua_State* dest){ void lua_set_global_table(lua_State* L){ lua_pushnil(L); for(;lua_next(L, -2) != 0;){ + if(lua_type(L, -2) != LUA_TSTRING){ + lua_pop(L, 1); + continue; + } + + //lua_pushstring(L, lua_tostring(L, -2)); lua_setglobal(L, lua_tostring(L, -2)); } } +//returns a table where index is the name at that index +void lua_upvalue_key_table(lua_State* L, int fidx){ + lua_newtable(L); + int tidx = lua_gettop(L); + char* name; + + for(int i = 1; (name = (char*)lua_getupvalue(L, fidx, i)) != NULL; i++){ + int idx = lua_gettop(L); + lua_pushinteger(L, lua_rawlen(L, tidx) + 1); + lua_pushstring(L, name); + lua_settable(L, tidx); + } + + lua_pushvalue(L, tidx); +} + +//sets each upvalue where the name exists in _locals table. +//if function was dumped it wont work if debug values are stripped +int lua_assign_upvalues(lua_State* L, int fidx){ + lua_getglobal(L, "_locals"); + int lidx = lua_gettop(L); + + lua_upvalue_key_table(L, fidx); + + lua_pushnil(L); + for(;lua_next(L, -2) != 0;){ + lua_gettable(L, lidx); + if(lua_isnil(L, -1)){ + lua_pop(L, 1); + } + lua_setupvalue(L, fidx, lua_tointeger(L, -2)); + } + + lua_pushvalue(L, fidx); + + return 0; +} diff --git a/src/lua.h b/src/lua.h index 4823ba0..3d58124 100644 --- a/src/lua.h +++ b/src/lua.h @@ -8,7 +8,8 @@ enum deep_copy_flags { SKIP_META = (1 << 0), SKIP_GC = (1 << 1), - IS_META = (1 << 2) + IS_META = (1 << 2), + SKIP__G = (1 << 3), }; #endif @@ -25,6 +26,11 @@ void luaI_deepcopy2(lua_State* src, lua_State* dest); void lua_set_global_table(lua_State*); //todo: char* _luaL_tolstring(lua_State*, int, size_t*); +void luaI_copyvars(lua_State* src, lua_State* dest); + +void lua_upvalue_key_table(lua_State* L, int fidx); +int lua_assign_upvalues(lua_State* L, int fidx); + //generic macro that takes other macros (see below) #define _tset_b(L, Tidx, K, V, F)\ lua_pushstring(L, K);\ diff --git a/src/math.h b/src/math.h index cfce896..3855019 100644 --- a/src/math.h +++ b/src/math.h @@ -1,4 +1,5 @@ #include "lua.h" +#include "config.h" int l_lcm(lua_State*); int l_gcd(lua_State*); @@ -9,3 +10,7 @@ static const luaL_Reg math_function_list [] = { {NULL,NULL} }; + +static struct config math_config[] = { + {.type = c_none} +}; diff --git a/src/net.c b/src/net.c index 38e70ff..9089f49 100644 --- a/src/net.c +++ b/src/net.c @@ -556,7 +556,7 @@ int l_srequest(lua_State* L){ int l_request(lua_State* L){ const char* host = luaL_checkstring(L, 1); - int sock = get_host((char*)host, lua_tostring(L, 2)); + int sock = get_host((char*)host, (char*)lua_tostring(L, 2)); char* path = "/"; if(lua_gettop(L) >= 3) @@ -809,6 +809,7 @@ void* handle_client(void *_arg){ luaL_loadbuffer(L, wowa->c, wowa->len, "fun"); int func = lua_gettop(L); + lua_assign_upvalues(L, func); //lua_pushvalue(L, func); // push function call lua_pushvalue(L, res_idx); //push methods related to dealing with the request @@ -816,6 +817,7 @@ void* handle_client(void *_arg){ //call the function if(lua_pcall(L, 2, 0, 0) != 0){ + printf("(net thread) %s\n", lua_tostring(L, -1)); //send an error message if send has not been called if(client_fd >= 0) net_error(client_fd, 500); @@ -941,7 +943,7 @@ int start_serv(lua_State* L, int port){ lua_getglobal(L, "_G"); //time_start(copy) - luaI_deepcopy(L, args->L, SKIP_GC); + luaI_copyvars(L, args->L); //time_end("copy", copy) lua_settop(L, old_top); diff --git a/src/net.h b/src/net.h index 05b6e34..ac5c6b7 100644 --- a/src/net.h +++ b/src/net.h @@ -10,6 +10,7 @@ #endif #include "lua.h" +#include "config.h" #include "types/str.h" #include "types/parray.h" #include @@ -48,3 +49,7 @@ static const luaL_Reg net_function_list [] = { {NULL,NULL} }; + +static struct config net_config[] = { + {.type = c_none} +}; diff --git a/src/reg.c b/src/reg.c index 7345d4b..64a2c2f 100644 --- a/src/reg.c +++ b/src/reg.c @@ -1,12 +1,12 @@ #include "lua.h" #include "table.h" #include "crypto.h" -#include "config.h" #include "io.h" #include "math.h" #include "net.h" #include "thread.h" #include "test.h" +#include "config.h" #include #include @@ -27,6 +27,9 @@ static int lua_exit(lua_State* L){ #define open_common(name)\ int luaopen_lullaby_##name (lua_State* L){\ luaL_register(L, NULL, name##_function_list);\ + int tidx = lua_gettop(L);\ + i_config_metatable(L, name##_config);\ + lua_settop(L, tidx);\ return 1;\ } @@ -34,7 +37,6 @@ open_common(array); open_common(crypto); open_common(io); open_common(math); -open_common(config); open_common(net); open_common(thread); open_common(test); @@ -43,6 +45,7 @@ open_common(test); lua_pushstring(L, #name);\ luaopen_lullaby_##name(L);\ lua_settable(L, T); + int luaopen_lullaby(lua_State* L) { /*lua_newuserdata(L, 1); @@ -61,11 +64,11 @@ int luaopen_lullaby(lua_State* L) { push(top, crypto); push(top, io); push(top, math); - push(top, config); push(top, net); push(top, thread); push(top, test); luaI_tsets(L, top, "version", GIT_COMMIT) + //lreg("array", array_function_list); //lreg("crypto", crypto_function_list); //lreg("io", io_function_list); diff --git a/src/table.h b/src/table.h index 704c917..a37dafc 100644 --- a/src/table.h +++ b/src/table.h @@ -1,6 +1,7 @@ #include "lua.h" #include "util.h" #include "sort.h" +#include "config.h" #include void i_shuffle(double*, size_t); @@ -46,3 +47,7 @@ static const luaL_Reg array_function_list [] = { {NULL,NULL} }; + +static struct config array_config[] = { + {.type = c_none} +}; diff --git a/src/test.c b/src/test.c index 4b52753..4403e60 100644 --- a/src/test.c +++ b/src/test.c @@ -4,7 +4,7 @@ int ld_match(lua_State* L){ parray_t* a = parray_init(); - int o = match_param(lua_tostring(L, 1), lua_tostring(L, 2), a); + int o = match_param((char*)lua_tostring(L, 1), (char*)lua_tostring(L, 2), a); if(o == 0){ lua_pushinteger(L, o); @@ -36,12 +36,13 @@ int l_stack_dump(lua_State* L){ //printf("%i\n", level); lua_Debug info; - for(int i = 0; ; i++){ + for(int i = 0;; i++){ if(lua_getstack(L, i, &info) == 0) break; for(int idx = 1;; idx++){ const char* name = lua_getlocal(L, &info, idx); if(name == NULL) break; - printf("l:%i | %s = %s %s\n", i, name, lua_tostring(L, -1), lua_typename(L, lua_type(L, -1))); + const char* type = lua_typename(L, lua_type(L, -1)); + printf("l:%i | %s = %s (%s)\n", i, name, lua_tostring(L, -1), type); lua_pop(L, 1); } } @@ -49,3 +50,8 @@ int l_stack_dump(lua_State* L){ //const char* name = lua_getlocal(L, &info, 2); return 0; } + +int l_upvalue_key_table(lua_State* L){ + lua_upvalue_key_table(L, 1); + return 1; +} diff --git a/src/test.h b/src/test.h index 85c6b5b..2eceaeb 100644 --- a/src/test.h +++ b/src/test.h @@ -1,10 +1,17 @@ #include "lua.h" +#include "config.h" int ld_match(lua_State*); int l_stack_dump(lua_State*); +int l_upvalue_key_table(lua_State* L); static const luaL_Reg test_function_list [] = { {"_match", ld_match}, - {"stack_dump", l_stack_dump}, + {"stack_dump", l_stack_dump}, + {"upvalue_key_table", l_upvalue_key_table}, {NULL,NULL} }; + +static struct config test_config[] = { + {.type = c_none} +}; diff --git a/src/thread.c b/src/thread.c index db8e54e..a6be01b 100644 --- a/src/thread.c +++ b/src/thread.c @@ -125,8 +125,10 @@ void* handle_thread(void* _args){ lua_setmetatable(L, res_idx); luaL_loadbuffer(L, args->function->c, args->function->len, "thread"); + int x = lua_gettop(L); str_free(args->function); + lua_assign_upvalues(L, x); lua_pushvalue(L, res_idx); lua_call(L, 1, 0); @@ -182,9 +184,10 @@ int l_async(lua_State* oL){ lua_gc(L, LUA_GCSTOP); luaL_openlibs(L); - lua_getglobal(oL, "_G"); - luaI_deepcopy(oL, L, SKIP_GC); - lua_set_global_table(L); + //lua_getglobal(oL, "_G"); + //luaI_deepcopy(oL, L, SKIP_GC); + //lua_set_global_table(L); + luaI_copyvars(oL, L); struct thread_info* args = calloc(1, sizeof * args); args->L = L; diff --git a/src/thread.h b/src/thread.h index b83db4c..714c499 100644 --- a/src/thread.h +++ b/src/thread.h @@ -1,4 +1,5 @@ #include "lua.h" +#include "config.h" int l_async(lua_State*); int l_tlock(lua_State*); @@ -16,3 +17,7 @@ static const luaL_Reg thread_function_list [] = { {"testcopy",l_testcopy}, {NULL,NULL} }; + +static struct config thread_config[] = { + {.type = c_none} +}; -- cgit v1.2.3