mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
update lua 5.4.2
This commit is contained in:
@@ -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.)
|
||||
*/
|
||||
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
|
||||
** 'e' will become a non-relocatable expression).
|
||||
** Ensure expression value is in register 'reg', making 'e' a
|
||||
** non-relocatable expression.
|
||||
** (Expression still may have jump lists.)
|
||||
*/
|
||||
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.)
|
||||
*/
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
** of recursive invocations in the C stack) or nyci (the same plus
|
||||
** increment number of non-yieldable calls).
|
||||
** 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 docall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
static void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
||||
CallInfo *ci;
|
||||
L->nCcalls += inc;
|
||||
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) {
|
||||
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.
|
||||
*/
|
||||
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 */
|
||||
CallInfo *ci = L->ci;
|
||||
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 */
|
||||
lua_assert(L->status == LUA_YIELD);
|
||||
L->status = LUA_OK; /* mark that it is running (again) */
|
||||
|
||||
@@ -254,9 +254,10 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
||||
|
||||
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
static size_t skip_sep (LexState *ls) {
|
||||
size_t count = 0;
|
||||
@@ -481,34 +482,34 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
||||
}
|
||||
case '=': {
|
||||
next(ls);
|
||||
if (check_next1(ls, '=')) return TK_EQ;
|
||||
if (check_next1(ls, '=')) return TK_EQ; /* '==' */
|
||||
else return '=';
|
||||
}
|
||||
case '<': {
|
||||
next(ls);
|
||||
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; /* '<<' */
|
||||
else return '<';
|
||||
}
|
||||
case '>': {
|
||||
next(ls);
|
||||
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; /* '>>' */
|
||||
else return '>';
|
||||
}
|
||||
case '/': {
|
||||
next(ls);
|
||||
if (check_next1(ls, '/')) return TK_IDIV;
|
||||
if (check_next1(ls, '/')) return TK_IDIV; /* '//' */
|
||||
else return '/';
|
||||
}
|
||||
case '~': {
|
||||
next(ls);
|
||||
if (check_next1(ls, '=')) return TK_NE;
|
||||
if (check_next1(ls, '=')) return TK_NE; /* '~=' */
|
||||
else return '~';
|
||||
}
|
||||
case ':': {
|
||||
next(ls);
|
||||
if (check_next1(ls, ':')) return TK_DBCOLON;
|
||||
if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */
|
||||
else return ':';
|
||||
}
|
||||
case '"': case '\'': { /* short literal strings */
|
||||
@@ -547,7 +548,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
||||
return TK_NAME;
|
||||
}
|
||||
}
|
||||
else { /* single-char tokens (+ - / ...) */
|
||||
else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
|
||||
int c = ls->current;
|
||||
next(ls);
|
||||
return c;
|
||||
|
||||
@@ -355,7 +355,7 @@ typedef l_uint32 Instruction;
|
||||
#else
|
||||
/* realloc stack keeping its size */
|
||||
#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
|
||||
|
||||
#if !defined(HARDMEMTESTS)
|
||||
|
||||
@@ -945,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) {
|
||||
|
||||
|
||||
static void parlist (LexState *ls) {
|
||||
/* parlist -> [ param { ',' param } ] */
|
||||
/* parlist -> [ {NAME ','} (NAME | '...') ] */
|
||||
FuncState *fs = ls->fs;
|
||||
Proto *f = fs->f;
|
||||
int nparams = 0;
|
||||
@@ -953,12 +953,12 @@ static void parlist (LexState *ls) {
|
||||
if (ls->t.token != ')') { /* is 'parlist' not empty? */
|
||||
do {
|
||||
switch (ls->t.token) {
|
||||
case TK_NAME: { /* param -> NAME */
|
||||
case TK_NAME: {
|
||||
new_localvar(ls, str_checkname(ls));
|
||||
nparams++;
|
||||
break;
|
||||
}
|
||||
case TK_DOTS: { /* param -> '...' */
|
||||
case TK_DOTS: {
|
||||
luaX_next(ls);
|
||||
isvararg = 1;
|
||||
break;
|
||||
@@ -1752,7 +1752,7 @@ static void checktoclose (LexState *ls, int level) {
|
||||
|
||||
|
||||
static void localstat (LexState *ls) {
|
||||
/* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */
|
||||
/* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */
|
||||
FuncState *fs = ls->fs;
|
||||
int toclose = -1; /* index of to-be-closed variable (if any) */
|
||||
Vardesc *var; /* last variable */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
/* kinds of variables/expressions */
|
||||
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) */
|
||||
VNIL, /* constant nil */
|
||||
VTRUE, /* constant true */
|
||||
@@ -38,7 +38,8 @@ typedef enum {
|
||||
VLOCAL, /* local variable; var.sidx = stack index (local register);
|
||||
var.vidx = relative index in 'actvar.arr' */
|
||||
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;
|
||||
ind.t = table register;
|
||||
ind.idx = key's R index */
|
||||
|
||||
@@ -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'.
|
||||
** 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.
|
||||
** 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, which can only happen if the original key was collectable.
|
||||
** All dead values are compared in the default case, by pointer
|
||||
** identity. (Note that dead long strings are also compared by
|
||||
** identity).
|
||||
** 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? */
|
||||
|
||||
@@ -416,14 +416,18 @@ 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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* mark in error messages for incomplete statements */
|
||||
|
||||
@@ -1094,15 +1094,11 @@ void luaV_finishOp (lua_State *L) {
|
||||
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
|
||||
|
||||
/*
|
||||
** 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.)
|
||||
*/
|
||||
#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 */
|
||||
#define checkGC(L,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
|
||||
#include "ljumptab.h"
|
||||
#endif
|
||||
execute:
|
||||
startfunc:
|
||||
trap = L->hookmask;
|
||||
returning: /* trap already set */
|
||||
cl = clLvalue(s2v(ci->func));
|
||||
k = cl->p->k;
|
||||
pc = ci->u.l.savedpc;
|
||||
if (trap) {
|
||||
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 */
|
||||
}
|
||||
base = ci->func + 1;
|
||||
/* main loop of interpreter */
|
||||
@@ -1617,10 +1616,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
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 invocation */
|
||||
else { /* Lua call: run function in this same C frame */
|
||||
ci = newci;
|
||||
ci->callstatus = 0; /* call re-uses 'luaV_execute' */
|
||||
goto execute;
|
||||
goto startfunc;
|
||||
}
|
||||
vmbreak;
|
||||
}
|
||||
@@ -1633,7 +1632,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
L->top = ra + b;
|
||||
else /* previous instruction set top */
|
||||
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)) {
|
||||
/* close upvalues from current call; the compiler ensures
|
||||
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 */
|
||||
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 */
|
||||
}
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||
goto execute; /* execute the callee */
|
||||
goto startfunc; /* execute the callee */
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
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;
|
||||
L->top = ra + n; /* set call for 'luaD_poscall' */
|
||||
luaD_poscall(L, ci, n);
|
||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||
goto ret;
|
||||
}
|
||||
vmcase(OP_RETURN0) {
|
||||
if (L->hookmask) {
|
||||
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 */
|
||||
int nres = ci->nresults;
|
||||
@@ -1694,7 +1697,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
vmcase(OP_RETURN1) {
|
||||
if (L->hookmask) {
|
||||
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 */
|
||||
int nres = ci->nresults;
|
||||
@@ -1708,12 +1713,12 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
setnilvalue(s2v(L->top++));
|
||||
}
|
||||
}
|
||||
ret:
|
||||
ret: /* return from a Lua function */
|
||||
if (ci->callstatus & CIST_FRESH)
|
||||
return; /* end this frame */
|
||||
else {
|
||||
ci = ci->previous;
|
||||
goto execute; /* continue running caller in this frame */
|
||||
goto returning; /* continue running caller in this frame */
|
||||
}
|
||||
}
|
||||
vmcase(OP_FORLOOP) {
|
||||
|
||||
Reference in New Issue
Block a user