diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-15 16:44:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2022-12-15 16:44:22 -0300 |
commit | d70a0c91ad42275af1f6f1b6e37c604442b3f0d1 (patch) | |
tree | 1507250574d5f9b34c32a0fade34fbeaecb7c5f9 /ldump.c | |
parent | 3e6818ca87b8d7aa007e6992295956a92bb89de4 (diff) | |
download | lua-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 'ldump.c')
-rw-r--r-- | ldump.c | 37 |
1 files changed, 31 insertions, 6 deletions
@@ -14,8 +14,10 @@ | |||
14 | 14 | ||
15 | #include "lua.h" | 15 | #include "lua.h" |
16 | 16 | ||
17 | #include "lgc.h" | ||
17 | #include "lobject.h" | 18 | #include "lobject.h" |
18 | #include "lstate.h" | 19 | #include "lstate.h" |
20 | #include "ltable.h" | ||
19 | #include "lundump.h" | 21 | #include "lundump.h" |
20 | 22 | ||
21 | 23 | ||
@@ -25,6 +27,8 @@ typedef struct { | |||
25 | void *data; | 27 | void *data; |
26 | int strip; | 28 | int strip; |
27 | int status; | 29 | int status; |
30 | Table *h; /* table to track saved strings */ | ||
31 | lua_Integer nstr; /* counter to number saved strings */ | ||
28 | } DumpState; | 32 | } DumpState; |
29 | 33 | ||
30 | 34 | ||
@@ -85,14 +89,33 @@ static void dumpInteger (DumpState *D, lua_Integer x) { | |||
85 | } | 89 | } |
86 | 90 | ||
87 | 91 | ||
88 | static void dumpString (DumpState *D, const TString *s) { | 92 | /* |
93 | ** Dump a String. First dump its "size": size==0 means NULL; | ||
94 | ** size==1 is followed by an index and means "reuse saved string with | ||
95 | ** that index"; size>=2 is followed by the string contents with real | ||
96 | ** size==size-2 and means that string, which will be saved with | ||
97 | ** the next available index. | ||
98 | */ | ||
99 | static void dumpString (DumpState *D, TString *s) { | ||
89 | if (s == NULL) | 100 | if (s == NULL) |
90 | dumpSize(D, 0); | 101 | dumpSize(D, 0); |
91 | else { | 102 | else { |
92 | size_t size = tsslen(s); | 103 | const TValue *idx = luaH_getstr(D->h, s); |
93 | const char *str = getstr(s); | 104 | if (ttisinteger(idx)) { /* string already saved? */ |
94 | dumpSize(D, size + 1); | 105 | dumpSize(D, 1); /* reuse a saved string */ |
95 | dumpVector(D, str, size); | 106 | dumpInt(D, ivalue(idx)); /* index of saved string */ |
107 | } | ||
108 | else { /* must write and save the string */ | ||
109 | TValue key, value; /* to save the string in the hash */ | ||
110 | size_t size = tsslen(s); | ||
111 | dumpSize(D, size + 2); | ||
112 | dumpVector(D, getstr(s), size); | ||
113 | D->nstr++; /* one more saved string */ | ||
114 | setsvalue(D->L, &key, s); /* the string is the key */ | ||
115 | setivalue(&value, D->nstr); /* its index is the value */ | ||
116 | luaH_finishset(D->L, D->h, &key, idx, &value); /* h[s] = nstr */ | ||
117 | /* integer value does not need barrier */ | ||
118 | } | ||
96 | } | 119 | } |
97 | } | 120 | } |
98 | 121 | ||
@@ -211,13 +234,15 @@ static void dumpHeader (DumpState *D) { | |||
211 | ** dump Lua function as precompiled chunk | 234 | ** dump Lua function as precompiled chunk |
212 | */ | 235 | */ |
213 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | 236 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, |
214 | int strip) { | 237 | int strip, Table *h) { |
215 | DumpState D; | 238 | DumpState D; |
216 | D.L = L; | 239 | D.L = L; |
217 | D.writer = w; | 240 | D.writer = w; |
218 | D.data = data; | 241 | D.data = data; |
219 | D.strip = strip; | 242 | D.strip = strip; |
220 | D.status = 0; | 243 | D.status = 0; |
244 | D.h = h; | ||
245 | D.nstr = 0; | ||
221 | dumpHeader(&D); | 246 | dumpHeader(&D); |
222 | dumpByte(&D, f->sizeupvalues); | 247 | dumpByte(&D, f->sizeupvalues); |
223 | dumpFunction(&D, f, NULL); | 248 | dumpFunction(&D, f, NULL); |