Sfoglia il codice sorgente

Dump doesn't need to reuse 'source'

All strings are being reused now, including 'source'.
Roberto Ierusalimschy 2 anni fa
parent
commit
7d6a97e42b
3 ha cambiato i file con 35 aggiunte e 12 eliminazioni
  1. 6 6
      ldump.c
  2. 4 6
      lundump.c
  3. 25 0
      testes/calls.lua

+ 6 - 6
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;
 }
 

+ 4 - 6
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 */

+ 25 - 0
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