aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-04-23 17:57:42 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-04-23 17:57:42 -0300
commit3228a97c6a953dcf397944161bb64b12f1ff5384 (patch)
tree6497f6f8e93ba3bb381c0b48aed71646fca3f9b0 /lparser.c
parent0c16a42d61d08266033ff63bc5dfade6312b7359 (diff)
downloadlua-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.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/lparser.c b/lparser.c
index 6b87773e..1850d6dc 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
2177LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 2179LClosure *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