aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c21
-rw-r--r--ldo.c17
-rw-r--r--ldo.h1
-rw-r--r--lgc.c8
-rw-r--r--lparser.c5
-rw-r--r--lstate.c5
-rw-r--r--ltests.c3
-rw-r--r--lua.h8
-rw-r--r--lvm.c3
-rwxr-xr-xmanual/2html2
-rw-r--r--testes/all.lua2
-rw-r--r--testes/api.lua4
-rw-r--r--testes/coroutine.lua19
-rw-r--r--testes/errors.lua4
-rw-r--r--testes/events.lua13
-rw-r--r--testes/gc.lua10
16 files changed, 102 insertions, 23 deletions
diff --git a/ldebug.c b/ldebug.c
index 591b3528..7264fce8 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -37,6 +37,9 @@
37static const char *funcnamefromcall (lua_State *L, CallInfo *ci, 37static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
38 const char **name); 38 const char **name);
39 39
40static const char strlocal[] = "local";
41static const char strupval[] = "upvalue";
42
40 43
41static int currentpc (CallInfo *ci) { 44static int currentpc (CallInfo *ci) {
42 lua_assert(isLua(ci)); 45 lua_assert(isLua(ci));
@@ -497,7 +500,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
497 int pc = *ppc; 500 int pc = *ppc;
498 *name = luaF_getlocalname(p, reg + 1, pc); 501 *name = luaF_getlocalname(p, reg + 1, pc);
499 if (*name) /* is a local? */ 502 if (*name) /* is a local? */
500 return "local"; 503 return strlocal;
501 /* else try symbolic execution */ 504 /* else try symbolic execution */
502 *ppc = pc = findsetreg(p, pc, reg); 505 *ppc = pc = findsetreg(p, pc, reg);
503 if (pc != -1) { /* could find instruction? */ 506 if (pc != -1) { /* could find instruction? */
@@ -512,7 +515,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
512 } 515 }
513 case OP_GETUPVAL: { 516 case OP_GETUPVAL: {
514 *name = upvalname(p, GETARG_B(i)); 517 *name = upvalname(p, GETARG_B(i));
515 return "upvalue"; 518 return strupval;
516 } 519 }
517 case OP_LOADK: return kname(p, GETARG_Bx(i), name); 520 case OP_LOADK: return kname(p, GETARG_Bx(i), name);
518 case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); 521 case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
@@ -547,15 +550,21 @@ static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
547 550
548/* 551/*
549** Check whether table being indexed by instruction 'i' is the 552** Check whether table being indexed by instruction 'i' is the
550** environment '_ENV' 553** environment '_ENV'. If the table is an upvalue, get its name;
554** otherwise, find some "name" for the table and check whether
555** that name is the name of a local variable (and not, for instance,
556** a string). Then check that, if there is a name, it is '_ENV'.
551*/ 557*/
552static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { 558static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
553 int t = GETARG_B(i); /* table index */ 559 int t = GETARG_B(i); /* table index */
554 const char *name; /* name of indexed variable */ 560 const char *name; /* name of indexed variable */
555 if (isup) /* is 't' an upvalue? */ 561 if (isup) /* is 't' an upvalue? */
556 name = upvalname(p, t); 562 name = upvalname(p, t);
557 else /* 't' is a register */ 563 else { /* 't' is a register */
558 basicgetobjname(p, &pc, t, &name); 564 const char *what = basicgetobjname(p, &pc, t, &name);
565 if (what != strlocal && what != strupval)
566 name = NULL; /* cannot be the variable _ENV */
567 }
559 return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; 568 return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
560} 569}
561 570
@@ -701,7 +710,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
701 for (i = 0; i < c->nupvalues; i++) { 710 for (i = 0; i < c->nupvalues; i++) {
702 if (c->upvals[i]->v.p == o) { 711 if (c->upvals[i]->v.p == o) {
703 *name = upvalname(c->p, i); 712 *name = upvalname(c->p, i);
704 return "upvalue"; 713 return strupval;
705 } 714 }
706 } 715 }
707 return NULL; 716 return NULL;
diff --git a/ldo.c b/ldo.c
index ea052950..c92573d6 100644
--- a/ldo.c
+++ b/ldo.c
@@ -94,10 +94,6 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
94 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ 94 setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
95 break; 95 break;
96 } 96 }
97 case LUA_ERRERR: {
98 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
99 break;
100 }
101 case LUA_OK: { /* special case only for closing upvalues */ 97 case LUA_OK: { /* special case only for closing upvalues */
102 setnilvalue(s2v(oldtop)); /* no error message */ 98 setnilvalue(s2v(oldtop)); /* no error message */
103 break; 99 break;
@@ -120,6 +116,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
120 else { /* thread has no error handler */ 116 else { /* thread has no error handler */
121 global_State *g = G(L); 117 global_State *g = G(L);
122 errcode = luaE_resetthread(L, errcode); /* close all upvalues */ 118 errcode = luaE_resetthread(L, errcode); /* close all upvalues */
119 L->status = errcode;
123 if (g->mainthread->errorJmp) { /* main thread has a handler? */ 120 if (g->mainthread->errorJmp) { /* main thread has a handler? */
124 setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */ 121 setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
125 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ 122 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
@@ -198,6 +195,16 @@ static void correctstack (lua_State *L) {
198/* some space for error handling */ 195/* some space for error handling */
199#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) 196#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
200 197
198
199/* raise an error while running the message handler */
200l_noret luaD_errerr (lua_State *L) {
201 TString *msg = luaS_newliteral(L, "error in error handling");
202 setsvalue2s(L, L->top.p, msg);
203 L->top.p++; /* assume EXTRA_STACK */
204 luaD_throw(L, LUA_ERRERR);
205}
206
207
201/* 208/*
202** Reallocate the stack to a new size, correcting all pointers into it. 209** Reallocate the stack to a new size, correcting all pointers into it.
203** In ISO C, any pointer use after the pointer has been deallocated is 210** In ISO C, any pointer use after the pointer has been deallocated is
@@ -247,7 +254,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
247 a stack error; cannot grow further than that. */ 254 a stack error; cannot grow further than that. */
248 lua_assert(stacksize(L) == ERRORSTACKSIZE); 255 lua_assert(stacksize(L) == ERRORSTACKSIZE);
249 if (raiseerror) 256 if (raiseerror)
250 luaD_throw(L, LUA_ERRERR); /* error inside message handler */ 257 luaD_errerr(L); /* error inside message handler */
251 return 0; /* if not 'raiseerror', just signal it */ 258 return 0; /* if not 'raiseerror', just signal it */
252 } 259 }
253 else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ 260 else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
diff --git a/ldo.h b/ldo.h
index 56008ab3..4de9540e 100644
--- a/ldo.h
+++ b/ldo.h
@@ -60,6 +60,7 @@
60/* type of protected functions, to be ran by 'runprotected' */ 60/* type of protected functions, to be ran by 'runprotected' */
61typedef void (*Pfunc) (lua_State *L, void *ud); 61typedef void (*Pfunc) (lua_State *L, void *ud);
62 62
63LUAI_FUNC l_noret luaD_errerr (lua_State *L);
63LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 64LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
64LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 65LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
65 const char *mode); 66 const char *mode);
diff --git a/lgc.c b/lgc.c
index 5817f9ee..c01660ab 100644
--- a/lgc.c
+++ b/lgc.c
@@ -553,8 +553,12 @@ static lu_mem traversetable (global_State *g, Table *h) {
553 traverseweakvalue(g, h); 553 traverseweakvalue(g, h);
554 else if (!weakvalue) /* strong values? */ 554 else if (!weakvalue) /* strong values? */
555 traverseephemeron(g, h, 0); 555 traverseephemeron(g, h, 0);
556 else /* all weak */ 556 else { /* all weak */
557 linkgclist(h, g->allweak); /* nothing to traverse now */ 557 if (g->gcstate == GCSpropagate)
558 linkgclist(h, g->grayagain); /* must visit again its metatable */
559 else
560 linkgclist(h, g->allweak); /* must clear collected entries */
561 }
558 } 562 }
559 else /* not weak */ 563 else /* not weak */
560 traversestrongtable(g, h); 564 traversestrongtable(g, h);
diff --git a/lparser.c b/lparser.c
index aebddaf7..1ac82990 100644
--- a/lparser.c
+++ b/lparser.c
@@ -849,12 +849,11 @@ static void recfield (LexState *ls, ConsControl *cc) {
849 FuncState *fs = ls->fs; 849 FuncState *fs = ls->fs;
850 int reg = ls->fs->freereg; 850 int reg = ls->fs->freereg;
851 expdesc tab, key, val; 851 expdesc tab, key, val;
852 if (ls->t.token == TK_NAME) { 852 if (ls->t.token == TK_NAME)
853 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
854 codename(ls, &key); 853 codename(ls, &key);
855 }
856 else /* ls->t.token == '[' */ 854 else /* ls->t.token == '[' */
857 yindex(ls, &key); 855 yindex(ls, &key);
856 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
858 cc->nh++; 857 cc->nh++;
859 checknext(ls, '='); 858 checknext(ls, '=');
860 tab = *cc->t; 859 tab = *cc->t;
diff --git a/lstate.c b/lstate.c
index 7fefacba..f3f2ccfd 100644
--- a/lstate.c
+++ b/lstate.c
@@ -166,7 +166,7 @@ void luaE_checkcstack (lua_State *L) {
166 if (getCcalls(L) == LUAI_MAXCCALLS) 166 if (getCcalls(L) == LUAI_MAXCCALLS)
167 luaG_runerror(L, "C stack overflow"); 167 luaG_runerror(L, "C stack overflow");
168 else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) 168 else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
169 luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ 169 luaD_errerr(L); /* error while handling stack error */
170} 170}
171 171
172 172
@@ -272,7 +272,9 @@ static void close_state (lua_State *L) {
272 luaC_freeallobjects(L); /* just collect its objects */ 272 luaC_freeallobjects(L); /* just collect its objects */
273 else { /* closing a fully built state */ 273 else { /* closing a fully built state */
274 L->ci = &L->base_ci; /* unwind CallInfo list */ 274 L->ci = &L->base_ci; /* unwind CallInfo list */
275 L->errfunc = 0; /* stack unwind can "throw away" the error function */
275 luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ 276 luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
277 L->top.p = L->stack.p + 1; /* empty the stack to run finalizers */
276 luaC_freeallobjects(L); /* collect all objects */ 278 luaC_freeallobjects(L); /* collect all objects */
277 luai_userstateclose(L); 279 luai_userstateclose(L);
278 } 280 }
@@ -328,6 +330,7 @@ int luaE_resetthread (lua_State *L, int status) {
328 if (status == LUA_YIELD) 330 if (status == LUA_YIELD)
329 status = LUA_OK; 331 status = LUA_OK;
330 L->status = LUA_OK; /* so it can run __close metamethods */ 332 L->status = LUA_OK; /* so it can run __close metamethods */
333 L->errfunc = 0; /* stack unwind can "throw away" the error function */
331 status = luaD_closeprotected(L, 1, status); 334 status = luaD_closeprotected(L, 1, status);
332 if (status != LUA_OK) /* errors? */ 335 if (status != LUA_OK) /* errors? */
333 luaD_seterrorobj(L, status, L->stack.p + 1); 336 luaD_seterrorobj(L, status, L->stack.p + 1);
diff --git a/ltests.c b/ltests.c
index a27cdb07..af0f43e2 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1655,6 +1655,9 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1655 int level = getnum; 1655 int level = getnum;
1656 luaL_traceback(L1, L1, msg, level); 1656 luaL_traceback(L1, L1, msg, level);
1657 } 1657 }
1658 else if EQ("threadstatus") {
1659 lua_pushstring(L1, statcodes[lua_status(L1)]);
1660 }
1658 else if EQ("return") { 1661 else if EQ("return") {
1659 int n = getnum; 1662 int n = getnum;
1660 if (L1 != L) { 1663 if (L1 != L) {
diff --git a/lua.h b/lua.h
index f050dac0..f3ea590d 100644
--- a/lua.h
+++ b/lua.h
@@ -18,14 +18,14 @@
18 18
19#define LUA_VERSION_MAJOR "5" 19#define LUA_VERSION_MAJOR "5"
20#define LUA_VERSION_MINOR "4" 20#define LUA_VERSION_MINOR "4"
21#define LUA_VERSION_RELEASE "7" 21#define LUA_VERSION_RELEASE "8"
22 22
23#define LUA_VERSION_NUM 504 23#define LUA_VERSION_NUM 504
24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7) 24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 8)
25 25
26#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR 26#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
27#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE 27#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
28#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio" 28#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2025 Lua.org, PUC-Rio"
29#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" 29#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
30 30
31 31
@@ -497,7 +497,7 @@ struct lua_Debug {
497 497
498 498
499/****************************************************************************** 499/******************************************************************************
500* Copyright (C) 1994-2024 Lua.org, PUC-Rio. 500* Copyright (C) 1994-2025 Lua.org, PUC-Rio.
501* 501*
502* Permission is hereby granted, free of charge, to any person obtaining 502* Permission is hereby granted, free of charge, to any person obtaining
503* a copy of this software and associated documentation files (the 503* a copy of this software and associated documentation files (the
diff --git a/lvm.c b/lvm.c
index fcd24e11..7023a04d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -339,7 +339,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
339 lua_assert(isempty(slot)); /* slot must be empty */ 339 lua_assert(isempty(slot)); /* slot must be empty */
340 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 340 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
341 if (tm == NULL) { /* no metamethod? */ 341 if (tm == NULL) { /* no metamethod? */
342 sethvalue2s(L, L->top.p, h); /* anchor 't' */
343 L->top.p++; /* assume EXTRA_STACK */
342 luaH_finishset(L, h, key, slot, val); /* set new value */ 344 luaH_finishset(L, h, key, slot, val); /* set new value */
345 L->top.p--;
343 invalidateTMcache(h); 346 invalidateTMcache(h);
344 luaC_barrierback(L, obj2gco(h), val); 347 luaC_barrierback(L, obj2gco(h), val);
345 return; 348 return;
diff --git a/manual/2html b/manual/2html
index 4a3e5771..1588c1e6 100755
--- a/manual/2html
+++ b/manual/2html
@@ -30,7 +30,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
30<p> 30<p>
31<small> 31<small>
32<a href="http://www.lua.org/copyright.html">Copyright</a> 32<a href="http://www.lua.org/copyright.html">Copyright</a>
33&copy; 2024 Lua.org, PUC-Rio. All rights reserved. 33&copy; 2025 Lua.org, PUC-Rio. All rights reserved.
34</small> 34</small>
35<hr> 35<hr>
36 36
diff --git a/testes/all.lua b/testes/all.lua
index 5df0ff9b..413d4da2 100644
--- a/testes/all.lua
+++ b/testes/all.lua
@@ -287,7 +287,7 @@ print("final OK !!!")
287 287
288--[[ 288--[[
289***************************************************************************** 289*****************************************************************************
290* Copyright (C) 1994-2016 Lua.org, PUC-Rio. 290* Copyright (C) 1994-2025 Lua.org, PUC-Rio.
291* 291*
292* Permission is hereby granted, free of charge, to any person obtaining 292* Permission is hereby granted, free of charge, to any person obtaining
293* a copy of this software and associated documentation files (the 293* a copy of this software and associated documentation files (the
diff --git a/testes/api.lua b/testes/api.lua
index 752ff18f..eab3059b 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -399,6 +399,10 @@ do
399 -- trivial error 399 -- trivial error
400 assert(T.checkpanic("pushstring hi; error") == "hi") 400 assert(T.checkpanic("pushstring hi; error") == "hi")
401 401
402 -- thread status inside panic (bug in 5.4.4)
403 assert(T.checkpanic("pushstring hi; error", "threadstatus; return 2") ==
404 "ERRRUN")
405
402 -- using the stack inside panic 406 -- using the stack inside panic
403 assert(T.checkpanic("pushstring hi; error;", 407 assert(T.checkpanic("pushstring hi; error;",
404 [[checkstack 5 XX 408 [[checkstack 5 XX
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index e566c86e..03e04451 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -493,6 +493,25 @@ assert(not pcall(a, a))
493a = nil 493a = nil
494 494
495 495
496do
497 -- bug in 5.4: thread can use message handler higher in the stack
498 -- than the variable being closed
499 local c = coroutine.create(function()
500 local clo <close> = setmetatable({}, {__close=function()
501 local x = 134 -- will overwrite message handler
502 error(x)
503 end})
504 -- yields coroutine but leaves a new message handler for it,
505 -- that would be used when closing the coroutine (except that it
506 -- will be overwritten)
507 xpcall(coroutine.yield, function() return "XXX" end)
508 end)
509
510 assert(coroutine.resume(c)) -- start coroutine
511 local st, msg = coroutine.close(c)
512 assert(not st and msg == 134)
513end
514
496-- access to locals of erroneous coroutines 515-- access to locals of erroneous coroutines
497local x = coroutine.create (function () 516local x = coroutine.create (function ()
498 local a = 10 517 local a = 10
diff --git a/testes/errors.lua b/testes/errors.lua
index 80d91a92..15401b4f 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -137,6 +137,10 @@ checkmessage("aaa=(1)..{}", "a table value")
137-- bug in 5.4.6 137-- bug in 5.4.6
138checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") 138checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
139 139
140-- a similar bug in 5.4.7, since 5.4.0
141checkmessage("print(('_ENV').x + 1)", "field 'x'")
142
143
140_G.aaa, _G.bbbb = nil 144_G.aaa, _G.bbbb = nil
141 145
142-- calls 146-- calls
diff --git a/testes/events.lua b/testes/events.lua
index 8d8563b9..def13dc8 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -370,6 +370,19 @@ x = 0 .."a".."b"..c..d.."e".."f".."g"
370assert(x.val == "0abcdefg") 370assert(x.val == "0abcdefg")
371 371
372 372
373do
374 -- bug since 5.4.1
375 local mt = setmetatable({__newindex={}}, {__mode='v'})
376 local t = setmetatable({}, mt)
377
378 if T then T.allocfailnext() end
379
380 -- seg. fault
381 for i=1, 10 do t[i] = 1 end
382end
383
384
385
373-- concat metamethod x numbers (bug in 5.1.1) 386-- concat metamethod x numbers (bug in 5.1.1)
374c = {} 387c = {}
375local x 388local x
diff --git a/testes/gc.lua b/testes/gc.lua
index 03093e34..f017f330 100644
--- a/testes/gc.lua
+++ b/testes/gc.lua
@@ -301,6 +301,16 @@ collectgarbage()
301assert(next(a) == string.rep('$', 11)) 301assert(next(a) == string.rep('$', 11))
302 302
303 303
304if T then -- bug since 5.3: all-weak tables are not being revisited
305 T.gcstate("propagate")
306 local t = setmetatable({}, {__mode = "kv"})
307 T.gcstate("atomic") -- 't' was visited
308 setmetatable(t, {__mode = "kv"})
309 T.gcstate("pause") -- its new metatable is not being visited
310 assert(getmetatable(t).__mode == "kv")
311end
312
313
304-- 'bug' in 5.1 314-- 'bug' in 5.1
305a = {} 315a = {}
306local t = {x = 10} 316local t = {x = 10}