2
0
Эх сурвалжийг харах

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.
Roberto Ierusalimschy 5 жил өмнө
parent
commit
f5eb809d3f
2 өөрчлөгдсөн 15 нэмэгдсэн , 8 устгасан
  1. 3 0
      lparser.c
  2. 12 8
      lundump.c

+ 3 - 0
lparser.c

@@ -544,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
   fs->bl = NULL;
   f = fs->f;
   f->source = ls->source;
+  luaC_objbarrier(ls->L, f, f->source);
   f->maxstacksize = 2;  /* registers 0/1 are always valid */
   enterblock(fs, bl, 0);
 }
@@ -1616,6 +1617,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
   fs->f->is_vararg = 1;  /* main function is always declared vararg */
   init_exp(&v, VLOCAL, 0);  /* create and... */
   newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
+  luaC_objbarrier(ls->L, fs->f, ls->envn);
   luaX_next(ls);  /* read first token */
   statlist(ls);  /* parse main body */
   check(ls, TK_EOS);
@@ -1634,6 +1636,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
   sethvalue(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 */
   lua_assert(iswhite(funcstate.f));  /* do not need barrier here */
   lexstate.buff = buff;

+ 12 - 8
lundump.c

@@ -85,8 +85,9 @@ static lua_Integer LoadInteger (LoadState *S) {
 }
 
 
-static TString *LoadString (LoadState *S) {
+static TString *LoadString (LoadState *S, Proto *p) {
   size_t size = LoadByte(S);
+  TString *ts;
   if (size == 0xFF)
     LoadVar(S, size);
   if (size == 0)
@@ -94,13 +95,14 @@ static TString *LoadString (LoadState *S) {
   else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */
     char buff[LUAI_MAXSHORTLEN];
     LoadVector(S, buff, size);
-    return luaS_newlstr(S->L, buff, size);
+    ts = luaS_newlstr(S->L, buff, size);
   }
   else {  /* long string */
-    TString *ts = luaS_createlngstrobj(S->L, size);
+    ts = luaS_createlngstrobj(S->L, size);
     LoadVector(S, getstr(ts), size);  /* load directly in final place */
-    return ts;
   }
+  luaC_objbarrier(S->L, p, ts);
+  return ts;
 }
 
 
@@ -140,7 +142,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
       break;
     case LUA_TSHRSTR:
     case LUA_TLNGSTR:
-      setsvalue2n(S->L, o, LoadString(S));
+      setsvalue2n(S->L, o, LoadString(S, f));
       break;
     default:
       lua_assert(0);
@@ -158,6 +160,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);
   }
 }
@@ -189,18 +192,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 = LoadString(S);
+    f->locvars[i].varname = LoadString(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 = LoadString(S);
+    f->upvalues[i].name = LoadString(S, f);
 }
 
 
 static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
-  f->source = LoadString(S);
+  f->source = LoadString(S, f);
   if (f->source == NULL)  /* no source in dump? */
     f->source = psource;  /* reuse parent's source */
   f->linedefined = LoadInt(S);
@@ -271,6 +274,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
   setclLvalue(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);