diff -Nr lua-5.4.1/Makefile lua-5.4.2/Makefile 49c49 < R= $V.1 --- > R= $V.2 diff -Nr lua-5.4.1/README lua-5.4.2/README 2c2 < This is Lua 5.4.1, released on 30 Sep 2020. --- > This is Lua 5.4.2, released on 13 Nov 2020. diff -Nr lua-5.4.1/doc/contents.html lua-5.4.2/doc/contents.html 201d200 < debug.setcstacklimit
479d477 < lua_setcstacklimit
668c666 < Wed Sep 30 06:45:10 -03 2020 --- > Tue Nov 10 20:58:52 UTC 2020 671c669 < Last change: revised for Lua 5.4.1 --- > Last change: revised for Lua 5.4.2 diff -Nr lua-5.4.1/doc/manual.html lua-5.4.2/doc/manual.html 2969,2970c2969,2980 < You can use the function lua_checkstack < to ensure that the stack has enough space for pushing new elements. --- > When you call any API function, > you must ensure the stack has enough room to accommodate the results. > > >

> There is one exception to the above rule: > When you call a Lua function > without a fixed number of results (see lua_call), > Lua ensures that the stack has enough space for all results. > However, it does not ensure any extra space. > So, before pushing anything on the stack after such a call > you should use lua_checkstack. 2981,2989c2991,2993 < < <

< When you call a Lua function < without a fixed number of results (see lua_call), < Lua ensures that the stack has enough space for all results, < but it does not ensure any extra space. < So, before pushing anything on the stack after such a call < you should use lua_checkstack. --- > Whenever necessary, > you can use the function lua_checkstack > to ensure that the stack has enough space for pushing new elements. 3065c3069,3070 < is valid while the value at that index is neither modified nor popped. --- > is valid while the string value at that index is not removed from the stack. > (It can be moved to another index, though.) 3285c3290 < because the longjmp removes its frame from the C stack. --- > because the longjmp removes its frame from the C stack. 3315c3320 < because its frame in the C stack was destroyed by the yield. --- > because its frame in the C stack was destroyed by the yield. 3454c3459 < (that is, one that does not depend on the stack top). --- > (that is, one that does not depend on the stack size). 4650c4655 < [-n, +0, –] --- > [-n, +0, e] 4656a4662,4666 >

> This function can run arbitrary code when removing an index > marked as to-be-closed from the stack. > > 5323c5333 < [-?, +?, –] --- > [-?, +?, e] 5333a5344,5348 >

> This function can run arbitrary code when removing an index > marked as to-be-closed from the stack. > > 5482c5497 < so that any automatic C variable declared in the calling function --- > so that any automatic C variable declared in the calling function 6270,6287d6284 <


lua_setcstacklimit

< [-0, +0, –] <

int (lua_setcstacklimit) (lua_State *L, unsigned int limit);
< <

< Sets a new limit for the C stack. < This limit controls how deeply nested calls can go in Lua, < with the intent of avoiding a stack overflow. < Returns the old limit in case of success, < or zero in case of error. < For more details about this function, < see debug.setcstacklimit, < its equivalent in the standard library. < < < < < 11284,11320d11280 <


debug.setcstacklimit (limit)

< < <

< Sets a new limit for the C stack. < This limit controls how deeply nested calls can go in Lua, < with the intent of avoiding a stack overflow. < A limit too small restricts recursive calls pointlessly; < a limit too large exposes the interpreter to stack-overflow crashes. < Unfortunately, there is no way to know a priori < the maximum safe limit for a platform. < < <

< Each call made from Lua code counts one unit. < Other operations (e.g., calls made from C to Lua or resuming a coroutine) < may have a higher cost. < < <

< This function has the following restrictions: < <

< If a call does not respect some restriction, < it returns a false value. < Otherwise, < the call returns the old limit. < < < < <

