update lua 5.4.2

This commit is contained in:
Cloud Wu
2020-11-04 10:18:33 +08:00
parent 84e600bed3
commit 3f8a2f69df
9 changed files with 90 additions and 68 deletions

View File

@@ -753,7 +753,7 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
/* /*
** Ensure that expression 'e' is not a variable (nor a constant). ** Ensure that expression 'e' is not a variable (nor a <const>).
** (Expression still may have jump lists.) ** (Expression still may have jump lists.)
*/ */
void luaK_dischargevars (FuncState *fs, expdesc *e) { void luaK_dischargevars (FuncState *fs, expdesc *e) {
@@ -805,8 +805,8 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
/* /*
** Ensures expression value is in register 'reg' (and therefore ** Ensure expression value is in register 'reg', making 'e' a
** 'e' will become a non-relocatable expression). ** non-relocatable expression.
** (Expression still may have jump lists.) ** (Expression still may have jump lists.)
*/ */
static void discharge2reg (FuncState *fs, expdesc *e, int reg) { static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
@@ -860,7 +860,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
/* /*
** Ensures expression value is in any register. ** Ensure expression value is in a register, making 'e' a
** non-relocatable expression.
** (Expression still may have jump lists.) ** (Expression still may have jump lists.)
*/ */
static void discharge2anyreg (FuncState *fs, expdesc *e) { static void discharge2anyreg (FuncState *fs, expdesc *e) {
@@ -946,8 +947,11 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
exp2reg(fs, e, e->u.info); /* put final result in it */ exp2reg(fs, e, e->u.info); /* put final result in it */
return e->u.info; return e->u.info;
} }
/* 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. */
} }
luaK_exp2nextreg(fs, e); /* otherwise, use next available register */ luaK_exp2nextreg(fs, e); /* default: use next available register */
return e->u.info; return e->u.info;
} }

View File

