mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
Update Lua lua 5.4.4 rc2
This commit is contained in:
@@ -1180,18 +1180,19 @@ LUA_API int lua_status (lua_State *L) {
|
||||
LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
va_list argp;
|
||||
int res = 0;
|
||||
global_State *g;
|
||||
global_State *g = G(L);
|
||||
if (g->gcstp & GCSTPGC) /* internal stop? */
|
||||
return -1; /* all options are invalid when stopped */
|
||||
lua_lock(L);
|
||||
g = G(L);
|
||||
va_start(argp, what);
|
||||
switch (what) {
|
||||
case LUA_GCSTOP: {
|
||||
g->gcrunning = 0;
|
||||
g->gcstp = GCSTPUSR; /* stopped by the user */
|
||||
break;
|
||||
}
|
||||
case LUA_GCRESTART: {
|
||||
luaE_setdebt(g, 0);
|
||||
g->gcrunning = 1;
|
||||
g->gcstp = 0; /* (GCSTPGC must be already zero here) */
|
||||
break;
|
||||
}
|
||||
case LUA_GCCOLLECT: {
|
||||
@@ -1210,8 +1211,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
case LUA_GCSTEP: {
|
||||
int data = va_arg(argp, int);
|
||||
l_mem debt = 1; /* =1 to signal that it did an actual step */
|
||||
lu_byte oldrunning = g->gcrunning;
|
||||
g->gcrunning = 1; /* allow GC to run */
|
||||
lu_byte oldstp = g->gcstp;
|
||||
g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */
|
||||
if (data == 0) {
|
||||
luaE_setdebt(g, 0); /* do a basic step */
|
||||
luaC_step(L);
|
||||
@@ -1221,7 +1222,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
luaE_setdebt(g, debt);
|
||||
luaC_checkGC(L);
|
||||
}
|
||||
g->gcrunning = oldrunning; /* restore previous state */
|
||||
g->gcstp = oldstp; /* restore previous state */
|
||||
if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
|
||||
res = 1; /* signal it */
|
||||
break;
|
||||
@@ -1239,7 +1240,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||
break;
|
||||
}
|
||||
case LUA_GCISRUNNING: {
|
||||
res = g->gcrunning;
|
||||
res = gcrunning(g);
|
||||
break;
|
||||
}
|
||||
case LUA_GCGEN: {
|
||||
|
||||
@@ -182,12 +182,20 @@ static int luaB_rawset (lua_State *L) {
|
||||
|
||||
|
||||
static int pushmode (lua_State *L, int oldmode) {
|
||||
lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
||||
: "generational");
|
||||
if (oldmode == -1)
|
||||
luaL_pushfail(L); /* invalid call to 'lua_gc' */
|
||||
else
|
||||
lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
||||
: "generational");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** check whether call to 'lua_gc' was valid (not inside a finalizer)
|
||||
*/
|
||||
#define checkvalres(res) { if (res == -1) break; }
|
||||
|
||||
static int luaB_collectgarbage (lua_State *L) {
|
||||
static const char *const opts[] = {"stop", "restart", "collect",
|
||||
"count", "step", "setpause", "setstepmul",
|
||||
@@ -200,12 +208,14 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
case LUA_GCCOUNT: {
|
||||
int k = lua_gc(L, o);
|
||||
int b = lua_gc(L, LUA_GCCOUNTB);
|
||||
checkvalres(k);
|
||||
lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
|
||||
return 1;
|
||||
}
|
||||
case LUA_GCSTEP: {
|
||||
int step = (int)luaL_optinteger(L, 2, 0);
|
||||
int res = lua_gc(L, o, step);
|
||||
checkvalres(res);
|
||||
lua_pushboolean(L, res);
|
||||
return 1;
|
||||
}
|
||||
@@ -213,11 +223,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
case LUA_GCSETSTEPMUL: {
|
||||
int p = (int)luaL_optinteger(L, 2, 0);
|
||||
int previous = lua_gc(L, o, p);
|
||||
checkvalres(previous);
|
||||
lua_pushinteger(L, previous);
|
||||
return 1;
|
||||
}
|
||||
case LUA_GCISRUNNING: {
|
||||
int res = lua_gc(L, o);
|
||||
checkvalres(res);
|
||||
lua_pushboolean(L, res);
|
||||
return 1;
|
||||
}
|
||||
@@ -234,10 +246,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
}
|
||||
default: {
|
||||
int res = lua_gc(L, o);
|
||||
checkvalres(res);
|
||||
lua_pushinteger(L, res);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
luaL_pushfail(L); /* invalid call (inside a finalizer) */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
|
||||
|
||||
|
||||
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
const char **name);
|
||||
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
||||
const char **name);
|
||||
|
||||
|
||||
static int currentpc (CallInfo *ci) {
|
||||
@@ -304,7 +304,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||
if (!p->is_vararg) /* regular function? */
|
||||
i = 0; /* consider all instructions */
|
||||
else { /* vararg function */
|
||||
lua_assert(p->code[0] == OP_VARARGPREP);
|
||||
lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
|
||||
currentline = nextline(p, currentline, 0);
|
||||
i = 1; /* skip first instruction (OP_VARARGPREP) */
|
||||
}
|
||||
@@ -317,15 +317,9 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||
|
||||
|
||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||
if (ci == NULL) /* no 'ci'? */
|
||||
return NULL; /* no info */
|
||||
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
|
||||
*name = "__gc";
|
||||
return "metamethod"; /* report it as such */
|
||||
}
|
||||
/* calling function is a known Lua function? */
|
||||
else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
|
||||
return funcnamefromcode(L, ci->previous, name);
|
||||
/* calling function is a known function? */
|
||||
if (ci != NULL && !(ci->callstatus & CIST_TAIL))
|
||||
return funcnamefromcall(L, ci->previous, name);
|
||||
else return NULL; /* no way to find a name */
|
||||
}
|
||||
|
||||
@@ -597,16 +591,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
** Returns what the name is (e.g., "for iterator", "method",
|
||||
** "metamethod") and sets '*name' to point to the name.
|
||||
*/
|
||||
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
const char **name) {
|
||||
static const char *funcnamefromcode (lua_State *L, const Proto *p,
|
||||
int pc, const char **name) {
|
||||
TMS tm = (TMS)0; /* (initial value avoids warnings) */
|
||||
const Proto *p = ci_func(ci)->p; /* calling function */
|
||||
int pc = currentpc(ci); /* calling instruction index */
|
||||
Instruction i = p->code[pc]; /* calling instruction */
|
||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||
*name = "?";
|
||||
return "hook";
|
||||
}
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_CALL:
|
||||
case OP_TAILCALL:
|
||||
@@ -643,6 +631,26 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
return "metamethod";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Try to find a name for a function based on how it was called.
|
||||
*/
|
||||
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
||||
const char **name) {
|
||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||
*name = "?";
|
||||
return "hook";
|
||||
}
|
||||
else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */
|
||||
*name = "__gc";
|
||||
return "metamethod"; /* report it as such */
|
||||
}
|
||||
else if (isLua(ci))
|
||||
return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
@@ -728,14 +736,14 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
||||
|
||||
|
||||
/*
|
||||
** Raise an error for calling a non-callable object. Try to find
|
||||
** a name for the object based on the code that made the call
|
||||
** ('funcnamefromcode'); if it cannot get a name there, try 'varinfo'.
|
||||
** Raise an error for calling a non-callable object. Try to find a name
|
||||
** for the object based on how it was called ('funcnamefromcall'); if it
|
||||
** cannot get a name there, try 'varinfo'.
|
||||
*/
|
||||
l_noret luaG_callerror (lua_State *L, const TValue *o) {
|
||||
CallInfo *ci = L->ci;
|
||||
const char *name = NULL; /* to avoid warnings */
|
||||
const char *kind = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL;
|
||||
const char *kind = funcnamefromcall(L, ci, &name);
|
||||
const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o);
|
||||
typeerror(L, o, "call", extra);
|
||||
}
|
||||
|
||||
@@ -530,10 +530,10 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
int nfixparams = p->numparams;
|
||||
int i;
|
||||
checkstackGCp(L, fsize - delta, func);
|
||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
||||
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||
setobjs2s(L, ci->func + i, func + i);
|
||||
checkstackGC(L, fsize);
|
||||
func = ci->func; /* moved-down function */
|
||||
for (; narg1 <= nfixparams; narg1++)
|
||||
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
||||
|
||||
@@ -908,18 +908,18 @@ static void GCTM (lua_State *L) {
|
||||
if (!notm(tm)) { /* is there a finalizer? */
|
||||
int status;
|
||||
lu_byte oldah = L->allowhook;
|
||||
int running = g->gcrunning;
|
||||
int oldgcstp = g->gcstp;
|
||||
g->gcstp = GCSTPGC; /* avoid GC steps */
|
||||
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
||||
g->gcrunning = 0; /* avoid GC steps */
|
||||
setobj2s(L, L->top++, tm); /* push finalizer... */
|
||||
setobj2s(L, L->top++, &v); /* ... and its argument */
|
||||
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
||||
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
|
||||
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
||||
L->allowhook = oldah; /* restore hooks */
|
||||
g->gcrunning = running; /* restore state */
|
||||
g->gcstp = oldgcstp; /* restore state */
|
||||
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
||||
luaE_warnerror(L, "__gc metamethod");
|
||||
luaE_warnerror(L, "__gc");
|
||||
L->top--; /* pops error object */
|
||||
}
|
||||
}
|
||||
@@ -1508,9 +1508,11 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
|
||||
*/
|
||||
void luaC_freeallobjects (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
g->gcstp = GCSTPGC;
|
||||
luaC_changemode(L, KGC_INC);
|
||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||
lua_assert(g->finobj == NULL);
|
||||
g->gcstp = 0;
|
||||
callallpendingfinalizers(L);
|
||||
deletelist(L, g->allgc, obj2gco(g->mainthread));
|
||||
deletelist(L, g->finobj, NULL);
|
||||
@@ -1653,6 +1655,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Performs a basic incremental step. The debt and step size are
|
||||
** converted from bytes to "units of work"; then the function loops
|
||||
@@ -1684,7 +1687,7 @@ static void incstep (lua_State *L, global_State *g) {
|
||||
void luaC_step (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
lua_assert(!g->gcemergency);
|
||||
if (g->gcrunning) { /* running? */
|
||||
if (gcrunning(g)) { /* running? */
|
||||
if(isdecGCmodegen(g))
|
||||
genstep(L, g);
|
||||
else
|
||||
|
||||
@@ -153,6 +153,15 @@
|
||||
*/
|
||||
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
|
||||
|
||||
|
||||
/*
|
||||
** Control when GC is running:
|
||||
*/
|
||||
#define GCSTPUSR 1 /* bit true when GC stopped by user */
|
||||
#define GCSTPGC 2 /* bit true when GC stopped by itself */
|
||||
#define gcrunning(g) ((g)->gcstp == 0)
|
||||
|
||||
|
||||
/*
|
||||
** Does one step of collection when debt becomes positive. 'pre'/'pos'
|
||||
** allows some adjustments to be done only when needed. macro
|
||||
|
||||
@@ -361,7 +361,7 @@ typedef l_uint32 Instruction;
|
||||
#define condchangemem(L,pre,pos) ((void)0)
|
||||
#else
|
||||
#define condchangemem(L,pre,pos) \
|
||||
{ if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
|
||||
{ if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -236,7 +236,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
luaS_init(L);
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
g->gcrunning = 1; /* allow gc */
|
||||
g->gcstp = 0; /* allow gc */
|
||||
setnilvalue(&g->nilvalue); /* now state is complete */
|
||||
luai_userstateopen(L);
|
||||
}
|
||||
@@ -271,6 +271,7 @@ static void close_state (lua_State *L) {
|
||||
if (!completestate(g)) /* closing a partially built state? */
|
||||
luaC_freeallobjects(L); /* just collect its objects */
|
||||
else { /* closing a fully built state */
|
||||
L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
||||
luaC_freeallobjects(L); /* collect all objects */
|
||||
luai_userstateclose(L);
|
||||
@@ -371,7 +372,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||
g->warnf = NULL;
|
||||
g->ud_warn = NULL;
|
||||
g->mainthread = L;
|
||||
g->gcrunning = 0; /* no GC while building state */
|
||||
g->gcstp = GCSTPGC; /* no GC while building state */
|
||||
g->strt.size = g->strt.nuse = 0;
|
||||
g->strt.hash = NULL;
|
||||
setnilvalue(&g->l_registry);
|
||||
|
||||
@@ -209,7 +209,7 @@ typedef struct CallInfo {
|
||||
#define CIST_YPCALL (1<<4) /* doing 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_FIN (1<<7) /* function "called" a finalizer */
|
||||
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
|
||||
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
|
||||
/* Bits 10-12 are used for CIST_RECST (see below) */
|
||||
@@ -262,7 +262,7 @@ typedef struct global_State {
|
||||
lu_byte gcstopem; /* stops emergency collections */
|
||||
lu_byte genminormul; /* control for minor generational collections */
|
||||
lu_byte genmajormul; /* control for major generational collections */
|
||||
lu_byte gcrunning; /* true if GC is running */
|
||||
lu_byte gcstp; /* control whether GC is running */
|
||||
lu_byte gcemergency; /* true if this is an emergency collection */
|
||||
lu_byte gcpause; /* size of pause between successive GCs */
|
||||
lu_byte gcstepmul; /* GC "speed" */
|
||||
|
||||
@@ -146,26 +146,24 @@ static int l_hashfloat (lua_Number n) {
|
||||
|
||||
/*
|
||||
** returns the 'main' position of an element in a table (that is,
|
||||
** the index of its hash value). The key comes broken (tag in 'ktt'
|
||||
** and value in 'vkl') so that we can call it on keys inserted into
|
||||
** nodes.
|
||||
** the index of its hash value).
|
||||
*/
|
||||
static Node *mainposition (const Table *t, int ktt, const Value kvl) {
|
||||
switch (withvariant(ktt)) {
|
||||
static Node *mainpositionTV (const Table *t, const TValue *key) {
|
||||
switch (ttypetag(key)) {
|
||||
case LUA_VNUMINT: {
|
||||
lua_Integer key = ivalueraw(kvl);
|
||||
return hashint(t, key);
|
||||
lua_Integer i = ivalue(key);
|
||||
return hashint(t, i);
|
||||
}
|
||||
case LUA_VNUMFLT: {
|
||||
lua_Number n = fltvalueraw(kvl);
|
||||
lua_Number n = fltvalue(key);
|
||||
return hashmod(t, l_hashfloat(n));
|
||||
}
|
||||
case LUA_VSHRSTR: {
|
||||
TString *ts = tsvalueraw(kvl);
|
||||
TString *ts = tsvalue(key);
|
||||
return hashstr(t, ts);
|
||||
}
|
||||
case LUA_VLNGSTR: {
|
||||
TString *ts = tsvalueraw(kvl);
|
||||
TString *ts = tsvalue(key);
|
||||
return hashpow2(t, luaS_hashlongstr(ts));
|
||||
}
|
||||
case LUA_VFALSE:
|
||||
@@ -173,26 +171,25 @@ static Node *mainposition (const Table *t, int ktt, const Value kvl) {
|
||||
case LUA_VTRUE:
|
||||
return hashboolean(t, 1);
|
||||
case LUA_VLIGHTUSERDATA: {
|
||||
void *p = pvalueraw(kvl);
|
||||
void *p = pvalue(key);
|
||||
return hashpointer(t, p);
|
||||
}
|
||||
case LUA_VLCF: {
|
||||
lua_CFunction f = fvalueraw(kvl);
|
||||
lua_CFunction f = fvalue(key);
|
||||
return hashpointer(t, f);
|
||||
}
|
||||
default: {
|
||||
GCObject *o = gcvalueraw(kvl);
|
||||
GCObject *o = gcvalue(key);
|
||||
return hashpointer(t, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Returns the main position of an element given as a 'TValue'
|
||||
*/
|
||||
static Node *mainpositionTV (const Table *t, const TValue *key) {
|
||||
return mainposition(t, rawtt(key), valraw(key));
|
||||
l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) {
|
||||
TValue key;
|
||||
getnodekey(cast(lua_State *, NULL), &key, nd);
|
||||
return mainpositionTV(t, &key);
|
||||
}
|
||||
|
||||
|
||||
@@ -695,7 +692,7 @@ void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
|
||||
return;
|
||||
}
|
||||
lua_assert(!isdummy(t));
|
||||
othern = mainposition(t, keytt(mp), keyval(mp));
|
||||
othern = mainpositionfromnode(t, mp);
|
||||
if (othern != mp) { /* is colliding node out of its main position? */
|
||||
/* yes; move colliding node into free position */
|
||||
while (othern + gnext(othern) != mp) /* find previous */
|
||||
|
||||
Reference in New Issue
Block a user