aboutsummaryrefslogtreecommitdiff
path: root/lundump.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-15 16:44:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-15 16:44:22 -0300
commitd70a0c91ad42275af1f6f1b6e37c604442b3f0d1 (patch)
tree1507250574d5f9b34c32a0fade34fbeaecb7c5f9 /lundump.c
parent3e6818ca87b8d7aa007e6992295956a92bb89de4 (diff)
downloadlua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.tar.gz
lua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.tar.bz2
lua-d70a0c91ad42275af1f6f1b6e37c604442b3f0d1.zip
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.
Diffstat (limited to 'lundump.c')
-rw-r--r--lundump.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/lundump.c b/lundump.c
index aba93f82..4048fdea 100644
--- a/lundump.c
+++ b/lundump.c
@@ -21,6 +21,7 @@
21#include "lmem.h" 21#include "lmem.h"
22#include "lobject.h" 22#include "lobject.h"
23#include "lstring.h" 23#include "lstring.h"
24#include "ltable.h"
24#include "lundump.h" 25#include "lundump.h"
25#include "lzio.h" 26#include "lzio.h"
26 27
@@ -34,6 +35,8 @@ typedef struct {
34 lua_State *L; 35 lua_State *L;
35 ZIO *Z; 36 ZIO *Z;
36 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */
39 lua_Integer nstr; /* number of strings in the list */
37} LoadState; 40} LoadState;
38 41
39 42
@@ -110,10 +113,16 @@ static lua_Integer loadInteger (LoadState *S) {
110static TString *loadStringN (LoadState *S, Proto *p) { 113static TString *loadStringN (LoadState *S, Proto *p) {
111 lua_State *L = S->L; 114 lua_State *L = S->L;
112 TString *ts; 115 TString *ts;
116 TValue sv;
113 size_t size = loadSize(S); 117 size_t size = loadSize(S);
114 if (size == 0) /* no string? */ 118 if (size == 0) /* no string? */
115 return NULL; 119 return NULL;
116 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 120 else if (size == 1) { /* previously saved string? */
121 int idx = loadInt(S); /* get its index */
122 const TValue *stv = luaH_getint(S->h, idx);
123 return tsvalue(stv);
124 }
125 else if (size -= 2, size <= LUAI_MAXSHORTLEN) { /* short string? */
117 char buff[LUAI_MAXSHORTLEN]; 126 char buff[LUAI_MAXSHORTLEN];
118 loadVector(S, buff, size); /* load string into buffer */ 127 loadVector(S, buff, size); /* load string into buffer */
119 ts = luaS_newlstr(L, buff, size); /* create string */ 128 ts = luaS_newlstr(L, buff, size); /* create string */
@@ -126,6 +135,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
126 L->top.p--; /* pop string */ 135 L->top.p--; /* pop string */
127 } 136 }
128 luaC_objbarrier(L, p, ts); 137 luaC_objbarrier(L, p, ts);
138 S->nstr++; /* add string to list of saved strings */
139 setsvalue(L, &sv, ts);
140 luaH_setint(L, S->h, S->nstr, &sv);
141 luaC_objbarrierback(L, obj2gco(S->h), ts);
129 return ts; 142 return ts;
130} 143}
131 144
@@ -323,11 +336,16 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
323 cl = luaF_newLclosure(L, loadByte(&S)); 336 cl = luaF_newLclosure(L, loadByte(&S));
324 setclLvalue2s(L, L->top.p, cl); 337 setclLvalue2s(L, L->top.p, cl);
325 luaD_inctop(L); 338 luaD_inctop(L);
339 S.h = luaH_new(L); /* create list of saved strings */
340 S.nstr = 0;
341 sethvalue2s(L, L->top.p, S.h); /* anchor it */
342 luaD_inctop(L);
326 cl->p = luaF_newproto(L); 343 cl->p = luaF_newproto(L);
327 luaC_objbarrier(L, cl, cl->p); 344 luaC_objbarrier(L, cl, cl->p);
328 loadFunction(&S, cl->p, NULL); 345 loadFunction(&S, cl->p, NULL);
329 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 346 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
330 luai_verifycode(L, cl->p); 347 luai_verifycode(L, cl->p);
348 L->top.p--; /* pop table */
331 return cl; 349 return cl;
332} 350}
333 351