mirror of
https://github.com/lua/lua.git
synced 2026-07-30 18:09:05 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e22fedb74 | ||
|
|
267ef461d0 | ||
|
|
d1ee2a4deb | ||
|
|
3fe7be956f | ||
|
|
983bc433e6 | ||
|
|
25da574fcb | ||
|
|
f5e55be2a0 | ||
|
|
9f0c0fe0de | ||
|
|
782ef85b22 | ||
|
|
30982bec96 | ||
|
|
1ab3208a1f | ||
|
|
21ff8de33a | ||
|
|
7eb1ed21b7 | ||
|
|
2db966fcbf | ||
|
|
ae9a0cbbb4 | ||
|
|
d5212c13b0 | ||
|
|
e0efebdbe4 | ||
|
|
e84f7bf198 | ||
|
|
dfbde4c7d5 | ||
|
|
de794a6527 | ||
|
|
8b83417de9 |
2
lapi.c
2
lapi.c
@@ -1343,7 +1343,7 @@ void lua_warning (lua_State *L, const char *msg, int tocont) {
|
|||||||
LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
|
LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
|
||||||
Udata *u;
|
Udata *u;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
|
api_check(L, 0 <= nuvalue && nuvalue < SHRT_MAX, "invalid value");
|
||||||
u = luaS_newudata(L, size, nuvalue);
|
u = luaS_newudata(L, size, nuvalue);
|
||||||
setuvalue(L, s2v(L->top.p), u);
|
setuvalue(L, s2v(L->top.p), u);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
|||||||
19
lauxlib.c
19
lauxlib.c
@@ -80,6 +80,7 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
|
|||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
lua_getinfo(L, "f", ar); /* push function */
|
lua_getinfo(L, "f", ar); /* push function */
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||||
|
luaL_checkstack(L, 6, "not enough stack"); /* slots for 'findfield' */
|
||||||
if (findfield(L, top + 1, 2)) {
|
if (findfield(L, top + 1, 2)) {
|
||||||
const char *name = lua_tostring(L, -1);
|
const char *name = lua_tostring(L, -1);
|
||||||
if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
|
if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
|
||||||
@@ -249,11 +250,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
const char *msg;
|
||||||
luaL_pushfail(L);
|
luaL_pushfail(L);
|
||||||
|
msg = (en != 0) ? strerror(en) : "(no extra info)";
|
||||||
if (fname)
|
if (fname)
|
||||||
lua_pushfstring(L, "%s: %s", fname, strerror(en));
|
lua_pushfstring(L, "%s: %s", fname, msg);
|
||||||
else
|
else
|
||||||
lua_pushstring(L, strerror(en));
|
lua_pushstring(L, msg);
|
||||||
lua_pushinteger(L, en);
|
lua_pushinteger(L, en);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@@ -732,9 +735,12 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
|
|||||||
|
|
||||||
|
|
||||||
static int errfile (lua_State *L, const char *what, int fnameindex) {
|
static int errfile (lua_State *L, const char *what, int fnameindex) {
|
||||||
const char *serr = strerror(errno);
|
int err = errno;
|
||||||
const char *filename = lua_tostring(L, fnameindex) + 1;
|
const char *filename = lua_tostring(L, fnameindex) + 1;
|
||||||
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
|
if (err != 0)
|
||||||
|
lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err));
|
||||||
|
else
|
||||||
|
lua_pushfstring(L, "cannot %s %s", what, filename);
|
||||||
lua_remove(L, fnameindex);
|
lua_remove(L, fnameindex);
|
||||||
return LUA_ERRFILE;
|
return LUA_ERRFILE;
|
||||||
}
|
}
|
||||||
@@ -787,6 +793,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_pushfstring(L, "@%s", filename);
|
lua_pushfstring(L, "@%s", filename);
|
||||||
|
errno = 0;
|
||||||
lf.f = fopen(filename, "r");
|
lf.f = fopen(filename, "r");
|
||||||
if (lf.f == NULL) return errfile(L, "open", fnameindex);
|
if (lf.f == NULL) return errfile(L, "open", fnameindex);
|
||||||
}
|
}
|
||||||
@@ -796,6 +803,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
|||||||
if (c == LUA_SIGNATURE[0]) { /* binary file? */
|
if (c == LUA_SIGNATURE[0]) { /* binary file? */
|
||||||
lf.n = 0; /* remove possible newline */
|
lf.n = 0; /* remove possible newline */
|
||||||
if (filename) { /* "real" file? */
|
if (filename) { /* "real" file? */
|
||||||
|
errno = 0;
|
||||||
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
|
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
|
||||||
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
|
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
|
||||||
skipcomment(lf.f, &c); /* re-read initial portion */
|
skipcomment(lf.f, &c); /* re-read initial portion */
|
||||||
@@ -803,6 +811,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
|||||||
}
|
}
|
||||||
if (c != EOF)
|
if (c != EOF)
|
||||||
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
|
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
|
||||||
|
errno = 0;
|
||||||
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
|
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
|
||||||
readstatus = ferror(lf.f);
|
readstatus = ferror(lf.f);
|
||||||
if (filename) fclose(lf.f); /* close file (even in case of errors) */
|
if (filename) fclose(lf.f); /* close file (even in case of errors) */
|
||||||
@@ -933,7 +942,7 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
|
|||||||
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
||||||
luaL_checkstack(L, nup, "too many upvalues");
|
luaL_checkstack(L, nup, "too many upvalues");
|
||||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||||
if (l->func == NULL) /* place holder? */
|
if (l->func == NULL) /* placeholder? */
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
else {
|
else {
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
9
lcode.c
9
lcode.c
@@ -35,6 +35,7 @@
|
|||||||
#define MAXREGS 255
|
#define MAXREGS 255
|
||||||
|
|
||||||
|
|
||||||
|
/* (note that expressions VJMP also have jumps.) */
|
||||||
#define hasjumps(e) ((e)->t != (e)->f)
|
#define hasjumps(e) ((e)->t != (e)->f)
|
||||||
|
|
||||||
|
|
||||||
@@ -776,7 +777,8 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VLOCAL: { /* already in a register */
|
case VLOCAL: { /* already in a register */
|
||||||
e->u.info = e->u.var.ridx;
|
int temp = e->u.var.ridx;
|
||||||
|
e->u.info = temp; /* (can't do a direct assignment; values overlap) */
|
||||||
e->k = VNONRELOC; /* becomes a non-relocatable value */
|
e->k = VNONRELOC; /* becomes a non-relocatable value */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -984,7 +986,7 @@ void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
|
|||||||
** or it is a constant.
|
** or it is a constant.
|
||||||
*/
|
*/
|
||||||
void luaK_exp2val (FuncState *fs, expdesc *e) {
|
void luaK_exp2val (FuncState *fs, expdesc *e) {
|
||||||
if (hasjumps(e))
|
if (e->k == VJMP || hasjumps(e))
|
||||||
luaK_exp2anyreg(fs, e);
|
luaK_exp2anyreg(fs, e);
|
||||||
else
|
else
|
||||||
luaK_dischargevars(fs, e);
|
luaK_dischargevars(fs, e);
|
||||||
@@ -1283,8 +1285,9 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
|
|||||||
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
|
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
|
||||||
luaK_exp2anyreg(fs, t); /* put it in a register */
|
luaK_exp2anyreg(fs, t); /* put it in a register */
|
||||||
if (t->k == VUPVAL) {
|
if (t->k == VUPVAL) {
|
||||||
|
int temp = t->u.info; /* upvalue index */
|
||||||
lua_assert(isKstr(fs, k));
|
lua_assert(isKstr(fs, k));
|
||||||
t->u.ind.t = t->u.info; /* upvalue index */
|
t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */
|
||||||
t->u.ind.idx = k->u.info; /* literal short string */
|
t->u.ind.idx = k->u.info; /* literal short string */
|
||||||
t->k = VINDEXUP;
|
t->k = VINDEXUP;
|
||||||
}
|
}
|
||||||
|
|||||||
57
ldebug.c
57
ldebug.c
@@ -31,12 +31,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
|
#define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL)
|
||||||
|
|
||||||
|
|
||||||
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
||||||
const char **name);
|
const char **name);
|
||||||
|
|
||||||
|
static const char strlocal[] = "local";
|
||||||
|
static const char strupval[] = "upvalue";
|
||||||
|
|
||||||
|
|
||||||
static int currentpc (CallInfo *ci) {
|
static int currentpc (CallInfo *ci) {
|
||||||
lua_assert(isLua(ci));
|
lua_assert(isLua(ci));
|
||||||
@@ -254,7 +257,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
|
|
||||||
|
|
||||||
static void funcinfo (lua_Debug *ar, Closure *cl) {
|
static void funcinfo (lua_Debug *ar, Closure *cl) {
|
||||||
if (noLuaClosure(cl)) {
|
if (!LuaClosure(cl)) {
|
||||||
ar->source = "=[C]";
|
ar->source = "=[C]";
|
||||||
ar->srclen = LL("=[C]");
|
ar->srclen = LL("=[C]");
|
||||||
ar->linedefined = -1;
|
ar->linedefined = -1;
|
||||||
@@ -288,29 +291,31 @@ static int nextline (const Proto *p, int currentline, int pc) {
|
|||||||
|
|
||||||
|
|
||||||
static void collectvalidlines (lua_State *L, Closure *f) {
|
static void collectvalidlines (lua_State *L, Closure *f) {
|
||||||
if (noLuaClosure(f)) {
|
if (!LuaClosure(f)) {
|
||||||
setnilvalue(s2v(L->top.p));
|
setnilvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i;
|
|
||||||
TValue v;
|
|
||||||
const Proto *p = f->l.p;
|
const Proto *p = f->l.p;
|
||||||
int currentline = p->linedefined;
|
int currentline = p->linedefined;
|
||||||
Table *t = luaH_new(L); /* new table to store active lines */
|
Table *t = luaH_new(L); /* new table to store active lines */
|
||||||
sethvalue2s(L, L->top.p, t); /* push it on stack */
|
sethvalue2s(L, L->top.p, t); /* push it on stack */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
if (p->lineinfo != NULL) { /* proto with debug information? */
|
||||||
if (!p->is_vararg) /* regular function? */
|
int i;
|
||||||
i = 0; /* consider all instructions */
|
TValue v;
|
||||||
else { /* vararg function */
|
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
||||||
lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
|
if (!p->is_vararg) /* regular function? */
|
||||||
currentline = nextline(p, currentline, 0);
|
i = 0; /* consider all instructions */
|
||||||
i = 1; /* skip first instruction (OP_VARARGPREP) */
|
else { /* vararg function */
|
||||||
}
|
lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
|
||||||
for (; i < p->sizelineinfo; i++) { /* for each instruction */
|
currentline = nextline(p, currentline, 0);
|
||||||
currentline = nextline(p, currentline, i); /* get its line */
|
i = 1; /* skip first instruction (OP_VARARGPREP) */
|
||||||
luaH_setint(L, t, currentline, &v); /* table[line] = true */
|
}
|
||||||
|
for (; i < p->sizelineinfo; i++) { /* for each instruction */
|
||||||
|
currentline = nextline(p, currentline, i); /* get its line */
|
||||||
|
luaH_setint(L, t, currentline, &v); /* table[line] = true */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +344,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|||||||
}
|
}
|
||||||
case 'u': {
|
case 'u': {
|
||||||
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
|
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
|
||||||
if (noLuaClosure(f)) {
|
if (!LuaClosure(f)) {
|
||||||
ar->isvararg = 1;
|
ar->isvararg = 1;
|
||||||
ar->nparams = 0;
|
ar->nparams = 0;
|
||||||
}
|
}
|
||||||
@@ -495,7 +500,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
|
|||||||
int pc = *ppc;
|
int pc = *ppc;
|
||||||
*name = luaF_getlocalname(p, reg + 1, pc);
|
*name = luaF_getlocalname(p, reg + 1, pc);
|
||||||
if (*name) /* is a local? */
|
if (*name) /* is a local? */
|
||||||
return "local";
|
return strlocal;
|
||||||
/* else try symbolic execution */
|
/* else try symbolic execution */
|
||||||
*ppc = pc = findsetreg(p, pc, reg);
|
*ppc = pc = findsetreg(p, pc, reg);
|
||||||
if (pc != -1) { /* could find instruction? */
|
if (pc != -1) { /* could find instruction? */
|
||||||
@@ -510,7 +515,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
|
|||||||
}
|
}
|
||||||
case OP_GETUPVAL: {
|
case OP_GETUPVAL: {
|
||||||
*name = upvalname(p, GETARG_B(i));
|
*name = upvalname(p, GETARG_B(i));
|
||||||
return "upvalue";
|
return strupval;
|
||||||
}
|
}
|
||||||
case OP_LOADK: return kname(p, GETARG_Bx(i), name);
|
case OP_LOADK: return kname(p, GETARG_Bx(i), name);
|
||||||
case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
|
case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
|
||||||
@@ -545,15 +550,21 @@ static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Check whether table being indexed by instruction 'i' is the
|
** Check whether table being indexed by instruction 'i' is the
|
||||||
** environment '_ENV'
|
** environment '_ENV'. If the table is an upvalue, get its name;
|
||||||
|
** otherwise, find some "name" for the table and check whether
|
||||||
|
** that name is the name of a local variable (and not, for instance,
|
||||||
|
** a string). Then check that, if there is a name, it is '_ENV'.
|
||||||
*/
|
*/
|
||||||
static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
|
static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
|
||||||
int t = GETARG_B(i); /* table index */
|
int t = GETARG_B(i); /* table index */
|
||||||
const char *name; /* name of indexed variable */
|
const char *name; /* name of indexed variable */
|
||||||
if (isup) /* is 't' an upvalue? */
|
if (isup) /* is 't' an upvalue? */
|
||||||
name = upvalname(p, t);
|
name = upvalname(p, t);
|
||||||
else /* 't' is a register */
|
else { /* 't' is a register */
|
||||||
basicgetobjname(p, &pc, t, &name);
|
const char *what = basicgetobjname(p, &pc, t, &name);
|
||||||
|
if (what != strlocal && what != strupval)
|
||||||
|
name = NULL; /* cannot be the variable _ENV */
|
||||||
|
}
|
||||||
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
|
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,7 +710,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
|
|||||||
for (i = 0; i < c->nupvalues; i++) {
|
for (i = 0; i < c->nupvalues; i++) {
|
||||||
if (c->upvals[i]->v.p == o) {
|
if (c->upvals[i]->v.p == o) {
|
||||||
*name = upvalname(c->p, i);
|
*name = upvalname(c->p, i);
|
||||||
return "upvalue";
|
return strupval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
17
ldo.c
17
ldo.c
@@ -94,10 +94,6 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
|
|||||||
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_ERRERR: {
|
|
||||||
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case LUA_OK: { /* special case only for closing upvalues */
|
case LUA_OK: { /* special case only for closing upvalues */
|
||||||
setnilvalue(s2v(oldtop)); /* no error message */
|
setnilvalue(s2v(oldtop)); /* no error message */
|
||||||
break;
|
break;
|
||||||
@@ -120,6 +116,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
|||||||
else { /* thread has no error handler */
|
else { /* thread has no error handler */
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
||||||
|
L->status = errcode;
|
||||||
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
||||||
setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
|
setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
|
||||||
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
|
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
|
||||||
@@ -198,6 +195,16 @@ static void correctstack (lua_State *L) {
|
|||||||
/* some space for error handling */
|
/* some space for error handling */
|
||||||
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
||||||
|
|
||||||
|
|
||||||
|
/* raise an error while running the message handler */
|
||||||
|
l_noret luaD_errerr (lua_State *L) {
|
||||||
|
TString *msg = luaS_newliteral(L, "error in error handling");
|
||||||
|
setsvalue2s(L, L->top.p, msg);
|
||||||
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
|
luaD_throw(L, LUA_ERRERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Reallocate the stack to a new size, correcting all pointers into it.
|
** Reallocate the stack to a new size, correcting all pointers into it.
|
||||||
** In ISO C, any pointer use after the pointer has been deallocated is
|
** In ISO C, any pointer use after the pointer has been deallocated is
|
||||||
@@ -247,7 +254,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
|||||||
a stack error; cannot grow further than that. */
|
a stack error; cannot grow further than that. */
|
||||||
lua_assert(stacksize(L) == ERRORSTACKSIZE);
|
lua_assert(stacksize(L) == ERRORSTACKSIZE);
|
||||||
if (raiseerror)
|
if (raiseerror)
|
||||||
luaD_throw(L, LUA_ERRERR); /* error inside message handler */
|
luaD_errerr(L); /* error inside message handler */
|
||||||
return 0; /* if not 'raiseerror', just signal it */
|
return 0; /* if not 'raiseerror', just signal it */
|
||||||
}
|
}
|
||||||
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
|
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
|
||||||
|
|||||||
1
ldo.h
1
ldo.h
@@ -60,6 +60,7 @@
|
|||||||
/* type of protected functions, to be ran by 'runprotected' */
|
/* type of protected functions, to be ran by 'runprotected' */
|
||||||
typedef void (*Pfunc) (lua_State *L, void *ud);
|
typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||||
|
|
||||||
|
LUAI_FUNC l_noret luaD_errerr (lua_State *L);
|
||||||
LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
|
LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
|
||||||
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||||
const char *mode);
|
const char *mode);
|
||||||
|
|||||||
2
lgc.c
2
lgc.c
@@ -1713,7 +1713,7 @@ static void fullinc (lua_State *L, global_State *g) {
|
|||||||
/* finish any pending sweep phase to start a new cycle */
|
/* finish any pending sweep phase to start a new cycle */
|
||||||
luaC_runtilstate(L, bitmask(GCSpause));
|
luaC_runtilstate(L, bitmask(GCSpause));
|
||||||
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
||||||
g->gcstate = GCSenteratomic; /* go straight to atomic phase ??? */
|
g->gcstate = GCSenteratomic; /* go straight to atomic phase */
|
||||||
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
|
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
|
||||||
/* estimate must be correct after a full GC cycle */
|
/* estimate must be correct after a full GC cycle */
|
||||||
lua_assert(g->GCestimate == gettotalbytes(g));
|
lua_assert(g->GCestimate == gettotalbytes(g));
|
||||||
|
|||||||
27
liolib.c
27
liolib.c
@@ -245,8 +245,8 @@ static int f_gc (lua_State *L) {
|
|||||||
*/
|
*/
|
||||||
static int io_fclose (lua_State *L) {
|
static int io_fclose (lua_State *L) {
|
||||||
LStream *p = tolstream(L);
|
LStream *p = tolstream(L);
|
||||||
int res = fclose(p->f);
|
errno = 0;
|
||||||
return luaL_fileresult(L, (res == 0), NULL);
|
return luaL_fileresult(L, (fclose(p->f) == 0), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -272,6 +272,7 @@ static int io_open (lua_State *L) {
|
|||||||
LStream *p = newfile(L);
|
LStream *p = newfile(L);
|
||||||
const char *md = mode; /* to traverse/check mode */
|
const char *md = mode; /* to traverse/check mode */
|
||||||
luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
|
luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
|
||||||
|
errno = 0;
|
||||||
p->f = fopen(filename, mode);
|
p->f = fopen(filename, mode);
|
||||||
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
|
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
|
||||||
}
|
}
|
||||||
@@ -292,6 +293,7 @@ static int io_popen (lua_State *L) {
|
|||||||
const char *mode = luaL_optstring(L, 2, "r");
|
const char *mode = luaL_optstring(L, 2, "r");
|
||||||
LStream *p = newprefile(L);
|
LStream *p = newprefile(L);
|
||||||
luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
|
luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
|
||||||
|
errno = 0;
|
||||||
p->f = l_popen(L, filename, mode);
|
p->f = l_popen(L, filename, mode);
|
||||||
p->closef = &io_pclose;
|
p->closef = &io_pclose;
|
||||||
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
|
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
|
||||||
@@ -300,6 +302,7 @@ static int io_popen (lua_State *L) {
|
|||||||
|
|
||||||
static int io_tmpfile (lua_State *L) {
|
static int io_tmpfile (lua_State *L) {
|
||||||
LStream *p = newfile(L);
|
LStream *p = newfile(L);
|
||||||
|
errno = 0;
|
||||||
p->f = tmpfile();
|
p->f = tmpfile();
|
||||||
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
|
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
|
||||||
}
|
}
|
||||||
@@ -567,6 +570,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
|
|||||||
int nargs = lua_gettop(L) - 1;
|
int nargs = lua_gettop(L) - 1;
|
||||||
int n, success;
|
int n, success;
|
||||||
clearerr(f);
|
clearerr(f);
|
||||||
|
errno = 0;
|
||||||
if (nargs == 0) { /* no arguments? */
|
if (nargs == 0) { /* no arguments? */
|
||||||
success = read_line(L, f, 1);
|
success = read_line(L, f, 1);
|
||||||
n = first + 1; /* to return 1 result */
|
n = first + 1; /* to return 1 result */
|
||||||
@@ -660,6 +664,7 @@ static int io_readline (lua_State *L) {
|
|||||||
static int g_write (lua_State *L, FILE *f, int arg) {
|
static int g_write (lua_State *L, FILE *f, int arg) {
|
||||||
int nargs = lua_gettop(L) - arg;
|
int nargs = lua_gettop(L) - arg;
|
||||||
int status = 1;
|
int status = 1;
|
||||||
|
errno = 0;
|
||||||
for (; nargs--; arg++) {
|
for (; nargs--; arg++) {
|
||||||
if (lua_type(L, arg) == LUA_TNUMBER) {
|
if (lua_type(L, arg) == LUA_TNUMBER) {
|
||||||
/* optimization: could be done exactly as for strings */
|
/* optimization: could be done exactly as for strings */
|
||||||
@@ -678,7 +683,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
|
|||||||
}
|
}
|
||||||
if (l_likely(status))
|
if (l_likely(status))
|
||||||
return 1; /* file handle already on stack top */
|
return 1; /* file handle already on stack top */
|
||||||
else return luaL_fileresult(L, status, NULL);
|
else
|
||||||
|
return luaL_fileresult(L, status, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -703,6 +709,7 @@ static int f_seek (lua_State *L) {
|
|||||||
l_seeknum offset = (l_seeknum)p3;
|
l_seeknum offset = (l_seeknum)p3;
|
||||||
luaL_argcheck(L, (lua_Integer)offset == p3, 3,
|
luaL_argcheck(L, (lua_Integer)offset == p3, 3,
|
||||||
"not an integer in proper range");
|
"not an integer in proper range");
|
||||||
|
errno = 0;
|
||||||
op = l_fseek(f, offset, mode[op]);
|
op = l_fseek(f, offset, mode[op]);
|
||||||
if (l_unlikely(op))
|
if (l_unlikely(op))
|
||||||
return luaL_fileresult(L, 0, NULL); /* error */
|
return luaL_fileresult(L, 0, NULL); /* error */
|
||||||
@@ -719,19 +726,25 @@ static int f_setvbuf (lua_State *L) {
|
|||||||
FILE *f = tofile(L);
|
FILE *f = tofile(L);
|
||||||
int op = luaL_checkoption(L, 2, NULL, modenames);
|
int op = luaL_checkoption(L, 2, NULL, modenames);
|
||||||
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
|
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
|
||||||
int res = setvbuf(f, NULL, mode[op], (size_t)sz);
|
int res;
|
||||||
|
errno = 0;
|
||||||
|
res = setvbuf(f, NULL, mode[op], (size_t)sz);
|
||||||
return luaL_fileresult(L, res == 0, NULL);
|
return luaL_fileresult(L, res == 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int io_flush (lua_State *L) {
|
static int io_flush (lua_State *L) {
|
||||||
return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
|
FILE *f = getiofile(L, IO_OUTPUT);
|
||||||
|
errno = 0;
|
||||||
|
return luaL_fileresult(L, fflush(f) == 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int f_flush (lua_State *L) {
|
static int f_flush (lua_State *L) {
|
||||||
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
|
FILE *f = tofile(L);
|
||||||
|
errno = 0;
|
||||||
|
return luaL_fileresult(L, fflush(f) == 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -773,7 +786,7 @@ static const luaL_Reg meth[] = {
|
|||||||
** metamethods for file handles
|
** metamethods for file handles
|
||||||
*/
|
*/
|
||||||
static const luaL_Reg metameth[] = {
|
static const luaL_Reg metameth[] = {
|
||||||
{"__index", NULL}, /* place holder */
|
{"__index", NULL}, /* placeholder */
|
||||||
{"__gc", f_gc},
|
{"__gc", f_gc},
|
||||||
{"__close", f_gc},
|
{"__close", f_gc},
|
||||||
{"__tostring", f_tostring},
|
{"__tostring", f_tostring},
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ static lua_Number I2d (Rand64 x) {
|
|||||||
SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
|
SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
|
||||||
lua_Number res = (lua_Number)(sx) * scaleFIG;
|
lua_Number res = (lua_Number)(sx) * scaleFIG;
|
||||||
if (sx < 0)
|
if (sx < 0)
|
||||||
res += 1.0; /* correct the two's complement if negative */
|
res += l_mathop(1.0); /* correct the two's complement if negative */
|
||||||
lua_assert(0 <= res && res < 1);
|
lua_assert(0 <= res && res < 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
2
loslib.c
2
loslib.c
@@ -155,6 +155,7 @@ static int os_execute (lua_State *L) {
|
|||||||
|
|
||||||
static int os_remove (lua_State *L) {
|
static int os_remove (lua_State *L) {
|
||||||
const char *filename = luaL_checkstring(L, 1);
|
const char *filename = luaL_checkstring(L, 1);
|
||||||
|
errno = 0;
|
||||||
return luaL_fileresult(L, remove(filename) == 0, filename);
|
return luaL_fileresult(L, remove(filename) == 0, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +163,7 @@ static int os_remove (lua_State *L) {
|
|||||||
static int os_rename (lua_State *L) {
|
static int os_rename (lua_State *L) {
|
||||||
const char *fromname = luaL_checkstring(L, 1);
|
const char *fromname = luaL_checkstring(L, 1);
|
||||||
const char *toname = luaL_checkstring(L, 2);
|
const char *toname = luaL_checkstring(L, 2);
|
||||||
|
errno = 0;
|
||||||
return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
|
return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ static int new_localvar (LexState *ls, TString *name) {
|
|||||||
checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
|
checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
|
||||||
MAXVARS, "local variables");
|
MAXVARS, "local variables");
|
||||||
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
|
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
|
||||||
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
|
dyd->actvar.size, Vardesc, SHRT_MAX, "local variables");
|
||||||
var = &dyd->actvar.arr[dyd->actvar.n++];
|
var = &dyd->actvar.arr[dyd->actvar.n++];
|
||||||
var->vd.kind = VDKREG; /* default */
|
var->vd.kind = VDKREG; /* default */
|
||||||
var->vd.name = name;
|
var->vd.name = name;
|
||||||
@@ -849,12 +849,11 @@ static void recfield (LexState *ls, ConsControl *cc) {
|
|||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int reg = ls->fs->freereg;
|
int reg = ls->fs->freereg;
|
||||||
expdesc tab, key, val;
|
expdesc tab, key, val;
|
||||||
if (ls->t.token == TK_NAME) {
|
if (ls->t.token == TK_NAME)
|
||||||
checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
|
|
||||||
codename(ls, &key);
|
codename(ls, &key);
|
||||||
}
|
|
||||||
else /* ls->t.token == '[' */
|
else /* ls->t.token == '[' */
|
||||||
yindex(ls, &key);
|
yindex(ls, &key);
|
||||||
|
checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
|
||||||
cc->nh++;
|
cc->nh++;
|
||||||
checknext(ls, '=');
|
checknext(ls, '=');
|
||||||
tab = *cc->t;
|
tab = *cc->t;
|
||||||
|
|||||||
5
lstate.c
5
lstate.c
@@ -166,7 +166,7 @@ void luaE_checkcstack (lua_State *L) {
|
|||||||
if (getCcalls(L) == LUAI_MAXCCALLS)
|
if (getCcalls(L) == LUAI_MAXCCALLS)
|
||||||
luaG_runerror(L, "C stack overflow");
|
luaG_runerror(L, "C stack overflow");
|
||||||
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
||||||
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
luaD_errerr(L); /* error while handling stack error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -272,7 +272,9 @@ static void close_state (lua_State *L) {
|
|||||||
luaC_freeallobjects(L); /* just collect its objects */
|
luaC_freeallobjects(L); /* just collect its objects */
|
||||||
else { /* closing a fully built state */
|
else { /* closing a fully built state */
|
||||||
L->ci = &L->base_ci; /* unwind CallInfo list */
|
L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||||
|
L->errfunc = 0; /* stack unwind can "throw away" the error function */
|
||||||
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
||||||
|
L->top.p = L->stack.p + 1; /* empty the stack to run finalizers */
|
||||||
luaC_freeallobjects(L); /* collect all objects */
|
luaC_freeallobjects(L); /* collect all objects */
|
||||||
luai_userstateclose(L);
|
luai_userstateclose(L);
|
||||||
}
|
}
|
||||||
@@ -328,6 +330,7 @@ int luaE_resetthread (lua_State *L, int status) {
|
|||||||
if (status == LUA_YIELD)
|
if (status == LUA_YIELD)
|
||||||
status = LUA_OK;
|
status = LUA_OK;
|
||||||
L->status = LUA_OK; /* so it can run __close metamethods */
|
L->status = LUA_OK; /* so it can run __close metamethods */
|
||||||
|
L->errfunc = 0; /* stack unwind can "throw away" the error function */
|
||||||
status = luaD_closeprotected(L, 1, status);
|
status = luaD_closeprotected(L, 1, status);
|
||||||
if (status != LUA_OK) /* errors? */
|
if (status != LUA_OK) /* errors? */
|
||||||
luaD_seterrorobj(L, status, L->stack.p + 1);
|
luaD_seterrorobj(L, status, L->stack.p + 1);
|
||||||
|
|||||||
8
ltests.c
8
ltests.c
@@ -1650,6 +1650,14 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
|||||||
int nres;
|
int nres;
|
||||||
status = lua_resume(lua_tothread(L1, i), L, getnum, &nres);
|
status = lua_resume(lua_tothread(L1, i), L, getnum, &nres);
|
||||||
}
|
}
|
||||||
|
else if EQ("traceback") {
|
||||||
|
const char *msg = getstring;
|
||||||
|
int level = getnum;
|
||||||
|
luaL_traceback(L1, L1, msg, level);
|
||||||
|
}
|
||||||
|
else if EQ("threadstatus") {
|
||||||
|
lua_pushstring(L1, statcodes[lua_status(L1)]);
|
||||||
|
}
|
||||||
else if EQ("return") {
|
else if EQ("return") {
|
||||||
int n = getnum;
|
int n = getnum;
|
||||||
if (L1 != L) {
|
if (L1 != L) {
|
||||||
|
|||||||
20
lua.c
20
lua.c
@@ -115,12 +115,13 @@ static void l_message (const char *pname, const char *msg) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Check whether 'status' is not OK and, if so, prints the error
|
** Check whether 'status' is not OK and, if so, prints the error
|
||||||
** message on the top of the stack. It assumes that the error object
|
** message on the top of the stack.
|
||||||
** is a string, as it was either generated by Lua or by 'msghandler'.
|
|
||||||
*/
|
*/
|
||||||
static int report (lua_State *L, int status) {
|
static int report (lua_State *L, int status) {
|
||||||
if (status != LUA_OK) {
|
if (status != LUA_OK) {
|
||||||
const char *msg = lua_tostring(L, -1);
|
const char *msg = lua_tostring(L, -1);
|
||||||
|
if (msg == NULL)
|
||||||
|
msg = "(error message not a string)";
|
||||||
l_message(progname, msg);
|
l_message(progname, msg);
|
||||||
lua_pop(L, 1); /* remove message */
|
lua_pop(L, 1); /* remove message */
|
||||||
}
|
}
|
||||||
@@ -211,7 +212,7 @@ static int dostring (lua_State *L, const char *s, const char *name) {
|
|||||||
/*
|
/*
|
||||||
** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
|
** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
|
||||||
** If there is no explicit modname and globname contains a '-', cut
|
** If there is no explicit modname and globname contains a '-', cut
|
||||||
** the sufix after '-' (the "version") to make the global name.
|
** the suffix after '-' (the "version") to make the global name.
|
||||||
*/
|
*/
|
||||||
static int dolibrary (lua_State *L, char *globname) {
|
static int dolibrary (lua_State *L, char *globname) {
|
||||||
int status;
|
int status;
|
||||||
@@ -230,7 +231,7 @@ static int dolibrary (lua_State *L, char *globname) {
|
|||||||
status = docall(L, 1, 1); /* call 'require(modname)' */
|
status = docall(L, 1, 1); /* call 'require(modname)' */
|
||||||
if (status == LUA_OK) {
|
if (status == LUA_OK) {
|
||||||
if (suffix != NULL) /* is there a suffix mark? */
|
if (suffix != NULL) /* is there a suffix mark? */
|
||||||
*suffix = '\0'; /* remove sufix from global name */
|
*suffix = '\0'; /* remove suffix from global name */
|
||||||
lua_setglobal(L, globname); /* globname = require(modname) */
|
lua_setglobal(L, globname); /* globname = require(modname) */
|
||||||
}
|
}
|
||||||
return report(L, status);
|
return report(L, status);
|
||||||
@@ -489,10 +490,8 @@ static int incomplete (lua_State *L, int status) {
|
|||||||
if (status == LUA_ERRSYNTAX) {
|
if (status == LUA_ERRSYNTAX) {
|
||||||
size_t lmsg;
|
size_t lmsg;
|
||||||
const char *msg = lua_tolstring(L, -1, &lmsg);
|
const char *msg = lua_tolstring(L, -1, &lmsg);
|
||||||
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
|
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0)
|
||||||
lua_pop(L, 1);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0; /* else... */
|
return 0; /* else... */
|
||||||
}
|
}
|
||||||
@@ -507,9 +506,9 @@ static int pushline (lua_State *L, int firstline) {
|
|||||||
size_t l;
|
size_t l;
|
||||||
const char *prmt = get_prompt(L, firstline);
|
const char *prmt = get_prompt(L, firstline);
|
||||||
int readstatus = lua_readline(L, b, prmt);
|
int readstatus = lua_readline(L, b, prmt);
|
||||||
if (readstatus == 0)
|
|
||||||
return 0; /* no input (prompt will be popped by caller) */
|
|
||||||
lua_pop(L, 1); /* remove prompt */
|
lua_pop(L, 1); /* remove prompt */
|
||||||
|
if (readstatus == 0)
|
||||||
|
return 0; /* no input */
|
||||||
l = strlen(b);
|
l = strlen(b);
|
||||||
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
|
||||||
b[--l] = '\0'; /* remove it */
|
b[--l] = '\0'; /* remove it */
|
||||||
@@ -551,8 +550,9 @@ static int multiline (lua_State *L) {
|
|||||||
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
|
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
|
||||||
if (!incomplete(L, status) || !pushline(L, 0)) {
|
if (!incomplete(L, status) || !pushline(L, 0)) {
|
||||||
lua_saveline(L, line); /* keep history */
|
lua_saveline(L, line); /* keep history */
|
||||||
return status; /* cannot or should not try to add continuation line */
|
return status; /* should not or cannot try to add continuation line */
|
||||||
}
|
}
|
||||||
|
lua_remove(L, -2); /* remove error message (from incomplete line) */
|
||||||
lua_pushliteral(L, "\n"); /* add newline... */
|
lua_pushliteral(L, "\n"); /* add newline... */
|
||||||
lua_insert(L, -2); /* ...between the two lines */
|
lua_insert(L, -2); /* ...between the two lines */
|
||||||
lua_concat(L, 3); /* join them */
|
lua_concat(L, 3); /* join them */
|
||||||
|
|||||||
40
lua.h
40
lua.h
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h $
|
** $Id: lua.h $
|
||||||
** Lua - A Scripting Language
|
** Lua - A Scripting Language
|
||||||
** Lua.org, PUC-Rio, Brazil (www.lua.org)
|
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||||
** See Copyright Notice at the end of this file
|
** See Copyright Notice at the end of this file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -13,21 +13,22 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio"
|
|
||||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
|
||||||
|
|
||||||
|
|
||||||
#define LUA_VERSION_MAJOR_N 5
|
|
||||||
#define LUA_VERSION_MINOR_N 4
|
|
||||||
#define LUA_VERSION_RELEASE_N 6
|
|
||||||
|
|
||||||
#define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N)
|
|
||||||
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N)
|
|
||||||
|
|
||||||
|
|
||||||
#include "luaconf.h"
|
#include "luaconf.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LUA_VERSION_MAJOR "5"
|
||||||
|
#define LUA_VERSION_MINOR "4"
|
||||||
|
#define LUA_VERSION_RELEASE "8"
|
||||||
|
|
||||||
|
#define LUA_VERSION_NUM 504
|
||||||
|
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 8)
|
||||||
|
|
||||||
|
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
||||||
|
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
||||||
|
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2025 Lua.org, PUC-Rio"
|
||||||
|
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
||||||
|
|
||||||
|
|
||||||
/* mark for precompiled code ('<esc>Lua') */
|
/* mark for precompiled code ('<esc>Lua') */
|
||||||
#define LUA_SIGNATURE "\x1bLua"
|
#define LUA_SIGNATURE "\x1bLua"
|
||||||
|
|
||||||
@@ -495,19 +496,8 @@ struct lua_Debug {
|
|||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
|
|
||||||
|
|
||||||
#define LUAI_TOSTRAUX(x) #x
|
|
||||||
#define LUAI_TOSTR(x) LUAI_TOSTRAUX(x)
|
|
||||||
|
|
||||||
#define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N)
|
|
||||||
#define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N)
|
|
||||||
#define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N)
|
|
||||||
|
|
||||||
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
|
||||||
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Copyright (C) 1994-2023 Lua.org, PUC-Rio.
|
* Copyright (C) 1994-2025 Lua.org, PUC-Rio.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|||||||
@@ -261,7 +261,7 @@
|
|||||||
/*
|
/*
|
||||||
** LUA_IGMARK is a mark to ignore all after it when building the
|
** LUA_IGMARK is a mark to ignore all after it when building the
|
||||||
** module name (e.g., used to build the luaopen_ function name).
|
** module name (e.g., used to build the luaopen_ function name).
|
||||||
** Typically, the sufix after the mark is the module version,
|
** Typically, the suffix after the mark is the module version,
|
||||||
** as in "mod-v1.2.so".
|
** as in "mod-v1.2.so".
|
||||||
*/
|
*/
|
||||||
#define LUA_IGMARK "-"
|
#define LUA_IGMARK "-"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
/*
|
/*
|
||||||
** Encode major-minor version in one byte, one nibble for each
|
** Encode major-minor version in one byte, one nibble for each
|
||||||
*/
|
*/
|
||||||
#define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N)
|
#define LUAC_VERSION (((LUA_VERSION_NUM / 100) * 16) + LUA_VERSION_NUM % 100)
|
||||||
|
|
||||||
#define LUAC_FORMAT 0 /* this is the official format */
|
#define LUAC_FORMAT 0 /* this is the official format */
|
||||||
|
|
||||||
|
|||||||
5
lvm.c
5
lvm.c
@@ -92,7 +92,7 @@ static int l_strton (const TValue *obj, TValue *result) {
|
|||||||
if (!cvt2num(obj)) /* is object not a string? */
|
if (!cvt2num(obj)) /* is object not a string? */
|
||||||
return 0;
|
return 0;
|
||||||
else {
|
else {
|
||||||
TString *st = tsvalue(obj);
|
TString *st = tsvalue(obj);
|
||||||
return (luaO_str2num(getstr(st), result) == tsslen(st) + 1);
|
return (luaO_str2num(getstr(st), result) == tsslen(st) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +339,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
|
|||||||
lua_assert(isempty(slot)); /* slot must be empty */
|
lua_assert(isempty(slot)); /* slot must be empty */
|
||||||
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
|
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
|
||||||
if (tm == NULL) { /* no metamethod? */
|
if (tm == NULL) { /* no metamethod? */
|
||||||
|
sethvalue2s(L, L->top.p, h); /* anchor 't' */
|
||||||
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
luaH_finishset(L, h, key, slot, val); /* set new value */
|
luaH_finishset(L, h, key, slot, val); /* set new value */
|
||||||
|
L->top.p--;
|
||||||
invalidateTMcache(h);
|
invalidateTMcache(h);
|
||||||
luaC_barrierback(L, obj2gco(h), val);
|
luaC_barrierback(L, obj2gco(h), val);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
|
|||||||
<p>
|
<p>
|
||||||
<small>
|
<small>
|
||||||
<a href="http://www.lua.org/copyright.html">Copyright</a>
|
<a href="http://www.lua.org/copyright.html">Copyright</a>
|
||||||
© 2023 Lua.org, PUC-Rio. All rights reserved.
|
© 2025 Lua.org, PUC-Rio. All rights reserved.
|
||||||
</small>
|
</small>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ Whenever there is an error,
|
|||||||
an @def{error object}
|
an @def{error object}
|
||||||
is propagated with information about the error.
|
is propagated with information about the error.
|
||||||
Lua itself only generates errors whose error object is a string,
|
Lua itself only generates errors whose error object is a string,
|
||||||
but programs may generate errors with
|
but programs can generate errors with
|
||||||
any value as the error object.
|
any value as the error object.
|
||||||
It is up to the Lua program or its host to handle such error objects.
|
It is up to the Lua program or its host to handle such error objects.
|
||||||
For historical reasons,
|
For historical reasons,
|
||||||
@@ -298,7 +298,7 @@ even though it does not have to be a string.
|
|||||||
|
|
||||||
|
|
||||||
When you use @Lid{xpcall} (or @Lid{lua_pcall}, in C)
|
When you use @Lid{xpcall} (or @Lid{lua_pcall}, in C)
|
||||||
you may give a @def{message handler}
|
you can give a @def{message handler}
|
||||||
to be called in case of errors.
|
to be called in case of errors.
|
||||||
This function is called with the original error object
|
This function is called with the original error object
|
||||||
and returns a new error object.
|
and returns a new error object.
|
||||||
@@ -343,7 +343,7 @@ which is then called a @def{metamethod}.
|
|||||||
In the previous example, the key is the string @St{__add}
|
In the previous example, the key is the string @St{__add}
|
||||||
and the metamethod is the function that performs the addition.
|
and the metamethod is the function that performs the addition.
|
||||||
Unless stated otherwise,
|
Unless stated otherwise,
|
||||||
a metamethod may in fact be any @x{callable value},
|
a metamethod can in fact be any @x{callable value},
|
||||||
which is either a function or a value with a @idx{__call} metamethod.
|
which is either a function or a value with a @idx{__call} metamethod.
|
||||||
|
|
||||||
You can query the metatable of any value
|
You can query the metatable of any value
|
||||||
@@ -1417,7 +1417,7 @@ labels in Lua are considered statements too:
|
|||||||
|
|
||||||
A label is visible in the entire block where it is defined,
|
A label is visible in the entire block where it is defined,
|
||||||
except inside nested functions.
|
except inside nested functions.
|
||||||
A goto may jump to any visible label as long as it does not
|
A goto can jump to any visible label as long as it does not
|
||||||
enter into the scope of a local variable.
|
enter into the scope of a local variable.
|
||||||
A label should not be declared
|
A label should not be declared
|
||||||
where a label with the same name is visible,
|
where a label with the same name is visible,
|
||||||
@@ -4416,7 +4416,7 @@ otherwise, returns @id{NULL}.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@APIEntry{void lua_toclose (lua_State *L, int index);|
|
@APIEntry{void lua_toclose (lua_State *L, int index);|
|
||||||
@apii{0,0,m}
|
@apii{0,0,v}
|
||||||
|
|
||||||
Marks the given index in the stack as a
|
Marks the given index in the stack as a
|
||||||
to-be-closed slot @see{to-be-closed}.
|
to-be-closed slot @see{to-be-closed}.
|
||||||
@@ -4433,6 +4433,9 @@ A slot marked as to-be-closed should not be removed from the stack
|
|||||||
by any other function in the API except @Lid{lua_settop} or @Lid{lua_pop},
|
by any other function in the API except @Lid{lua_settop} or @Lid{lua_pop},
|
||||||
unless previously deactivated by @Lid{lua_closeslot}.
|
unless previously deactivated by @Lid{lua_closeslot}.
|
||||||
|
|
||||||
|
This function raises an error if the value at the given slot
|
||||||
|
neither has a @idx{__close} metamethod nor is a false value.
|
||||||
|
|
||||||
This function should not be called for an index
|
This function should not be called for an index
|
||||||
that is equal to or below an active to-be-closed slot.
|
that is equal to or below an active to-be-closed slot.
|
||||||
|
|
||||||
@@ -4488,7 +4491,7 @@ but can contain other zeros in its body.
|
|||||||
|
|
||||||
This function can raise memory errors only
|
This function can raise memory errors only
|
||||||
when converting a number to a string
|
when converting a number to a string
|
||||||
(as then it has to create a new string).
|
(as then it may create a new string).
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8773,13 +8776,13 @@ The returned table can contain all the fields returned by @Lid{lua_getinfo},
|
|||||||
with the string @id{what} describing which fields to fill in.
|
with the string @id{what} describing which fields to fill in.
|
||||||
The default for @id{what} is to get all information available,
|
The default for @id{what} is to get all information available,
|
||||||
except the table of valid lines.
|
except the table of valid lines.
|
||||||
If present,
|
The option @Char{f}
|
||||||
the option @Char{f}
|
|
||||||
adds a field named @id{func} with the function itself.
|
adds a field named @id{func} with the function itself.
|
||||||
If present,
|
The option @Char{L} adds a field named @id{activelines}
|
||||||
the option @Char{L}
|
with the table of valid lines,
|
||||||
adds a field named @id{activelines} with the table of
|
provided the function is a Lua function.
|
||||||
valid lines.
|
If the function has no debug information,
|
||||||
|
the table is empty.
|
||||||
|
|
||||||
For instance, the expression @T{debug.getinfo(1,"n").name} returns
|
For instance, the expression @T{debug.getinfo(1,"n").name} returns
|
||||||
a name for the current function,
|
a name for the current function,
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ print("final OK !!!")
|
|||||||
|
|
||||||
--[[
|
--[[
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
|
* Copyright (C) 1994-2025 Lua.org, PUC-Rio.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|||||||
@@ -399,6 +399,10 @@ do
|
|||||||
-- trivial error
|
-- trivial error
|
||||||
assert(T.checkpanic("pushstring hi; error") == "hi")
|
assert(T.checkpanic("pushstring hi; error") == "hi")
|
||||||
|
|
||||||
|
-- thread status inside panic (bug in 5.4.4)
|
||||||
|
assert(T.checkpanic("pushstring hi; error", "threadstatus; return 2") ==
|
||||||
|
"ERRRUN")
|
||||||
|
|
||||||
-- using the stack inside panic
|
-- using the stack inside panic
|
||||||
assert(T.checkpanic("pushstring hi; error;",
|
assert(T.checkpanic("pushstring hi; error;",
|
||||||
[[checkstack 5 XX
|
[[checkstack 5 XX
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
|
|
||||||
print "testing closures"
|
print "testing closures"
|
||||||
|
|
||||||
|
do -- bug in 5.4.7
|
||||||
|
_ENV[true] = 10
|
||||||
|
local function aux () return _ENV[1 < 2] end
|
||||||
|
assert(aux() == 10)
|
||||||
|
_ENV[true] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local A,B = 0,{g=10}
|
local A,B = 0,{g=10}
|
||||||
local function f(x)
|
local function f(x)
|
||||||
local a = {}
|
local a = {}
|
||||||
|
|||||||
@@ -493,6 +493,25 @@ assert(not pcall(a, a))
|
|||||||
a = nil
|
a = nil
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- bug in 5.4: thread can use message handler higher in the stack
|
||||||
|
-- than the variable being closed
|
||||||
|
local c = coroutine.create(function()
|
||||||
|
local clo <close> = setmetatable({}, {__close=function()
|
||||||
|
local x = 134 -- will overwrite message handler
|
||||||
|
error(x)
|
||||||
|
end})
|
||||||
|
-- yields coroutine but leaves a new message handler for it,
|
||||||
|
-- that would be used when closing the coroutine (except that it
|
||||||
|
-- will be overwritten)
|
||||||
|
xpcall(coroutine.yield, function() return "XXX" end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert(coroutine.resume(c)) -- start coroutine
|
||||||
|
local st, msg = coroutine.close(c)
|
||||||
|
assert(not st and msg == 134)
|
||||||
|
end
|
||||||
|
|
||||||
-- access to locals of erroneous coroutines
|
-- access to locals of erroneous coroutines
|
||||||
local x = coroutine.create (function ()
|
local x = coroutine.create (function ()
|
||||||
local a = 10
|
local a = 10
|
||||||
|
|||||||
@@ -49,6 +49,15 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- bug in 5.4.4-5.4.6: activelines in vararg functions
|
||||||
|
-- without debug information
|
||||||
|
do
|
||||||
|
local func = load(string.dump(load("print(10)"), true))
|
||||||
|
local actl = debug.getinfo(func, "L").activelines
|
||||||
|
assert(#actl == 0) -- no line info
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- test file and string names truncation
|
-- test file and string names truncation
|
||||||
local a = "function f () end"
|
local a = "function f () end"
|
||||||
local function dostring (s, x) return load(s, x)() end
|
local function dostring (s, x) return load(s, x)() end
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ end
|
|||||||
|
|
||||||
if not T then
|
if not T then
|
||||||
(Message or print)
|
(Message or print)
|
||||||
('\n >>> testC not active: skipping memory message test <<<\n')
|
('\n >>> testC not active: skipping tests for messages in C <<<\n')
|
||||||
else
|
else
|
||||||
print "testing memory error message"
|
print "testing memory error message"
|
||||||
local a = {}
|
local a = {}
|
||||||
@@ -104,6 +104,19 @@ else
|
|||||||
end)
|
end)
|
||||||
T.totalmem(0)
|
T.totalmem(0)
|
||||||
assert(not st and msg == "not enough" .. " memory")
|
assert(not st and msg == "not enough" .. " memory")
|
||||||
|
|
||||||
|
-- stack space for luaL_traceback (bug in 5.4.6)
|
||||||
|
local res = T.testC[[
|
||||||
|
# push 16 elements on the stack
|
||||||
|
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
|
||||||
|
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
|
||||||
|
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
|
||||||
|
pushnum 1;
|
||||||
|
# traceback should work with 4 remaining slots
|
||||||
|
traceback xuxu 1;
|
||||||
|
return 1
|
||||||
|
]]
|
||||||
|
assert(string.find(res, "xuxu.-main chunk"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -124,6 +137,10 @@ checkmessage("aaa=(1)..{}", "a table value")
|
|||||||
-- bug in 5.4.6
|
-- bug in 5.4.6
|
||||||
checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
|
checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
|
||||||
|
|
||||||
|
-- a similar bug in 5.4.7, since 5.4.0
|
||||||
|
checkmessage("print(('_ENV').x + 1)", "field 'x'")
|
||||||
|
|
||||||
|
|
||||||
_G.aaa, _G.bbbb = nil
|
_G.aaa, _G.bbbb = nil
|
||||||
|
|
||||||
-- calls
|
-- calls
|
||||||
|
|||||||
@@ -370,6 +370,19 @@ x = 0 .."a".."b"..c..d.."e".."f".."g"
|
|||||||
assert(x.val == "0abcdefg")
|
assert(x.val == "0abcdefg")
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- bug since 5.4.1
|
||||||
|
local mt = setmetatable({__newindex={}}, {__mode='v'})
|
||||||
|
local t = setmetatable({}, mt)
|
||||||
|
|
||||||
|
if T then T.allocfailnext() end
|
||||||
|
|
||||||
|
-- seg. fault
|
||||||
|
for i=1, 10 do t[i] = 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- concat metamethod x numbers (bug in 5.1.1)
|
-- concat metamethod x numbers (bug in 5.1.1)
|
||||||
c = {}
|
c = {}
|
||||||
local x
|
local x
|
||||||
|
|||||||
@@ -349,6 +349,11 @@ prepfile("a = [[b\nc\nd\ne]]\n=a")
|
|||||||
RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
|
RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
|
||||||
checkprogout("b\nc\nd\ne\n\n")
|
checkprogout("b\nc\nd\ne\n\n")
|
||||||
|
|
||||||
|
-- input interrupted in continuation line
|
||||||
|
prepfile("a.\n")
|
||||||
|
RUN([[lua -i < %s > /dev/null 2> %s]], prog, out)
|
||||||
|
checkprogout("near <eof>\n")
|
||||||
|
|
||||||
local prompt = "alo"
|
local prompt = "alo"
|
||||||
prepfile[[ --
|
prepfile[[ --
|
||||||
a = 2
|
a = 2
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu")
|
|||||||
|
|
||||||
-- Adapt a pattern to UTF-8
|
-- Adapt a pattern to UTF-8
|
||||||
local function PU (p)
|
local function PU (p)
|
||||||
-- break '?' into each individual byte of a character
|
-- reapply '?' into each individual byte of a character.
|
||||||
|
-- (For instance, "á?" becomes "\195?\161?".)
|
||||||
p = string.gsub(p, "(" .. utf8.charpattern .. ")%?", function (c)
|
p = string.gsub(p, "(" .. utf8.charpattern .. ")%?", function (c)
|
||||||
return string.gsub(c, ".", "%0?")
|
return string.gsub(c, ".", "%0?")
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user