diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2026-04-23 17:57:42 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2026-04-23 17:57:42 -0300 |
| commit | 3228a97c6a953dcf397944161bb64b12f1ff5384 (patch) | |
| tree | 6497f6f8e93ba3bb381c0b48aed71646fca3f9b0 /lparser.c | |
| parent | 0c16a42d61d08266033ff63bc5dfade6312b7359 (diff) | |
| download | lua-3228a97c6a953dcf397944161bb64b12f1ff5384.tar.gz lua-3228a97c6a953dcf397944161bb64b12f1ff5384.tar.bz2 lua-3228a97c6a953dcf397944161bb64b12f1ff5384.zip | |
Bug: 'lua_load' does not preserve the stack
'lua_load' does not preserve the stack through the calls to the
reader function, as it should. Immediately after the first call (to
detect whether chunk is binary) it adds stuff, and it also adds a new
table when starting the compilation of each new function.
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 23 |
1 files changed, 11 insertions, 12 deletions
| @@ -821,8 +821,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |||
| 821 | luaC_objbarrier(L, f, f->source); | 821 | luaC_objbarrier(L, f, f->source); |
| 822 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 822 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
| 823 | fs->kcache = luaH_new(L); /* create table for function */ | 823 | fs->kcache = luaH_new(L); /* create table for function */ |
| 824 | sethvalue2s(L, L->top.p, fs->kcache); /* anchor it */ | 824 | luaD_anchorobj(L, ls->h, obj2gco(fs->kcache)); /* anchor it */ |
| 825 | luaD_inctop(L); | ||
| 826 | enterblock(fs, bl, 0); | 825 | enterblock(fs, bl, 0); |
| 827 | } | 826 | } |
| 828 | 827 | ||
| @@ -831,6 +830,7 @@ static void close_func (LexState *ls) { | |||
| 831 | lua_State *L = ls->L; | 830 | lua_State *L = ls->L; |
| 832 | FuncState *fs = ls->fs; | 831 | FuncState *fs = ls->fs; |
| 833 | Proto *f = fs->f; | 832 | Proto *f = fs->f; |
| 833 | TValue temp; | ||
| 834 | luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ | 834 | luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ |
| 835 | leaveblock(fs); | 835 | leaveblock(fs); |
| 836 | lua_assert(fs->bl == NULL); | 836 | lua_assert(fs->bl == NULL); |
| @@ -843,8 +843,10 @@ static void close_func (LexState *ls) { | |||
| 843 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); | 843 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); |
| 844 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); | 844 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); |
| 845 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | 845 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); |
| 846 | /* remove kcache table from scanner table ("weigh" its anchor) */ | ||
| 847 | sethvalue(L, &temp, fs->kcache); /* key to be set to nil */ | ||
| 848 | luaH_set(L, ls->h, &temp, &G(L)->nilvalue); | ||
| 846 | ls->fs = fs->prev; | 849 | ls->fs = fs->prev; |
| 847 | L->top.p--; /* pop kcache table */ | ||
| 848 | luaC_checkGC(L); | 850 | luaC_checkGC(L); |
| 849 | } | 851 | } |
| 850 | 852 | ||
| @@ -2174,16 +2176,14 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
| 2174 | } | 2176 | } |
| 2175 | 2177 | ||
| 2176 | 2178 | ||
| 2177 | LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | 2179 | LClosure *luaY_parser (lua_State *L, ZIO *z, Table *anchor, Mbuffer *buff, |
| 2178 | Dyndata *dyd, const char *name, int firstchar) { | 2180 | Dyndata *dyd, const char *name, int firstchar) { |
| 2179 | LexState lexstate; | 2181 | LexState lexstate; |
| 2180 | FuncState funcstate; | 2182 | FuncState funcstate; |
| 2181 | LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ | 2183 | LClosure *cl; |
| 2182 | setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */ | 2184 | lexstate.h = anchor; /* table for scanner */ |
| 2183 | luaD_inctop(L); | 2185 | cl = luaF_newLclosure(L, 1); /* create main closure */ |
| 2184 | lexstate.h = luaH_new(L); /* create table for scanner */ | 2186 | luaD_anchorobj(L, anchor, obj2gco(cl)); /* anchor it in scanner table */ |
| 2185 | sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */ | ||
| 2186 | luaD_inctop(L); | ||
| 2187 | funcstate.f = cl->p = luaF_newproto(L); | 2187 | funcstate.f = cl->p = luaF_newproto(L); |
| 2188 | luaC_objbarrier(L, cl, cl->p); | 2188 | luaC_objbarrier(L, cl, cl->p); |
| 2189 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 2189 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
| @@ -2196,7 +2196,6 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
| 2196 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | 2196 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
| 2197 | /* all scopes should be correctly finished */ | 2197 | /* all scopes should be correctly finished */ |
| 2198 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); | 2198 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); |
| 2199 | L->top.p--; /* remove scanner's table */ | 2199 | return cl; |
| 2200 | return cl; /* closure is on the stack, too */ | ||
| 2201 | } | 2200 | } |
| 2202 | 2201 | ||
