diff -Nr lua-5.4.2/Makefile lua-5.4.3/Makefile 49c49 < R= $V.2 --- > R= $V.3 diff -Nr lua-5.4.2/README lua-5.4.3/README 2c2 < This is Lua 5.4.2, released on 13 Nov 2020. --- > This is Lua 5.4.3, released on 15 Mar 2021. diff -Nr lua-5.4.2/doc/contents.html lua-5.4.3/doc/contents.html 35c35 < Copyright © 2020 Lua.org, PUC-Rio. --- > Copyright © 2020–2021 Lua.org, PUC-Rio. 398a399 > lua_closeslot
666c667 < Tue Nov 10 20:58:52 UTC 2020 --- > Wed Mar 3 13:04:44 UTC 2021 669c670 < Last change: revised for Lua 5.4.2 --- > Last change: revised for Lua 5.4.3 diff -Nr lua-5.4.2/doc/manual.html lua-5.4.3/doc/manual.html 22c22 < Copyright © 2020 Lua.org, PUC-Rio. --- > Copyright © 2020–2021 Lua.org, PUC-Rio. 145a146,150 > Despite its name, > false is frequently used as an alternative to nil, > with the key difference that false behaves > like a regular value in a table, > while a nil in a table represents an absent key. 437c442 < Lua checks for a function in the field "__add" of the value's metatable. --- > Lua checks for a function in the field __add of the value's metatable. 904c909 < and the metatable has a field indexed by the string "__gc". --- > and the metatable has a __gc metamethod. 1995,1998d1999 < However, Lua may call the method one more time. < < <

2001,2004d2001 < Errors in these methods < interrupt the respective method and generate a warning, < but are otherwise ignored; < the error reported is only the original one. 3765a3763,3785 >


lua_closeslot

> [-0, +0, e] >

void lua_closeslot (lua_State *L, int index);
> >

> Close the to-be-closed slot at the given index and set its value to nil. > The index must be the last index previously marked to be closed > (see lua_toclose) that is still active (that is, not closed yet). > > >

> A __close metamethod cannot yield > when called through this function. > > >

> (Exceptionally, this function was introduced in release 5.4.3. > It is not present in previous 5.4 releases.) > > > > > 4660,4664c4680 < < <

< This function can run arbitrary code when removing an index < marked as to-be-closed from the stack. --- > It is implemented as a macro over lua_settop. 5143c5159,5161 < LUA_OK for no errors in closing methods, --- > LUA_OK for no errors in the thread > (either the original error that stopped the thread or > errors in closing methods), 5146c5164 < leaves the error object on the top of the stack, --- > leaves the error object on the top of the stack. 5469c5487 < to-be-closed "variable" (see §3.3.8). --- > to-be-closed slot (see §3.3.8). 5471c5489 < the value at that index in the stack will be closed --- > the value at that slot in the stack will be closed 5475,5479c5493,5499 < there is an error, < or the index is removed from the stack through < lua_settop or lua_pop. < An index marked as to-be-closed should not be removed from the stack < by any other function in the API except lua_settop or lua_pop. --- > or there is an error, > or the slot is removed from the stack through > lua_settop or lua_pop, > or there is a call to lua_closeslot. > A slot marked as to-be-closed should not be removed from the stack > by any other function in the API except lua_settop or lua_pop, > unless previously deactivated by lua_closeslot. 5484,5490c5504 < that is equal to or below an active to-be-closed index. < < <

