summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-06-16 09:54:20 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-06-16 09:54:20 -0300
commit6d7cd31feec58011a593cf732274a33dcc1bcb53 (patch)
treea464a23b3636c45c10b998046671573422fe075c
parent993c58fde3a85c27f52f094002ec57dabca81028 (diff)
downloadlua-6d7cd31feec58011a593cf732274a33dcc1bcb53.tar.gz
lua-6d7cd31feec58011a593cf732274a33dcc1bcb53.tar.bz2
lua-6d7cd31feec58011a593cf732274a33dcc1bcb53.zip
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.
-rw-r--r--lparser.c3
-rw-r--r--lundump.c33
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) {
737 fs->firstlabel = ls->dyd->label.n; 737 fs->firstlabel = ls->dyd->label.n;
738 fs->bl = NULL; 738 fs->bl = NULL;
739 f->source = ls->source; 739 f->source = ls->source;
740 luaC_objbarrier(ls->L, f, f->source);
740 f->maxstacksize = 2; /* registers 0/1 are always valid */ 741 f->maxstacksize = 2; /* registers 0/1 are always valid */
741 enterblock(fs, bl, 0); 742 enterblock(fs, bl, 0);
742} 743}
@@ -1959,6 +1960,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
1959 env->idx = 0; 1960 env->idx = 0;
1960 env->kind = VDKREG; 1961 env->kind = VDKREG;
1961 env->name = ls->envn; 1962 env->name = ls->envn;
1963 luaC_objbarrier(ls->L, fs->f, env->name);
1962 luaX_next(ls); /* read first token */ 1964 luaX_next(ls); /* read first token */
1963 statlist(ls); /* parse main body */ 1965 statlist(ls); /* parse main body */
1964 check(ls, TK_EOS); 1966 check(ls, TK_EOS);
@@ -1977,6 +1979,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1977 sethvalue2s(L, L->top, lexstate.h); /* anchor it */ 1979 sethvalue2s(L, L->top, lexstate.h); /* anchor it */
1978 luaD_inctop(L); 1980 luaD_inctop(L);
1979 funcstate.f = cl->p = luaF_newproto(L); 1981 funcstate.f = cl->p = luaF_newproto(L);
1982 luaC_objbarrier(L, cl, cl->p);
1980 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ 1983 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1981 luaC_objbarrier(L, funcstate.f, funcstate.f->source); 1984 luaC_objbarrier(L, funcstate.f, funcstate.f->source);
1982 lexstate.buff = buff; 1985 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) {
105 105
106 106
107/* 107/*
108** Load a nullable string. 108** Load a nullable string into prototype 'p'.
109*/ 109*/
110static TString *loadStringN (LoadState *S) { 110static TString *loadStringN (LoadState *S, Proto *p) {
111 lua_State *L = S->L;
112 TString *ts;
111 size_t size = loadSize(S); 113 size_t size = loadSize(S);
112 if (size == 0) 114 if (size == 0) /* no string? */
113 return NULL; 115 return NULL;
114 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 116 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
115 char buff[LUAI_MAXSHORTLEN]; 117 char buff[LUAI_MAXSHORTLEN];
116 loadVector(S, buff, size); 118 loadVector(S, buff, size); /* load string into buffer */
117 return luaS_newlstr(S->L, buff, size); 119 ts = luaS_newlstr(L, buff, size); /* create string */
118 } 120 }
119 else { /* long string */ 121 else { /* long string */
120 TString *ts = luaS_createlngstrobj(S->L, size); 122 ts = luaS_createlngstrobj(L, size); /* create string */
121 loadVector(S, getstr(ts), size); /* load directly in final place */ 123 loadVector(S, getstr(ts), size); /* load directly in final place */
122 return ts;
123 } 124 }
125 luaC_objbarrier(L, p, ts);
126 return ts;
124} 127}
125 128
126 129
127/* 130/*
128** Load a non-nullable string. 131** Load a non-nullable string into prototype 'p'.
129*/ 132*/
130static TString *loadString (LoadState *S) { 133static TString *loadString (LoadState *S, Proto *p) {
131 TString *st = loadStringN(S); 134 TString *st = loadStringN(S, p);
132 if (st == NULL) 135 if (st == NULL)
133 error(S, "bad format for constant string"); 136 error(S, "bad format for constant string");
134 return st; 137 return st;
@@ -174,7 +177,7 @@ static void loadConstants (LoadState *S, Proto *f) {
174 break; 177 break;
175 case LUA_VSHRSTR: 178 case LUA_VSHRSTR:
176 case LUA_VLNGSTR: 179 case LUA_VLNGSTR:
177 setsvalue2n(S->L, o, loadString(S)); 180 setsvalue2n(S->L, o, loadString(S, f));
178 break; 181 break;
179 default: lua_assert(0); 182 default: lua_assert(0);
180 } 183 }
@@ -191,6 +194,7 @@ static void loadProtos (LoadState *S, Proto *f) {
191 f->p[i] = NULL; 194 f->p[i] = NULL;
192 for (i = 0; i < n; i++) { 195 for (i = 0; i < n; i++) {
193 f->p[i] = luaF_newproto(S->L); 196 f->p[i] = luaF_newproto(S->L);
197 luaC_objbarrier(S->L, f, f->p[i]);
194 loadFunction(S, f->p[i], f->source); 198 loadFunction(S, f->p[i], f->source);
195 } 199 }
196} 200}
@@ -229,18 +233,18 @@ static void loadDebug (LoadState *S, Proto *f) {
229 for (i = 0; i < n; i++) 233 for (i = 0; i < n; i++)
230 f->locvars[i].varname = NULL; 234 f->locvars[i].varname = NULL;
231 for (i = 0; i < n; i++) { 235 for (i = 0; i < n; i++) {
232 f->locvars[i].varname = loadStringN(S); 236 f->locvars[i].varname = loadStringN(S, f);
233 f->locvars[i].startpc = loadInt(S); 237 f->locvars[i].startpc = loadInt(S);
234 f->locvars[i].endpc = loadInt(S); 238 f->locvars[i].endpc = loadInt(S);
235 } 239 }
236 n = loadInt(S); 240 n = loadInt(S);
237 for (i = 0; i < n; i++) 241 for (i = 0; i < n; i++)
238 f->upvalues[i].name = loadStringN(S); 242 f->upvalues[i].name = loadStringN(S, f);
239} 243}
240 244
241 245
242static void loadFunction (LoadState *S, Proto *f, TString *psource) { 246static void loadFunction (LoadState *S, Proto *f, TString *psource) {
243 f->source = loadStringN(S); 247 f->source = loadStringN(S, f);
244 if (f->source == NULL) /* no source in dump? */ 248 if (f->source == NULL) /* no source in dump? */
245 f->source = psource; /* reuse parent's source */ 249 f->source = psource; /* reuse parent's source */
246 f->linedefined = loadInt(S); 250 f->linedefined = loadInt(S);
@@ -310,6 +314,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
310 setclLvalue2s(L, L->top, cl); 314 setclLvalue2s(L, L->top, cl);
311 luaD_inctop(L); 315 luaD_inctop(L);
312 cl->p = luaF_newproto(L); 316 cl->p = luaF_newproto(L);
317 luaC_objbarrier(L, cl, cl->p);
313 loadFunction(&S, cl->p, NULL); 318 loadFunction(&S, cl->p, NULL);
314 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 319 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
315 luai_verifycode(L, buff, cl->p); 320 luai_verifycode(L, buff, cl->p);