commit 7d6a97e42bc3328b9c5ec1dabbd7e280e81c3efd
parent d70a0c91ad42275af1f6f1b6e37c604442b3f0d1
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 20 Dec 2022 11:14:25 -0300
Dump doesn't need to reuse 'source'
All strings are being reused now, including 'source'.
Diffstat:
3 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/ldump.c b/ldump.c
@@ -126,7 +126,7 @@ static void dumpCode (DumpState *D, const Proto *f) {
}
-static void dumpFunction(DumpState *D, const Proto *f, TString *psource);
+static void dumpFunction(DumpState *D, const Proto *f);
static void dumpConstants (DumpState *D, const Proto *f) {
int i;
@@ -159,7 +159,7 @@ static void dumpProtos (DumpState *D, const Proto *f) {
int n = f->sizep;
dumpInt(D, n);
for (i = 0; i < n; i++)
- dumpFunction(D, f->p[i], f->source);
+ dumpFunction(D, f->p[i]);
}
@@ -199,9 +199,9 @@ static void dumpDebug (DumpState *D, const Proto *f) {
}
-static void dumpFunction (DumpState *D, const Proto *f, TString *psource) {
- if (D->strip || f->source == psource)
- dumpString(D, NULL); /* no debug info or same source as its parent */
+static void dumpFunction (DumpState *D, const Proto *f) {
+ if (D->strip)
+ dumpString(D, NULL); /* no debug info */
else
dumpString(D, f->source);
dumpInt(D, f->linedefined);
@@ -245,7 +245,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
D.nstr = 0;
dumpHeader(&D);
dumpByte(&D, f->sizeupvalues);
- dumpFunction(&D, f, NULL);
+ dumpFunction(&D, f);
return D.status;
}
diff --git a/lundump.c b/lundump.c
@@ -162,7 +162,7 @@ static void loadCode (LoadState *S, Proto *f) {
}
-static void loadFunction(LoadState *S, Proto *f, TString *psource);
+static void loadFunction(LoadState *S, Proto *f);
static void loadConstants (LoadState *S, Proto *f) {
@@ -211,7 +211,7 @@ static void loadProtos (LoadState *S, Proto *f) {
for (i = 0; i < n; i++) {
f->p[i] = luaF_newproto(S->L);
luaC_objbarrier(S->L, f, f->p[i]);
- loadFunction(S, f->p[i], f->source);
+ loadFunction(S, f->p[i]);
}
}
@@ -266,10 +266,8 @@ static void loadDebug (LoadState *S, Proto *f) {
}
-static void loadFunction (LoadState *S, Proto *f, TString *psource) {
+static void loadFunction (LoadState *S, Proto *f) {
f->source = loadStringN(S, f);
- if (f->source == NULL) /* no source in dump? */
- f->source = psource; /* reuse parent's source */
f->linedefined = loadInt(S);
f->lastlinedefined = loadInt(S);
f->numparams = loadByte(S);
@@ -342,7 +340,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
luaD_inctop(L);
cl->p = luaF_newproto(L);
luaC_objbarrier(L, cl, cl->p);
- loadFunction(&S, cl->p, NULL);
+ loadFunction(&S, cl->p);
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luai_verifycode(L, cl->p);
L->top.p--; /* pop table */
diff --git a/testes/calls.lua b/testes/calls.lua
@@ -487,5 +487,30 @@ do
end
end
+
+do -- check reuse of strings in dumps
+ local str = "|" .. string.rep("X", 50) .. "|"
+ local foo = load(string.format([[
+ local str <const> = "%s"
+ return {
+ function () return str end,
+ function () return str end,
+ function () return str end
+ }
+ ]], str))
+ -- count occurrences of 'str' inside the dump
+ local dump = string.dump(foo)
+ local _, count = string.gsub(dump, str, {})
+ -- there should be only two occurrences:
+ -- one inside the source, other the string itself.
+ assert(count == 2)
+
+ if T then -- check reuse of strings in undump
+ local funcs = load(dump)()
+ assert(string.format("%p", T.listk(funcs[1])[1]) ==
+ string.format("%p", T.listk(funcs[3])[1]))
+ end
+end
+
print('OK')
return deep