diff --git a/changelog.md b/changelog.md index 04cf891ce882..f475312844df 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,8 @@ ### Campaigns ### Editor ### Multiplayer + ### Lua API + * Upgrade to Lua 5.3.6. ### Packaging ### Terrain ### Translations diff --git a/src/lua/COPYRIGHT b/src/lua/COPYRIGHT index dda38f35f123..64834b625a6a 100644 --- a/src/lua/COPYRIGHT +++ b/src/lua/COPYRIGHT @@ -8,7 +8,7 @@ and commercial purposes at absolutely no cost. For details and rationale, see http://www.lua.org/license.html . /****************************************************************************** -* Copyright (C) 1994-2018 Lua.org, PUC-Rio. +* Copyright (C) 1994-2020 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/src/lua/lapi.cpp b/src/lua/lapi.cpp index 02b7fab7ead7..711895b395b6 100644 --- a/src/lua/lapi.cpp +++ b/src/lua/lapi.cpp @@ -1254,13 +1254,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { +static UpVal **getupvalref (lua_State *L, int fidx, int n) { LClosure *f; StkId fi = index2addr(L, fidx); api_check(L, ttisLclosure(fi), "Lua function expected"); f = clLvalue(fi); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (pf) *pf = f; return &f->upvals[n - 1]; /* get its upvalue pointer */ } @@ -1269,7 +1268,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { StkId fi = index2addr(L, fidx); switch (ttype(fi)) { case LUA_TLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); + return *getupvalref(L, fidx, n); } case LUA_TCCL: { /* C closure */ CClosure *f = clCvalue(fi); @@ -1286,9 +1285,10 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + UpVal **up1 = getupvalref(L, fidx1, n1); + UpVal **up2 = getupvalref(L, fidx2, n2); + if (*up1 == *up2) + return; luaC_upvdeccount(L, *up1); *up1 = *up2; (*up1)->refcount++; diff --git a/src/lua/lauxlib.cpp b/src/lua/lauxlib.cpp index 8bdada50a7eb..ac68bd32da90 100644 --- a/src/lua/lauxlib.cpp +++ b/src/lua/lauxlib.cpp @@ -1011,8 +1011,13 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { free(ptr); return NULL; } - else - return realloc(ptr, nsize); + else { /* cannot fail when shrinking a block */ + void *newptr = realloc(ptr, nsize); + if (newptr == NULL && ptr != NULL && nsize <= osize) + return ptr; /* keep the original block */ + else /* no fail or not shrinking */ + return newptr; /* use the new block */ + } } diff --git a/src/lua/lcode.cpp b/src/lua/lcode.cpp index 12619f54a027..dc7271d61419 100644 --- a/src/lua/lcode.cpp +++ b/src/lua/lcode.cpp @@ -1061,7 +1061,7 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { /* -** Aplly prefix operation 'op' to expression 'e'. +** Apply prefix operation 'op' to expression 'e'. */ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; diff --git a/src/lua/ldebug.cpp b/src/lua/ldebug.cpp index e1389296e9e5..bb0e1d4aceda 100644 --- a/src/lua/ldebug.cpp +++ b/src/lua/ldebug.cpp @@ -133,10 +133,11 @@ static const char *upvalname (Proto *p, int uv) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) { int nparams = clLvalue(ci->func)->p->numparams; - if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; + if (n <= -nvararg) return NULL; /* no such vararg */ else { - *pos = ci->func + nparams + n; + *pos = ci->func + nparams - n; return "(*vararg)"; /* generic name for any vararg */ } } @@ -148,7 +149,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, StkId base; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); + return findvararg(ci, n, pos); else { base = ci->u.l.base; name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); diff --git a/src/lua/liolib.cpp b/src/lua/liolib.cpp index 8a9e75cd089a..027d4bd0db45 100644 --- a/src/lua/liolib.cpp +++ b/src/lua/liolib.cpp @@ -277,6 +277,8 @@ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); + luaL_argcheck(L, ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0'), + 2, "invalid mode"); p->f = l_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; diff --git a/src/lua/llex.cpp b/src/lua/llex.cpp index 66fd411ba9d8..b6d9a465fe44 100644 --- a/src/lua/llex.cpp +++ b/src/lua/llex.cpp @@ -244,12 +244,12 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { /* -** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return -** its number of '='s; otherwise, return a negative number (-1 iff there -** are no '='s after initial bracket) +** 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 '[==...'). */ -static int skip_sep (LexState *ls) { - int count = 0; +static size_t skip_sep (LexState *ls) { + size_t count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); @@ -257,11 +257,14 @@ static int skip_sep (LexState *ls) { save_and_next(ls); count++; } - return (ls->current == s) ? count : (-count) - 1; + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; + } -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { int line = ls->linenumber; /* initial line (for error message) */ save_and_next(ls); /* skip 2nd '[' */ if (currIsNewline(ls)) /* string starts with a newline? */ @@ -295,8 +298,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } } endloop: if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); } @@ -444,9 +447,9 @@ static int llex (LexState *ls, SemInfo *seminfo) { /* else is a comment */ next(ls); if (ls->current == '[') { /* long comment? */ - int sep = skip_sep(ls); + size_t sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ - if (sep >= 0) { + if (sep >= 2) { read_long_string(ls, NULL, sep); /* skip long comment */ luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ break; @@ -458,12 +461,12 @@ static int llex (LexState *ls, SemInfo *seminfo) { break; } case '[': { /* long string or simply '[' */ - int sep = skip_sep(ls); - if (sep >= 0) { + size_t sep = skip_sep(ls); + if (sep >= 2) { read_long_string(ls, seminfo, sep); return TK_STRING; } - else if (sep != -1) /* '[=...' missing second bracket */ + else if (sep == 0) /* '[=...' missing second bracket */ lexerror(ls, "invalid long string delimiter", TK_STRING); return '['; } diff --git a/src/lua/lobject.cpp b/src/lua/lobject.cpp index 2218c8cdd771..355bf58d6372 100644 --- a/src/lua/lobject.cpp +++ b/src/lua/lobject.cpp @@ -266,7 +266,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) ** - '.' just optimizes the search for the common case (nothing special) ** This function accepts both the current locale or a dot as the radix -** mark. If the convertion fails, it may mean number has a dot but +** mark. If the conversion fails, it may mean number has a dot but ** locale accepts something else. In that case, the code copies 's' ** to a buffer (because 's' is read-only), changes the dot to the ** current locale radix mark, and tries to convert again. diff --git a/src/lua/lparser.cpp b/src/lua/lparser.cpp index cc54de43c634..2f41e00b803d 100644 --- a/src/lua/lparser.cpp +++ b/src/lua/lparser.cpp @@ -544,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->bl = NULL; f = fs->f; f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ enterblock(fs, bl, 0); } @@ -1616,6 +1617,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { fs->f->is_vararg = 1; /* main function is always declared vararg */ init_exp(&v, VLOCAL, 0); /* create and... */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaC_objbarrier(ls->L, fs->f, ls->envn); luaX_next(ls); /* read first token */ statlist(ls); /* parse main body */ check(ls, TK_EOS); @@ -1634,6 +1636,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, sethvalue(L, L->top, lexstate.h); /* anchor it */ luaD_inctop(L); funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lexstate.buff = buff; diff --git a/src/lua/lua.h b/src/lua/lua.h index c236e3609579..9394c5ef8fd6 100644 --- a/src/lua/lua.h +++ b/src/lua/lua.h @@ -1,5 +1,4 @@ /* -** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -19,11 +18,11 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "3" #define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "5" +#define LUA_VERSION_RELEASE "6" #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-2018 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -460,7 +459,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2018 Lua.org, PUC-Rio. +* Copyright (C) 1994-2020 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/src/lua/luaconf.h b/src/lua/luaconf.h index ce322efcf6cd..9eeeea69e205 100644 --- a/src/lua/luaconf.h +++ b/src/lua/luaconf.h @@ -755,7 +755,11 @@ ** smaller buffer would force a memory allocation for each call to ** 'string.format'.) */ +#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE #define LUAL_BUFFERSIZE 8192 +#else +#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) +#endif /* }================================================================== */ diff --git a/src/lua/lundump.cpp b/src/lua/lundump.cpp index 7a67d75aaa04..edf9eb8d0089 100644 --- a/src/lua/lundump.cpp +++ b/src/lua/lundump.cpp @@ -85,8 +85,10 @@ static lua_Integer LoadInteger (LoadState *S) { } -static TString *LoadString (LoadState *S) { +static TString *LoadString (LoadState *S, Proto *p) { + lua_State *L = S->L; size_t size = LoadByte(S); + TString *ts; if (size == 0xFF) LoadVar(S, size); if (size == 0) @@ -94,13 +96,17 @@ static TString *LoadString (LoadState *S) { else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ char buff[LUAI_MAXSHORTLEN]; LoadVector(S, buff, size); - return luaS_newlstr(S->L, buff, size); + ts = luaS_newlstr(L, buff, size); } else { /* long string */ - TString *ts = luaS_createlngstrobj(S->L, size); + ts = luaS_createlngstrobj(L, size); + setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); LoadVector(S, getstr(ts), size); /* load directly in final place */ - return ts; + L->top--; /* pop string */ } + luaC_objbarrier(L, p, ts); + return ts; } @@ -140,7 +146,7 @@ static void LoadConstants (LoadState *S, Proto *f) { break; case LUA_TSHRSTR: case LUA_TLNGSTR: - setsvalue2n(S->L, o, LoadString(S)); + setsvalue2n(S->L, o, LoadString(S, f)); break; default: lua_assert(0); @@ -158,6 +164,7 @@ static void LoadProtos (LoadState *S, Proto *f) { f->p[i] = NULL; for (i = 0; i < n; i++) { f->p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, f->p[i]); LoadFunction(S, f->p[i], f->source); } } @@ -189,18 +196,18 @@ static void LoadDebug (LoadState *S, Proto *f) { for (i = 0; i < n; i++) f->locvars[i].varname = NULL; for (i = 0; i < n; i++) { - f->locvars[i].varname = LoadString(S); + f->locvars[i].varname = LoadString(S, f); f->locvars[i].startpc = LoadInt(S); f->locvars[i].endpc = LoadInt(S); } n = LoadInt(S); for (i = 0; i < n; i++) - f->upvalues[i].name = LoadString(S); + f->upvalues[i].name = LoadString(S, f); } static void LoadFunction (LoadState *S, Proto *f, TString *psource) { - f->source = LoadString(S); + f->source = LoadString(S, f); if (f->source == NULL) /* no source in dump? */ f->source = psource; /* reuse parent's source */ f->linedefined = LoadInt(S); @@ -271,6 +278,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { setclLvalue(L, L->top, cl); luaD_inctop(L); cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p); diff --git a/src/wesnoth_lua_config.md b/src/wesnoth_lua_config.md index 89155d315aee..3e427fe18367 100644 --- a/src/wesnoth_lua_config.md +++ b/src/wesnoth_lua_config.md @@ -1,6 +1,6 @@ # Lua for Wesnoth -This document describes the process used to install Lua 5.3.5 for Wesnoth. +This document describes the process used to install Lua 5.3.6 for Wesnoth. The goal of this process was, as much as possible, install clean, unchanged sources. Traditionally, Wesnoth maintainers have made changes directly to the Lua source kit. @@ -21,25 +21,25 @@ And be sure you are working in a private branch. $ cd ~/wesnoth $ git checkout master $ git pull --rebase upstream master - $ git checkout -b Upgrade_to_Lua-5.3.5 + $ git checkout -b Upgrade_to_Lua-5.3.6 ## 2) Update Lua Source Download the current source kit from [the Lua maintainers](http://www.lua.org). -For Lua 5.3.5, this was . +For Lua 5.3.6, this was . The following presumes you are working on Unix. Windows is a bit more work, but generally follows the same process. $ cd ~ - $ wget http://www.lua.org/ftp/lua-5.3.5.tar.gz + $ wget http://www.lua.org/ftp/lua-5.3.6.tar.gz Unpack into your home folder. - $ tar -zxf lua-5.3.5.tar.gz + $ tar -zxf lua-5.3.6.tar.gz Change into the Lua source folder. - $ cd ~/lua-5.3.5/src + $ cd ~/lua-5.3.6/src We do not need, or want, the Lua command line interpreter, the Lua compiler or the Makefile, so delete them. We compile using C++ so cannot allow the use of "C" linkage from the provided header. @@ -83,7 +83,7 @@ Updating the project files for other target platforms is optional at this point. $ cd ~/wesnoth $ git add . - $ git commit -m 'Upgrade to Lua 5.3.5' + $ git commit -m 'Upgrade to Lua 5.3.6' ## 6) Apply official patches