< In the case of an out-of-memory error, < the value in the given index is immediately closed, < as if it was already marked. --- > that is equal to or below an active to-be-closed slot. 5498c5512 < will be out of scope. --- > (e.g., a buffer) will be out of scope. 8401c8415,8417 < In case of error closing some variable, --- > In case of error > (either the original error that stopped the coroutine or > errors in closing methods), 9963,9965c9979,9981 < before the second in the final order < (so that, after the sort, < i < j implies not comp(list[j],list[i])). --- > before the second in the final order, > so that, after the sort, > i <= j implies not comp(list[j],list[i]). 9971,9974c9987,9990 < Note that the comp function must define < a strict partial order over the elements in the list; < that is, it must be asymmetric and transitive. < Otherwise, no valid sort may be possible. --- > The comp function must define a consistent order; > more formally, the function must define a strict weak order. > (A weak order is similar to a total order, > but it can equate different elements for comparison purposes.) 9979c9995 < elements considered equal by the given order --- > Different elements considered equal by the given order 11911c11927 < Fri Nov 13 15:35:22 UTC 2020 --- > Mon Mar 15 13:39:42 UTC 2021 11914c11930 < Last change: revised for Lua 5.4.2 --- > Last change: revised for Lua 5.4.3 diff -Nr lua-5.4.2/doc/readme.html lua-5.4.3/doc/readme.html 113c113 < the top-level directory, which is named lua-5.4.2. --- > the top-level directory, which is named lua-5.4.3. 306c306 < Copyright © 1994–2020 Lua.org, PUC-Rio. --- > Copyright © 1994–2021 Lua.org, PUC-Rio. 333c333 < Tue Nov 10 20:55:28 UTC 2020 --- > Wed Mar 3 10:16:26 UTC 2021 336c336 < Last change: revised for Lua 5.4.2 --- > Last change: revised for Lua 5.4.3 diff -Nr lua-5.4.2/src/Makefile lua-5.4.3/src/Makefile 70c70 < ./lua -v --- > ./$(LUA_T) -v 110a111,112 > @echo '*** Make sure to compile all external Lua libraries' > @echo '*** with LUA_USE_C89 to ensure consistency' diff -Nr lua-5.4.2/src/lapi.c lua-5.4.3/src/lapi.c 42c42 < ** Test for a valid index. --- > ** Test for a valid index (one that is not the 'nilvalue'). 77c77,78 < return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : &G(L)->nilvalue; --- > return (idx <= func->nupvalues) ? &func->upvalue[idx-1] > : &G(L)->nilvalue; 175c176 < StkId func; --- > StkId func, newtop; 190,192c191,210 < if (diff < 0 && hastocloseCfunc(ci->nresults)) < luaF_close(L, L->top + diff, LUA_OK); < L->top += diff; /* correct top only after closing any upvalue */ --- > api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot"); > newtop = L->top + diff; > if (diff < 0 && L->tbclist >= newtop) { > lua_assert(hastocloseCfunc(ci->nresults)); > luaF_close(L, newtop, CLOSEKTOP, 0); > } > L->top = newtop; /* correct top only after closing any upvalue */ > lua_unlock(L); > } > > > LUA_API void lua_closeslot (lua_State *L, int idx) { > StkId level; > lua_lock(L); > level = index2stack(L, idx); > api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level, > "no variable to close at given level"); > luaF_close(L, level, CLOSEKTOP, 0); > level = index2stack(L, idx); /* stack may be moved */ > setnilvalue(s2v(level)); 631a650,659 > /* > ** Get the global table in the registry. Since all predefined > ** indices in the registry were inserted right when the registry > ** was created and never removed, they must always be in the array > ** part of the registry. > */ > #define getGtable(L) \ > (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1]) > > 633c661 < Table *reg; --- > const TValue *G; 635,636c663,664 < reg = hvalue(&G(L)->l_registry); < return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); --- > G = getGtable(L); > return auxgetstr(L, G, name); 814c842 < Table *reg; --- > const TValue *G; 816,817c844,845 < reg = hvalue(&G(L)->l_registry); < auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); --- > G = getGtable(L); > auxsetstr(L, G, name); 864d891 < TValue *slot; 868,869c895 < slot = luaH_set(L, t, key); < setobj2t(L, slot, s2v(L->top - 1)); --- > luaH_set(L, t, key, s2v(L->top - 1)); 1066,1067c1092 < Table *reg = hvalue(&G(L)->l_registry); < const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); --- > const TValue *gt = getGtable(L); 1243,1244c1268 < api_check(L, L->openupval == NULL || uplevel(L->openupval) <= o, < "marked index below or equal new one"); --- > api_check(L, L->tbclist < o, "given index below or equal a marked one"); diff -Nr lua-5.4.2/src/lapi.h lua-5.4.3/src/lapi.h 44a45 > /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 45a47 > #define decodeNresults(n) (-(n) - 3) diff -Nr lua-5.4.2/src/lauxlib.c lua-5.4.3/src/lauxlib.c 193c193 < int luaL_typeerror (lua_State *L, int arg, const char *tname) { --- > LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) { 381c381 < if (!lua_checkstack(L, space)) { --- > if (l_unlikely(!lua_checkstack(L, space))) { 391c391 < if (lua_type(L, arg) != t) --- > if (l_unlikely(lua_type(L, arg) != t)) 397c397 < if (lua_type(L, arg) == LUA_TNONE) --- > if (l_unlikely(lua_type(L, arg) == LUA_TNONE)) 404c404 < if (!s) tag_error(L, arg, LUA_TSTRING); --- > if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING); 423c423 < if (!isnum) --- > if (l_unlikely(!isnum)) 445c445 < if (!isnum) { --- > if (l_unlikely(!isnum)) { 478c478 < if (temp == NULL && newsize > 0) { /* allocation error? */ --- > if (l_unlikely(temp == NULL && newsize > 0)) { /* allocation error? */ 518a519,527 > ** Whenever buffer is accessed, slot 'idx' must either be a box (which > ** cannot be NULL) or it is a placeholder for the buffer. > */ > #define checkbufferlevel(B,idx) \ > lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \ > : lua_touserdata(B->L, idx) == (void*)B) > > > /* 524c533 < if (MAX_SIZET - sz < B->n) /* overflow in (B->n + sz)? */ --- > if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */ 534,535c543,544 < ** 'B'. 'boxidx' is the relative position in the stack where the < ** buffer's box is or should be. --- > ** 'B'. 'boxidx' is the relative position in the stack where is the > ** buffer's box or its placeholder. 537a547 > checkbufferlevel(B, boxidx); 548c558 < lua_pushnil(L); /* reserve slot for final result */ --- > lua_remove(L, boxidx); /* remove placeholder */ 550,551c560 < /* move box (and slot) to its intended position */ < lua_rotate(L, boxidx - 1, 2); --- > lua_insert(L, boxidx); /* move box to its intended position */ 585a595 > checkbufferlevel(B, -1); 587,590c597,599 < if (buffonstack(B)) { < lua_copy(L, -1, -3); /* move string to reserved slot */ < lua_pop(L, 2); /* pop string and box (closing the box) */ < } --- > if (buffonstack(B)) > lua_closeslot(L, -2); /* close the box */ > lua_remove(L, -2); /* remove box or placeholder from the stack */ 624a634 > lua_pushlightuserdata(L, (void*)B); /* push placeholder */ 642,644c652,653 < /* index of free-list header */ < #define freelist 0 < --- > /* index of free-list header (after the predefined values) */ > #define freelist (LUA_RIDX_LAST + 1) 645a655,659 > /* > ** The previously freed references form a linked list: > ** t[freelist] is the index of a first free index, or zero if list is > ** empty; t[t[freelist]] is the index of the second element; etc. > */ 653,655c667,676 < lua_rawgeti(L, t, freelist); /* get first free element */ < ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ < lua_pop(L, 1); /* remove it from stack */ --- > if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ > ref = 0; /* list is empty */ > lua_pushinteger(L, 0); /* initialize as an empty list */ > lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ > } > else { /* already initialized */ > lua_assert(lua_isinteger(L, -1)); > ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ > } > lua_pop(L, 1); /* remove element from stack */ 670a692 > lua_assert(lua_isinteger(L, -1)); 854c876 < if (!isnum) --- > if (l_unlikely(!isnum)) 1067c1089 < if (L) { --- > if (l_likely(L)) { diff -Nr lua-5.4.2/src/lauxlib.h lua-5.4.3/src/lauxlib.h 14a15 > #include "luaconf.h" 133c134 < ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) --- > ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) 136c137 < ((void)((cond) || luaL_typeerror(L, (arg), (tname)))) --- > ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) 160a162,177 > ** Internal assertions for in-house debugging > */ > #if !defined(lua_assert) > > #if defined LUAI_ASSERT > #include > #define lua_assert(c) assert(c) > #else > #define lua_assert(c) ((void)0) > #endif > > #endif > > > > /* diff -Nr lua-5.4.2/src/lbaselib.c lua-5.4.3/src/lbaselib.c 141c141 < if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) --- > if (l_unlikely(luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)) 185c185,186 < lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational"); --- > lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" > : "generational"); 302c303 < if (status == LUA_OK) { --- > if (l_likely(status == LUA_OK)) { 358c359 < else if (!lua_isstring(L, -1)) --- > else if (l_unlikely(!lua_isstring(L, -1))) 396c397 < if (luaL_loadfile(L, fname) != LUA_OK) --- > if (l_unlikely(luaL_loadfile(L, fname) != LUA_OK)) 404c405 < if (lua_toboolean(L, 1)) /* condition is true? */ --- > if (l_likely(lua_toboolean(L, 1))) /* condition is true? */ 440c441 < if (status != LUA_OK && status != LUA_YIELD) { /* error? */ --- > if (l_unlikely(status != LUA_OK && status != LUA_YIELD)) { /* error? */ diff -Nr lua-5.4.2/src/lcode.c lua-5.4.3/src/lcode.c 317,325d316 < /* < ** MAXimum number of successive Instructions WiTHout ABSolute line < ** information. < */ < #if !defined(MAXIWTHABS) < #define MAXIWTHABS 120 < #endif < < 340c331 < if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) { --- > if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) { 346c337 < fs->iwthabs = 0; /* restart counter */ --- > fs->iwthabs = 1; /* restart counter */ 547a539,540 > ** Note that all functions share the same table, so entering or exiting > ** a function can make some indices wrong. 549a543 > TValue val; 552c546 < TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ --- > const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ 566c560,561 < setivalue(idx, k); --- > setivalue(&val, k); > luaH_finishset(L, fs->ls->h, key, idx, &val); 766c761 < e->u.info = e->u.var.sidx; --- > e->u.info = e->u.var.ridx; 1039c1034 < exp2reg(fs, ex, var->u.var.sidx); /* compute 'ex' into proper place */ --- > exp2reg(fs, ex, var->u.var.ridx); /* compute 'ex' into proper place */ 1279c1274 < t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info; --- > t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; 1306c1301,1302 < return (tointegerns(v1, &i) && tointegerns(v2, &i)); --- > return (luaV_tointegerns(v1, &i, LUA_FLOORN2I) && > luaV_tointegerns(v2, &i, LUA_FLOORN2I)); diff -Nr lua-5.4.2/src/lcorolib.c lua-5.4.3/src/lcorolib.c 34c34 < if (!lua_checkstack(co, narg)) { --- > if (l_unlikely(!lua_checkstack(co, narg))) { 40,41c40,41 < if (status == LUA_OK || status == LUA_YIELD) { < if (!lua_checkstack(L, nres + 1)) { --- > if (l_likely(status == LUA_OK || status == LUA_YIELD)) { > if (l_unlikely(!lua_checkstack(L, nres + 1))) { 60c60 < if (r < 0) { --- > if (l_unlikely(r < 0)) { 76c76 < if (r < 0) { /* error? */ --- > if (l_unlikely(r < 0)) { /* error? */ 78,79c78,82 < if (stat != LUA_OK && stat != LUA_YIELD) /* error in the coroutine? */ < lua_resetthread(co); /* close its tbc variables */ --- > if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ > stat = lua_resetthread(co); /* close its tbc variables */ > lua_assert(stat != LUA_OK); > lua_xmove(co, L, 1); /* copy error message */ > } diff -Nr lua-5.4.2/src/ldblib.c lua-5.4.3/src/ldblib.c 36c36 < if (L != L1 && !lua_checkstack(L1, n)) --- > if (l_unlikely(L != L1 && !lua_checkstack(L1, n))) 154a155 > luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'"); 215c216 < if (!lua_getstack(L1, level, &ar)) /* out of range? */ --- > if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ 240c241 < if (!lua_getstack(L1, level, &ar)) /* out of range? */ --- > if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ 380c381 < lua_pushstring(L, "k"); --- > lua_pushliteral(L, "k"); 423c424 < if (fgets(buffer, sizeof(buffer), stdin) == 0 || --- > if (fgets(buffer, sizeof(buffer), stdin) == NULL || diff -Nr lua-5.4.2/src/ldebug.c lua-5.4.3/src/ldebug.c 36,37d35 < /* inverse of 'pcRel' */ < #define invpcRel(pc, p) ((p)->code + (pc) + 1) 51,54c49,58 < ** For that, search the array of absolute line info for the largest saved < ** instruction smaller or equal to the wanted instruction. A special < ** case is when there is no absolute info or the instruction is before < ** the first absolute one. --- > ** Base lines are regularly placed at MAXIWTHABS intervals, so usually > ** an integer division gets the right place. When the source file has > ** large sequences of empty/comment lines, it may need extra entries, > ** so the original estimate needs a correction. > ** If the original estimate is -1, the initial 'if' ensures that the > ** 'while' will run at least once. > ** The assertion that the estimate is a lower bound for the correct base > ** is valid as long as the debug info has been generated with the same > ** value for MAXIWTHABS or smaller. (Previous releases use a little > ** smaller value.) 62,75c66,71 < unsigned int i; < if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc) < i = f->sizeabslineinfo - 1; /* instruction is after last saved one */ < else { /* binary search */ < unsigned int j = f->sizeabslineinfo - 1; /* pc < anchorlines[j] */ < i = 0; /* abslineinfo[i] <= pc */ < while (i < j - 1) { < unsigned int m = (j + i) / 2; < if (pc >= f->abslineinfo[m].pc) < i = m; < else < j = m; < } < } --- > int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ > /* estimate must be a lower bond of the correct base */ > lua_assert(i < 0 || > (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc)); > while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) > i++; /* low estimate; adjust it */ 308,309c304,305 < for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */ < currentline = nextline(p, currentline, i); --- > for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ > currentline = nextline(p, currentline, i); /* get its line */ 632,637c628,631 < case OP_LT: case OP_LE: case OP_LTI: case OP_LEI: < *name = "order"; /* '<=' can call '__lt', etc. */ < return "metamethod"; < case OP_CLOSE: case OP_RETURN: < *name = "close"; < return "metamethod"; --- > /* no cases for OP_EQI and OP_EQK, as they don't call metamethods */ > case OP_LT: case OP_LTI: case OP_GTI: tm = TM_LT; break; > case OP_LE: case OP_LEI: case OP_GEI: tm = TM_LE; break; > case OP_CLOSE: case OP_RETURN: tm = TM_CLOSE; break; 650,652c644,647 < ** The subtraction of two potentially unrelated pointers is < ** not ISO C, but it should not crash a program; the subsequent < ** checks are ISO C and ensure a correct result. --- > ** Check whether pointer 'o' points to some value in the stack > ** frame of the current function. Because 'o' may not point to a > ** value in this stack, we cannot compare it with the region > ** boundaries (undefined behaviour in ISO C). 655,657c650,655 < StkId base = ci->func + 1; < ptrdiff_t i = cast(StkId, o) - base; < return (0 <= i && i < (ci->top - base) && s2v(base + i) == o); --- > StkId pos; > for (pos = ci->func + 1; pos < ci->top; pos++) { > if (o == s2v(pos)) > return 1; > } > return 0; /* not found */ 699a698,710 > l_noret luaG_callerror (lua_State *L, const TValue *o) { > CallInfo *ci = L->ci; > const char *name = NULL; /* to avoid warnings */ > const char *what = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL; > if (what != NULL) { > const char *t = luaT_objtypename(L, o); > luaG_runerror(L, "%s '%s' is not callable (a %s value)", what, name, t); > } > else > luaG_typeerror(L, o, "call"); > } > > 725c736 < if (!tointegerns(p1, &temp)) --- > if (!luaV_tointegerns(p1, &temp, LUA_FLOORN2I)) 783c794,798 < ** previous instruction 'oldpc'. --- > ** previous instruction 'oldpc'. More often than not, 'newpc' is only > ** one or a few instructions after 'oldpc' (it must be after, see > ** caller), so try to avoid calling 'luaG_getfuncline'. If they are > ** too far apart, there is a good chance of a ABSLINEINFO in the way, > ** so it goes directly to 'luaG_getfuncline'. 788,790c803,813 < while (oldpc++ < newpc) { < if (p->lineinfo[oldpc] != 0) < return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc)); --- > if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */ > int delta = 0; /* line diference */ > int pc = oldpc; > for (;;) { > int lineinfo = p->lineinfo[++pc]; > if (lineinfo == ABSLINEINFO) > break; /* cannot compute delta; fall through */ > delta += lineinfo; > if (pc == newpc) > return (delta != 0); /* delta computed successfully */ > } 792c815,817 < return 0; /* no line changes between positions */ --- > /* either instructions are too far apart or there is an absolute line > info in the way; compute line difference explicitly */ > return (luaG_getfuncline(p, oldpc) != luaG_getfuncline(p, newpc)); 800,805c825,831 < ** function, 'npci' will be zero and will test as a new line without < ** the need for 'oldpc'; so, 'oldpc' does not need to be initialized < ** before. Some exceptional conditions may return to a function without < ** updating 'oldpc'. In that case, 'oldpc' may be invalid; if so, it is < ** reset to zero. (A wrong but valid 'oldpc' at most causes an extra < ** call to a line hook.) --- > ** function, 'npci' will be zero and will test as a new line whatever > ** the value of 'oldpc'. Some exceptional conditions may return to > ** a function without setting 'oldpc'. In that case, 'oldpc' may be > ** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc' > ** at most causes an extra call to a line hook.) > ** This function is not "Protected" when called, so it should correct > ** 'L->top' before calling anything that can run the GC. 812,813d837 < /* 'L->oldpc' may be invalid; reset it in this case */ < int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; 829,830c853,854 < if (!isIT(*(ci->u.l.savedpc - 1))) < L->top = ci->top; /* prepare top */ --- > if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ > L->top = ci->top; /* correct top */ 833a858,859 > /* 'L->oldpc' may be invalid; use zero in this case */ > int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; 835,837c861,862 < if (npci == 0 || /* call linehook when enter a new function, */ < pc <= invpcRel(oldpc, p) || /* when jump back (loop), or when */ < changedline(p, oldpc, npci)) { /* enter new line */ --- > if (npci <= oldpc || /* call hook when jump back (loop), */ > changedline(p, oldpc, npci)) { /* or when enter new line */ diff -Nr lua-5.4.2/src/ldebug.h lua-5.4.3/src/ldebug.h 28a29,38 > > /* > ** MAXimum number of successive Instructions WiTHout ABSolute line > ** information. (A power of two allows fast divisions.) > */ > #if !defined(MAXIWTHABS) > #define MAXIWTHABS 128 > #endif > > 33a44 > LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); diff -Nr lua-5.4.2/src/ldo.c lua-5.4.3/src/ldo.c 101c101 < case CLOSEPROTECT: { --- > case LUA_OK: { /* special case only for closing upvalues */ 105a106 > lua_assert(errorstatus(errcode)); /* real error */ 121,122c122 < errcode = luaF_close(L, L->stack, errcode); /* close all upvalues */ < L->status = cast_byte(errcode); /* mark it as dead */ --- > errcode = luaE_resetthread(L, errcode); /* close all upvalues */ 129,131d128 < luaD_seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ < if (L->ci->top < L->top) < L->ci->top = L->top; /* pushing msg. can break this invariant */ 166,167d162 < if (oldstack == newstack) < return; /* stack address did not change */ 168a164 > L->tbclist = (L->tbclist - oldstack) + newstack; 183a180,190 > /* > ** Reallocate the stack to a new size, correcting all pointers into > ** it. (There are pointers to a stack from its upvalues, from its list > ** of call infos, plus a few individual pointers.) The reallocation is > ** done in two steps (allocation + free) because the correction must be > ** done while both addresses (the old stack and the new one) are valid. > ** (In ISO C, any pointer use after the pointer has been deallocated is > ** undefined behavior.) > ** In case of allocation error, raise an error or return false according > ** to 'raiseerror'. > */ 185,187c192,195 < int lim = stacksize(L); < StkId newstack = luaM_reallocvector(L, L->stack, < lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); --- > int oldsize = stacksize(L); > int i; > StkId newstack = luaM_reallocvector(L, NULL, 0, > newsize + EXTRA_STACK, StackValue); 189c197 < if (unlikely(newstack == NULL)) { /* reallocation failed? */ --- > if (l_unlikely(newstack == NULL)) { /* reallocation failed? */ 194,195c202,206 < for (; lim < newsize; lim++) < setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */ --- > /* number of elements to be copied to the new stack */ > i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK; > memcpy(newstack, L->stack, i * sizeof(StackValue)); > for (; i < newsize + EXTRA_STACK; i++) > setnilvalue(s2v(newstack + i)); /* erase new segment */ 196a208 > luaM_freearray(L, L->stack, oldsize + EXTRA_STACK); 209c221 < if (unlikely(size > LUAI_MAXSTACK)) { --- > if (l_unlikely(size > LUAI_MAXSTACK)) { 225c237 < if (likely(newsize <= LUAI_MAXSTACK)) --- > if (l_likely(newsize <= LUAI_MAXSTACK)) 300,301c312,313 < ptrdiff_t top = savestack(L, L->top); < ptrdiff_t ci_top = savestack(L, ci->top); --- > ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */ > ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */ 310a323,324 > if (isLua(ci) && L->top < ci->top) > L->top = ci->top; /* protect entire activation register */ 312c326 < if (L->top + LUA_MINSTACK > ci->top) --- > if (ci->top < L->top + LUA_MINSTACK) 334,342c348,356 < int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; < Proto *p; < if (!(L->hookmask & LUA_MASKCALL)) /* some other hook? */ < return; /* don't call hook */ < p = clLvalue(s2v(ci->func))->p; < L->top = ci->top; /* prepare top */ < ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ < luaD_hook(L, hook, -1, 1, p->numparams); < ci->u.l.savedpc--; /* correct 'pc' */ --- > L->oldpc = 0; /* set 'oldpc' for new function */ > if (L->hookmask & LUA_MASKCALL) { /* is call hook on? */ > int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL > : LUA_HOOKCALL; > Proto *p = ci_func(ci)->p; > ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ > luaD_hook(L, event, -1, 1, p->numparams); > ci->u.l.savedpc--; /* correct 'pc' */ > } 346,355c360,365 < static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { < ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */ < int delta = 0; < if (isLuacode(ci)) { < Proto *p = ci_func(ci)->p; < if (p->is_vararg) < delta = ci->u.l.nextraargs + p->numparams + 1; < if (L->top < ci->top) < L->top = ci->top; /* correct top to run hook */ < } --- > /* > ** Executes a return hook for Lua and C functions and sets/corrects > ** 'oldpc'. (Note that this correction is needed by the line hook, so it > ** is done even when return hooks are off.) > */ > static void rethook (lua_State *L, CallInfo *ci, int nres) { 356a367,368 > StkId firstres = L->top - nres; /* index of first result */ > int delta = 0; /* correction for vararg functions */ 357a370,374 > if (isLua(ci)) { > Proto *p = ci_func(ci)->p; > if (p->is_vararg) > delta = ci->u.l.nextraargs + p->numparams + 1; > } 364,365c381 < L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* update 'oldpc' */ < return restorestack(L, oldtop); --- > L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */ 377,378c393,394 < if (unlikely(ttisnil(tm))) < luaG_typeerror(L, s2v(func), "call"); /* nothing to call */ --- > if (l_unlikely(ttisnil(tm))) > luaG_callerror(L, s2v(func)); /* nothing to call */ 402c418 < else --- > else /* at least one result */ 409c425 < default: /* multiple results (or to-be-closed variables) */ --- > default: /* two/more results and/or to-be-closed variables */ 412,414c428,435 < luaF_close(L, res, LUA_OK); /* may change the stack */ < res = restorestack(L, savedres); < wanted = codeNresults(wanted); /* correct value */ --- > L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ > L->ci->u2.nres = nres; > luaF_close(L, res, CLOSEKTOP, 1); > L->ci->callstatus &= ~CIST_CLSRET; > if (L->hookmask) /* if needed, call hook after '__close's */ > rethook(L, L->ci, nres); > res = restorestack(L, savedres); /* close and hook can move stack */ > wanted = decodeNresults(wanted); 416c437 < wanted = nres; --- > wanted = nres; /* we want all results */ 419a441 > /* generic case */ 421,422c443,445 < /* move all results to correct place */ < for (i = 0; i < nres && i < wanted; i++) --- > if (nres > wanted) /* extra results? */ > nres = wanted; /* don't need them */ > for (i = 0; i < nres; i++) /* move all results to correct place */ 431,432c454,457 < ** Finishes a function call: calls hook if necessary, removes CallInfo, < ** moves current number of results to proper place. --- > ** Finishes a function call: calls hook if necessary, moves current > ** number of results to proper place, and returns to previous call > ** info. If function has to close variables, hook must be called after > ** that. 435,437c460,462 < if (L->hookmask) < L->top = rethook(L, ci, L->top - nres, nres); < L->ci = ci->previous; /* back to caller */ --- > int wanted = ci->nresults; > if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted))) > rethook(L, ci, nres); 439c464,468 < moveresults(L, ci->func, nres, ci->nresults); --- > moveresults(L, ci->func, nres, wanted); > /* function cannot be in any of these cases when returning */ > lua_assert(!(ci->callstatus & > (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET))); > L->ci = ci->previous; /* back to caller (after closing variables) */ 498c527 < if (L->hookmask & LUA_MASKCALL) { --- > if (l_unlikely(L->hookmask & LUA_MASKCALL)) { 544c573 < if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) --- > if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) 571,591c600,667 < ** Completes the execution of an interrupted C function, calling its < ** continuation function. < */ < static void finishCcall (lua_State *L, int status) { < CallInfo *ci = L->ci; < int n; < /* must have a continuation and must be able to call it */ < lua_assert(ci->u.c.k != NULL && yieldable(L)); < /* error status can only happen in a protected call */ < lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); < if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ < ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ < L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ < } < /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already < handled */ < adjustresults(L, ci->nresults); < lua_unlock(L); < n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ < lua_lock(L); < api_checknelems(L, n); --- > ** Finish the job of 'lua_pcallk' after it was interrupted by an yield. > ** (The caller, 'finishCcall', does the final call to 'adjustresults'.) > ** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'. > ** If a '__close' method yields here, eventually control will be back > ** to 'finishCcall' (when that '__close' method finally returns) and > ** 'finishpcallk' will run again and close any still pending '__close' > ** methods. Similarly, if a '__close' method errs, 'precover' calls > ** 'unroll' which calls ''finishCcall' and we are back here again, to > ** close any pending '__close' methods. > ** Note that, up to the call to 'luaF_close', the corresponding > ** 'CallInfo' is not modified, so that this repeated run works like the > ** first one (except that it has at least one less '__close' to do). In > ** particular, field CIST_RECST preserves the error status across these > ** multiple runs, changing only if there is a new error. > */ > static int finishpcallk (lua_State *L, CallInfo *ci) { > int status = getcistrecst(ci); /* get original status */ > if (l_likely(status == LUA_OK)) /* no error? */ > status = LUA_YIELD; /* was interrupted by an yield */ > else { /* error */ > StkId func = restorestack(L, ci->u2.funcidx); > L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ > luaF_close(L, func, status, 1); /* can yield or raise an error */ > func = restorestack(L, ci->u2.funcidx); /* stack may be moved */ > luaD_seterrorobj(L, status, func); > luaD_shrinkstack(L); /* restore stack size in case of overflow */ > setcistrecst(ci, LUA_OK); /* clear original status */ > } > ci->callstatus &= ~CIST_YPCALL; > L->errfunc = ci->u.c.old_errfunc; > /* if it is here, there were errors or yields; unlike 'lua_pcallk', > do not change status */ > return status; > } > > > /* > ** Completes the execution of a C function interrupted by an yield. > ** The interruption must have happened while the function was either > ** closing its tbc variables in 'moveresults' or executing > ** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes > ** 'luaD_poscall'. In the second case, the call to 'finishpcallk' > ** finishes the interrupted execution of 'lua_pcallk'. After that, it > ** calls the continuation of the interrupted function and finally it > ** completes the job of the 'luaD_call' that called the function. In > ** the call to 'adjustresults', we do not know the number of results > ** of the function called by 'lua_callk'/'lua_pcallk', so we are > ** conservative and use LUA_MULTRET (always adjust). > */ > static void finishCcall (lua_State *L, CallInfo *ci) { > int n; /* actual number of results from C function */ > if (ci->callstatus & CIST_CLSRET) { /* was returning? */ > lua_assert(hastocloseCfunc(ci->nresults)); > n = ci->u2.nres; /* just redo 'luaD_poscall' */ > /* don't need to reset CIST_CLSRET, as it will be set again anyway */ > } > else { > int status = LUA_YIELD; /* default if there were no errors */ > /* must have a continuation and must be able to call it */ > lua_assert(ci->u.c.k != NULL && yieldable(L)); > if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */ > status = finishpcallk(L, ci); /* finish it */ > adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */ > lua_unlock(L); > n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */ > lua_lock(L); > api_checknelems(L, n); > } 599,602c675 < ** interruption long-jumps out of the loop). If the coroutine is < ** recovering from an error, 'ud' points to the error status, which must < ** be passed to the first continuation function (otherwise the default < ** status is LUA_YIELD). --- > ** interruption long-jumps out of the loop). 606,607c679 < if (ud != NULL) /* error status? */ < finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ --- > UNUSED(ud); 610c682 < finishCcall(L, LUA_YIELD); /* complete its execution */ --- > finishCcall(L, ci); /* complete its execution */ 634,655d705 < ** Recovers from an error in a coroutine. Finds a recover point (if < ** there is one) and completes the execution of the interrupted < ** 'luaD_pcall'. If there is no recover point, returns zero. < */ < static int recover (lua_State *L, int status) { < StkId oldtop; < CallInfo *ci = findpcall(L); < if (ci == NULL) return 0; /* no recovery point */ < /* "finish" luaD_pcall */ < oldtop = restorestack(L, ci->u2.funcidx); < L->ci = ci; < L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ < status = luaF_close(L, oldtop, status); /* may change the stack */ < oldtop = restorestack(L, ci->u2.funcidx); < luaD_seterrorobj(L, status, oldtop); < luaD_shrinkstack(L); /* restore stack size in case of overflow */ < L->errfunc = ci->u.c.old_errfunc; < return 1; /* continue running the coroutine */ < } < < < /* 686c736,737 < if (isLua(ci)) /* yielded inside a hook? */ --- > if (isLua(ci)) { /* yielded inside a hook? */ > L->top = firstArg; /* discard arguments */ 687a739 > } 700a753,772 > > /* > ** Unrolls a coroutine in protected mode while there are recoverable > ** errors, that is, errors inside a protected call. (Any error > ** interrupts 'unroll', and this loop protects it again so it can > ** continue.) Stops with a normal end (status == LUA_OK), an yield > ** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't > ** find a recover point). > */ > static int precover (lua_State *L, int status) { > CallInfo *ci; > while (errorstatus(status) && (ci = findpcall(L)) != NULL) { > L->ci = ci; /* go down to recovery functions */ > setcistrecst(ci, status); /* status to finish 'pcall' */ > status = luaD_rawrunprotected(L, unroll, NULL); > } > return status; > } > > 718,722c790,791 < while (errorstatus(status) && recover(L, status)) { < /* unroll continuation */ < status = luaD_rawrunprotected(L, unroll, &status); < } < if (likely(!errorstatus(status))) --- > status = precover(L, status); > if (l_likely(!errorstatus(status))) 748c817 < if (unlikely(!yieldable(L))) { --- > if (l_unlikely(!yieldable(L))) { 754a824 > ci->u2.nyield = nresults; /* save number of results */ 756a827 > api_check(L, nresults == 0, "hooks cannot yield values"); 758d828 < ci->u2.nyield = 0; /* no results */ 763d832 < ci->u2.nyield = nresults; /* save number of results */ 772a842,880 > ** Auxiliary structure to call 'luaF_close' in protected mode. > */ > struct CloseP { > StkId level; > int status; > }; > > > /* > ** Auxiliary function to call 'luaF_close' in protected mode. > */ > static void closepaux (lua_State *L, void *ud) { > struct CloseP *pcl = cast(struct CloseP *, ud); > luaF_close(L, pcl->level, pcl->status, 0); > } > > > /* > ** Calls 'luaF_close' in protected mode. Return the original status > ** or, in case of errors, the new status. > */ > int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) { > CallInfo *old_ci = L->ci; > lu_byte old_allowhooks = L->allowhook; > for (;;) { /* keep closing upvalues until no more errors */ > struct CloseP pcl; > pcl.level = restorestack(L, level); pcl.status = status; > status = luaD_rawrunprotected(L, &closepaux, &pcl); > if (l_likely(status == LUA_OK)) /* no more errors? */ > return pcl.status; > else { /* an error occurred; restore saved state and repeat */ > L->ci = old_ci; > L->allowhook = old_allowhooks; > } > } > } > > > /* 785,786c893 < if (unlikely(status != LUA_OK)) { /* an error occurred? */ < StkId oldtop = restorestack(L, old_top); --- > if (l_unlikely(status != LUA_OK)) { /* an error occurred? */ 789,791c896,897 < status = luaF_close(L, oldtop, status); < oldtop = restorestack(L, old_top); /* previous call may change stack */ < luaD_seterrorobj(L, status, oldtop); --- > status = luaD_closeprotected(L, old_top, status); > luaD_seterrorobj(L, status, restorestack(L, old_top)); diff -Nr lua-5.4.2/src/ldo.h lua-5.4.3/src/ldo.h 26c26 < if (L->stack_last - L->top <= (n)) \ --- > if (l_unlikely(L->stack_last - L->top <= (n))) \ 65a66 > LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); diff -Nr lua-5.4.2/src/lfunc.c lua-5.4.3/src/lfunc.c 103,108d102 < static void callclose (lua_State *L, void *ud) { < UNUSED(ud); < luaD_callnoyield(L, L->top - 3, 0); < } < < 110,111c104,106 < ** Prepare closing method plus its arguments for object 'obj' with < ** error message 'err'. (This function assumes EXTRA_STACK.) --- > ** Call closing method for object 'obj' with error message 'err'. The > ** boolean 'yy' controls whether the call is yieldable. > ** (This function assumes EXTRA_STACK.) 113c108 < static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) { --- > static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { 116,117d110 < if (ttisnil(tm)) /* no metamethod? */ < return 0; /* nothing to call */ 122c115,118 < return 1; --- > if (yy) > luaD_call(L, top, 0); > else > luaD_callnoyield(L, top, 0); 127,128c123,124 < ** Raise an error with message 'msg', inserting the name of the < ** local variable at position 'level' in the stack. --- > ** Check whether object at given level has a close metamethod and raise > ** an error if not. 130,134c126,133 < static void varerror (lua_State *L, StkId level, const char *msg) { < int idx = cast_int(level - L->ci->func); < const char *vname = luaG_findlocal(L, L->ci, idx, NULL); < if (vname == NULL) vname = "?"; < luaG_runerror(L, msg, vname); --- > static void checkclosemth (lua_State *L, StkId level) { > const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); > if (ttisnil(tm)) { /* no metamethod? */ > int idx = cast_int(level - L->ci->func); /* variable index */ > const char *vname = luaG_findlocal(L, L->ci, idx, NULL); > if (vname == NULL) vname = "?"; > luaG_runerror(L, "variable '%s' got a non-closable value", vname); > } 139,148c138,142 < ** Prepare and call a closing method. If status is OK, code is still < ** inside the original protected call, and so any error will be handled < ** there. Otherwise, a previous error already activated the original < ** protected call, and so the call to the closing method must be < ** protected here. (A status == CLOSEPROTECT behaves like a previous < ** error, to also run the closing method in protected mode). < ** If status is OK, the call to the closing method will be pushed < ** at the top of the stack. Otherwise, values are pushed after < ** the 'level' of the upvalue being closed, as everything after < ** that won't be used again. --- > ** Prepare and call a closing method. > ** If status is CLOSEKTOP, the call to the closing method will be pushed > ** at the top of the stack. Otherwise, values can be pushed right after > ** the 'level' of the upvalue being closed, as everything after that > ** won't be used again. 150c144 < static int callclosemth (lua_State *L, StkId level, int status) { --- > static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { 152,174c146,151 < if (likely(status == LUA_OK)) { < if (prepclosingmethod(L, uv, &G(L)->nilvalue)) /* something to call? */ < callclose(L, NULL); /* call closing method */ < else if (!l_isfalse(uv)) /* non-closable non-false value? */ < varerror(L, level, "attempt to close non-closable variable '%s'"); < } < else { /* must close the object in protected mode */ < ptrdiff_t oldtop; < level++; /* space for error message */ < oldtop = savestack(L, level + 1); /* top will be after that */ < luaD_seterrorobj(L, status, level); /* set error message */ < if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ < int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0); < if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */ < status = newstatus; /* this will be the new error */ < else { < if (newstatus != LUA_OK) /* suppressed error? */ < luaE_warnerror(L, "__close metamethod"); < /* leave original error (or nil) on top */ < L->top = restorestack(L, oldtop); < } < } < /* else no metamethod; ignore this case and keep original error */ --- > TValue *errobj; > if (status == CLOSEKTOP) > errobj = &G(L)->nilvalue; /* error object is nil */ > else { /* 'luaD_seterrorobj' will set top to level + 2 */ > errobj = s2v(level + 1); /* error object goes after 'uv' */ > luaD_seterrorobj(L, status, level + 1); /* set error object */ 176c153 < return status; --- > callclosemethod(L, uv, errobj, yy); 181,182c158,160 < ** Try to create a to-be-closed upvalue < ** (can raise a memory-allocation error) --- > ** Maximum value for deltas in 'tbclist', dependent on the type > ** of delta. (This macro assumes that an 'L' is in scope where it > ** is used.) 184,186c162,163 < static void trynewtbcupval (lua_State *L, void *ud) { < newupval(L, 1, cast(StkId, ud), &L->openupval); < } --- > #define MAXDELTA \ > ((256ul << ((sizeof(L->stack->tbclist.delta) - 1) * 8)) - 1) 190,192c167 < ** Create a to-be-closed upvalue. If there is a memory error < ** when creating the upvalue, the closing method must be called here, < ** as there is no upvalue to call it later. --- > ** Insert a variable in the list of to-be-closed variables. 195,210c170,176 < TValue *obj = s2v(level); < lua_assert(L->openupval == NULL || uplevel(L->openupval) < level); < if (!l_isfalse(obj)) { /* false doesn't need to be closed */ < int status; < const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); < if (ttisnil(tm)) /* no metamethod? */ < varerror(L, level, "variable '%s' got a non-closable value"); < status = luaD_rawrunprotected(L, trynewtbcupval, level); < if (unlikely(status != LUA_OK)) { /* memory error creating upvalue? */ < lua_assert(status == LUA_ERRMEM); < luaD_seterrorobj(L, LUA_ERRMEM, level + 1); /* save error message */ < /* next call must succeed, as object is closable */ < prepclosingmethod(L, s2v(level), s2v(level + 1)); < callclose(L, NULL); /* call closing method */ < luaD_throw(L, LUA_ERRMEM); /* throw memory error */ < } --- > lua_assert(level > L->tbclist); > if (l_isfalse(s2v(level))) > return; /* false doesn't need to be closed */ > checkclosemth(L, level); /* value must have a close method */ > while (cast_uint(level - L->tbclist) > MAXDELTA) { > L->tbclist += MAXDELTA; /* create a dummy node at maximum delta */ > L->tbclist->tbclist.delta = 0; 211a178,179 > level->tbclist.delta = cast(unsigned short, level - L->tbclist); > L->tbclist = level; 223c191,194 < int luaF_close (lua_State *L, StkId level, int status) { --- > /* > ** Close all upvalues up to the given stack level. > */ > void luaF_closeupval (lua_State *L, StkId level) { 225c196,197 < while ((uv = L->openupval) != NULL && uplevel(uv) >= level) { --- > StkId upl; /* stack index pointed by 'uv' */ > while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { 228,234c200 < if (uv->tbc && status != NOCLOSINGMETH) { < /* must run closing method, which may change the stack */ < ptrdiff_t levelrel = savestack(L, level); < status = callclosemth(L, uplevel(uv), status); < level = restorestack(L, levelrel); < } < luaF_unlinkupval(uv); --- > luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ 242c208,236 < return status; --- > } > > > /* > ** Remove firt element from the tbclist plus its dummy nodes. > */ > static void poptbclist (lua_State *L) { > StkId tbc = L->tbclist; > lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ > tbc -= tbc->tbclist.delta; > while (tbc > L->stack && tbc->tbclist.delta == 0) > tbc -= MAXDELTA; /* remove dummy nodes */ > L->tbclist = tbc; > } > > > /* > ** Close all upvalues and to-be-closed variables up to the given stack > ** level. > */ > void luaF_close (lua_State *L, StkId level, int status, int yy) { > ptrdiff_t levelrel = savestack(L, level); > luaF_closeupval(L, level); /* first, close the upvalues */ > while (L->tbclist >= level) { /* traverse tbc's down to that level */ > StkId tbc = L->tbclist; /* get variable index */ > poptbclist(L); /* remove it from list */ > prepcallclosemth(L, tbc, status, yy); /* close variable */ > level = restorestack(L, levelrel); > } diff -Nr lua-5.4.2/src/lfunc.h lua-5.4.3/src/lfunc.h 45,47d44 < /* < ** Special "status" for 'luaF_close' < */ 49,53c46,47 < /* close upvalues without running their closing methods */ < #define NOCLOSINGMETH (-1) < < /* close upvalues running all closing methods in protected mode */ < #define CLOSEPROTECT (-2) --- > /* special status to close upvalues preserving the top of the stack */ > #define CLOSEKTOP (-1) 62c56,57 < LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status); --- > LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); > LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); diff -Nr lua-5.4.2/src/lgc.c lua-5.4.3/src/lgc.c 919c919 < if (unlikely(status != LUA_OK)) { /* error while running __gc? */ --- > if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ 1577a1578,1580 > lu_mem work; > lua_assert(!g->gcstopem); /* collector is not reentrant */ > g->gcstopem = 1; /* no emergency collections while collecting */ 1582c1585,1586 < return 1; --- > work = 1; > break; 1587c1591 < return 0; --- > work = 0; 1590c1594,1595 < return propagatemark(g); /* traverse one gray object */ --- > work = propagatemark(g); /* traverse one gray object */ > break; 1593c1598 < lu_mem work = atomic(L); /* work is what was traversed by 'atomic' */ --- > work = atomic(L); /* work is what was traversed by 'atomic' */ 1596c1601 < return work; --- > break; 1599c1604,1605 < return sweepstep(L, g, GCSswpfinobj, &g->finobj); --- > work = sweepstep(L, g, GCSswpfinobj, &g->finobj); > break; 1602c1608,1609 < return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); --- > work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); > break; 1605c1612,1613 < return sweepstep(L, g, GCSswpend, NULL); --- > work = sweepstep(L, g, GCSswpend, NULL); > break; 1610c1618,1619 < return 0; --- > work = 0; > break; 1614,1615c1623,1624 < int n = runafewfinalizers(L, GCFINMAX); < return n * GCFINALIZECOST; --- > g->gcstopem = 0; /* ok collections during finalizers */ > work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; 1619c1628 < return 0; --- > work = 0; 1620a1630 > break; 1623a1634,1635 > g->gcstopem = 0; > return work; diff -Nr lua-5.4.2/src/liolib.c lua-5.4.3/src/liolib.c 55,60d54 < #if !defined(l_checkmodep) < /* By default, Lua accepts only "r" or "w" as mode */ < #define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0') < #endif < < 72a67,72 > #if !defined(l_checkmodep) > /* Windows accepts "[rw][bt]?" as valid modes */ > #define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && \ > (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0'))) > #endif > 85a86,91 > > #if !defined(l_checkmodep) > /* By default, Lua accepts only "r" or "w" as valid modes */ > #define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0') > #endif > 183c189 < if (isclosed(p)) --- > if (l_unlikely(isclosed(p))) 258c264 < if (p->f == NULL) --- > if (l_unlikely(p->f == NULL)) 306c312 < if (isclosed(p)) --- > if (l_unlikely(isclosed(p))) 433c439 < if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */ --- > if (l_unlikely(rn->n >= L_MAXLENNUM)) { /* buffer overflow? */ 496,497c502,503 < if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ < return 1; /* ok */ --- > if (l_likely(lua_stringtonumber(L, rn.buff))) > return 1; /* ok, it is a valid number */ 673c679,680 < if (status) return 1; /* file handle already on stack top */ --- > if (l_likely(status)) > return 1; /* file handle already on stack top */ 700c707 < if (op) --- > if (l_unlikely(op)) diff -Nr lua-5.4.2/src/llex.c lua-5.4.3/src/llex.c 125,127c125,132 < ** creates a new string and anchors it in scanner's table so that < ** it will not be collected until the end of the compilation < ** (by that time it should be anchored somewhere) --- > ** Creates a new string and anchors it in scanner's table so that it > ** will not be collected until the end of the compilation; by that time > ** it should be anchored somewhere. It also internalizes long strings, > ** ensuring there is only one copy of each unique string. The table > ** here is used as a set: the string enters as the key, while its value > ** is irrelevant. We use the string itself as the value only because it > ** is a TValue readly available. Later, the code generation can change > ** this value. 131d135 < TValue *o; /* entry for 'str' */ 133,138c137,144 < setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ < o = luaH_set(L, ls->h, s2v(L->top - 1)); < if (isempty(o)) { /* not in use yet? */ < /* boolean value does not need GC barrier; < table is not a metatable, so it does not need to invalidate cache */ < setbtvalue(o); /* t[string] = true */ --- > const TValue *o = luaH_getstr(ls->h, ts); > if (!ttisnil(o)) /* string already present? */ > ts = keystrval(nodefromval(o)); /* get saved copy */ > else { /* not in use yet */ > TValue *stv = s2v(L->top++); /* reserve stack space for string */ > setsvalue(L, stv, ts); /* temporarily anchor the string */ > luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ > /* table is not a metatable, so it does not need to invalidate cache */ 139a146 > L->top--; /* remove string from stack */ 141,144d147 < else { /* string already present */ < ts = keystrval(nodefromval(o)); /* re-use value previously stored */ < } < L->top--; /* remove string from stack */ diff -Nr lua-5.4.2/src/llimits.h lua-5.4.3/src/llimits.h 153,168d152 < ** macros to improve jump prediction (used mainly for error handling) < */ < #if !defined(likely) < < #if defined(__GNUC__) < #define likely(x) (__builtin_expect(((x) != 0), 1)) < #define unlikely(x) (__builtin_expect(((x) != 0), 0)) < #else < #define likely(x) (x) < #define unlikely(x) (x) < #endif < < #endif < < < /* diff -Nr lua-5.4.2/src/lmathlib.c lua-5.4.3/src/lmathlib.c 76c76 < if (valid) --- > if (l_likely(valid)) 178c178,179 < res = l_mathop(log2)(x); else --- > res = l_mathop(log2)(x); > else diff -Nr lua-5.4.2/src/lmem.c lua-5.4.3/src/lmem.c 27,29c27,29 < ** First allocation will fail whenever not building initial state < ** and not shrinking a block. (This fail will trigger 'tryagain' and < ** a full GC cycle at every allocation.) --- > ** First allocation will fail whenever not building initial state. > ** (This fail will trigger 'tryagain' and a full GC cycle at every > ** allocation.) 32c32 < if (ttisnil(&g->nilvalue) && ns > os) --- > if (completestate(g) && ns > 0) /* frees never fail */ 86c86 < if (unlikely(size >= limit)) /* cannot grow even a little? */ --- > if (l_unlikely(size >= limit)) /* cannot grow even a little? */ 141,144c141,146 < ** In case of allocation fail, this function will call the GC to try < ** to free some memory and then try the allocation again. < ** (It should not be called when shrinking a block, because then the < ** interpreter may be in the middle of a collection step.) --- > ** In case of allocation fail, this function will do an emergency > ** collection to free some memory and then try the allocation again. > ** The GC should not be called while state is not fully built, as the > ** collector is not yet fully initialized. Also, it should not be called > ** when 'gcstopem' is true, because then the interpreter is in the > ** middle of a collection step. 149c151 < if (ttisnil(&g->nilvalue)) { /* is state fully build? */ --- > if (completestate(g) && !g->gcstopem) { 159,160d160 < ** If allocation fails while shrinking a block, do not try again; the < ** GC shrinks some blocks and it is not reentrant. 167,169c167,168 < if (unlikely(newblock == NULL && nsize > 0)) { < if (nsize > osize) /* not shrinking a block? */ < newblock = tryagain(L, block, osize, nsize); --- > if (l_unlikely(newblock == NULL && nsize > 0)) { > newblock = tryagain(L, block, osize, nsize); 182c181 < if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ --- > if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ 194c193 < if (unlikely(newblock == NULL)) { --- > if (l_unlikely(newblock == NULL)) { diff -Nr lua-5.4.2/src/loadlib.c lua-5.4.3/src/loadlib.c 135c135,136 < if (lib == NULL) lua_pushstring(L, dlerror()); --- > if (l_unlikely(lib == NULL)) > lua_pushstring(L, dlerror()); 142c143,144 < if (f == NULL) lua_pushstring(L, dlerror()); --- > if (l_unlikely(f == NULL)) > lua_pushstring(L, dlerror()); 413c415 < if (stat == 0) /* no errors? */ --- > if (l_likely(stat == 0)) /* no errors? */ 526c528 < if (path == NULL) --- > if (l_unlikely(path == NULL)) 533c535 < if (stat) { /* module loaded successfully? */ --- > if (l_likely(stat)) { /* module loaded successfully? */ 626c628,629 < if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) --- > if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers") > != LUA_TTABLE)) 632c635 < if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ --- > if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */ diff -Nr lua-5.4.2/src/lobject.h lua-5.4.3/src/lobject.h 139c139,144 < ** Entries in the Lua stack --- > ** Entries in a Lua stack. Field 'tbclist' forms a list of all > ** to-be-closed variables active in this stack. Dummy entries are > ** used when the distance between two tbc variables does not fit > ** in an unsigned short. They are represented by delta==0, and > ** their real delta is always the maximum value that fits in > ** that field. 142a148,151 > struct { > TValuefields; > unsigned short delta; > } tbclist; 573d581 < #define ttisclosure(o) ((rawtt(o) & 0x1F) == LUA_VLCL) 576a585,586 > #define ttisclosure(o) (ttisLclosure(o) || ttisCclosure(o)) > diff -Nr lua-5.4.2/src/lopcodes.h lua-5.4.3/src/lopcodes.h 228,234c228,234 < OP_ADDK,/* A B C R[A] := R[B] + K[C] */ < OP_SUBK,/* A B C R[A] := R[B] - K[C] */ < OP_MULK,/* A B C R[A] := R[B] * K[C] */ < OP_MODK,/* A B C R[A] := R[B] % K[C] */ < OP_POWK,/* A B C R[A] := R[B] ^ K[C] */ < OP_DIVK,/* A B C R[A] := R[B] / K[C] */ < OP_IDIVK,/* A B C R[A] := R[B] // K[C] */ --- > OP_ADDK,/* A B C R[A] := R[B] + K[C]:number */ > OP_SUBK,/* A B C R[A] := R[B] - K[C]:number */ > OP_MULK,/* A B C R[A] := R[B] * K[C]:number */ > OP_MODK,/* A B C R[A] := R[B] % K[C]:number */ > OP_POWK,/* A B C R[A] := R[B] ^ K[C]:number */ > OP_DIVK,/* A B C R[A] := R[B] / K[C]:number */ > OP_IDIVK,/* A B C R[A] := R[B] // K[C]:number */ diff -Nr lua-5.4.2/src/loslib.c lua-5.4.3/src/loslib.c 173c173 < if (err) --- > if (l_unlikely(err)) 211c211 < if (value > LUA_MAXINTEGER - delta) --- > if (l_unlikely(value > LUA_MAXINTEGER - delta)) 256c256 < if (t != LUA_TNIL) /* some other value? */ --- > if (l_unlikely(t != LUA_TNIL)) /* some other value? */ 258c258 < else if (d < 0) /* absent field; no default? */ --- > else if (l_unlikely(d < 0)) /* absent field; no default? */ diff -Nr lua-5.4.2/src/lparser.c lua-5.4.3/src/lparser.c 131c131 < if (unlikely(!testnext(ls, what))) { --- > if (l_unlikely(!testnext(ls, what))) { 225,228c225,227 < ** Convert 'nvar', a compiler index level, to it corresponding < ** stack index level. For that, search for the highest variable < ** below that level that is in the stack and uses its stack < ** index ('sidx'). --- > ** Convert 'nvar', a compiler index level, to its corresponding > ** register. For that, search for the highest variable below that level > ** that is in a register and uses its register index ('ridx') plus one. 230c229 < static int stacklevel (FuncState *fs, int nvar) { --- > static int reglevel (FuncState *fs, int nvar) { 232,234c231,233 < Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */ < if (vd->vd.kind != RDKCTC) /* is in the stack? */ < return vd->vd.sidx + 1; --- > Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ > if (vd->vd.kind != RDKCTC) /* is in a register? */ > return vd->vd.ridx + 1; 236c235 < return 0; /* no variables in the stack */ --- > return 0; /* no variables in registers */ 241c240,241 < ** Return the number of variables in the stack for function 'fs' --- > ** Return the number of variables in the register stack for the given > ** function. 244c244 < return stacklevel(fs, fs->nactvar); --- > return reglevel(fs, fs->nactvar); 270c270 < e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx; --- > e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; 313c313 < int stklevel = luaY_nvarstack(fs); --- > int reglevel = luaY_nvarstack(fs); 318c318 < var->vd.sidx = stklevel++; --- > var->vd.ridx = reglevel++; 369c369 < up->idx = v->u.var.sidx; --- > up->idx = v->u.var.ridx; 520c520 < if (unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ --- > if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ 623c623 < if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar)) --- > if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar)) 664c664 < int stklevel = stacklevel(fs, bl->nactvar); /* level outside the block */ --- > int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ 1333c1333 < if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) { --- > if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) { 1339c1339 < lh->v.u.ind.idx == v->u.var.sidx) { --- > lh->v.u.ind.idx == v->u.var.ridx) { 1349c1349 < luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0); --- > luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0); 1414c1414 < int lblevel = stacklevel(fs, lb->nactvar); /* label level */ --- > int lblevel = reglevel(fs, lb->nactvar); /* label level */ 1438c1438 < if (unlikely(lb != NULL)) { /* already defined? */ --- > if (l_unlikely(lb != NULL)) { /* already defined? */ 1491c1491 < luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0); --- > luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0); 1523c1523 < if (unlikely(offset > MAXARG_Bx)) --- > if (l_unlikely(offset > MAXARG_Bx)) 1711c1711 < luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0); --- > luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0); diff -Nr lua-5.4.2/src/lparser.h lua-5.4.3/src/lparser.h 38c38 < VLOCAL, /* local variable; var.sidx = stack index (local register); --- > VLOCAL, /* local variable; var.ridx = register index; 80c80 < lu_byte sidx; /* index in the stack */ --- > lu_byte ridx; /* register holding the variable */ 100c100 < lu_byte sidx; /* index of the variable in the stack */ --- > lu_byte ridx; /* register holding the variable */ diff -Nr lua-5.4.2/src/lstate.c lua-5.4.3/src/lstate.c 175c175 < if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) --- > if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) 183a184 > L1->tbclist = L1->stack; 216d216 < TValue temp; 222,226c222,224 < setthvalue(L, &temp, L); /* temp = L */ < luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); < /* registry[LUA_RIDX_GLOBALS] = table of globals */ < sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ < luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); --- > setthvalue(L, ®istry->array[LUA_RIDX_MAINTHREAD - 1], L); > /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */ > sethvalue(L, ®istry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L)); 232,233d229 < ** ('g->nilvalue' being a nil value flags that the state was completely < ** build.) 244c240 < setnilvalue(&g->nilvalue); --- > setnilvalue(&g->nilvalue); /* now state is complete */ 258a255 > L->nCcalls = 0; 274,276c271,275 < luaF_close(L, L->stack, CLOSEPROTECT); /* close all upvalues */ < luaC_freeallobjects(L); /* collect all objects */ < if (ttisnil(&g->nilvalue)) /* closing a fully built state? */ --- > if (!completestate(g)) /* closing a partially built state? */ > luaC_freeallobjects(L); /* jucst collect its objects */ > else { /* closing a fully built state */ > luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ > luaC_freeallobjects(L); /* collect all objects */ 277a277 > } 302d301 < L1->nCcalls = 0; 319c318 < luaF_close(L1, L1->stack, NOCLOSINGMETH); /* close all upvalues */ --- > luaF_closeupval(L1, L1->stack); /* close all upvalues */ 327,331c326,327 < int lua_resetthread (lua_State *L) { < CallInfo *ci; < int status; < lua_lock(L); < L->ci = ci = &L->base_ci; /* unwind CallInfo list */ --- > int luaE_resetthread (lua_State *L, int status) { > CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ 335,338c331 < status = luaF_close(L, L->stack, CLOSEPROTECT); < if (status != CLOSEPROTECT) /* real errors? */ < luaD_seterrorobj(L, status, L->stack + 1); < else { --- > if (status == LUA_YIELD) 339a333,336 > status = luaD_closeprotected(L, 1, status); > if (status != LUA_OK) /* errors? */ > luaD_seterrorobj(L, status, L->stack + 1); > else 341d337 < } 343c339,348 < L->status = status; --- > L->status = cast_byte(status); > luaD_reallocstack(L, cast_int(ci->top - L->stack), 0); > return status; > } > > > LUA_API int lua_resetthread (lua_State *L) { > int status; > lua_lock(L); > status = luaE_resetthread(L, L->status); 363d367 < L->nCcalls = 0; 377a382 > g->gcstopem = 0; diff -Nr lua-5.4.2/src/lstate.h lua-5.4.3/src/lstate.h 158a159,170 > ** About union 'u': > ** - field 'l' is used only for Lua functions; > ** - field 'c' is used only for C functions. > ** About union 'u2': > ** - field 'funcidx' is used only by C functions while doing a > ** protected call; > ** - field 'nyield' is used only while a function is "doing" an > ** yield (from the yield until the next resume); > ** - field 'nres' is used only while closing tbc variables when > ** returning from a C function; > ** - field 'transferinfo' is used only during call/returnhooks, > ** before the function starts or after it ends. 178a191 > int nres; /* number of values returned */ 194c207 < #define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ --- > #define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ 196c209 < #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ --- > #define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ 199c212 < #define CIST_FIN (1<<7) /* call is running a finalizer */ --- > #define CIST_FIN (1<<7) /* call is running a finalizer */ 200a214,216 > #define CIST_CLSRET (1<<9) /* function is closing tbc variables */ > /* Bits 10-12 are used for CIST_RECST (see below) */ > #define CIST_RECST 10 202c218 < #define CIST_LEQ (1<<9) /* using __lt for __le */ --- > #define CIST_LEQ (1<<13) /* using __lt for __le */ 204a221,234 > > /* > ** Field CIST_RECST stores the "recover status", used to keep the error > ** status while closing to-be-closed variables in coroutines, so that > ** Lua can correctly resume after an yield from a __close method called > ** because of an error. (Three bits are enough for error status.) > */ > #define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) > #define setcistrecst(ci,st) \ > check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ > ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ > | ((st) << CIST_RECST))) > > 232a263 > lu_byte gcstopem; /* stops emergency collections */ 283a315 > StkId tbclist; /* list of to-be-closed variables */ 299a332,337 > /* > ** 'g->nilvalue' being a nil value flags that the state was completely > ** build. > */ > #define completestate(g) ttisnil(&g->nilvalue) > 361a400 > LUAI_FUNC int luaE_resetthread (lua_State *L, int status); diff -Nr lua-5.4.2/src/lstring.c lua-5.4.3/src/lstring.c 92c92 < if (unlikely(newvect == NULL)) { /* reallocation failed? */ --- > if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ 175c175 < if (unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ --- > if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ 226c226 < if (unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) --- > if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) 262c262 < if (unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) --- > if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) diff -Nr lua-5.4.2/src/lstrlib.c lua-5.4.3/src/lstrlib.c 155,156c155,157 < if (n <= 0) lua_pushliteral(L, ""); < else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ --- > if (n <= 0) > lua_pushliteral(L, ""); > else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n)) 184c185 < if (pose - posi >= (size_t)INT_MAX) /* arithmetic overflow? */ --- > if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */ 238c239 < if (lua_dump(L, writer, &state, strip) != 0) --- > if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) 278c279,280 < if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) --- > if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || > !luaL_getmetafield(L, 2, mtname))) 386c388,389 < if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) --- > if (l_unlikely(l < 0 || l >= ms->level || > ms->capture[l].len == CAP_UNFINISHED)) 403c406 < if (p == ms->p_end) --- > if (l_unlikely(p == ms->p_end)) 410c413 < if (p == ms->p_end) --- > if (l_unlikely(p == ms->p_end)) 485c488 < if (p >= ms->p_end - 1) --- > if (l_unlikely(p >= ms->p_end - 1)) 568c571 < if (ms->matchdepth-- == 0) --- > if (l_unlikely(ms->matchdepth-- == 0)) 602c605 < if (*p != '[') --- > if (l_unlikely(*p != '[')) 702c705 < if (i != 0) --- > if (l_unlikely(i != 0)) 710c713 < if (capl == CAP_UNFINISHED) --- > if (l_unlikely(capl == CAP_UNFINISHED)) 929c932 < else if (!lua_isstring(L, -1)) --- > else if (l_unlikely(!lua_isstring(L, -1))) 1061c1064 < else if (fmt[SIZELENMOD] != 'a') --- > else if (l_unlikely(fmt[SIZELENMOD] != 'a')) 1362,1371d1364 < ** Union for serializing floats < */ < typedef union Ftypes { < float f; < double d; < lua_Number n; < } Ftypes; < < < /* 1387c1380,1382 < Kfloat, /* floating-point numbers */ --- > Kfloat, /* single-precision floating-point numbers */ > Knumber, /* Lua "native" floating-point numbers */ > Kdouble, /* double-precision floating-point numbers */ 1422c1417 < if (sz > MAXINTSIZE || sz <= 0) --- > if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) 1456,1457c1451,1452 < case 'd': *size = sizeof(double); return Kfloat; < case 'n': *size = sizeof(lua_Number); return Kfloat; --- > case 'n': *size = sizeof(lua_Number); return Knumber; > case 'd': *size = sizeof(double); return Kdouble; 1463c1458 < if (*size == -1) --- > if (l_unlikely(*size == -1)) 1502c1497 < if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ --- > if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ 1583,1591c1578,1598 < case Kfloat: { /* floating-point options */ < Ftypes u; < char *buff = luaL_prepbuffsize(&b, size); < lua_Number n = luaL_checknumber(L, arg); /* get argument */ < if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ < else if (size == sizeof(u.d)) u.d = (double)n; < else u.n = n; < /* move 'u' to final result, correcting endianness if needed */ < copywithendian(buff, (char *)&u, size, h.islittle); --- > case Kfloat: { /* C float */ > float f = (float)luaL_checknumber(L, arg); /* get argument */ > char *buff = luaL_prepbuffsize(&b, sizeof(f)); > /* move 'f' to final result, correcting endianness if needed */ > copywithendian(buff, (char *)&f, sizeof(f), h.islittle); > luaL_addsize(&b, size); > break; > } > case Knumber: { /* Lua float */ > lua_Number f = luaL_checknumber(L, arg); /* get argument */ > char *buff = luaL_prepbuffsize(&b, sizeof(f)); > /* move 'f' to final result, correcting endianness if needed */ > copywithendian(buff, (char *)&f, sizeof(f), h.islittle); > luaL_addsize(&b, size); > break; > } > case Kdouble: { /* C double */ > double f = (double)luaL_checknumber(L, arg); /* get argument */ > char *buff = luaL_prepbuffsize(&b, sizeof(f)); > /* move 'f' to final result, correcting endianness if needed */ > copywithendian(buff, (char *)&f, sizeof(f), h.islittle); 1682c1689 < if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) --- > if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) 1717,1723c1724,1738 < Ftypes u; < lua_Number num; < copywithendian((char *)&u, data + pos, size, h.islittle); < if (size == sizeof(u.f)) num = (lua_Number)u.f; < else if (size == sizeof(u.d)) num = (lua_Number)u.d; < else num = u.n; < lua_pushnumber(L, num); --- > float f; > copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); > lua_pushnumber(L, (lua_Number)f); > break; > } > case Knumber: { > lua_Number f; > copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); > lua_pushnumber(L, f); > break; > } > case Kdouble: { > double f; > copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); > lua_pushnumber(L, (lua_Number)f); diff -Nr lua-5.4.2/src/ltable.c lua-5.4.3/src/ltable.c 70a71,74 > /* > ** When the original hash value is good, hashing by a power of 2 > ** avoids the cost of '%'. > */ 73,77d76 < #define hashstr(t,str) hashpow2(t, (str)->hash) < #define hashboolean(t,p) hashpow2(t, p) < #define hashint(t,i) hashpow2(t, i) < < 79,80c78,79 < ** for some types, it is better to avoid modulus by power of 2, as < ** they tend to have many 2 factors. --- > ** for other types, it is better to avoid modulo by power of 2, as > ** they can have many 2 factors. 84a84,89 > #define hashstr(t,str) hashpow2(t, (str)->hash) > #define hashboolean(t,p) hashpow2(t, p) > > #define hashint(t,i) hashpow2(t, i) > > 138,145c143,158 < case LUA_VNUMINT: < return hashint(t, ivalueraw(*kvl)); < case LUA_VNUMFLT: < return hashmod(t, l_hashfloat(fltvalueraw(*kvl))); < case LUA_VSHRSTR: < return hashstr(t, tsvalueraw(*kvl)); < case LUA_VLNGSTR: < return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl))); --- > case LUA_VNUMINT: { > lua_Integer key = ivalueraw(*kvl); > return hashint(t, key); > } > case LUA_VNUMFLT: { > lua_Number n = fltvalueraw(*kvl); > return hashmod(t, l_hashfloat(n)); > } > case LUA_VSHRSTR: { > TString *ts = tsvalueraw(*kvl); > return hashstr(t, ts); > } > case LUA_VLNGSTR: { > TString *ts = tsvalueraw(*kvl); > return hashpow2(t, luaS_hashlongstr(ts)); > } 150,155c163,174 < case LUA_VLIGHTUSERDATA: < return hashpointer(t, pvalueraw(*kvl)); < case LUA_VLCF: < return hashpointer(t, fvalueraw(*kvl)); < default: < return hashpointer(t, gcvalueraw(*kvl)); --- > case LUA_VLIGHTUSERDATA: { > void *p = pvalueraw(*kvl); > return hashpointer(t, p); > } > case LUA_VLCF: { > lua_CFunction f = fvalueraw(*kvl); > return hashpointer(t, f); > } > default: { > GCObject *o = gcvalueraw(*kvl); > return hashpointer(t, o); > } 310c329 < if (unlikely(isabstkey(n))) --- > if (l_unlikely(isabstkey(n))) 488c507 < setobjt2t(L, luaH_set(L, t, &k), gval(old)); --- > luaH_set(L, t, &k, gval(old)); 544c563 < if (unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ --- > if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ 635c654 < TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { --- > void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { 638c657 < if (unlikely(ttisnil(key))) --- > if (l_unlikely(ttisnil(key))) 647c666 < else if (unlikely(luai_numisnan(f))) --- > else if (l_unlikely(luai_numisnan(f))) 649a669,670 > if (ttisnil(value)) > return; /* do not insert nil values */ 657c678,679 < return luaH_set(L, t, key); /* insert key into grown table */ --- > luaH_set(L, t, key, value); /* insert key into grown table */ > return; 685c707 < return gval(mp); --- > setobj2t(L, gval(mp), value); 772a795,809 > ** Finish a raw "set table" operation, where 'slot' is where the value > ** should have been (the result of a previous "get table"). > ** Beware: when using this function you probably need to check a GC > ** barrier and invalidate the TM cache. > */ > void luaH_finishset (lua_State *L, Table *t, const TValue *key, > const TValue *slot, TValue *value) { > if (isabstkey(slot)) > luaH_newkey(L, t, key, value); > else > setobj2t(L, cast(TValue *, slot), value); > } > > > /* 776,780c813,815 < TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { < const TValue *p = luaH_get(t, key); < if (!isabstkey(p)) < return cast(TValue *, p); < else return luaH_newkey(L, t, key); --- > void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { > const TValue *slot = luaH_get(t, key); > luaH_finishset(L, t, key, slot, value); 786,789c821 < TValue *cell; < if (!isabstkey(p)) < cell = cast(TValue *, p); < else { --- > if (isabstkey(p)) { 792c824 < cell = luaH_newkey(L, t, &k); --- > luaH_newkey(L, t, &k, value); 794c826,827 < setobj2t(L, cell, value); --- > else > setobj2t(L, cast(TValue *, p), value); diff -Nr lua-5.4.2/src/ltable.h lua-5.4.3/src/ltable.h 44,45c44,49 < LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); < LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); --- > LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, > TValue *value); > LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, > TValue *value); > LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, > const TValue *slot, TValue *value); diff -Nr lua-5.4.2/src/ltablib.c lua-5.4.3/src/ltablib.c 148,149c148,149 < if (!lua_isstring(L, -1)) < luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", --- > if (l_unlikely(!lua_isstring(L, -1))) > luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", 199c199,200 < if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) --- > if (l_unlikely(n >= (unsigned int)INT_MAX || > !lua_checkstack(L, (int)(++n)))) 303c304 < if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ --- > if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */ 310c311 < if (j < i) /* j < i but a[j] > P ?? */ --- > if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */ diff -Nr lua-5.4.2/src/ltm.c lua-5.4.3/src/ltm.c 150c150 < if (!callbinTM(L, p1, p2, res, event)) { --- > if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { 169c169,170 < if (!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, TM_CONCAT)) --- > if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, > TM_CONCAT))) diff -Nr lua-5.4.2/src/lua.c lua-5.4.3/src/lua.c 39a40,59 > #if defined(LUA_USE_POSIX) /* { */ > > /* > ** Use 'sigaction' when available. > */ > static void setsignal (int sig, void (*handler)(int)) { > struct sigaction sa; > sa.sa_handler = handler; > sa.sa_flags = 0; > sigemptyset(&sa.sa_mask); /* do not mask any signal */ > sigaction(sig, &sa, NULL); > } > > #else /* }{ */ > > #define setsignal signal > > #endif /* } */ > > 58c78 < signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ --- > setsignal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ 138c158 < signal(SIGINT, laction); /* set C-signal handler */ --- > setsignal(SIGINT, laction); /* set C-signal handler */ 140c160 < signal(SIGINT, SIG_DFL); /* reset C-signal handler */ --- > setsignal(SIGINT, SIG_DFL); /* reset C-signal handler */ diff -Nr lua-5.4.2/src/lua.h lua-5.4.3/src/lua.h 21c21 < #define LUA_VERSION_RELEASE "2" --- > #define LUA_VERSION_RELEASE "3" 28c28 < #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" --- > #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2021 Lua.org, PUC-Rio" 350c350,351 < LUA_API void (lua_toclose) (lua_State *L, int idx); --- > LUA_API void (lua_toclose) (lua_State *L, int idx); > LUA_API void (lua_closeslot) (lua_State *L, int idx); 494c495 < * Copyright (C) 1994-2020 Lua.org, PUC-Rio. --- > * Copyright (C) 1994-2021 Lua.org, PUC-Rio. diff -Nr lua-5.4.2/src/luaconf.h lua-5.4.3/src/luaconf.h 19,25c19,25 < ** Some definitions here can be changed externally, through the < ** compiler (e.g., with '-D' options). Those are protected by < ** '#if !defined' guards. However, several other definitions should < ** be changed directly here, either because they affect the Lua < ** ABI (by making the changes here, you ensure that all software < ** connected to Lua, such as C libraries, will be compiled with the < ** same configuration); or because they are seldom changed. --- > ** Some definitions here can be changed externally, through the compiler > ** (e.g., with '-D' options): They are commented out or protected > ** by '#if !defined' guards. However, several other definitions > ** should be changed directly here, either because they affect the > ** Lua ABI (by making the changes here, you ensure that all software > ** connected to Lua, such as C libraries, will be compiled with the same > ** configuration); or because they are seldom changed. 84c84,86 < ** Configuration for Number types. --- > ** Configuration for Number types. These options should not be > ** set externally, because any other code connected to Lua must > ** use the same configuration. 89,104d90 < @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. < */ < /* #define LUA_32BITS */ < < < /* < @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for < ** C89 ('long' and 'double'); Windows always has '__int64', so it does < ** not need to use this case. < */ < #if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) < #define LUA_C89_NUMBERS < #endif < < < /* 124c110,134 < #if defined(LUA_32BITS) /* { */ --- > > /* Default configuration ('long long' and 'double', for 64-bit Lua) */ > #define LUA_INT_DEFAULT LUA_INT_LONGLONG > #define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE > > > /* > @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. > */ > #define LUA_32BITS 0 > > > /* > @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for > ** C89 ('long' and 'double'); Windows always has '__int64', so it does > ** not need to use this case. > */ > #if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) > #define LUA_C89_NUMBERS 1 > #else > #define LUA_C89_NUMBERS 0 > #endif > > > #if LUA_32BITS /* { */ 135c145 < #elif defined(LUA_C89_NUMBERS) /* }{ */ --- > #elif LUA_C89_NUMBERS /* }{ */ 142c152,153 < #endif /* } */ --- > #else /* }{ */ > /* use defaults */ 143a155,156 > #define LUA_INT_TYPE LUA_INT_DEFAULT > #define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT 145,150c158 < /* < ** default configuration for 64-bit Lua ('long long' and 'double') < */ < #if !defined(LUA_INT_TYPE) < #define LUA_INT_TYPE LUA_INT_LONGLONG < #endif --- > #endif /* } */ 152,154d159 < #if !defined(LUA_FLOAT_TYPE) < #define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE < #endif 376c381 < ** Configuration for Numbers. --- > ** Configuration for Numbers (low-level part). 383d387 < @@ LUA_NUMBER is the floating-point type used by Lua. 476,477d479 < @@ LUA_INTEGER is the integer type used by Lua. < ** 479d480 < ** 661a663,690 > > /* > ** macros to improve jump prediction, used mostly for error handling > ** and debug facilities. (Some macros in the Lua API use these macros. > ** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your > ** code.) > */ > #if !defined(luai_likely) > > #if defined(__GNUC__) && !defined(LUA_NOBUILTIN) > #define luai_likely(x) (__builtin_expect(((x) != 0), 1)) > #define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) > #else > #define luai_likely(x) (x) > #define luai_unlikely(x) (x) > #endif > > #endif > > > #if defined(LUA_CORE) || defined(LUA_LIB) > /* shorter names for Lua's own use */ > #define l_likely(x) luai_likely(x) > #define l_unlikely(x) luai_unlikely(x) > #endif > > > diff -Nr lua-5.4.2/src/lualib.h lua-5.4.3/src/lualib.h 52,57d51 < < #if !defined(lua_assert) < #define lua_assert(x) ((void)0) < #endif < < diff -Nr lua-5.4.2/src/lvm.c lua-5.4.3/src/lvm.c 238c238 < if (unlikely(!tonumber(plimit, &limit))) --- > if (l_unlikely(!tonumber(plimit, &limit))) 240c240 < if (unlikely(!tonumber(pstep, &step))) --- > if (l_unlikely(!tonumber(pstep, &step))) 242c242 < if (unlikely(!tonumber(pinit, &init))) --- > if (l_unlikely(!tonumber(pinit, &init))) 295c295 < if (unlikely(notm(tm))) --- > if (l_unlikely(notm(tm))) 340,343c340 < if (isabstkey(slot)) /* no previous entry? */ < slot = luaH_newkey(L, h, key); /* create one */ < /* no metamethod and (now) there is an entry with given key */ < setobj2t(L, cast(TValue *, slot), val); /* set its new value */ --- > luaH_finishset(L, h, key, slot, val); /* set new value */ 352c349 < if (unlikely(notm(tm))) --- > if (l_unlikely(notm(tm))) 574,575c571,577 < lua_Integer i1, i2; /* compare them as integers */ < return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2); --- > /* One of them is an integer. If the other does not have an > integer value, they cannot be equal; otherwise, compare their > integer values. */ > lua_Integer i1, i2; > return (luaV_tointegerns(t1, &i1, F2Ieq) && > luaV_tointegerns(t2, &i2, F2Ieq) && > i1 == i2); 657c659 < if (unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) --- > if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) 701c703 < if (unlikely(notm(tm))) /* no metamethod? */ --- > if (l_unlikely(notm(tm))) /* no metamethod? */ 717c719 < if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ --- > if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ 737c739 < if (unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ --- > if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ 847a850,853 > case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */ > ci->u.l.savedpc--; /* repeat instruction to close other vars. */ > break; > } 923c929 < TValue *v2 = KC(i); \ --- > TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ 952c958 < TValue *v2 = KC(i); \ --- > TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ 1051c1057,1058 < #define updatestack(ci) { if (trap) { updatebase(ci); ra = RA(i); } } --- > #define updatestack(ci) \ > { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } } 1109c1116 < if (trap) { /* stack reallocation or hooks? */ \ --- > if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \ 1137c1144 < if (trap) { --- > if (l_unlikely(trap)) { 1151a1159,1160 > // low-level line tracing for debugging Lua > // printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); 1530c1539 < Protect(luaF_close(L, ra, LUA_OK)); --- > Protect(luaF_close(L, ra, LUA_OK, 1)); 1635,1638c1644,1645 < /* close upvalues from current call; the compiler ensures < that there are no to-be-closed variables here, so this < call cannot change the stack */ < luaF_close(L, base, NOCLOSINGMETH); --- > luaF_closeupval(L, base); /* close upvalues from current call */ > lua_assert(L->tbclist < base); /* no pending tbc variables */ 1668c1675 < luaF_close(L, base, LUA_OK); --- > luaF_close(L, base, CLOSEKTOP, 1); 1680c1687 < if (L->hookmask) { --- > if (l_unlikely(L->hookmask)) { 1687c1694 < int nres = ci->nresults; --- > int nres; 1690c1697 < while (nres-- > 0) --- > for (nres = ci->nresults; l_unlikely(nres > 0); nres--) 1696c1703 < if (L->hookmask) { --- > if (l_unlikely(L->hookmask)) { 1710,1711c1717,1718 < while (--nres > 0) /* complete missing results */ < setnilvalue(s2v(L->top++)); --- > for (; l_unlikely(nres > 1); nres--) > setnilvalue(s2v(L->top++)); /* complete missing results */ 1814c1821 < if (trap) { --- > if (l_unlikely(trap)) { /* previous "Protect" updated trap */ diff -Nr lua-5.4.2/src/lvm.h lua-5.4.3/src/lvm.h 63c63,64 < (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) --- > (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ > : luaV_tointeger(o,i,LUA_FLOORN2I)) 68c69,70 < (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointegerns(o,i,LUA_FLOORN2I)) --- > (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ > : luaV_tointegerns(o,i,LUA_FLOORN2I))