From d70a0c91ad42275af1f6f1b6e37c604442b3f0d1 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 15 Dec 2022 16:44:22 -0300 Subject: Dump/undump reuse strings A repeated string in a dump is represented as an index to its first occurence, instead of another copy of the string. --- lundump.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'lundump.c') diff --git a/lundump.c b/lundump.c index aba93f82..4048fdea 100644 --- a/lundump.c +++ b/lundump.c @@ -21,6 +21,7 @@ #include "lmem.h" #include "lobject.h" #include "lstring.h" +#include "ltable.h" #include "lundump.h" #include "lzio.h" @@ -34,6 +35,8 @@ typedef struct { lua_State *L; ZIO *Z; const char *name; + Table *h; /* list for string reuse */ + lua_Integer nstr; /* number of strings in the list */ } LoadState; @@ -110,10 +113,16 @@ static lua_Integer loadInteger (LoadState *S) { static TString *loadStringN (LoadState *S, Proto *p) { lua_State *L = S->L; TString *ts; + TValue sv; size_t size = loadSize(S); if (size == 0) /* no string? */ return NULL; - else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ + else if (size == 1) { /* previously saved string? */ + int idx = loadInt(S); /* get its index */ + const TValue *stv = luaH_getint(S->h, idx); + return tsvalue(stv); + } + else if (size -= 2, size <= LUAI_MAXSHORTLEN) { /* short string? */ char buff[LUAI_MAXSHORTLEN]; loadVector(S, buff, size); /* load string into buffer */ ts = luaS_newlstr(L, buff, size); /* create string */ @@ -126,6 +135,10 @@ static TString *loadStringN (LoadState *S, Proto *p) { L->top.p--; /* pop string */ } luaC_objbarrier(L, p, ts); + S->nstr++; /* add string to list of saved strings */ + setsvalue(L, &sv, ts); + luaH_setint(L, S->h, S->nstr, &sv); + luaC_objbarrierback(L, obj2gco(S->h), ts); return ts; } @@ -323,11 +336,16 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { cl = luaF_newLclosure(L, loadByte(&S)); setclLvalue2s(L, L->top.p, cl); luaD_inctop(L); + S.h = luaH_new(L); /* create list of saved strings */ + S.nstr = 0; + sethvalue2s(L, L->top.p, S.h); /* anchor it */ + luaD_inctop(L); cl->p = luaF_newproto(L); luaC_objbarrier(L, cl, cl->p); loadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, cl->p); + L->top.p--; /* pop table */ return cl; } -- cgit v1.2.3-55-g6feb