11951c11911 < Wed Sep 30 09:46:30 UTC 2020 --- > Fri Nov 13 15:35:22 UTC 2020 11954c11914 < Last change: revised for Lua 5.4.1 --- > Last change: revised for Lua 5.4.2 diff -Nr lua-5.4.1/doc/readme.html lua-5.4.2/doc/readme.html 113c113 < the top-level directory, which is named lua-5.4.1. --- > the top-level directory, which is named lua-5.4.2. 333c333 < Wed Sep 30 09:55:45 UTC 2020 --- > Tue Nov 10 20:55:28 UTC 2020 336c336 < Last change: revised for Lua 5.4.1 --- > Last change: revised for Lua 5.4.2 diff -Nr lua-5.4.1/src/Makefile lua-5.4.2/src/Makefile 29c29 < CMCFLAGS= -Os --- > CMCFLAGS= diff -Nr lua-5.4.1/src/lapi.c lua-5.4.2/src/lapi.c 1385a1386 > static const UpVal *const nullup = NULL; 1390d1390 < api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); 1392c1392,1395 < return &f->upvals[n - 1]; /* get its upvalue pointer */ --- > if (1 <= n && n <= f->p->sizeupvalues) > return &f->upvals[n - 1]; /* get its upvalue pointer */ > else > return (UpVal**)&nullup; 1404,1406c1407,1412 < api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); < return &f->upvalue[n - 1]; < } --- > if (1 <= n && n <= f->nupvalues) > return &f->upvalue[n - 1]; > /* else */ > } /* FALLTHROUGH */ > case LUA_VLCF: > return NULL; /* light C functions have no upvalues */ 1408c1414 < api_check(L, 0, "closure expected"); --- > api_check(L, 0, "function expected"); 1419a1426 > api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index"); diff -Nr lua-5.4.1/src/lauxlib.c lua-5.4.2/src/lauxlib.c 286d285 < const char *what = "exit"; /* type of termination */ 289a289 > const char *what = "exit"; /* type of termination */ 1009,1026c1009,1046 < ** Emit a warning. '*warnstate' means: < ** 0 - warning system is off; < ** 1 - ready to start a new message; < ** 2 - previous message is to be continued. < */ < static void warnf (void *ud, const char *message, int tocont) { < int *warnstate = (int *)ud; < if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */ < if (strcmp(message, "@off") == 0) < *warnstate = 0; < else if (strcmp(message, "@on") == 0) < *warnstate = 1; < return; < } < else if (*warnstate == 0) /* warnings off? */ < return; < if (*warnstate == 1) /* previous message was the last? */ < lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ --- > ** Warning functions: > ** warnfoff: warning system is off > ** warnfon: ready to start a new message > ** warnfcont: previous message is to be continued > */ > static void warnfoff (void *ud, const char *message, int tocont); > static void warnfon (void *ud, const char *message, int tocont); > static void warnfcont (void *ud, const char *message, int tocont); > > > /* > ** Check whether message is a control message. If so, execute the > ** control or ignore it if unknown. > */ > static int checkcontrol (lua_State *L, const char *message, int tocont) { > if (tocont || *(message++) != '@') /* not a control message? */ > return 0; > else { > if (strcmp(message, "off") == 0) > lua_setwarnf(L, warnfoff, L); /* turn warnings off */ > else if (strcmp(message, "on") == 0) > lua_setwarnf(L, warnfon, L); /* turn warnings on */ > return 1; /* it was a control message */ > } > } > > > static void warnfoff (void *ud, const char *message, int tocont) { > checkcontrol((lua_State *)ud, message, tocont); > } > > > /* > ** Writes the message and handle 'tocont', finishing the message > ** if needed and setting the next warn function. > */ > static void warnfcont (void *ud, const char *message, int tocont) { > lua_State *L = (lua_State *)ud; 1029c1049 < *warnstate = 2; /* to be continued */ --- > lua_setwarnf(L, warnfcont, L); /* to be continued */ 1032c1052 < *warnstate = 1; /* ready to start a new message */ --- > lua_setwarnf(L, warnfon, L); /* next call is a new message */ 1036a1057,1064 > static void warnfon (void *ud, const char *message, int tocont) { > if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */ > return; /* nothing else to be done */ > lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ > warnfcont(ud, message, tocont); /* finish processing */ > } > > 1040d1067 < int *warnstate; /* space for warning state */ 1042,1045c1069 < warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0); < luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ < *warnstate = 0; /* default is warnings off */ < lua_setwarnf(L, warnf, warnstate); --- > lua_setwarnf(L, warnfoff, L); /* default is warnings off */ diff -Nr lua-5.4.1/src/lcode.c lua-5.4.2/src/lcode.c 756c756 < ** Ensure that expression 'e' is not a variable (nor a constant). --- > ** Ensure that expression 'e' is not a variable (nor a ). 808,809c808,809 < ** Ensures expression value is in register 'reg' (and therefore < ** 'e' will become a non-relocatable expression). --- > ** Ensure expression value is in register 'reg', making 'e' a > ** non-relocatable expression. 863c863,864 < ** Ensures expression value is in any register. --- > ** Ensure expression value is in a register, making 'e' a > ** non-relocatable expression. 948a950,952 > /* else expression has jumps and cannot change its register > to hold the jump values, because it is a local variable. > Go through to the default case. */ 950c954 < luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ --- > luaK_exp2nextreg(fs, e); /* default: use next available register */ diff -Nr lua-5.4.1/src/ldblib.c lua-5.4.2/src/ldblib.c 284c284,285 < static int checkupval (lua_State *L, int argf, int argnup) { --- > static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) { > void *id; 287,289c288,293 < luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, < "invalid upvalue index"); < return nup; --- > id = lua_upvalueid(L, argf, nup); > if (pnup) { > luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index"); > *pnup = nup; > } > return id; 294,295c298,302 < int n = checkupval(L, 1, 2); < lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); --- > void *id = checkupval(L, 1, 2, NULL); > if (id != NULL) > lua_pushlightuserdata(L, id); > else > luaL_pushfail(L); 301,302c308,310 < int n1 = checkupval(L, 1, 2); < int n2 = checkupval(L, 3, 4); --- > int n1, n2; > checkupval(L, 1, 2, &n1); > checkupval(L, 3, 4, &n2); 443,446c451 < if (res == 0) < lua_pushboolean(L, 0); < else < lua_pushinteger(L, res); --- > lua_pushinteger(L, res); diff -Nr lua-5.4.1/src/ldo.c lua-5.4.2/src/ldo.c 142,143c142 < global_State *g = G(L); < l_uint32 oldnCcalls = g->Cstacklimit - (L->nCcalls + L->nci); --- > l_uint32 oldnCcalls = L->nCcalls; 152c151 < L->nCcalls = g->Cstacklimit - oldnCcalls - L->nci; --- > L->nCcalls = oldnCcalls; 186,187c185,187 < int lim = L->stacksize; < StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); --- > int lim = stacksize(L); > StkId newstack = luaM_reallocvector(L, L->stack, > lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); 189d188 < lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); 196c195 < setnilvalue(s2v(newstack + lim)); /* erase new segment */ --- > setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */ 199,200c198 < L->stacksize = newsize; < L->stack_last = L->stack + newsize - EXTRA_STACK; --- > L->stack_last = L->stack + newsize; 210,212c208,213 < int size = L->stacksize; < int newsize = 2 * size; /* tentative new size */ < if (unlikely(size > LUAI_MAXSTACK)) { /* need more space after extra size? */ --- > int size = stacksize(L); > if (unlikely(size > LUAI_MAXSTACK)) { > /* if stack is larger than maximum, thread is already using the > extra space reserved for errors, that is, thread is handling > a stack error; cannot grow further than that. */ > lua_assert(stacksize(L) == ERRORSTACKSIZE); 215c216 < else return 0; --- > return 0; /* if not 'raiseerror', just signal it */ 218c219,220 < int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; --- > int newsize = 2 * size; /* tentative new size */ > int needed = cast_int(L->top - L->stack) + n; 223c225,227 < if (unlikely(newsize > LUAI_MAXSTACK)) { /* stack overflow? */ --- > if (likely(newsize <= LUAI_MAXSTACK)) > return luaD_reallocstack(L, newsize, raiseerror); > else { /* stack overflow */ 228c232 < else return 0; --- > return 0; 230,231c234 < } /* else no errors */ < return luaD_reallocstack(L, newsize, raiseerror); --- > } 236a240 > int res; 242c246,249 < return cast_int(lim - L->stack) + 1; /* part of stack in use */ --- > res = cast_int(lim - L->stack) + 1; /* part of stack in use */ > if (res < LUA_MINSTACK) > res = LUA_MINSTACK; /* ensure a minimum size */ > return res; 245a253,261 > /* > ** If stack size is more than 3 times the current use, reduce that size > ** to twice the current use. (So, the final stack size is at most 2/3 the > ** previous size, and half of its entries are empty.) > ** As a particular case, if stack was handling a stack overflow and now > ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than > ** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack > ** will be reduced to a "regular" size. > */ 248,250c264,270 < int goodsize = inuse + BASIC_STACK_SIZE; < if (goodsize > LUAI_MAXSTACK) < goodsize = LUAI_MAXSTACK; /* respect stack limit */ --- > int nsize = inuse * 2; /* proposed new size */ > int max = inuse * 3; /* maximum "reasonable" size */ > if (max > LUAI_MAXSTACK) { > max = LUAI_MAXSTACK; /* respect stack limit */ > if (nsize > LUAI_MAXSTACK) > nsize = LUAI_MAXSTACK; > } 252,254c272,274 < good size is smaller than current size, shrink its stack */ < if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize) < luaD_reallocstack(L, goodsize, 0); /* ok if that fails */ --- > size is larger than maximum "reasonable" size, shrink it */ > if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) > luaD_reallocstack(L, nsize, 0); /* ok if that fails */ 351c371 < ** stack, below original 'func', so that 'luaD_call' can call it. Raise --- > ** stack, below original 'func', so that 'luaD_precall' can call it. Raise 452,455c472,477 < ** Call a function (C or Lua). The function to be called is at *func. < ** The arguments are on the stack, right after the function. < ** When returns, all the results are on the stack, starting at the original < ** function position. --- > ** Prepares the call to a function (C or Lua). For C functions, also do > ** the call. The function to be called is at '*func'. The arguments > ** are on the stack, right after the function. Returns the CallInfo > ** to be executed, if it was a Lua function. Otherwise (a C function) > ** returns NULL, with all the results on the stack, starting at the > ** original function position. 457c479 < void luaD_call (lua_State *L, StkId func, int nresults) { --- > CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { 485c507 < break; --- > return NULL; 497d518 < ci->callstatus = 0; 504,505c525 < luaV_execute(L, ci); /* run the function */ < break; --- > return ci; 516a537,562 > ** Call a function (C or Lua) through C. 'inc' can be 1 (increment > ** number of recursive invocations in the C stack) or nyci (the same > ** plus increment number of non-yieldable calls). > */ > static void ccall (lua_State *L, StkId func, int nResults, int inc) { > CallInfo *ci; > L->nCcalls += inc; > if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) > luaE_checkcstack(L); > if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ > ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ > luaV_execute(L, ci); /* call it */ > } > L->nCcalls -= inc; > } > > > /* > ** External interface for 'ccall' > */ > void luaD_call (lua_State *L, StkId func, int nResults) { > ccall(L, func, nResults, 1); > } > > > /* 520,526c566 < incXCcalls(L); < if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */ < luaE_exitCcall(L); /* to compensate decrement in next call */ < luaE_enterCcall(L); /* check properly */ < } < luaD_call(L, func, nResults); < decXCcalls(L); --- > ccall(L, func, nResults, nyci); 604,606d643 < luaF_close(L, oldtop, status); /* may change the stack */ < oldtop = restorestack(L, ci->u2.funcidx); < luaD_seterrorobj(L, status, oldtop); 609c646,649 < luaD_shrinkstack(L); --- > 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 */ 640,642c680,681 < if (L->status == LUA_OK) { /* starting a coroutine? */ < luaD_call(L, firstArg - 1, LUA_MULTRET); < } --- > if (L->status == LUA_OK) /* starting a coroutine? */ > ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ 645a685 > luaE_incCstack(L); /* control the C stack */ 673,678c713 < if (from == NULL) < L->nCcalls = CSTACKTHREAD; < else /* correct 'nCcalls' for this thread */ < L->nCcalls = getCcalls(from) - L->nci - CSTACKCF; < if (L->nCcalls <= CSTACKERR) < return resume_error(L, "C stack overflow", nargs); --- > L->nCcalls = (from) ? getCcalls(from) : 0; 757c792 < luaD_shrinkstack(L); --- > luaD_shrinkstack(L); /* restore stack size in case of overflow */ diff -Nr lua-5.4.1/src/ldo.h lua-5.4.2/src/ldo.h 61a62 > LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); diff -Nr lua-5.4.1/src/lfunc.c lua-5.4.2/src/lfunc.c 56c56 < luaC_objbarrier(L, cl, o); --- > luaC_objbarrier(L, cl, uv); diff -Nr lua-5.4.1/src/lgc.c lua-5.4.2/src/lgc.c 164,170c164,169 < ** Clear keys for empty entries in tables. If entry is empty < ** and its key is not marked, mark its entry as dead. This allows the < ** collection of the key, but keeps its entry in the table (its removal < ** could break a chain). The main feature of a dead key is that it must < ** be different from any other value, to do not disturb searches. < ** Other places never manipulate dead keys, because its associated empty < ** value is enough to signal that the entry is logically empty. --- > ** Clear keys for empty entries in tables. If entry is empty, mark its > ** entry as dead. This allows the collection of the key, but keeps its > ** entry in the table: its removal could break a chain and could break > ** a table traversal. Other places never manipulate dead keys, because > ** its associated empty value is enough to signal that the entry is > ** logically empty. 174,175c173,174 < if (keyiswhite(n)) < setdeadkey(n); /* unused and unmarked key; remove it */ --- > if (keyiscollectable(n)) > setdeadkey(n); /* unused key; remove it */ 304c303 < set2black(o); /* closed upvalues are visited here */ --- > set2black(uv); /* closed upvalues are visited here */ 312c311 < set2black(o); /* nothing else to mark */ --- > set2black(u); /* nothing else to mark */ 636,638c635,636 < StkId lim = th->stack + th->stacksize; /* real end of stack */ < for (; o < lim; o++) /* clear not-marked stack slice */ < setnilvalue(s2v(o)); --- > for (; o < th->stack_last + EXTRA_STACK; o++) > setnilvalue(s2v(o)); /* clear dead stack slice */ 647c645 < return 1 + th->stacksize; --- > return 1 + stacksize(th); 774,775c772,774 < case LUA_VLCL: < luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); --- > case LUA_VLCL: { > LClosure *cl = gco2lcl(o); > luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); 777,778c776,779 < case LUA_VCCL: < luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); --- > } > case LUA_VCCL: { > CClosure *cl = gco2ccl(o); > luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); 779a781 > } 791,793c793,796 < case LUA_VSHRSTR: < luaS_remove(L, gco2ts(o)); /* remove it from hash table */ < luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); --- > case LUA_VSHRSTR: { > TString *ts = gco2ts(o); > luaS_remove(L, ts); /* remove it from hash table */ > luaM_freemem(L, ts, sizelstring(ts->shrlen)); 795,796c798,801 < case LUA_VLNGSTR: < luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); --- > } > case LUA_VLNGSTR: { > TString *ts = gco2ts(o); > luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); 797a803 > } diff -Nr lua-5.4.1/src/llex.c lua-5.4.2/src/llex.c 257,259c257,260 < ** reads a sequence '[=*[' or ']=*]', leaving the last bracket. < ** If sequence is well formed, return its number of '='s + 2; otherwise, < ** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). --- > ** read a sequence '[=*[' or ']=*]', leaving the last bracket. If > ** sequence is well formed, return its number of '='s + 2; otherwise, > ** return 1 if it is a single bracket (no '='s and no 2nd bracket); > ** otherwise (an unfinished '[==...') return 0. 484c485 < if (check_next1(ls, '=')) return TK_EQ; --- > if (check_next1(ls, '=')) return TK_EQ; /* '==' */ 489,490c490,491 < if (check_next1(ls, '=')) return TK_LE; < else if (check_next1(ls, '<')) return TK_SHL; --- > if (check_next1(ls, '=')) return TK_LE; /* '<=' */ > else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */ 495,496c496,497 < if (check_next1(ls, '=')) return TK_GE; < else if (check_next1(ls, '>')) return TK_SHR; --- > if (check_next1(ls, '=')) return TK_GE; /* '>=' */ > else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */ 501c502 < if (check_next1(ls, '/')) return TK_IDIV; --- > if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ 506c507 < if (check_next1(ls, '=')) return TK_NE; --- > if (check_next1(ls, '=')) return TK_NE; /* '~=' */ 511c512 < if (check_next1(ls, ':')) return TK_DBCOLON; --- > if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */ 550c551 < else { /* single-char tokens (+ - / ...) */ --- > else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */ diff -Nr lua-5.4.1/src/llimits.h lua-5.4.2/src/llimits.h 237a238,248 > ** Maximum depth for nested C calls, syntactical nested non-terminals, > ** and other features implemented through recursion in C. (Value must > ** fit in a 16-bit unsigned integer. It must also be compatible with > ** the size of the C stack.) > */ > #if !defined(LUAI_MAXCCALLS) > #define LUAI_MAXCCALLS 200 > #endif > > > /* 318c329,330 < #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) --- > #define luai_numpow(L,a,b) \ > ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b)) 347c359 < { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_, 0); pos; } --- > { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } diff -Nr lua-5.4.1/src/lobject.c lua-5.4.2/src/lobject.c 261c261 < if (strlen(s) > L_MAXLENNUM || pdot == NULL) --- > if (pdot == NULL || strlen(s) > L_MAXLENNUM) diff -Nr lua-5.4.1/src/lobject.h lua-5.4.2/src/lobject.h 23a24,25 > #define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */ > 27c29 < ** number of all possible types (including LUA_TNONE) --- > ** number of all possible types (including LUA_TNONE but excluding DEADKEY) 558c560 < ** Closures --- > ** Functions 746,750c748,751 < ** Use a "nil table" to mark dead keys in a table. Those keys serve < ** to keep space for removed entries, which may still be part of < ** chains. Note that the 'keytt' does not have the BIT_ISCOLLECTABLE < ** set, so these values are considered not collectable and are different < ** from any valid value. --- > ** Dead keys in tables have the tag DEADKEY but keep their original > ** gcvalue. This distinguishes them from regular keys but allows them to > ** be found when searched in a special way. ('next' needs that to find > ** keys removed from a table during a traversal.) 752c753,754 < #define setdeadkey(n) (keytt(n) = LUA_TTABLE, gckey(n) = NULL) --- > #define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) > #define keyisdead(node) (keytt(node) == LUA_TDEADKEY) diff -Nr lua-5.4.1/src/lopcodes.h lua-5.4.2/src/lopcodes.h 264c264 < OP_LEN,/* A B R[A] := length of R[B] */ --- > OP_LEN,/* A B R[A] := #R[B] (length operator) */ 300c300 < OP_SETLIST,/* A B C k R[A][(C-1)*FPF+i] := R[A+i], 1 <= i <= B */ --- > OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ diff -Nr lua-5.4.1/src/lparser.c lua-5.4.2/src/lparser.c 492,495c492 < /* < ** Macros to limit the maximum recursion depth while parsing < */ < #define enterlevel(ls) luaE_enterCcall((ls)->L) --- > #define enterlevel(ls) luaE_incCstack(ls->L) 497c494,495 < #define leavelevel(ls) luaE_exitCcall((ls)->L) --- > > #define leavelevel(ls) ((ls)->L->nCcalls--) 950c948 < /* parlist -> [ param { ',' param } ] */ --- > /* parlist -> [ {NAME ','} (NAME | '...') ] */ 958c956 < case TK_NAME: { /* param -> NAME */ --- > case TK_NAME: { 963c961 < case TK_DOTS: { /* param -> '...' */ --- > case TK_DOTS: { 1628,1660d1625 < /* < ** Check whether next instruction is a single jump (a 'break', a 'goto' < ** to a forward label, or a 'goto' to a backward label with no variable < ** to close). If so, set the name of the 'label' it is jumping to < ** ("break" for a 'break') or to where it is jumping to ('target') and < ** return true. If not a single jump, leave input unchanged, to be < ** handled as a regular statement. < */ < static int issinglejump (LexState *ls, TString **label, int *target) { < if (testnext(ls, TK_BREAK)) { /* a break? */ < *label = luaS_newliteral(ls->L, "break"); < return 1; < } < else if (ls->t.token != TK_GOTO || luaX_lookahead(ls) != TK_NAME) < return 0; /* not a valid goto */ < else { < TString *lname = ls->lookahead.seminfo.ts; /* label's id */ < Labeldesc *lb = findlabel(ls, lname); < if (lb) { /* a backward jump? */ < /* does it need to close variables? */ < if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar)) < return 0; /* not a single jump; cannot optimize */ < *target = lb->pc; < } < else /* jump forward */ < *label = lname; < luaX_next(ls); /* skip goto */ < luaX_next(ls); /* skip name */ < return 1; < } < } < < 1664d1628 < int line; 1666,1667d1629 < TString *jlb = NULL; < int target = NO_JUMP; 1673,1675c1635,1638 < line = ls->linenumber; < if (issinglejump(ls, &jlb, &target)) { /* 'if x then goto' ? */ < luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ --- > if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */ > int line = ls->linenumber; > luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */ > luaX_next(ls); /* skip 'break' */ 1677,1680c1640 < if (jlb != NULL) /* forward jump? */ < newgotoentry(ls, jlb, line, v.t); /* will be resolved later */ < else /* backward jump */ < luaK_patchlist(fs, v.t, target); /* jump directly to 'target' */ --- > newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t); 1689c1649 < else { /* regular case (not a jump) */ --- > else { /* regular case (not a break) */ 1757c1717 < /* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ --- > /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ diff -Nr lua-5.4.1/src/lparser.h lua-5.4.2/src/lparser.h 26c26 < VVOID, /* when 'expdesc' describes the last expression a list, --- > VVOID, /* when 'expdesc' describes the last expression of a list, 41c41,42 < VCONST, /* compile-time constant; info = absolute index in 'actvar.arr' */ --- > VCONST, /* compile-time variable; > info = absolute index in 'actvar.arr' */ diff -Nr lua-5.4.1/src/lstate.c lua-5.4.2/src/lstate.c 79c79 < return luaS_hash(buff, p, h, 1); --- > return luaS_hash(buff, p, h); 100,152c100,101 < global_State *g = G(L); < int ccalls; < luaE_freeCI(L); /* release unused CIs */ < ccalls = getCcalls(L); < if (limit >= 40000) < return 0; /* out of bounds */ < limit += CSTACKERR; < if (L != g-> mainthread) < return 0; /* only main thread can change the C stack */ < else if (ccalls <= CSTACKERR) < return 0; /* handling overflow */ < else { < int diff = limit - g->Cstacklimit; < if (ccalls + diff <= CSTACKERR) < return 0; /* new limit would cause an overflow */ < g->Cstacklimit = limit; /* set new limit */ < L->nCcalls += diff; /* correct 'nCcalls' */ < return limit - diff - CSTACKERR; /* success; return previous limit */ < } < } < < < /* < ** Decrement count of "C calls" and check for overflows. In case of < ** a stack overflow, check appropriate error ("regular" overflow or < ** overflow while handling stack overflow). If 'nCcalls' is smaller < ** than CSTACKERR but larger than CSTACKMARK, it means it has just < ** entered the "overflow zone", so the function raises an overflow < ** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is < ** already handling an overflow) but larger than CSTACKERRMARK, does < ** not report an error (to allow message handling to work). Otherwise, < ** report a stack overflow while handling a stack overflow (probably < ** caused by a repeating error in the message handling function). < */ < < void luaE_enterCcall (lua_State *L) { < int ncalls = getCcalls(L); < L->nCcalls--; < if (ncalls <= CSTACKERR) { /* possible overflow? */ < luaE_freeCI(L); /* release unused CIs */ < ncalls = getCcalls(L); /* update call count */ < if (ncalls <= CSTACKERR) { /* still overflow? */ < if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */ < luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ < else if (ncalls >= CSTACKMARK) { < /* not in error-handling zone; raise the error now */ < L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */ < luaG_runerror(L, "C stack overflow"); < } < /* else stack is in the error-handling zone; < allow message handler to work */ < } < } --- > UNUSED(L); UNUSED(limit); > return LUAI_MAXCCALLS; /* warning?? */ 159d107 < luaE_enterCcall(L); 178d125 < L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ 184d130 < L->nCcalls -= L->nci; /* adjust result */ 197d142 < L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ 210c155,176 < L->nCcalls -= L->nci; /* adjust result */ --- > } > > > /* > ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. > ** If equal, raises an overflow error. If value is larger than > ** LUAI_MAXCCALLS (which means it is handling an overflow) but > ** not much larger, does not report an error (to allow overflow > ** handling to work). > */ > void luaE_checkcstack (lua_State *L) { > if (getCcalls(L) == LUAI_MAXCCALLS) > luaG_runerror(L, "C stack overflow"); > else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) > luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ > } > > > LUAI_FUNC void luaE_incCstack (lua_State *L) { > L->nCcalls++; > if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) > luaE_checkcstack(L); 217,219c183,184 < L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); < L1->stacksize = BASIC_STACK_SIZE; < for (i = 0; i < BASIC_STACK_SIZE; i++) --- > L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); > for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) 222c187 < L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; --- > L1->stack_last = L1->stack + BASIC_STACK_SIZE; 243c208 < luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ --- > luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */ 293d257 < L->stacksize = 0; 338c302 < L1->nCcalls = getCcalls(L); --- > L1->nCcalls = 0; 399c363 < g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; --- > L->nCcalls = 0; diff -Nr lua-5.4.1/src/lstate.h lua-5.4.2/src/lstate.h 90,108c90,94 < ** About 'nCcalls': each thread in Lua (a lua_State) keeps a count of < ** how many "C calls" it still can do in the C stack, to avoid C-stack < ** overflow. This count is very rough approximation; it considers only < ** recursive functions inside the interpreter, as non-recursive calls < ** can be considered using a fixed (although unknown) amount of stack < ** space. < ** < ** The count has two parts: the lower part is the count itself; the < ** higher part counts the number of non-yieldable calls in the stack. < ** (They are together so that we can change both with one instruction.) < ** < ** Because calls to external C functions can use an unknown amount < ** of space (e.g., functions using an auxiliary buffer), calls < ** to these functions add more than one to the count (see CSTACKCF). < ** < ** The proper count excludes the number of CallInfo structures allocated < ** by Lua, as a kind of "potential" calls. So, when Lua calls a function < ** (and "consumes" one CallInfo), it needs neither to decrement nor to < ** check 'nCcalls', as its use of C stack is already accounted for. --- > ** About 'nCcalls': This count has two parts: the lower 16 bits counts > ** the number of recursive invocations in the C stack; the higher > ** 16 bits counts the number of non-yieldable calls in the stack. > ** (They are together so that we can change and save both with one > ** instruction.) 111,132d96 < /* number of "C stack slots" used by an external C function */ < #define CSTACKCF 10 < < < /* < ** The C-stack size is sliced in the following zones: < ** - larger than CSTACKERR: normal stack; < ** - [CSTACKMARK, CSTACKERR]: buffer zone to signal a stack overflow; < ** - [CSTACKCF, CSTACKERRMARK]: error-handling zone; < ** - below CSTACKERRMARK: buffer zone to signal overflow during overflow; < ** (Because the counter can be decremented CSTACKCF at once, we need < ** the so called "buffer zones", with at least that size, to properly < ** detect a change from one zone to the next.) < */ < #define CSTACKERR (8 * CSTACKCF) < #define CSTACKMARK (CSTACKERR - (CSTACKCF + 2)) < #define CSTACKERRMARK (CSTACKCF + 2) < < < /* initial limit for the C-stack of threads */ < #define CSTACKTHREAD (2 * CSTACKERR) < 147,153c111,112 < /* Increment the number of non-yieldable calls and decrement nCcalls */ < #define incXCcalls(L) ((L)->nCcalls += 0x10000 - CSTACKCF) < < /* Decrement the number of non-yieldable calls and increment nCcalls */ < #define decXCcalls(L) ((L)->nCcalls -= 0x10000 - CSTACKCF) < < --- > /* Non-yieldable call increment */ > #define nyci (0x10000 | 1) 171c130,136 < /* extra stack space to handle TM calls and some other extras */ --- > /* > ** Extra stack space to handle TM calls and some other extras. This > ** space is not included in 'stack_last'. It is used only to avoid stack > ** checks, either because the element will be promptly popped or because > ** there will be a stack check soon after the push. Function frames > ** never use this extra space, so it does not need to be kept clean. > */ 176a142,143 > #define stacksize(th) cast_int((th)->stack_last - (th)->stack) > 227,232c194,200 < #define CIST_HOOKED (1<<2) /* call is running a debug hook */ < #define CIST_YPCALL (1<<3) /* call is a yieldable protected call */ < #define CIST_TAIL (1<<4) /* call was tail called */ < #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ < #define CIST_FIN (1<<6) /* call is running a finalizer */ < #define CIST_TRAN (1<<7) /* 'ci' has transfer information */ --- > #define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ > #define CIST_HOOKED (1<<3) /* call is running a debug hook */ > #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ > #define CIST_TAIL (1<<5) /* call was tail called */ > #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ > #define CIST_FIN (1<<7) /* call is running a finalizer */ > #define CIST_TRAN (1<<8) /* 'ci' has transfer information */ 234c202 < #define CIST_LEQ (1<<8) /* using __lt for __le */ --- > #define CIST_LEQ (1<<9) /* using __lt for __le */ 299d266 < unsigned int Cstacklimit; /* current limit for the C stack */ 314c281 < StkId stack_last; /* last free slot in the stack */ --- > StkId stack_last; /* end of stack (last element + 1) */ 323c290 < l_uint32 nCcalls; /* number of allowed nested C calls - 'nci' */ --- > l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ 325d291 < int stacksize; 392c358,359 < LUAI_FUNC void luaE_enterCcall (lua_State *L); --- > LUAI_FUNC void luaE_checkcstack (lua_State *L); > LUAI_FUNC void luaE_incCstack (lua_State *L); 397,398d363 < #define luaE_exitCcall(L) ((L)->nCcalls++) < diff -Nr lua-5.4.1/src/lstring.c lua-5.4.2/src/lstring.c 26,35d25 < ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a long string to < ** compute its hash < */ < #if !defined(LUAI_HASHLIMIT) < #define LUAI_HASHLIMIT 5 < #endif < < < < /* 53,54c43 < unsigned int luaS_hash (const char *str, size_t l, unsigned int seed, < size_t step) { --- > unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 56c45 < for (; l >= step; l -= step) --- > for (; l > 0; l--) 66,67c55 < size_t step = (len >> LUAI_HASHLIMIT) + 1; < ts->hash = luaS_hash(getstr(ts), len, ts->hash, step); --- > ts->hash = luaS_hash(getstr(ts), len, ts->hash); 204c192 < unsigned int h = luaS_hash(str, l, g->seed, 1); --- > unsigned int h = luaS_hash(str, l, g->seed); diff -Nr lua-5.4.1/src/lstring.h lua-5.4.2/src/lstring.h 44,45c44 < LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, < unsigned int seed, size_t step); --- > LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); diff -Nr lua-5.4.1/src/lstrlib.c lua-5.4.2/src/lstrlib.c 1368d1367 < char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ 1538c1537 < static void copywithendian (volatile char *dest, volatile const char *src, --- > static void copywithendian (char *dest, const char *src, 1540,1543c1539,1540 < if (islittle == nativeendian.little) { < while (size-- != 0) < *(dest++) = *(src++); < } --- > if (islittle == nativeendian.little) > memcpy(dest, src, size); 1587c1584 < volatile Ftypes u; --- > Ftypes u; 1594c1591 < copywithendian(buff, u.buff, size, h.islittle); --- > copywithendian(buff, (char *)&u, size, h.islittle); 1720c1717 < volatile Ftypes u; --- > Ftypes u; 1722c1719 < copywithendian(u.buff, data + pos, size, h.islittle); --- > copywithendian((char *)&u, data + pos, size, h.islittle); 1741c1738 < size_t len = (int)strlen(data + pos); --- > size_t len = strlen(data + pos); diff -Nr lua-5.4.1/src/ltable.c lua-5.4.2/src/ltable.c 169,177c169,190 < ** Check whether key 'k1' is equal to the key in node 'n2'. < ** This equality is raw, so there are no metamethods. Floats < ** with integer values have been normalized, so integers cannot < ** be equal to floats. It is assumed that 'eqshrstr' is simply < ** pointer equality, so that short strings are handled in the < ** default case. < */ < static int equalkey (const TValue *k1, const Node *n2) { < if (rawtt(k1) != keytt(n2)) /* not the same variants? */ --- > ** Check whether key 'k1' is equal to the key in node 'n2'. This > ** equality is raw, so there are no metamethods. Floats with integer > ** values have been normalized, so integers cannot be equal to > ** floats. It is assumed that 'eqshrstr' is simply pointer equality, so > ** that short strings are handled in the default case. > ** A true 'deadok' means to accept dead keys as equal to their original > ** values. All dead keys are compared in the default case, by pointer > ** identity. (Only collectable objects can produce dead keys.) Note that > ** dead long strings are also compared by identity. > ** Once a key is dead, its corresponding value may be collected, and > ** then another value can be created with the same address. If this > ** other value is given to 'next', 'equalkey' will signal a false > ** positive. In a regular traversal, this situation should never happen, > ** as all keys given to 'next' came from the table itself, and therefore > ** could not have been collected. Outside a regular traversal, we > ** have garbage in, garbage out. What is relevant is that this false > ** positive does not break anything. (In particular, 'next' will return > ** some other valid item on the table or nil.) > */ > static int equalkey (const TValue *k1, const Node *n2, int deadok) { > if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ > !(deadok && keyisdead(n2) && iscollectable(k1))) 179c192 < switch (ttypetag(k1)) { --- > switch (keytt(n2)) { 190c203 < case LUA_VLNGSTR: --- > case ctb(LUA_VLNGSTR): 253a267 > ** See explanation about 'deadok' in function 'equalkey'. 255c269 < static const TValue *getgeneric (Table *t, const TValue *key) { --- > static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { 258c272 < if (equalkey(key, n)) --- > if (equalkey(key, n, deadok)) 295c309 < const TValue *n = getgeneric(t, key); --- > const TValue *n = getgeneric(t, key, 1); 733c747 < return getgeneric(t, &ko); --- > return getgeneric(t, &ko, 0); 753c767 < return getgeneric(t, key); --- > return getgeneric(t, key, 0); diff -Nr lua-5.4.1/src/lua.c lua-5.4.2/src/lua.c 419c419,421 < ** Returns the string to be used as a prompt by the interpreter. --- > ** Return the string to be used as a prompt by the interpreter. Leave > ** the string (or nil, if using the default value) on the stack, to keep > ** it anchored. 422,426c424,430 < const char *p; < lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); < p = lua_tostring(L, -1); < if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); < return p; --- > if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL) > return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */ > else { /* apply 'tostring' over the value */ > const char *p = luaL_tolstring(L, -1, NULL); > lua_remove(L, -2); /* remove original value */ > return p; > } diff -Nr lua-5.4.1/src/lua.h lua-5.4.2/src/lua.h 21c21 < #define LUA_VERSION_RELEASE "1" --- > #define LUA_VERSION_RELEASE "2" diff -Nr lua-5.4.1/src/luaconf.h lua-5.4.2/src/luaconf.h 40,54d39 < @@ LUAI_MAXCSTACK defines the maximum depth for nested calls and < ** also limits the maximum depth of other recursive algorithms in < ** the implementation, such as syntactic analysis. A value too < ** large may allow the interpreter to crash (C-stack overflow). < ** The default value seems ok for regular machines, but may be < ** too high for restricted hardware. < ** The test file 'cstack.lua' may help finding a good limit. < ** (It will crash with a limit too high.) < */ < #if !defined(LUAI_MAXCSTACK) < #define LUAI_MAXCSTACK 2000 < #endif < < < /* diff -Nr lua-5.4.1/src/lvm.c lua-5.4.2/src/lvm.c 232c232 < needed anymore */ --- > needed anymore) */ 1095,1097c1095,1096 < ** Protect code that will finish the loop (returns) or can only raise < ** errors. (That is, it will not return to the interpreter main loop < ** after changing the stack or hooks.) --- > ** Protect code that can only raise errors. (That is, it cannnot change > ** the stack or hooks.) 1101,1103d1099 < /* idem, but without changing the stack */ < #define halfProtectNT(exp) (savepc(L), (exp)) < 1135c1131 < tailcall: --- > startfunc: 1136a1133 > returning: /* trap already set */ 1141,1145c1138,1144 < if (cl->p->is_vararg) < trap = 0; /* hooks will start after VARARGPREP instruction */ < else if (pc == cl->p->code) /* first instruction (not resuming)? */ < luaD_hookcall(L, ci); < ci->u.l.trap = 1; /* there may be other hooks */ --- > if (pc == cl->p->code) { /* first instruction (not resuming)? */ > if (cl->p->is_vararg) > trap = 0; /* hooks will start after VARARGPREP instruction */ > else /* check 'call' hook */ > luaD_hookcall(L, ci); > } > ci->u.l.trap = 1; /* assume trap is on, for now */ 1154c1153 < lua_assert(base <= L->top && L->top < L->stack + L->stacksize); --- > lua_assert(base <= L->top && L->top < L->stack_last); 1608a1608 > CallInfo *newci; 1614c1614,1621 < ProtectNT(luaD_call(L, ra, nresults)); --- > savepc(L); /* in case of errors */ > if ((newci = luaD_precall(L, ra, nresults)) == NULL) > updatetrap(ci); /* C call; nothing else to be done */ > else { /* Lua call: run function in this same C frame */ > ci = newci; > ci->callstatus = 0; /* call re-uses 'luaV_execute' */ > goto startfunc; > } 1620c1627 < /* delat is virtual 'func' - real 'func' (vararg functions) */ --- > /* delta is virtual 'func' - real 'func' (vararg functions) */ 1626c1633 < savepc(ci); /* some calls here can raise errors */ --- > savepc(ci); /* several calls here can raise errors */ 1640c1647 < luaD_call(L, ra, LUA_MULTRET); /* call it */ --- > luaD_precall(L, ra, LUA_MULTRET); /* call it */ 1643,1645c1650,1653 < ci->func -= delta; < luaD_poscall(L, ci, cast_int(L->top - ra)); < return; --- > ci->func -= delta; /* restore 'func' (if vararg) */ > luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ > updatetrap(ci); /* 'luaD_poscall' can change hooks */ > goto ret; /* caller returns after the tail call */ 1647c1655 < ci->func -= delta; --- > ci->func -= delta; /* restore 'func' (if vararg) */ 1649c1657 < goto tailcall; --- > goto startfunc; /* execute the callee */ 1668c1676,1677 < return; --- > updatetrap(ci); /* 'luaD_poscall' can change hooks */ > goto ret; 1673c1682,1684 < halfProtectNT(luaD_poscall(L, ci, 0)); /* no hurry... */ --- > savepc(ci); > luaD_poscall(L, ci, 0); /* no hurry... */ > trap = 1; 1682c1693 < return; --- > goto ret; 1687c1698,1700 < halfProtectNT(luaD_poscall(L, ci, 1)); /* no hurry... */ --- > savepc(ci); > luaD_poscall(L, ci, 1); /* no hurry... */ > trap = 1; 1701c1714,1720 < return; --- > ret: /* return from a Lua function */ > if (ci->callstatus & CIST_FRESH) > return; /* end this frame */ > else { > ci = ci->previous; > goto returning; /* continue running caller in this frame */ > }