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.
This commit is contained in:
33
lundump.c
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);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user