Browse Source

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.
pull/24/head
Roberto Ierusalimschy 4 years ago
parent
commit
6d7cd31fee
  1. 3
      lparser.c
  2. 33
      lundump.c

3
lparser.c

@ -737,6 +737,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
fs->firstlabel = ls->dyd->label.n; fs->firstlabel = ls->dyd->label.n;
fs->bl = NULL; fs->bl = NULL;
f->source = ls->source; f->source = ls->source;
luaC_objbarrier(ls->L, f, f->source);
f->maxstacksize = 2; /* registers 0/1 are always valid */ f->maxstacksize = 2; /* registers 0/1 are always valid */
enterblock(fs, bl, 0); enterblock(fs, bl, 0);
} }
@ -1959,6 +1960,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
env->idx = 0; env->idx = 0;
env->kind = VDKREG; env->kind = VDKREG;
env->name = ls->envn; env->name = ls->envn;
luaC_objbarrier(ls->L, fs->f, env->name);
luaX_next(ls); /* read first token */ luaX_next(ls); /* read first token */
statlist(ls); /* parse main body */ statlist(ls); /* parse main body */
check(ls, TK_EOS); 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 */ sethvalue2s(L, L->top, lexstate.h); /* anchor it */
luaD_inctop(L); luaD_inctop(L);
funcstate.f = cl->p = luaF_newproto(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 */ funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
luaC_objbarrier(L, funcstate.f, funcstate.f->source); luaC_objbarrier(L, funcstate.f, funcstate.f->source);
lexstate.buff = buff; lexstate.buff = buff;

33
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); size_t size = loadSize(S);
if (size == 0) if (size == 0) /* no string? */
return NULL; return NULL;
else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
char buff[LUAI_MAXSHORTLEN]; char buff[LUAI_MAXSHORTLEN];
loadVector(S, buff, size); loadVector(S, buff, size); /* load string into buffer */
return luaS_newlstr(S->L, buff, size); ts = luaS_newlstr(L, buff, size); /* create string */
} }
else { /* long 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 */ 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) { static TString *loadString (LoadState *S, Proto *p) {
TString *st = loadStringN(S); TString *st = loadStringN(S, p);
if (st == NULL) if (st == NULL)
error(S, "bad format for constant string"); error(S, "bad format for constant string");
return st; return st;
@ -174,7 +177,7 @@ static void loadConstants (LoadState *S, Proto *f) {
break; break;
case LUA_VSHRSTR: case LUA_VSHRSTR:
case LUA_VLNGSTR: case LUA_VLNGSTR:
setsvalue2n(S->L, o, loadString(S)); setsvalue2n(S->L, o, loadString(S, f));
break; break;
default: lua_assert(0); default: lua_assert(0);
} }
@ -191,6 +194,7 @@ static void loadProtos (LoadState *S, Proto *f) {
f->p[i] = NULL; f->p[i] = NULL;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
f->p[i] = luaF_newproto(S->L); 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], f->source);
} }
} }
@ -229,18 +233,18 @@ static void loadDebug (LoadState *S, Proto *f) {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
f->locvars[i].varname = NULL; f->locvars[i].varname = NULL;
for (i = 0; i < n; i++) { 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].startpc = loadInt(S);
f->locvars[i].endpc = loadInt(S); f->locvars[i].endpc = loadInt(S);
} }
n = loadInt(S); n = loadInt(S);
for (i = 0; i < n; i++) 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) { 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? */ if (f->source == NULL) /* no source in dump? */
f->source = psource; /* reuse parent's source */ f->source = psource; /* reuse parent's source */
f->linedefined = loadInt(S); f->linedefined = loadInt(S);
@ -310,6 +314,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
setclLvalue2s(L, L->top, cl); setclLvalue2s(L, L->top, cl);
luaD_inctop(L); luaD_inctop(L);
cl->p = luaF_newproto(L); cl->p = luaF_newproto(L);
luaC_objbarrier(L, cl, cl->p);
loadFunction(&S, cl->p, NULL); loadFunction(&S, cl->p, NULL);
lua_assert(cl->nupvalues == cl->p->sizeupvalues); lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luai_verifycode(L, buff, cl->p); luai_verifycode(L, buff, cl->p);

Loading…
Cancel
Save