aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c1
-rw-r--r--lauxlib.c17
-rw-r--r--ldo.c21
-rw-r--r--ldo.h1
-rw-r--r--lgc.c7
-rw-r--r--lparser.c2
-rw-r--r--lstate.c17
-rw-r--r--lstate.h2
-rw-r--r--lstrlib.c3
-rw-r--r--lua.h8
-rw-r--r--lutf8lib.c4
-rw-r--r--lvm.c7
-rwxr-xr-xmanual/2html9
-rw-r--r--manual/manual.of18
-rw-r--r--testes/events.lua10
15 files changed, 93 insertions, 34 deletions
diff --git a/lapi.c b/lapi.c
index 04e09cff..588ab333 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1089,6 +1089,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
1089 ZIO z; 1089 ZIO z;
1090 int status; 1090 int status;
1091 lua_lock(L); 1091 lua_lock(L);
1092 luaC_checkGC(L);
1092 if (!chunkname) chunkname = "?"; 1093 if (!chunkname) chunkname = "?";
1093 luaZ_init(L, &z, reader, data); 1094 luaZ_init(L, &z, reader, data);
1094 status = luaD_protectedparser(L, &z, chunkname, mode); 1095 status = luaD_protectedparser(L, &z, chunkname, mode);
diff --git a/lauxlib.c b/lauxlib.c
index 923105ed..f9a45384 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -501,12 +501,25 @@ static const luaL_Reg boxmt[] = { /* box metamethods */
501}; 501};
502 502
503 503
504/*
505** Get/create metatable (MT) for boxes
506*/
507static void getBoxMT (lua_State *L) {
508 const char *BOXMT = "_UBOX*"; /* key for the metatable */
509 if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */
510 luaL_newlibtable(L, boxmt); /* create it */
511 luaL_setfuncs(L, boxmt, 0); /* initialize it */
512 lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */
513 lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */
514 }
515}
516
517
504static void newbox (lua_State *L) { 518static void newbox (lua_State *L) {
505 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); 519 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
506 box->box = NULL; 520 box->box = NULL;
507 box->bsize = 0; 521 box->bsize = 0;
508 if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ 522 getBoxMT(L);
509 luaL_setfuncs(L, boxmt, 0); /* set its metamethods */
510 lua_setmetatable(L, -2); 523 lua_setmetatable(L, -2);
511} 524}
512 525
diff --git a/ldo.c b/ldo.c
index c92573d6..8085b735 100644
--- a/ldo.c
+++ b/ldo.c
@@ -206,6 +206,25 @@ l_noret luaD_errerr (lua_State *L) {
206 206
207 207
208/* 208/*
209** Check whether stacks have enough space to run a simple function (such
210** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two
211** available CallInfos, and two "slots" in the C stack.
212*/
213int luaD_checkminstack (lua_State *L) {
214 if (getCcalls(L) >= LUAI_MAXCCALLS - 2)
215 return 0; /* not enough C-stack slots */
216 if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL)
217 return 0; /* unable to allocate first ci */
218 if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL)
219 return 0; /* unable to allocate second ci */
220 if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE)
221 return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */
222 else /* try to grow stack to a size with enough free slots */
223 return luaD_growstack(L, BASIC_STACK_SIZE, 0);
224}
225
226
227/*
209** Reallocate the stack to a new size, correcting all pointers into it. 228** Reallocate the stack to a new size, correcting all pointers into it.
210** In ISO C, any pointer use after the pointer has been deallocated is 229** In ISO C, any pointer use after the pointer has been deallocated is
211** undefined behavior. So, before the reallocation, all pointers are 230** undefined behavior. So, before the reallocation, all pointers are
@@ -503,7 +522,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
503 522
504 523
505 524
506#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) 525#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1))
507 526
508 527
509l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, 528l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
diff --git a/ldo.h b/ldo.h
index 4de9540e..4c8db865 100644
--- a/ldo.h
+++ b/ldo.h
@@ -80,6 +80,7 @@ LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror);
80LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 80LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror);
81LUAI_FUNC void luaD_shrinkstack (lua_State *L); 81LUAI_FUNC void luaD_shrinkstack (lua_State *L);
82LUAI_FUNC void luaD_inctop (lua_State *L); 82LUAI_FUNC void luaD_inctop (lua_State *L);
83LUAI_FUNC int luaD_checkminstack (lua_State *L);
83 84
84LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 85LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
85LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 86LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
diff --git a/lgc.c b/lgc.c
index c01660ab..52cea240 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1242,7 +1242,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
1242 correctgraylists(g); 1242 correctgraylists(g);
1243 checkSizes(L, g); 1243 checkSizes(L, g);
1244 g->gcstate = GCSpropagate; /* skip restart */ 1244 g->gcstate = GCSpropagate; /* skip restart */
1245 if (!g->gcemergency) 1245 if (g->tobefnz != NULL && !g->gcemergency && luaD_checkminstack(L))
1246 callallpendingfinalizers(L); 1246 callallpendingfinalizers(L);
1247} 1247}
1248 1248
@@ -1632,11 +1632,12 @@ static lu_mem singlestep (lua_State *L) {
1632 break; 1632 break;
1633 } 1633 }
1634 case GCScallfin: { /* call remaining finalizers */ 1634 case GCScallfin: { /* call remaining finalizers */
1635 if (g->tobefnz && !g->gcemergency) { 1635 if (g->tobefnz && !g->gcemergency && luaD_checkminstack(L)) {
1636 g->gcstopem = 0; /* ok collections during finalizers */ 1636 g->gcstopem = 0; /* ok collections during finalizers */
1637 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; 1637 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST;
1638 } 1638 }
1639 else { /* emergency mode or no more finalizers */ 1639 else { /* no more finalizers or emergency mode or no enough stack
1640 to run finalizers */
1640 g->gcstate = GCSpause; /* finish collection */ 1641 g->gcstate = GCSpause; /* finish collection */
1641 work = 0; 1642 work = 0;
1642 } 1643 }
diff --git a/lparser.c b/lparser.c
index 1ac82990..f4bfc963 100644
--- a/lparser.c
+++ b/lparser.c
@@ -940,6 +940,8 @@ static void constructor (LexState *ls, expdesc *t) {
940 if (ls->t.token == '}') break; 940 if (ls->t.token == '}') break;
941 closelistfield(fs, &cc); 941 closelistfield(fs, &cc);
942 field(ls, &cc); 942 field(ls, &cc);
943 checklimit(fs, cc.tostore + cc.na + cc.nh, INT_MAX/2,
944 "items in a constructor");
943 } while (testnext(ls, ',') || testnext(ls, ';')); 945 } while (testnext(ls, ',') || testnext(ls, ';'));
944 check_match(ls, '}', '{', line); 946 check_match(ls, '}', '{', line);
945 lastlistfield(fs, &cc); 947 lastlistfield(fs, &cc);
diff --git a/lstate.c b/lstate.c
index f3f2ccfd..059be806 100644
--- a/lstate.c
+++ b/lstate.c
@@ -102,14 +102,19 @@ LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) {
102} 102}
103 103
104 104
105CallInfo *luaE_extendCI (lua_State *L) { 105CallInfo *luaE_extendCI (lua_State *L, int err) {
106 CallInfo *ci; 106 CallInfo *ci;
107 lua_assert(L->ci->next == NULL); 107 ci = luaM_reallocvector(L, NULL, 0, 1, CallInfo);
108 ci = luaM_new(L, CallInfo); 108 if (l_unlikely(ci == NULL)) { /* allocation failed? */
109 lua_assert(L->ci->next == NULL); 109 if (err)
110 L->ci->next = ci; 110 luaM_error(L); /* raise the error */
111 return NULL; /* else only report it */
112 }
113 ci->next = L->ci->next;
111 ci->previous = L->ci; 114 ci->previous = L->ci;
112 ci->next = NULL; 115 L->ci->next = ci;
116 if (ci->next)
117 ci->next->previous = ci;
113 ci->u.l.trap = 0; 118 ci->u.l.trap = 0;
114 L->nci++; 119 L->nci++;
115 return ci; 120 return ci;
diff --git a/lstate.h b/lstate.h
index 007704c8..97bb3e8f 100644
--- a/lstate.h
+++ b/lstate.h
@@ -395,7 +395,7 @@ union GCUnion {
395 395
396LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 396LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
397LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 397LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
398LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 398LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L, int err);
399LUAI_FUNC void luaE_shrinkCI (lua_State *L); 399LUAI_FUNC void luaE_shrinkCI (lua_State *L);
400LUAI_FUNC void luaE_checkcstack (lua_State *L); 400LUAI_FUNC void luaE_checkcstack (lua_State *L);
401LUAI_FUNC void luaE_incCstack (lua_State *L); 401LUAI_FUNC void luaE_incCstack (lua_State *L);
diff --git a/lstrlib.c b/lstrlib.c
index 03167161..f748bf88 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -757,7 +757,6 @@ static int nospecials (const char *p, size_t l) {
757static void prepstate (MatchState *ms, lua_State *L, 757static void prepstate (MatchState *ms, lua_State *L,
758 const char *s, size_t ls, const char *p, size_t lp) { 758 const char *s, size_t ls, const char *p, size_t lp) {
759 ms->L = L; 759 ms->L = L;
760 ms->matchdepth = MAXCCALLS;
761 ms->src_init = s; 760 ms->src_init = s;
762 ms->src_end = s + ls; 761 ms->src_end = s + ls;
763 ms->p_end = p + lp; 762 ms->p_end = p + lp;
@@ -765,8 +764,8 @@ static void prepstate (MatchState *ms, lua_State *L,
765 764
766 765
767static void reprepstate (MatchState *ms) { 766static void reprepstate (MatchState *ms) {
767 ms->matchdepth = MAXCCALLS;
768 ms->level = 0; 768 ms->level = 0;
769 lua_assert(ms->matchdepth == MAXCCALLS);
770} 769}
771 770
772 771
diff --git a/lua.h b/lua.h
index f3ea590d..211b97cf 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 "8" 21#define LUA_VERSION_RELEASE "9"
22 22
23#define LUA_VERSION_NUM 504 23#define LUA_VERSION_NUM 504
24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 8) 24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 9)
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-2025 Lua.org, PUC-Rio" 28#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2026 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-2025 Lua.org, PUC-Rio. 500* Copyright (C) 1994-2026 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/lutf8lib.c b/lutf8lib.c
index 3a5b9bc3..e41a8255 100644
--- a/lutf8lib.c
+++ b/lutf8lib.c
@@ -65,6 +65,8 @@ static const char *utf8_decode (const char *s, utfint *val, int strict) {
65 utfint res = 0; /* final result */ 65 utfint res = 0; /* final result */
66 if (c < 0x80) /* ascii? */ 66 if (c < 0x80) /* ascii? */
67 res = c; 67 res = c;
68 else if (c >= 0xfe) /* c >= 1111 1110b ? */
69 return NULL; /* would need six or more continuation bytes */
68 else { 70 else {
69 int count = 0; /* to count number of continuation bytes */ 71 int count = 0; /* to count number of continuation bytes */
70 for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ 72 for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */
@@ -74,7 +76,7 @@ static const char *utf8_decode (const char *s, utfint *val, int strict) {
74 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 76 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
75 } 77 }
76 res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ 78 res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */
77 if (count > 5 || res > MAXUTF || res < limits[count]) 79 if (res > MAXUTF || res < limits[count])
78 return NULL; /* invalid byte sequence */ 80 return NULL; /* invalid byte sequence */
79 s += count; /* skip continuation bytes read */ 81 s += count; /* skip continuation bytes read */
80 } 82 }
diff --git a/lvm.c b/lvm.c
index 7023a04d..bbadf0a6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -361,7 +361,12 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
361 } 361 }
362 t = tm; /* else repeat assignment over 'tm' */ 362 t = tm; /* else repeat assignment over 'tm' */
363 if (luaV_fastget(L, t, key, slot, luaH_get)) { 363 if (luaV_fastget(L, t, key, slot, luaH_get)) {
364 luaV_finishfastset(L, t, slot, val); 364 /* execute 'luaV_finishfastset', but preserving the original 't'
365 for the barrier. 't' and 'slot' can point to the same value,
366 and so the assignment can change 't' value */
367 GCObject *h = gcvalue(t);
368 setobj2t(L, cast(TValue *,slot), val);
369 luaC_barrierback(L, h, val);
365 return; /* done */ 370 return; /* done */
366 } 371 }
367 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ 372 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */
diff --git a/manual/2html b/manual/2html
index 1588c1e6..f7952bd6 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; 2025 Lua.org, PUC-Rio. All rights reserved. 33&copy; 2026 Lua.org, PUC-Rio. All rights reserved.
34</small> 34</small>
35<hr> 35<hr>
36 36
@@ -58,7 +58,7 @@ end
58 58
59local function compose (f,g) 59local function compose (f,g)
60 assert(f and g) 60 assert(f and g)
61 return function (s) return g(f(s)) end 61 return function (...) return g(f(...)) end
62end 62end
63 63
64local function concat (f, g) 64local function concat (f, g)
@@ -395,9 +395,10 @@ APIEntry = function (e)
395 local apiicmd, ne = string.match(e, "^(.-</span>)(.*)") 395 local apiicmd, ne = string.match(e, "^(.-</span>)(.*)")
396--io.stderr:write(e) 396--io.stderr:write(e)
397 if not apiicmd then 397 if not apiicmd then
398 return antipara(Tag.hr() .. Tag.h3(a)) .. Tag.pre(h) .. e 398 return antipara(Tag.hr() .. Tag.h3(a)) .. Tag.pre(h, {class="api"}) .. e
399 else 399 else
400 return antipara(Tag.hr() .. Tag.h3(a)) .. apiicmd .. Tag.pre(h) .. ne 400 return antipara(Tag.hr() .. Tag.h3(a)) .. apiicmd ..
401 Tag.pre(h, {class="api"}) .. ne
401 end 402 end
402end, 403end,
403 404
diff --git a/manual/manual.of b/manual/manual.of
index da71fbe9..e565ea7e 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -107,7 +107,7 @@ for small machines and embedded systems.
107 107
108Unless stated otherwise, 108Unless stated otherwise,
109any overflow when manipulating integer values @def{wrap around}, 109any overflow when manipulating integer values @def{wrap around},
110according to the usual rules of two-complement arithmetic. 110according to the usual rules of two's complement arithmetic.
111(In other words, 111(In other words,
112the actual result is the unique representable integer 112the actual result is the unique representable integer
113that is equal modulo @M{2@sp{n}} to the mathematical result, 113that is equal modulo @M{2@sp{n}} to the mathematical result,
@@ -609,7 +609,7 @@ as soon as the collector can be sure the object
609will not be accessed again in the normal execution of the program. 609will not be accessed again in the normal execution of the program.
610(@Q{Normal execution} here excludes finalizers, 610(@Q{Normal execution} here excludes finalizers,
611which can resurrect dead objects @see{finalizers}, 611which can resurrect dead objects @see{finalizers},
612and excludes also operations using the debug library.) 612and it excludes also operations using the debug library.)
613Note that the time when the collector can be sure that an object 613Note that the time when the collector can be sure that an object
614is dead may not coincide with the programmer's expectations. 614is dead may not coincide with the programmer's expectations.
615The only guarantees are that Lua will not collect an object 615The only guarantees are that Lua will not collect an object
@@ -1950,12 +1950,12 @@ Note that keys that are not positive integers
1950do not interfere with borders. 1950do not interfere with borders.
1951 1951
1952A table with exactly one border is called a @def{sequence}. 1952A table with exactly one border is called a @def{sequence}.
1953For instance, the table @T{{10, 20, 30, 40, 50}} is a sequence, 1953For instance, the table @T{{10,20,30,40,50}} is a sequence,
1954as it has only one border (5). 1954as it has only one border (5).
1955The table @T{{10, 20, 30, nil, 50}} has two borders (3 and 5), 1955The table @T{{10,20,30,nil,50}} has two borders (3 and 5),
1956and therefore it is not a sequence. 1956and therefore it is not a sequence.
1957(The @nil at index 4 is called a @emphx{hole}.) 1957(The @nil at index 4 is called a @emphx{hole}.)
1958The table @T{{nil, 20, 30, nil, nil, 60, nil}} 1958The table @T{{nil,20,30,nil,nil,60,nil}}
1959has three borders (0, 3, and 6), 1959has three borders (0, 3, and 6),
1960so it is not a sequence, too. 1960so it is not a sequence, too.
1961The table @T{{}} is a sequence with border 0. 1961The table @T{{}} is a sequence with border 0.
@@ -2318,7 +2318,7 @@ we recommend assigning the vararg expression
2318to a single variable and using that variable 2318to a single variable and using that variable
2319in its place. 2319in its place.
2320 2320
2321Here are some examples of uses of mutlres expressions. 2321Here are some examples of uses of multires expressions.
2322In all cases, when the construction needs 2322In all cases, when the construction needs
2323@Q{the n-th result} and there is no such result, 2323@Q{the n-th result} and there is no such result,
2324it uses a @nil. 2324it uses a @nil.
@@ -3471,9 +3471,9 @@ because a pseudo-index is not an actual stack position.
3471The type of integers in Lua. 3471The type of integers in Lua.
3472 3472
3473By default this type is @id{long long}, 3473By default this type is @id{long long},
3474(usually a 64-bit two-complement integer), 3474(usually a 64-bit two's complement integer),
3475but that can be changed to @id{long} or @id{int} 3475but that can be changed to @id{long} or @id{int}
3476(usually a 32-bit two-complement integer). 3476(usually a 32-bit two's complement integer).
3477(See @id{LUA_INT_TYPE} in @id{luaconf.h}.) 3477(See @id{LUA_INT_TYPE} in @id{luaconf.h}.)
3478 3478
3479Lua also defines the constants 3479Lua also defines the constants
@@ -3689,7 +3689,7 @@ passes to the allocator in every call.
3689@apii{0,1,m} 3689@apii{0,1,m}
3690 3690
3691Creates a new empty table and pushes it onto the stack. 3691Creates a new empty table and pushes it onto the stack.
3692It is equivalent to @T{lua_createtable(L, 0, 0)}. 3692It is equivalent to @T{lua_createtable(L,0,0)}.
3693 3693
3694} 3694}
3695 3695
diff --git a/testes/events.lua b/testes/events.lua
index def13dc8..d0a48c66 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -382,6 +382,16 @@ do
382end 382end
383 383
384 384
385do -- bug in 5.4
386 local parent = {}
387 parent.__newindex = parent
388 collectgarbage()
389 local child = setmetatable({}, parent)
390 child.__newindex = {x = "hello"}
391 collectgarbage("step")
392 assert(parent.__newindex.x == "hello")
393end
394
385 395
386-- concat metamethod x numbers (bug in 5.1.1) 396-- concat metamethod x numbers (bug in 5.1.1)
387c = {} 397c = {}