diff options
| author | ame <[email protected]> | 2026-02-02 03:23:21 -0600 |
|---|---|---|
| committer | ame <[email protected]> | 2026-02-02 03:23:21 -0600 |
| commit | 2f81ec62dd0690cf03d7386d8f1e828388ba7e58 (patch) | |
| tree | 9ffaedc81fa1c66113fb7c34986be127e7e96ba9 | |
| parent | 24098695eb033bc62c2301a6b5ec76feeddfcfed (diff) | |
cleanliness and recursive upvalues
| -rw-r--r-- | src/lua.c | 52 | ||||
| -rw-r--r-- | src/lua.h | 1 |
2 files changed, 36 insertions, 17 deletions
@@ -158,6 +158,25 @@ int writer(lua_State *L, const void* p, size_t sz, void* ud){ return 0;
}
+enum table_cache {
+ CACHE_HIT, CACHE_MISS
+};
+
+enum table_cache table_cache(lua_State* L, char* key, int index){
+ lua_getfield(L, LUA_REGISTRYINDEX, key);
+ if(lua_type(L, -1) == LUA_TNIL){
+ lua_pushstring(L, key);
+ lua_pushvalue(L, index);
+ lua_settable(L, LUA_REGISTRYINDEX);
+ lua_pop(L, 1);
+ return CACHE_MISS;
+ } else {
+ //lua_pop(dest, 1);
+ lua_remove(L, -2);
+ return CACHE_HIT;
+ }
+}
+
/**
* @brief copy top element from src to dest
*
@@ -200,25 +219,14 @@ void luaI_deepcopy(lua_State* src, lua_State* dest, enum deep_copy_flags flags){ at2 = lua_gettop(src);
//printf("before\n");
char* aauwu = calloc(sizeof * aauwu, 50);
- sprintf(aauwu, "%p", lua_topointer(src, at2));
- //lua_pushstring(dest, aauwu);
- //lua_gettable(dest, LUA_REGISTRYINDEX);
- lua_getfield(dest, LUA_REGISTRYINDEX, aauwu);
- if(lua_type(dest, -1) == LUA_TNIL){
- //printf("new %p\n", lua_topointer(src, at2));
- lua_pushstring(dest, aauwu);
- lua_pushvalue(dest, at);
- lua_settable(dest, LUA_REGISTRYINDEX);
- lua_pop(dest, 1);
- } else {
- //printf("use %p\n", lua_topointer(src, at2));
- //lua_pop(dest, 1);
- lua_remove(dest, -2);
+ sprintf(aauwu, "tab-%p", lua_topointer(src, at2));
+
+ if(table_cache(dest, aauwu, at) == CACHE_HIT){
free(aauwu);
return;
}
+
free(aauwu);
- //printf("after %i:%i\n", at, lua_gettop(dest));
lua_pushnil(src);
for(;lua_next(src, at2) != 0;){
@@ -257,11 +265,21 @@ 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");
+ int f = lua_gettop(dest);
//if(!(flags & SKIP_LOCALS)) lua_assign_upvalues(dest, lua_gettop(dest));
+ char* poi = calloc(sizeof * poi, 50);
+ sprintf(poi, "fun-%p", lua_topointer(src, old_top));
+
+ if(table_cache(dest, poi, f) == CACHE_HIT){
+ free(poi);
+ return;
+ }
+ free(poi);
+
- int f = lua_gettop(dest);
for(int i = 1; lua_getupvalue(src, -1, i) != NULL; i++){
- luaI_deepcopy(src, dest, flags);
+ luaI_deepcopy(src, dest, flags | IS_UPVALUE);
+
lua_setupvalue(dest, f, i);
lua_pop(src, 1);
}
@@ -15,6 +15,7 @@ enum deep_copy_flags { SKIP__G = (1 << 3),
SKIP_LOCALS = (1 << 4),
STRIP_GC = (1 << 5),
+ IS_UPVALUE = (1 << 6),
};
#endif
|
