From 6d7cd31feec58011a593cf732274a33dcc1bcb53 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 16 Jun 2020 09:54:20 -0300 Subject: [PATCH] Fixed missing GC barriers in compiler and undump While building a new prototype, the GC needs barriers for every object (strings and nested prototypes) that is attached to the new prototype. --- lparser.c | 3 +++ lundump.c | 33 +++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lparser.c b/lparser.c index 37102b72..bc7d9a4f 100644 --- a/lparser.c +++ b/lparser.c @@ -737,6 +737,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->firstlabel = ls->dyd->label.n; fs->bl = NULL; f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ enterblock(fs, bl, 0); } @@ -1959,6 +1960,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { env->idx = 0; env->kind = VDKREG; env->name = ls->envn; + luaC_objbarrier(ls->L, fs->f, env->name); luaX_next(ls); /* read first token */ statlist(ls); /* parse main body */ check(ls, TK_EOS); @@ -1977,6 +1979,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, sethvalue2s(L, L->top, lexstate.h); /* anchor it */ luaD_inctop(L); funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ luaC_objbarrier(L, funcstate.f, funcstate.f->source); lexstate.buff = buff; diff --git a/lundump.c b/lundump.c index d6b249d5..77ba1955 100644 --- a/lundump.c +++ b/lundump.c @@ -105,30 +105,33 @@ static lua_Integer loadInteger (LoadState *S) { /* -** Load a nullable string. +** Load a nullable string into prototype 'p'. */ -static TString *loadStringN (LoadState *S) { +static TString *loadStringN (LoadState *S, Proto *p) { + lua_State *L = S->L; + TString *ts; size_t size = loadSize(S); - if (size == 0) + if (size == 0) /* no string? */ return NULL; else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ char buff[LUAI_MAXSHORTLEN]; - loadVector(S, buff, size); - return luaS_newlstr(S->L, buff, size); + loadVector(S, buff, size); /* load string into buffer */ + ts = luaS_newlstr(L, buff, size); /* create string */ } else { /* long string */ - TString *ts = luaS_createlngstrobj(S->L, size); + ts = luaS_createlngstrobj(L, size); /* create string */ loadVector(S, getstr(ts), size); /* load directly in final place */ - return ts; } + luaC_objbarrier(L, p, ts); + return ts; } /* -** Load a non-nullable string. +** Load a non-nullable string into prototype 'p'. */ -static TString *loadString (LoadState *S) { - TString *st = loadStringN(S); +static TString *loadString (LoadState *S, Proto *p) { + TString *st = loadStringN(S, p); if (st == NULL) error(S, "bad format for constant string"); return st; @@ -174,7 +177,7 @@ static void loadConstants (LoadState *S, Proto *f) { break; case LUA_VSHRSTR: case LUA_VLNGSTR: - setsvalue2n(S->L, o, loadString(S)); + setsvalue2n(S->L, o, loadString(S, f)); break; default: lua_assert(0); } @@ -191,6 +194,7 @@ static void loadProtos (LoadState *S, Proto *f) { f->p[i] = NULL; 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); } } @@ -229,18 +233,18 @@ static void loadDebug (LoadState *S, Proto *f) { for (i = 0; i < n; i++) f->locvars[i].varname = NULL; for (i = 0; i < n; i++) { - f->locvars[i].varname = loadStringN(S); + f->locvars[i].varname = loadStringN(S, f); f->locvars[i].startpc = loadInt(S); f->locvars[i].endpc = loadInt(S); } n = loadInt(S); for (i = 0; i < n; i++) - f->upvalues[i].name = loadStringN(S); + f->upvalues[i].name = loadStringN(S, f); } static void loadFunction (LoadState *S, Proto *f, TString *psource) { - f->source = loadStringN(S); + f->source = loadStringN(S, f); if (f->source == NULL) /* no source in dump? */ f->source = psource; /* reuse parent's source */ f->linedefined = loadInt(S); @@ -310,6 +314,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { setclLvalue2s(L, L->top, cl); luaD_inctop(L); cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); loadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p);