@@ -534,11 +534,11 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
/* /*
** Call a function (C or Lua). 'inc' can be 1 (increment number ** Call a function (C or Lua) through C. 'inc' can be 1 (increment
** of recursive invocations in the C stack) or nyci (the same plus ** number of recursive invocations in the C stack) or nyci (the same
** increment number of non-yieldable calls). ** plus increment number of non-yieldable calls).
*/ */
static void docall (lua_State *L, StkId func, int nResults, int inc) { static void ccall (lua_State *L, StkId func, int nResults, int inc) {
CallInfo *ci; CallInfo *ci;
L->nCcalls += inc; L->nCcalls += inc;
if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
@@ -552,10 +552,10 @@ static void docall (lua_State *L, StkId func, int nResults, int inc) {
/* /*
** External interface for 'docall' ** External interface for 'ccall'
*/ */
void luaD_call (lua_State *L, StkId func, int nResults) { void luaD_call (lua_State *L, StkId func, int nResults) {
return docall(L, func, nResults, 1); ccall(L, func, nResults, 1);
} }
@@ -563,7 +563,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
** Similar to 'luaD_call', but does not allow yields during the call. ** Similar to 'luaD_call', but does not allow yields during the call.
*/ */
void luaD_callnoyield (lua_State *L, StkId func, int nResults) { void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
return docall(L, func, nResults, nyci); ccall(L, func, nResults, nyci);
} }
@@ -678,7 +678,7 @@ static void resume (lua_State *L, void *ud) {
StkId firstArg = L->top - n; /* first argument */ StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
if (L->status == LUA_OK) /* starting a coroutine? */ if (L->status == LUA_OK) /* starting a coroutine? */
docall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
else { /* resuming from previous yield */ else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD); lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */ L->status = LUA_OK; /* mark that it is running (again) */

View File

@@ -254,9 +254,10 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
/* /*
** reads a sequence '[=*[' or ']=*]', leaving the last bracket. ** read a sequence '[=*[' or ']=*]', leaving the last bracket. If
** If sequence is well formed, return its number of '='s + 2; otherwise, ** sequence is well formed, return its number of '='s + 2; otherwise,
** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). ** return 1 if it is a single bracket (no '='s and no 2nd bracket);
** otherwise (an unfinished '[==...') return 0.
*/ */
static size_t skip_sep (LexState *ls) { static size_t skip_sep (LexState *ls) {
size_t count = 0; size_t count = 0;
@@ -481,34 +482,34 @@ static int llex (LexState *ls, SemInfo *seminfo) {
} }
case '=': { case '=': {
next(ls); next(ls);
if (check_next1(ls, '=')) return TK_EQ; if (check_next1(ls, '=')) return TK_EQ; /* '==' */
else return '='; else return '=';
} }
case '<': { case '<': {
next(ls); next(ls);
if (check_next1(ls, '=')) return TK_LE; if (check_next1(ls, '=')) return TK_LE; /* '<=' */
else if (check_next1(ls, '<')) return TK_SHL; else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */
else return '<'; else return '<';
} }
case '>': { case '>': {
next(ls); next(ls);
if (check_next1(ls, '=')) return TK_GE; if (check_next1(ls, '=')) return TK_GE; /* '>=' */
else if (check_next1(ls, '>')) return TK_SHR; else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */
else return '>'; else return '>';
} }
case '/': { case '/': {
next(ls); next(ls);
if (check_next1(ls, '/')) return TK_IDIV; if (check_next1(ls, '/')) return TK_IDIV; /* '//' */
else return '/'; else return '/';
} }
case '~': { case '~': {
next(ls); next(ls);
if (check_next1(ls, '=')) return TK_NE; if (check_next1(ls, '=')) return TK_NE; /* '~=' */
else return '~'; else return '~';
} }
case ':': { case ':': {
next(ls); next(ls);
if (check_next1(ls, ':')) return TK_DBCOLON; if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */
else return ':'; else return ':';
} }
case '"': case '\'': { /* short literal strings */ case '"': case '\'': { /* short literal strings */
@@ -547,7 +548,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_NAME; return TK_NAME;
} }
} }
else { /* single-char tokens (+ - / ...) */ else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
int c = ls->current; int c = ls->current;
next(ls); next(ls);
return c; return c;

View File

@@ -355,7 +355,7 @@ typedef l_uint32 Instruction;
#else #else
/* realloc stack keeping its size */ /* realloc stack keeping its size */
#define condmovestack(L,pre,pos) \ #define condmovestack(L,pre,pos) \
{ int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_, 0); pos; } { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; }
#endif #endif
#if !defined(HARDMEMTESTS) #if !defined(HARDMEMTESTS)

View File

@@ -945,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) {
static void parlist (LexState *ls) { static void parlist (LexState *ls) {
/* parlist -> [ param { ',' param } ] */ /* parlist -> [ {NAME ','} (NAME | '...') ] */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
Proto *f = fs->f; Proto *f = fs->f;
int nparams = 0; int nparams = 0;
@@ -953,12 +953,12 @@ static void parlist (LexState *ls) {
if (ls->t.token != ')') { /* is 'parlist' not empty? */ if (ls->t.token != ')') { /* is 'parlist' not empty? */
do { do {
switch (ls->t.token) { switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */ case TK_NAME: {
new_localvar(ls, str_checkname(ls)); new_localvar(ls, str_checkname(ls));
nparams++; nparams++;
break; break;
} }
case TK_DOTS: { /* param -> '...' */ case TK_DOTS: {
luaX_next(ls); luaX_next(ls);
isvararg = 1; isvararg = 1;
break; break;
@@ -1752,7 +1752,7 @@ static void checktoclose (LexState *ls, int level) {
static void localstat (LexState *ls) { static void localstat (LexState *ls) {
/* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
int toclose = -1; /* index of to-be-closed variable (if any) */ int toclose = -1; /* index of to-be-closed variable (if any) */
Vardesc *var; /* last variable */ Vardesc *var; /* last variable */

View File

@@ -23,7 +23,7 @@
/* kinds of variables/expressions */ /* kinds of variables/expressions */
typedef enum { typedef enum {
VVOID, /* when 'expdesc' describes the last expression a list, VVOID, /* when 'expdesc' describes the last expression of a list,
this kind means an empty list (so, no expression) */ this kind means an empty list (so, no expression) */
VNIL, /* constant nil */ VNIL, /* constant nil */
VTRUE, /* constant true */ VTRUE, /* constant true */
@@ -38,7 +38,8 @@ typedef enum {
VLOCAL, /* local variable; var.sidx = stack index (local register); VLOCAL, /* local variable; var.sidx = stack index (local register);
var.vidx = relative index in 'actvar.arr' */ var.vidx = relative index in 'actvar.arr' */
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
VCONST, /* compile-time constant; info = absolute index in 'actvar.arr' */ VCONST, /* compile-time <const> variable;
info = absolute index in 'actvar.arr' */
VINDEXED, /* indexed variable; VINDEXED, /* indexed variable;
ind.t = table register; ind.t = table register;
ind.idx = key's R index */ ind.idx = key's R index */

View File

@@ -166,17 +166,24 @@ static Node *mainpositionTV (const Table *t, const TValue *key) {
/* /*
** Check whether key 'k1' is equal to the key in node 'n2'. ** Check whether key 'k1' is equal to the key in node 'n2'. This
** This equality is raw, so there are no metamethods. Floats ** equality is raw, so there are no metamethods. Floats with integer
** with integer values have been normalized, so integers cannot ** values have been normalized, so integers cannot be equal to
** be equal to floats. It is assumed that 'eqshrstr' is simply ** floats. It is assumed that 'eqshrstr' is simply pointer equality, so
** pointer equality, so that short strings are handled in the ** that short strings are handled in the default case.
** default case.
** A true 'deadok' means to accept dead keys as equal to their original ** A true 'deadok' means to accept dead keys as equal to their original
** values, which can only happen if the original key was collectable. ** values. All dead keys are compared in the default case, by pointer
** All dead values are compared in the default case, by pointer ** identity. (Only collectable objects can produce dead keys.) Note that
** identity. (Note that dead long strings are also compared by ** dead long strings are also compared by identity.
** 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) { static int equalkey (const TValue *k1, const Node *n2, int deadok) {
if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */

View File

@@ -416,15 +416,19 @@ static int handle_luainit (lua_State *L) {
/* /*
** 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.
*/ */
static const char *get_prompt (lua_State *L, int firstline) { static const char *get_prompt (lua_State *L, int firstline) {
const char *p; if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL)
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */
p = lua_tostring(L, -1); else { /* apply 'tostring' over the value */
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); const char *p = luaL_tolstring(L, -1, NULL);
lua_remove(L, -2); /* remove original value */
return p; return p;
} }
}
/* mark in error messages for incomplete statements */ /* mark in error messages for incomplete statements */
#define EOFMARK "<eof>" #define EOFMARK "<eof>"

View File

@@ -1094,15 +1094,11 @@ void luaV_finishOp (lua_State *L) {
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
/* /*
** Protect code that will finish the loop (returns) or can only raise ** Protect code that can only raise errors. (That is, it cannnot change
** errors. (That is, it will not return to the interpreter main loop ** the stack or hooks.)
** after changing the stack or hooks.)
*/ */
#define halfProtect(exp) (savestate(L,ci), (exp)) #define halfProtect(exp) (savestate(L,ci), (exp))
/* idem, but without changing the stack */
#define halfProtectNT(exp) (savepc(L), (exp))
/* 'c' is the limit of live values in the stack */ /* 'c' is the limit of live values in the stack */
#define checkGC(L,c) \ #define checkGC(L,c) \
{ luaC_condGC(L, (savepc(L), L->top = (c)), \ { luaC_condGC(L, (savepc(L), L->top = (c)), \
@@ -1134,17 +1130,20 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
#if LUA_USE_JUMPTABLE #if LUA_USE_JUMPTABLE
#include "ljumptab.h" #include "ljumptab.h"
#endif #endif
execute: startfunc:
trap = L->hookmask; trap = L->hookmask;
returning: /* trap already set */
cl = clLvalue(s2v(ci->func)); cl = clLvalue(s2v(ci->func));
k = cl->p->k; k = cl->p->k;
pc = ci->u.l.savedpc; pc = ci->u.l.savedpc;
if (trap) { if (trap) {
if (pc == cl->p->code) { /* first instruction (not resuming)? */
if (cl->p->is_vararg) if (cl->p->is_vararg)
trap = 0; /* hooks will start after VARARGPREP instruction */ trap = 0; /* hooks will start after VARARGPREP instruction */
else if (pc == cl->p->code) /* first instruction (not resuming)? */ else /* check 'call' hook */
luaD_hookcall(L, ci); luaD_hookcall(L, ci);
ci->u.l.trap = 1; /* there may be other hooks */ }
ci->u.l.trap = 1; /* assume trap is on, for now */
} }
base = ci->func + 1; base = ci->func + 1;
/* main loop of interpreter */ /* main loop of interpreter */
@@ -1617,10 +1616,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
savepc(L); /* in case of errors */ savepc(L); /* in case of errors */
if ((newci = luaD_precall(L, ra, nresults)) == NULL) if ((newci = luaD_precall(L, ra, nresults)) == NULL)
updatetrap(ci); /* C call; nothing else to be done */ updatetrap(ci); /* C call; nothing else to be done */
else { /* Lua call: run function in this same invocation */ else { /* Lua call: run function in this same C frame */
ci = newci; ci = newci;
ci->callstatus = 0; /* call re-uses 'luaV_execute' */ ci->callstatus = 0; /* call re-uses 'luaV_execute' */
goto execute; goto startfunc;
} }
vmbreak; vmbreak;
} }
@@ -1633,7 +1632,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
L->top = ra + b; L->top = ra + b;
else /* previous instruction set top */ else /* previous instruction set top */
b = cast_int(L->top - ra); b = cast_int(L->top - ra);
savepc(ci); /* some calls here can raise errors */ savepc(ci); /* several calls here can raise errors */
if (TESTARG_k(i)) { if (TESTARG_k(i)) {
/* close upvalues from current call; the compiler ensures /* close upvalues from current call; the compiler ensures
that there are no to-be-closed variables here, so this that there are no to-be-closed variables here, so this
@@ -1652,11 +1651,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
updatestack(ci); /* stack may have been relocated */ updatestack(ci); /* stack may have been relocated */
ci->func -= delta; /* restore 'func' (if vararg) */ ci->func -= delta; /* restore 'func' (if vararg) */
luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ 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 */ goto ret; /* caller returns after the tail call */
} }
ci->func -= delta; /* restore 'func' (if vararg) */ ci->func -= delta; /* restore 'func' (if vararg) */
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
goto execute; /* execute the callee */ goto startfunc; /* execute the callee */
} }
vmcase(OP_RETURN) { vmcase(OP_RETURN) {
int n = GETARG_B(i) - 1; /* number of results */ int n = GETARG_B(i) - 1; /* number of results */
@@ -1675,12 +1675,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
ci->func -= ci->u.l.nextraargs + nparams1; ci->func -= ci->u.l.nextraargs + nparams1;
L->top = ra + n; /* set call for 'luaD_poscall' */ L->top = ra + n; /* set call for 'luaD_poscall' */
luaD_poscall(L, ci, n); luaD_poscall(L, ci, n);
updatetrap(ci); /* 'luaD_poscall' can change hooks */
goto ret; goto ret;
} }
vmcase(OP_RETURN0) { vmcase(OP_RETURN0) {
if (L->hookmask) { if (L->hookmask) {
L->top = ra; L->top = ra;
halfProtectNT(luaD_poscall(L, ci, 0)); /* no hurry... */ savepc(ci);
luaD_poscall(L, ci, 0); /* no hurry... */
trap = 1;
} }
else { /* do the 'poscall' here */ else { /* do the 'poscall' here */
int nres = ci->nresults; int nres = ci->nresults;
@@ -1694,7 +1697,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
vmcase(OP_RETURN1) { vmcase(OP_RETURN1) {
if (L->hookmask) { if (L->hookmask) {
L->top = ra + 1; L->top = ra + 1;
halfProtectNT(luaD_poscall(L, ci, 1)); /* no hurry... */ savepc(ci);
luaD_poscall(L, ci, 1); /* no hurry... */
trap = 1;
} }
else { /* do the 'poscall' here */ else { /* do the 'poscall' here */
int nres = ci->nresults; int nres = ci->nresults;
@@ -1708,12 +1713,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
setnilvalue(s2v(L->top++)); setnilvalue(s2v(L->top++));
} }
} }
ret: ret: /* return from a Lua function */
if (ci->callstatus & CIST_FRESH) if (ci->callstatus & CIST_FRESH)
return; /* end this frame */ return; /* end this frame */
else { else {
ci = ci->previous; ci = ci->previous;
goto execute; /* continue running caller in this frame */ goto returning; /* continue running caller in this frame */
} }
} }
vmcase(OP_FORLOOP) { vmcase(OP_FORLOOP) {