diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-18 15:56:45 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-18 15:56:45 -0300 |
| commit | f5eb809d3f1da13683cd02184042e67228206205 (patch) | |
| tree | 68177f3b093bce54c4293ae68bb2d9a9fc5ea496 | |
| parent | d71a548685eb3ac5ea598d6a9e7481389c558808 (diff) | |
| download | lua-f5eb809d3f1da13683cd02184042e67228206205.tar.gz lua-f5eb809d3f1da13683cd02184042e67228206205.tar.bz2 lua-f5eb809d3f1da13683cd02184042e67228206205.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.c | 3 | ||||
| -rw-r--r-- | lundump.c | 20 |
2 files changed, 15 insertions, 8 deletions
| @@ -544,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |||
| 544 | fs->bl = NULL; | 544 | fs->bl = NULL; |
| 545 | f = fs->f; | 545 | f = fs->f; |
| 546 | f->source = ls->source; | 546 | f->source = ls->source; |
| 547 | luaC_objbarrier(ls->L, f, f->source); | ||
| 547 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 548 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
| 548 | enterblock(fs, bl, 0); | 549 | enterblock(fs, bl, 0); |
| 549 | } | 550 | } |
| @@ -1616,6 +1617,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
| 1616 | fs->f->is_vararg = 1; /* main function is always declared vararg */ | 1617 | fs->f->is_vararg = 1; /* main function is always declared vararg */ |
| 1617 | init_exp(&v, VLOCAL, 0); /* create and... */ | 1618 | init_exp(&v, VLOCAL, 0); /* create and... */ |
| 1618 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ | 1619 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ |
| 1620 | luaC_objbarrier(ls->L, fs->f, ls->envn); | ||
| 1619 | luaX_next(ls); /* read first token */ | 1621 | luaX_next(ls); /* read first token */ |
| 1620 | statlist(ls); /* parse main body */ | 1622 | statlist(ls); /* parse main body */ |
| 1621 | check(ls, TK_EOS); | 1623 | check(ls, TK_EOS); |
| @@ -1634,6 +1636,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
| 1634 | sethvalue(L, L->top, lexstate.h); /* anchor it */ | 1636 | sethvalue(L, L->top, lexstate.h); /* anchor it */ |
| 1635 | luaD_inctop(L); | 1637 | luaD_inctop(L); |
| 1636 | funcstate.f = cl->p = luaF_newproto(L); | 1638 | funcstate.f = cl->p = luaF_newproto(L); |
| 1639 | luaC_objbarrier(L, cl, cl->p); | ||
| 1637 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 1640 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
| 1638 | lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ | 1641 | lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ |
| 1639 | lexstate.buff = buff; | 1642 | lexstate.buff = buff; |
| @@ -85,8 +85,9 @@ static lua_Integer LoadInteger (LoadState *S) { | |||
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | 87 | ||
| 88 | static TString *LoadString (LoadState *S) { | 88 | static TString *LoadString (LoadState *S, Proto *p) { |
| 89 | size_t size = LoadByte(S); | 89 | size_t size = LoadByte(S); |
| 90 | TString *ts; | ||
| 90 | if (size == 0xFF) | 91 | if (size == 0xFF) |
| 91 | LoadVar(S, size); | 92 | LoadVar(S, size); |
| 92 | if (size == 0) | 93 | if (size == 0) |
| @@ -94,13 +95,14 @@ static TString *LoadString (LoadState *S) { | |||
| 94 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ | 95 | else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ |
| 95 | char buff[LUAI_MAXSHORTLEN]; | 96 | char buff[LUAI_MAXSHORTLEN]; |
| 96 | LoadVector(S, buff, size); | 97 | LoadVector(S, buff, size); |
| 97 | return luaS_newlstr(S->L, buff, size); | 98 | ts = luaS_newlstr(S->L, buff, size); |
| 98 | } | 99 | } |
| 99 | else { /* long string */ | 100 | else { /* long string */ |
| 100 | TString *ts = luaS_createlngstrobj(S->L, size); | 101 | ts = luaS_createlngstrobj(S->L, size); |
| 101 | LoadVector(S, getstr(ts), size); /* load directly in final place */ | 102 | LoadVector(S, getstr(ts), size); /* load directly in final place */ |
| 102 | return ts; | ||
| 103 | } | 103 | } |
| 104 | luaC_objbarrier(S->L, p, ts); | ||
| 105 | return ts; | ||
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | 108 | ||
| @@ -140,7 +142,7 @@ static void LoadConstants (LoadState *S, Proto *f) { | |||
| 140 | break; | 142 | break; |
| 141 | case LUA_TSHRSTR: | 143 | case LUA_TSHRSTR: |
| 142 | case LUA_TLNGSTR: | 144 | case LUA_TLNGSTR: |
| 143 | setsvalue2n(S->L, o, LoadString(S)); | 145 | setsvalue2n(S->L, o, LoadString(S, f)); |
| 144 | break; | 146 | break; |
| 145 | default: | 147 | default: |
| 146 | lua_assert(0); | 148 | lua_assert(0); |
| @@ -158,6 +160,7 @@ static void LoadProtos (LoadState *S, Proto *f) { | |||
| 158 | f->p[i] = NULL; | 160 | f->p[i] = NULL; |
| 159 | for (i = 0; i < n; i++) { | 161 | for (i = 0; i < n; i++) { |
| 160 | f->p[i] = luaF_newproto(S->L); | 162 | f->p[i] = luaF_newproto(S->L); |
| 163 | luaC_objbarrier(S->L, f, f->p[i]); | ||
| 161 | LoadFunction(S, f->p[i], f->source); | 164 | LoadFunction(S, f->p[i], f->source); |
| 162 | } | 165 | } |
| 163 | } | 166 | } |
| @@ -189,18 +192,18 @@ static void LoadDebug (LoadState *S, Proto *f) { | |||
| 189 | for (i = 0; i < n; i++) | 192 | for (i = 0; i < n; i++) |
| 190 | f->locvars[i].varname = NULL; | 193 | f->locvars[i].varname = NULL; |
| 191 | for (i = 0; i < n; i++) { | 194 | for (i = 0; i < n; i++) { |
| 192 | f->locvars[i].varname = LoadString(S); | 195 | f->locvars[i].varname = LoadString(S, f); |
| 193 | f->locvars[i].startpc = LoadInt(S); | 196 | f->locvars[i].startpc = LoadInt(S); |
| 194 | f->locvars[i].endpc = LoadInt(S); | 197 | f->locvars[i].endpc = LoadInt(S); |
| 195 | } | 198 | } |
| 196 | n = LoadInt(S); | 199 | n = LoadInt(S); |
| 197 | for (i = 0; i < n; i++) | 200 | for (i = 0; i < n; i++) |
| 198 | f->upvalues[i].name = LoadString(S); | 201 | f->upvalues[i].name = LoadString(S, f); |
| 199 | } | 202 | } |
| 200 | 203 | ||
| 201 | 204 | ||
| 202 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { | 205 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { |
| 203 | f->source = LoadString(S); | 206 | f->source = LoadString(S, f); |
| 204 | if (f->source == NULL) /* no source in dump? */ | 207 | if (f->source == NULL) /* no source in dump? */ |
| 205 | f->source = psource; /* reuse parent's source */ | 208 | f->source = psource; /* reuse parent's source */ |
| 206 | f->linedefined = LoadInt(S); | 209 | f->linedefined = LoadInt(S); |
| @@ -271,6 +274,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { | |||
| 271 | setclLvalue(L, L->top, cl); | 274 | setclLvalue(L, L->top, cl); |
| 272 | luaD_inctop(L); | 275 | luaD_inctop(L); |
| 273 | cl->p = luaF_newproto(L); | 276 | cl->p = luaF_newproto(L); |
| 277 | luaC_objbarrier(L, cl, cl->p); | ||
| 274 | LoadFunction(&S, cl->p, NULL); | 278 | LoadFunction(&S, cl->p, NULL); |
| 275 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | 279 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); |
| 276 | luai_verifycode(L, buff, cl->p); | 280 | luai_verifycode(L, buff, cl->p); |
