lua

A copy of the Lua development repository
Log | Files | Refs | README

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:
Mldump.c | 12++++++------
Mlundump.c | 10++++------
Mtestes/calls.lua | 25+++++++++++++++++++++++++
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