summaryrefslogtreecommitdiff
path: root/libs/lua
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-07-18 12:28:36 +0200
committerRobin Gareus <robin@gareus.org>2016-07-18 12:28:36 +0200
commitc5fb7e1d833b7fd4abf69d65981436abb480eee0 (patch)
tree91d02cb211c42276b6f2168aa1e34d56a1c609a7 /libs/lua
parentd527fdf30a565e11d39edea1183237e98d15a788 (diff)
update to lua-5.3.3
Diffstat (limited to 'libs/lua')
-rw-r--r--libs/lua/lua-5.3.3/README (renamed from libs/lua/lua-5.3.2/README)8
-rw-r--r--libs/lua/lua-5.3.3/lapi.c (renamed from libs/lua/lua-5.3.2/lapi.c)48
-rw-r--r--libs/lua/lua-5.3.3/lapi.h (renamed from libs/lua/lua-5.3.2/lapi.h)0
-rw-r--r--libs/lua/lua-5.3.3/lauxlib.c (renamed from libs/lua/lua-5.3.2/lauxlib.c)29
-rw-r--r--libs/lua/lua-5.3.3/lauxlib.h (renamed from libs/lua/lua-5.3.2/lauxlib.h)0
-rw-r--r--libs/lua/lua-5.3.3/lbaselib.c (renamed from libs/lua/lua-5.3.2/lbaselib.c)11
-rw-r--r--libs/lua/lua-5.3.3/lbitlib.c (renamed from libs/lua/lua-5.3.2/lbitlib.c)0
-rw-r--r--libs/lua/lua-5.3.3/lcode.c (renamed from libs/lua/lua-5.3.2/lcode.c)692
-rw-r--r--libs/lua/lua-5.3.3/lcode.h (renamed from libs/lua/lua-5.3.2/lcode.h)5
-rw-r--r--libs/lua/lua-5.3.3/lcorolib.c (renamed from libs/lua/lua-5.3.2/lcorolib.c)4
-rw-r--r--libs/lua/lua-5.3.3/lctype.c (renamed from libs/lua/lua-5.3.2/lctype.c)0
-rw-r--r--libs/lua/lua-5.3.3/lctype.h (renamed from libs/lua/lua-5.3.2/lctype.h)0
-rw-r--r--libs/lua/lua-5.3.3/ldblib.c (renamed from libs/lua/lua-5.3.2/ldblib.c)0
-rw-r--r--libs/lua/lua-5.3.3/ldebug.c (renamed from libs/lua/lua-5.3.2/ldebug.c)18
-rw-r--r--libs/lua/lua-5.3.3/ldebug.h (renamed from libs/lua/lua-5.3.2/ldebug.h)0
-rw-r--r--libs/lua/lua-5.3.3/ldo.c (renamed from libs/lua/lua-5.3.2/ldo.c)9
-rw-r--r--libs/lua/lua-5.3.3/ldo.h (renamed from libs/lua/lua-5.3.2/ldo.h)4
-rw-r--r--libs/lua/lua-5.3.3/ldump.c (renamed from libs/lua/lua-5.3.2/ldump.c)0
-rw-r--r--libs/lua/lua-5.3.3/lfunc.c (renamed from libs/lua/lua-5.3.2/lfunc.c)0
-rw-r--r--libs/lua/lua-5.3.3/lfunc.h (renamed from libs/lua/lua-5.3.2/lfunc.h)0
-rw-r--r--libs/lua/lua-5.3.3/lgc.c (renamed from libs/lua/lua-5.3.2/lgc.c)35
-rw-r--r--libs/lua/lua-5.3.3/lgc.h (renamed from libs/lua/lua-5.3.2/lgc.h)4
-rw-r--r--libs/lua/lua-5.3.3/linit.c (renamed from libs/lua/lua-5.3.2/linit.c)0
-rw-r--r--libs/lua/lua-5.3.3/liolib.c (renamed from libs/lua/lua-5.3.2/liolib.c)19
-rw-r--r--libs/lua/lua-5.3.3/llex.c (renamed from libs/lua/lua-5.3.2/llex.c)35
-rw-r--r--libs/lua/lua-5.3.3/llex.h (renamed from libs/lua/lua-5.3.2/llex.h)3
-rw-r--r--libs/lua/lua-5.3.3/llimits.h (renamed from libs/lua/lua-5.3.2/llimits.h)0
-rw-r--r--libs/lua/lua-5.3.3/lmathlib.c (renamed from libs/lua/lua-5.3.2/lmathlib.c)0
-rw-r--r--libs/lua/lua-5.3.3/lmem.c (renamed from libs/lua/lua-5.3.2/lmem.c)0
-rw-r--r--libs/lua/lua-5.3.3/lmem.h (renamed from libs/lua/lua-5.3.2/lmem.h)0
-rw-r--r--libs/lua/lua-5.3.3/loadlib.c (renamed from libs/lua/lua-5.3.2/loadlib.c)0
-rw-r--r--libs/lua/lua-5.3.3/lobject.c (renamed from libs/lua/lua-5.3.2/lobject.c)86
-rw-r--r--libs/lua/lua-5.3.3/lobject.h (renamed from libs/lua/lua-5.3.2/lobject.h)0
-rw-r--r--libs/lua/lua-5.3.3/lopcodes.c (renamed from libs/lua/lua-5.3.2/lopcodes.c)0
-rw-r--r--libs/lua/lua-5.3.3/lopcodes.h (renamed from libs/lua/lua-5.3.2/lopcodes.h)0
-rw-r--r--libs/lua/lua-5.3.3/loslib.c (renamed from libs/lua/lua-5.3.2/loslib.c)91
-rw-r--r--libs/lua/lua-5.3.3/lparser.c (renamed from libs/lua/lua-5.3.2/lparser.c)40
-rw-r--r--libs/lua/lua-5.3.3/lparser.h (renamed from libs/lua/lua-5.3.2/lparser.h)53
-rw-r--r--libs/lua/lua-5.3.3/lprefix.h (renamed from libs/lua/lua-5.3.2/lprefix.h)0
-rw-r--r--libs/lua/lua-5.3.3/lstate.c (renamed from libs/lua/lua-5.3.2/lstate.c)0
-rw-r--r--libs/lua/lua-5.3.3/lstate.h (renamed from libs/lua/lua-5.3.2/lstate.h)15
-rw-r--r--libs/lua/lua-5.3.3/lstring.c (renamed from libs/lua/lua-5.3.2/lstring.c)0
-rw-r--r--libs/lua/lua-5.3.3/lstring.h (renamed from libs/lua/lua-5.3.2/lstring.h)0
-rw-r--r--libs/lua/lua-5.3.3/lstrlib.c (renamed from libs/lua/lua-5.3.2/lstrlib.c)143
-rw-r--r--libs/lua/lua-5.3.3/ltable.c (renamed from libs/lua/lua-5.3.2/ltable.c)0
-rw-r--r--libs/lua/lua-5.3.3/ltable.h (renamed from libs/lua/lua-5.3.2/ltable.h)0
-rw-r--r--libs/lua/lua-5.3.3/ltablib.c (renamed from libs/lua/lua-5.3.2/ltablib.c)41
-rw-r--r--libs/lua/lua-5.3.3/ltm.c (renamed from libs/lua/lua-5.3.2/ltm.c)18
-rw-r--r--libs/lua/lua-5.3.3/ltm.h (renamed from libs/lua/lua-5.3.2/ltm.h)5
-rw-r--r--libs/lua/lua-5.3.3/lua.c (renamed from libs/lua/lua-5.3.2/lua.c)0
-rw-r--r--libs/lua/lua-5.3.3/lua.h (renamed from libs/lua/lua-5.3.2/lua.h)10
-rw-r--r--libs/lua/lua-5.3.3/lua.hpp (renamed from libs/lua/lua-5.3.2/lua.hpp)0
-rw-r--r--libs/lua/lua-5.3.3/luac.c (renamed from libs/lua/lua-5.3.2/luac.c)0
-rw-r--r--libs/lua/lua-5.3.3/luaconf.h (renamed from libs/lua/lua-5.3.2/luaconf.h)4
-rw-r--r--libs/lua/lua-5.3.3/lualib.h (renamed from libs/lua/lua-5.3.2/lualib.h)0
-rw-r--r--libs/lua/lua-5.3.3/lundump.c (renamed from libs/lua/lua-5.3.2/lundump.c)0
-rw-r--r--libs/lua/lua-5.3.3/lundump.h (renamed from libs/lua/lua-5.3.2/lundump.h)0
-rw-r--r--libs/lua/lua-5.3.3/lutf8lib.c (renamed from libs/lua/lua-5.3.2/lutf8lib.c)0
-rw-r--r--libs/lua/lua-5.3.3/lvm.c (renamed from libs/lua/lua-5.3.2/lvm.c)105
-rw-r--r--libs/lua/lua-5.3.3/lvm.h (renamed from libs/lua/lua-5.3.2/lvm.h)31
-rw-r--r--libs/lua/lua-5.3.3/lzio.c (renamed from libs/lua/lua-5.3.2/lzio.c)0
-rw-r--r--libs/lua/lua-5.3.3/lzio.h (renamed from libs/lua/lua-5.3.2/lzio.h)0
-rw-r--r--libs/lua/lua.cc76
63 files changed, 1014 insertions, 628 deletions
diff --git a/libs/lua/lua-5.3.2/README b/libs/lua/lua-5.3.3/README
index 0a1417863a..dd74fdf4b5 100644
--- a/libs/lua/lua-5.3.2/README
+++ b/libs/lua/lua-5.3.3/README
@@ -1,12 +1,14 @@
+This is Lua 5.3.3, released on 30 May 2016.
+
The Lua source is imported in the repository in order to ensure that it
is compiled with the same C++ compiler as Ardour (setjmp/longjmp, exceptions)
and available on all platforms that Ardour is.
-This directory contains files from src/ directory from lua-5.3.2.
-The original source can be downloaded from http://www.lua.org/ftp/
+This directory contains files from src/ directory from lua-5.3.3.
+The original source can be downloaded from https://www.lua.org/ftp/lua-5.3.3.tar.gz
-Copyright © 1994–2015 Lua.org, PUC-Rio.
+Copyright © 1994–2016 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 "Software"), to deal in
diff --git a/libs/lua/lua-5.3.2/lapi.c b/libs/lua/lua-5.3.3/lapi.c
index 9a6a3fbd0c..c9455a5d8c 100644
--- a/libs/lua/lua-5.3.2/lapi.c
+++ b/libs/lua/lua-5.3.3/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.257 2015/11/02 18:48:07 roberto Exp $
+** $Id: lapi.c,v 2.259 2016/02/29 14:27:14 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -378,9 +378,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
return NULL;
}
lua_lock(L); /* 'luaO_tostring' may create a new string */
+ luaO_tostring(L, o);
luaC_checkGC(L);
o = index2addr(L, idx); /* previous call may reallocate the stack */
- luaO_tostring(L, o);
lua_unlock(L);
}
if (len != NULL)
@@ -479,10 +479,10 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
TString *ts;
lua_lock(L);
- luaC_checkGC(L);
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
setsvalue2s(L, L->top, ts);
api_incr_top(L);
+ luaC_checkGC(L);
lua_unlock(L);
return getstr(ts);
}
@@ -494,12 +494,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
setnilvalue(L->top);
else {
TString *ts;
- luaC_checkGC(L);
ts = luaS_new(L, s);
setsvalue2s(L, L->top, ts);
s = getstr(ts); /* internal copy's address */
}
api_incr_top(L);
+ luaC_checkGC(L);
lua_unlock(L);
return s;
}
@@ -509,8 +509,8 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
va_list argp) {
const char *ret;
lua_lock(L);
- luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, argp);
+ luaC_checkGC(L);
lua_unlock(L);
return ret;
}
@@ -520,10 +520,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
const char *ret;
va_list argp;
lua_lock(L);
- luaC_checkGC(L);
va_start(argp, fmt);
ret = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
+ luaC_checkGC(L);
lua_unlock(L);
return ret;
}
@@ -538,7 +538,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
CClosure *cl;
api_checknelems(L, n);
api_check(L, n <= MAXUPVAL, "upvalue index too large");
- luaC_checkGC(L);
cl = luaF_newCclosure(L, n);
cl->f = fn;
L->top -= n;
@@ -549,6 +548,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
setclCvalue(L, L->top, cl);
}
api_incr_top(L);
+ luaC_checkGC(L);
lua_unlock(L);
}
@@ -585,16 +585,16 @@ LUA_API int lua_pushthread (lua_State *L) {
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
- const TValue *aux;
+ const TValue *slot;
TString *str = luaS_new(L, k);
- if (luaV_fastget(L, t, str, aux, luaH_getstr)) {
- setobj2s(L, L->top, aux);
+ if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
+ setobj2s(L, L->top, slot);
api_incr_top(L);
}
else {
setsvalue2s(L, L->top, str);
api_incr_top(L);
- luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
+ luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
}
lua_unlock(L);
return ttnov(L->top - 1);
@@ -626,17 +626,17 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
StkId t;
- const TValue *aux;
+ const TValue *slot;
lua_lock(L);
t = index2addr(L, idx);
- if (luaV_fastget(L, t, n, aux, luaH_getint)) {
- setobj2s(L, L->top, aux);
+ if (luaV_fastget(L, t, n, slot, luaH_getint)) {
+ setobj2s(L, L->top, slot);
api_incr_top(L);
}
else {
setivalue(L->top, n);
api_incr_top(L);
- luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
+ luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
}
lua_unlock(L);
return ttnov(L->top - 1);
@@ -683,12 +683,12 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
Table *t;
lua_lock(L);
- luaC_checkGC(L);
t = luaH_new(L);
sethvalue(L, L->top, t);
api_incr_top(L);
if (narray > 0 || nrec > 0)
luaH_resize(L, t, narray, nrec);
+ luaC_checkGC(L);
lua_unlock(L);
}
@@ -740,15 +740,15 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
** t[k] = value at the top of the stack (where 'k' is a string)
*/
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
- const TValue *aux;
+ const TValue *slot;
TString *str = luaS_new(L, k);
api_checknelems(L, 1);
- if (luaV_fastset(L, t, str, aux, luaH_getstr, L->top - 1))
+ if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
L->top--; /* pop value */
else {
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
api_incr_top(L);
- luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
+ luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
L->top -= 2; /* pop value and key */
}
lua_unlock(L); /* lock done by caller */
@@ -781,16 +781,16 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
StkId t;
- const TValue *aux;
+ const TValue *slot;
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
- if (luaV_fastset(L, t, n, aux, luaH_getint, L->top - 1))
+ if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
L->top--; /* pop value */
else {
setivalue(L->top, n);
api_incr_top(L);
- luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
+ luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
L->top -= 2; /* pop value and key */
}
lua_unlock(L);
@@ -1140,7 +1140,6 @@ LUA_API void lua_concat (lua_State *L, int n) {
lua_lock(L);
api_checknelems(L, n);
if (n >= 2) {
- luaC_checkGC(L);
luaV_concat(L, n);
}
else if (n == 0) { /* push empty string */
@@ -1148,6 +1147,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
api_incr_top(L);
}
/* else n == 1; nothing to do */
+ luaC_checkGC(L);
lua_unlock(L);
}
@@ -1183,10 +1183,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
lua_lock(L);
- luaC_checkGC(L);
u = luaS_newudata(L, size);
setuvalue(L, L->top, u);
api_incr_top(L);
+ luaC_checkGC(L);
lua_unlock(L);
return getudatamem(u);
}
diff --git a/libs/lua/lua-5.3.2/lapi.h b/libs/lua/lua-5.3.3/lapi.h
index 6d36dee3fb..6d36dee3fb 100644
--- a/libs/lua/lua-5.3.2/lapi.h
+++ b/libs/lua/lua-5.3.3/lapi.h
diff --git a/libs/lua/lua-5.3.2/lauxlib.c b/libs/lua/lua-5.3.3/lauxlib.c
index 5d362c35a2..bacf43b3e2 100644
--- a/libs/lua/lua-5.3.2/lauxlib.c
+++ b/libs/lua/lua-5.3.3/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.284 2015/11/19 19:16:22 roberto Exp $
+** $Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -17,7 +17,8 @@
#include <string.h>
-/* This file uses only the official API of Lua.
+/*
+** This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
*/
@@ -198,6 +199,10 @@ static void tag_error (lua_State *L, int arg, int tag) {
}
+/*
+** The use of 'lua_pushfstring' ensures this function does not
+** need reserved stack space when called.
+*/
LUALIB_API void luaL_where (lua_State *L, int level) {
lua_Debug ar;
if (lua_getstack(L, level, &ar)) { /* check function at level */
@@ -207,10 +212,15 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
return;
}
}
- lua_pushliteral(L, ""); /* else, no information available... */
+ lua_pushfstring(L, ""); /* else, no information available... */
}
+/*
+** Again, the use of 'lua_pushvfstring' ensures this function does
+** not need reserved stack space when called. (At worst, it generates
+** an error with "stack overflow" instead of the given message.)
+*/
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
@@ -349,10 +359,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
}
+/*
+** Ensures the stack has at least 'space' extra slots, raising an error
+** if it cannot fulfill the request. (The error handling needs a few
+** extra slots to format the error message. In case of an error without
+** this extra space, Lua will generate the same 'stack overflow' error,
+** but without 'msg'.)
+*/
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
- /* keep some extra space to run error routines, if needed */
- const int extra = LUA_MINSTACK;
- if (!lua_checkstack(L, space + extra)) {
+ if (!lua_checkstack(L, space)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
@@ -678,7 +693,7 @@ static int skipcomment (LoadF *lf, int *cp) {
if (c == '#') { /* first line is a comment (Unix exec. file)? */
do { /* skip first line */
c = getc(lf->f);
- } while (c != EOF && c != '\n') ;
+ } while (c != EOF && c != '\n');
*cp = getc(lf->f); /* skip end-of-line, if present */
return 1; /* there was a comment */
}
diff --git a/libs/lua/lua-5.3.2/lauxlib.h b/libs/lua/lua-5.3.3/lauxlib.h
index ddb7c22838..ddb7c22838 100644
--- a/libs/lua/lua-5.3.2/lauxlib.h
+++ b/libs/lua/lua-5.3.3/lauxlib.h
diff --git a/libs/lua/lua-5.3.2/lbaselib.c b/libs/lua/lua-5.3.3/lbaselib.c
index 861823d8c2..d481c4e1ef 100644
--- a/libs/lua/lua-5.3.2/lbaselib.c
+++ b/libs/lua/lua-5.3.3/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.312 2015/10/29 15:21:04 roberto Exp $
+** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -102,8 +102,8 @@ static int luaB_tonumber (lua_State *L) {
static int luaB_error (lua_State *L) {
int level = (int)luaL_optinteger(L, 2, 1);
lua_settop(L, 1);
- if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
- luaL_where(L, level);
+ if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
+ luaL_where(L, level); /* add extra information */
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
@@ -251,9 +251,8 @@ static int ipairsaux (lua_State *L) {
/*
-** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
-** traverse a table, depending on whether the table has metamethods
-** that can affect the traversal.
+** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
+** (The given "table" may not be a table.)
*/
static int luaB_ipairs (lua_State *L) {
#if defined(LUA_COMPAT_IPAIRS)
diff --git a/libs/lua/lua-5.3.2/lbitlib.c b/libs/lua/lua-5.3.3/lbitlib.c
index 1cb1d5b932..1cb1d5b932 100644
--- a/libs/lua/lua-5.3.2/lbitlib.c
+++ b/libs/lua/lua-5.3.3/lbitlib.c
diff --git a/libs/lua/lua-5.3.2/lcode.c b/libs/lua/lua-5.3.3/lcode.c
index 7c6918fda4..2cd0dd2d5c 100644
--- a/libs/lua/lua-5.3.2/lcode.c
+++ b/libs/lua/lua-5.3.3/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.103 2015/11/19 19:16:22 roberto Exp $
+** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -36,6 +36,10 @@
#define hasjumps(e) ((e)->t != (e)->f)
+/*
+** If expression is a numeric constant, fills 'v' with its value
+** and returns 1. Otherwise, returns 0.
+*/
static int tonumeral(expdesc *e, TValue *v) {
if (hasjumps(e))
return 0; /* not a numeral */
@@ -51,13 +55,19 @@ static int tonumeral(expdesc *e, TValue *v) {
}
+/*
+** Create a OP_LOADNIL instruction, but try to optimize: if the previous
+** instruction is also OP_LOADNIL and ranges are compatible, adjust
+** range of previous instruction instead of emitting a new one. (For
+** instance, 'local a; local b' will generate a single opcode.)
+*/
void luaK_nil (FuncState *fs, int from, int n) {
Instruction *previous;
int l = from + n - 1; /* last register to set nil */
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
previous = &fs->f->code[fs->pc-1];
- if (GET_OPCODE(*previous) == OP_LOADNIL) {
- int pfrom = GETARG_A(*previous);
+ if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */
+ int pfrom = GETARG_A(*previous); /* get previous range */
int pl = pfrom + GETARG_B(*previous);
if ((pfrom <= from && from <= pl + 1) ||
(from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
@@ -73,37 +83,84 @@ void luaK_nil (FuncState *fs, int from, int n) {
}
+/*
+** Gets the destination address of a jump instruction. Used to traverse
+** a list of jumps.
+*/
+static int getjump (FuncState *fs, int pc) {
+ int offset = GETARG_sBx(fs->f->code[pc]);
+ if (offset == NO_JUMP) /* point to itself represents end of list */
+ return NO_JUMP; /* end of list */
+ else
+ return (pc+1)+offset; /* turn offset into absolute position */
+}
+
+
+/*
+** Fix jump instruction at position 'pc' to jump to 'dest'.
+** (Jump addresses are relative in Lua)
+*/
+static void fixjump (FuncState *fs, int pc, int dest) {
+ Instruction *jmp = &fs->f->code[pc];
+ int offset = dest - (pc + 1);
+ lua_assert(dest != NO_JUMP);
+ if (abs(offset) > MAXARG_sBx)
+ luaX_syntaxerror(fs->ls, "control structure too long");
+ SETARG_sBx(*jmp, offset);
+}
+
+
+/*
+** Concatenate jump-list 'l2' into jump-list 'l1'
+*/
+void luaK_concat (FuncState *fs, int *l1, int l2) {
+ if (l2 == NO_JUMP) return; /* nothing to concatenate? */
+ else if (*l1 == NO_JUMP) /* no original list? */
+ *l1 = l2; /* 'l1' points to 'l2' */
+ else {
+ int list = *l1;
+ int next;
+ while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
+ list = next;
+ fixjump(fs, list, l2); /* last element links to 'l2' */
+ }
+}
+
+
+/*
+** Create a jump instruction and return its position, so its destination
+** can be fixed later (with 'fixjump'). If there are jumps to
+** this position (kept in 'jpc'), link them all together so that
+** 'patchlistaux' will fix all them directly to the final destination.
+*/
int luaK_jump (FuncState *fs) {
int jpc = fs->jpc; /* save list of jumps to here */
int j;
- fs->jpc = NO_JUMP;
+ fs->jpc = NO_JUMP; /* no more jumps to here */
j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
luaK_concat(fs, &j, jpc); /* keep them on hold */
return j;
}
+/*
+** Code a 'return' instruction
+*/
void luaK_ret (FuncState *fs, int first, int nret) {
luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
}
+/*
+** Code a "conditional jump", that is, a test or comparison opcode
+** followed by a jump. Return jump position.
+*/
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
}
-static void fixjump (FuncState *fs, int pc, int dest) {
- Instruction *jmp = &fs->f->code[pc];
- int offset = dest-(pc+1);
- lua_assert(dest != NO_JUMP);
- if (abs(offset) > MAXARG_sBx)
- luaX_syntaxerror(fs->ls, "control structure too long");
- SETARG_sBx(*jmp, offset);
-}
-
-
/*
** returns current 'pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
@@ -114,15 +171,11 @@ int luaK_getlabel (FuncState *fs) {
}
-static int getjump (FuncState *fs, int pc) {
- int offset = GETARG_sBx(fs->f->code[pc]);
- if (offset == NO_JUMP) /* point to itself represents end of list */
- return NO_JUMP; /* end of list */
- else
- return (pc+1)+offset; /* turn offset into absolute position */
-}
-
-
+/*
+** Returns the position of the instruction "controlling" a given
+** jump (that is, its condition), or the jump itself if it is
+** unconditional.
+*/
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->code[pc];
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
@@ -133,37 +186,41 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
/*
-** check whether list has any jump that do not produce a value
-** (or produce an inverted value)
+** Patch destination register for a TESTSET instruction.
+** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
+** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
+** register. Otherwise, change instruction to a simple 'TEST' (produces
+** no register value)
*/
-static int need_value (FuncState *fs, int list) {
- for (; list != NO_JUMP; list = getjump(fs, list)) {
- Instruction i = *getjumpcontrol(fs, list);
- if (GET_OPCODE(i) != OP_TESTSET) return 1;
- }
- return 0; /* not found */
-}
-
-
static int patchtestreg (FuncState *fs, int node, int reg) {
Instruction *i = getjumpcontrol(fs, node);
if (GET_OPCODE(*i) != OP_TESTSET)
return 0; /* cannot patch other instructions */
if (reg != NO_REG && reg != GETARG_B(*i))
SETARG_A(*i, reg);
- else /* no register to put value or register already has the value */
+ else {
+ /* no register to put value or register already has the value;
+ change instruction to simple test */
*i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
-
+ }
return 1;
}
+/*
+** Traverse a list of tests ensuring no one produces a value
+*/
static void removevalues (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list))
patchtestreg(fs, list, NO_REG);
}
+/*
+** Traverse a list of tests, patching their destination address and
+** registers: tests producing values jump to 'vtarget' (and put their
+** values in 'reg'), other tests jump to 'dtarget'.
+*/
static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
int dtarget) {
while (list != NO_JUMP) {
@@ -177,15 +234,35 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
}
+/*
+** Ensure all pending jumps to current position are fixed (jumping
+** to current position with no values) and reset list of pending
+** jumps
+*/
static void dischargejpc (FuncState *fs) {
patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
fs->jpc = NO_JUMP;
}
+/*
+** Add elements in 'list' to list of pending jumps to "here"
+** (current position)
+*/
+void luaK_patchtohere (FuncState *fs, int list) {
+ luaK_getlabel(fs); /* mark "here" as a jump target */
+ luaK_concat(fs, &fs->jpc, list);
+}
+
+
+/*
+** Path all jumps in 'list' to jump to 'target'.
+** (The assert means that we cannot fix a jump to a forward address
+** because we only know addresses once code is generated.)
+*/
void luaK_patchlist (FuncState *fs, int list, int target) {
- if (target == fs->pc)
- luaK_patchtohere(fs, list);
+ if (target == fs->pc) /* 'target' is current position? */
+ luaK_patchtohere(fs, list); /* add list to pending jumps */
else {
lua_assert(target < fs->pc);
patchlistaux(fs, list, target, NO_REG, target);
@@ -193,39 +270,26 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
}
+/*
+** Path all jumps in 'list' to close upvalues up to given 'level'
+** (The assertion checks that jumps either were closing nothing
+** or were closing higher levels, from inner blocks.)
+*/
void luaK_patchclose (FuncState *fs, int list, int level) {
level++; /* argument is +1 to reserve 0 as non-op */
- while (list != NO_JUMP) {
- int next = getjump(fs, list);
+ for (; list != NO_JUMP; list = getjump(fs, list)) {
lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
(GETARG_A(fs->f->code[list]) == 0 ||
GETARG_A(fs->f->code[list]) >= level));
SETARG_A(fs->f->code[list], level);
- list = next;
- }
-}
-
-
-void luaK_patchtohere (FuncState *fs, int list) {
- luaK_getlabel(fs);
- luaK_concat(fs, &fs->jpc, list);
-}
-
-
-void luaK_concat (FuncState *fs, int *l1, int l2) {
- if (l2 == NO_JUMP) return;
- else if (*l1 == NO_JUMP)
- *l1 = l2;
- else {
- int list = *l1;
- int next;
- while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
- list = next;
- fixjump(fs, list, l2);
}
}
+/*
+** Emit instruction 'i', checking for array sizes and saving also its
+** line information. Return 'i' position.
+*/
static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f;
dischargejpc(fs); /* 'pc' will change */
@@ -241,6 +305,10 @@ static int luaK_code (FuncState *fs, Instruction i) {
}
+/*
+** Format and emit an 'iABC' instruction. (Assertions check consistency
+** of parameters versus opcode.)
+*/
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
lua_assert(getOpMode(o) == iABC);
lua_assert(getBMode(o) != OpArgN || b == 0);
@@ -250,6 +318,9 @@ int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
}
+/*
+** Format and emit an 'iABx' instruction.
+*/
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
lua_assert(getCMode(o) == OpArgN);
@@ -258,12 +329,20 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
}
+/*
+** Emit an "extra argument" instruction (format 'iAx')
+*/
static int codeextraarg (FuncState *fs, int a) {
lua_assert(a <= MAXARG_Ax);
return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
}
+/*
+** Emit a "load constant" instruction, using either 'OP_LOADK'
+** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
+** instruction with "extra argument".
+*/
int luaK_codek (FuncState *fs, int reg, int k) {
if (k <= MAXARG_Bx)
return luaK_codeABx(fs, OP_LOADK, reg, k);
@@ -275,6 +354,10 @@ int luaK_codek (FuncState *fs, int reg, int k) {
}
+/*
+** Check register-stack level, keeping track of its maximum size
+** in field 'maxstacksize'
+*/
void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
@@ -286,12 +369,20 @@ void luaK_checkstack (FuncState *fs, int n) {
}
+/*
+** Reserve 'n' registers in register stack
+*/
void luaK_reserveregs (FuncState *fs, int n) {
luaK_checkstack(fs, n);
fs->freereg += n;
}
+/*
+** Free register 'reg', if it is neither a constant index nor
+** a local variable.
+)
+*/
static void freereg (FuncState *fs, int reg) {
if (!ISK(reg) && reg >= fs->nactvar) {
fs->freereg--;
@@ -300,6 +391,9 @@ static void freereg (FuncState *fs, int reg) {
}
+/*
+** Free register used by expression 'e' (if any)
+*/
static void freeexp (FuncState *fs, expdesc *e) {
if (e->k == VNONRELOC)
freereg(fs, e->u.info);
@@ -307,8 +401,29 @@ static void freeexp (FuncState *fs, expdesc *e) {
/*
+** Free registers used by expressions 'e1' and 'e2' (if any) in proper
+** order.
+*/
+static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
+ int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
+ int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
+ if (r1 > r2) {
+ freereg(fs, r1);
+ freereg(fs, r2);
+ }
+ else {
+ freereg(fs, r2);
+ freereg(fs, r1);
+ }
+}
+
+
+/*
+** Add constant 'v' to prototype's list of constants (field 'k').
** Use scanner's table to cache position of constants in constant list
-** and try to reuse constants
+** and try to reuse constants. Because some values should not be used
+** as keys (nil cannot be a key, integer keys can collapse with float
+** keys), the caller must provide a useful 'key' for indexing the cache.
*/
static int addk (FuncState *fs, TValue *key, TValue *v) {
lua_State *L = fs->ls->L;
@@ -337,17 +452,21 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
}
+/*
+** Add a string to list of constants and return its index.
+*/
int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
setsvalue(fs->ls->L, &o, s);
- return addk(fs, &o, &o);
+ return addk(fs, &o, &o); /* use string itself as key */
}
/*
-** Integers use userdata as keys to avoid collision with floats with same
-** value; conversion to 'void*' used only for hashing, no "precision"
-** problems
+** Add an integer to list of constants and return its index.
+** Integers use userdata as keys to avoid collision with floats with
+** same value; conversion to 'void*' is used only for hashing, so there
+** are no "precision" problems.
*/
int luaK_intK (FuncState *fs, lua_Integer n) {
TValue k, o;
@@ -356,21 +475,29 @@ int luaK_intK (FuncState *fs, lua_Integer n) {
return addk(fs, &k, &o);
}
-
+/*
+** Add a float to list of constants and return its index.
+*/
static int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
setfltvalue(&o, r);
- return addk(fs, &o, &o);
+ return addk(fs, &o, &o); /* use number itself as key */
}
+/*
+** Add a boolean to list of constants and return its index.
+*/
static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue(&o, b);
- return addk(fs, &o, &o);
+ return addk(fs, &o, &o); /* use boolean itself as key */
}
+/*
+** Add nil to list of constants and return its index.
+*/
static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
@@ -380,54 +507,79 @@ static int nilK (FuncState *fs) {
}
+/*
+** Fix an expression to return the number of results 'nresults'.
+** Either 'e' is a multi-ret expression (function call or vararg)
+** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
+*/
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
if (e->k == VCALL) { /* expression is an open function call? */
- SETARG_C(getcode(fs, e), nresults+1);
+ SETARG_C(getinstruction(fs, e), nresults + 1);
}
else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), nresults+1);
- SETARG_A(getcode(fs, e), fs->freereg);
+ Instruction *pc = &getinstruction(fs, e);
+ SETARG_B(*pc, nresults + 1);
+ SETARG_A(*pc, fs->freereg);
luaK_reserveregs(fs, 1);
}
+ else lua_assert(nresults == LUA_MULTRET);
}
+/*
+** Fix an expression to return one result.
+** If expression is not a multi-ret expression (function call or
+** vararg), it already returns one result, so nothing needs to be done.
+** Function calls become VNONRELOC expressions (as its result comes
+** fixed in the base register of the call), while vararg expressions
+** become VRELOCABLE (as OP_VARARG puts its results where it wants).
+** (Calls are created returning one result, so that does not need
+** to be fixed.)
+*/
void luaK_setoneret (FuncState *fs, expdesc *e) {
if (e->k == VCALL) { /* expression is an open function call? */
- e->k = VNONRELOC;
- e->u.info = GETARG_A(getcode(fs, e));
+ /* already returns 1 value */
+ lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
+ e->k = VNONRELOC; /* result has fixed position */
+ e->u.info = GETARG_A(getinstruction(fs, e));
}
else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), 2);
+ SETARG_B(getinstruction(fs, e), 2);
e->k = VRELOCABLE; /* can relocate its simple result */
}
}
+/*
+** Ensure that expression 'e' is not a variable.
+*/
void luaK_dischargevars (FuncState *fs, expdesc *e) {
switch (e->k) {
- case VLOCAL: {
- e->k = VNONRELOC;
+ case VLOCAL: { /* already in a register */
+ e->k = VNONRELOC; /* becomes a non-relocatable value */
break;
}
- case VUPVAL: {
+ case VUPVAL: { /* move value to some (pending) register */
e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
e->k = VRELOCABLE;
break;
}
case VINDEXED: {
- OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
+ OpCode op;
freereg(fs, e->u.ind.idx);
- if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
+ if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */
freereg(fs, e->u.ind.t);
op = OP_GETTABLE;
}
+ else {
+ lua_assert(e->u.ind.vt == VUPVAL);
+ op = OP_GETTABUP; /* 't' is in an upvalue */
+ }
e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
- case VVARARG:
- case VCALL: {
+ case VVARARG: case VCALL: {
luaK_setoneret(fs, e);
break;
}
@@ -436,12 +588,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
}
-static int code_label (FuncState *fs, int A, int b, int jump) {
- luaK_getlabel(fs); /* those instructions may be jump targets */
- return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
-}
-
-
+/*
+** Ensures expression value is in register 'reg' (and therefore
+** 'e' will become a non-relocatable expression).
+*/
static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
luaK_dischargevars(fs, e);
switch (e->k) {
@@ -466,8 +616,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
break;
}
case VRELOCABLE: {
- Instruction *pc = &getcode(fs, e);
- SETARG_A(*pc, reg);
+ Instruction *pc = &getinstruction(fs, e);
+ SETARG_A(*pc, reg); /* instruction will put result in 'reg' */
break;
}
case VNONRELOC: {
@@ -476,7 +626,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
break;
}
default: {
- lua_assert(e->k == VVOID || e->k == VJMP);
+ lua_assert(e->k == VJMP);
return; /* nothing to do... */
}
}
@@ -485,17 +635,46 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
}
+/*
+** Ensures expression value is in any register.
+*/
static void discharge2anyreg (FuncState *fs, expdesc *e) {
- if (e->k != VNONRELOC) {
- luaK_reserveregs(fs, 1);
- discharge2reg(fs, e, fs->freereg-1);
+ if (e->k != VNONRELOC) { /* no fixed register yet? */
+ luaK_reserveregs(fs, 1); /* get a register */
+ discharge2reg(fs, e, fs->freereg-1); /* put value there */
}
}
+static int code_loadbool (FuncState *fs, int A, int b, int jump) {
+ luaK_getlabel(fs); /* those instructions may be jump targets */
+ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
+}
+
+
+/*
+** check whether list has any jump that do not produce a value
+** or produce an inverted value
+*/
+static int need_value (FuncState *fs, int list) {
+ for (; list != NO_JUMP; list = getjump(fs, list)) {
+ Instruction i = *getjumpcontrol(fs, list);
+ if (GET_OPCODE(i) != OP_TESTSET) return 1;
+ }
+ return 0; /* not found */
+}
+
+
+/*
+** Ensures final expression result (including results from its jump
+** lists) is in register 'reg'.
+** If expression has jumps, need to patch these jumps either to
+** its final position or to "load" instructions (for those tests
+** that do not produce values).
+*/
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
- if (e->k == VJMP)
+ if (e->k == VJMP) /* expression itself is a test? */
luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
if (hasjumps(e)) {
int final; /* position after whole expression */
@@ -503,8 +682,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
int p_t = NO_JUMP; /* position of an eventual LOAD true */
if (need_value(fs, e->t) || need_value(fs, e->f)) {
int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
- p_f = code_label(fs, reg, 0, 1);
- p_t = code_label(fs, reg, 1, 0);
+ p_f = code_loadbool(fs, reg, 0, 1);
+ p_t = code_loadbool(fs, reg, 1, 0);
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
@@ -517,6 +696,10 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
}
+/*
+** Ensures final expression result (including results from its jump
+** lists) is in next available register.
+*/
void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
freeexp(fs, e);
@@ -525,26 +708,39 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
}
+/*
+** Ensures final expression result (including results from its jump
+** lists) is in some (any) register and return that register.
+*/
int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
- if (e->k == VNONRELOC) {
- if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
+ if (e->k == VNONRELOC) { /* expression already has a register? */
+ if (!hasjumps(e)) /* no jumps? */
+ return e->u.info; /* result is already in a register */
if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
- exp2reg(fs, e, e->u.info); /* put value on it */
+ exp2reg(fs, e, e->u.info); /* put final result in it */
return e->u.info;
}
}
- luaK_exp2nextreg(fs, e); /* default */
+ luaK_exp2nextreg(fs, e); /* otherwise, use next available register */
return e->u.info;
}
+/*
+** Ensures final expression result is either in a register or in an
+** upvalue.
+*/
void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
if (e->k != VUPVAL || hasjumps(e))
luaK_exp2anyreg(fs, e);
}
+/*
+** Ensures final expression result is either in a register or it is
+** a constant.
+*/
void luaK_exp2val (FuncState *fs, expdesc *e) {
if (hasjumps(e))
luaK_exp2anyreg(fs, e);
@@ -553,35 +749,26 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
}
+/*
+** Ensures final expression result is in a valid R/K index
+** (that is, it is either in a register or in 'k' with an index
+** in the range of R/K indices).
+** Returns R/K index.
+*/
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
- switch (e->k) {
- case VTRUE:
- case VFALSE:
- case VNIL: {
- if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
- e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
- e->k = VK;
- return RKASK(e->u.info);
- }
- else break;
- }
- case VKINT: {
- e->u.info = luaK_intK(fs, e->u.ival);
- e->k = VK;
- goto vk;
- }
- case VKFLT: {
- e->u.info = luaK_numberK(fs, e->u.nval);
- e->k = VK;
- }
- /* FALLTHROUGH */
- case VK: {
+ switch (e->k) { /* move constants to 'k' */
+ case VTRUE: e->u.info = boolK(fs, 1); goto vk;
+ case VFALSE: e->u.info = boolK(fs, 0); goto vk;
+ case VNIL: e->u.info = nilK(fs); goto vk;
+ case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
+ case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
+ case VK:
vk:
+ e->k = VK;
if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
return RKASK(e->u.info);
else break;
- }
default: break;
}
/* not a constant in the right range: put it in a register */
@@ -589,11 +776,14 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
}
+/*
+** Generate code to store result of expression 'ex' into variable 'var'.
+*/
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) {
case VLOCAL: {
freeexp(fs, ex);
- exp2reg(fs, ex, var->u.info);
+ exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */
return;
}
case VUPVAL: {
@@ -607,29 +797,32 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
break;
}
- default: {
- lua_assert(0); /* invalid var kind to store */
- break;
- }
+ default: lua_assert(0); /* invalid var kind to store */
}
freeexp(fs, ex);
}
+/*
+** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
+*/
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
int ereg;
luaK_exp2anyreg(fs, e);
ereg = e->u.info; /* register where 'e' was placed */
freeexp(fs, e);
e->u.info = fs->freereg; /* base register for op_self */
- e->k = VNONRELOC;
+ e->k = VNONRELOC; /* self expression has a fixed register */
luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
freeexp(fs, key);
}
-static void invertjump (FuncState *fs, expdesc *e) {
+/*
+** Negate condition 'e' (where 'e' is a comparison).
+*/
+static void negatecondition (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->u.info);
lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
GET_OPCODE(*pc) != OP_TEST);
@@ -637,9 +830,15 @@ static void invertjump (FuncState *fs, expdesc *e) {
}
+/*
+** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
+** is true, code will jump if 'e' is true.) Return jump position.
+** Optimize when 'e' is 'not' something, inverting the condition
+** and removing the 'not'.
+*/
static int jumponcond (FuncState *fs, expdesc *e, int cond) {
if (e->k == VRELOCABLE) {
- Instruction ie = getcode(fs, e);
+ Instruction ie = getinstruction(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */
return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
@@ -652,13 +851,16 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
}
+/*
+** Emit code to go through if 'e' is true, jump otherwise.
+*/
void luaK_goiftrue (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
+ int pc; /* pc of new jump */
luaK_dischargevars(fs, e);
switch (e->k) {
- case VJMP: {
- invertjump(fs, e);
- pc = e->u.info;
+ case VJMP: { /* condition? */
+ negatecondition(fs, e); /* jump when it is false */
+ pc = e->u.info; /* save jump position */
break;
}
case VK: case VKFLT: case VKINT: case VTRUE: {
@@ -666,22 +868,25 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
break;
}
default: {
- pc = jumponcond(fs, e, 0);
+ pc = jumponcond(fs, e, 0); /* jump when false */
break;
}
}
- luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */
- luaK_patchtohere(fs, e->t);
+ luaK_concat(fs, &e->f, pc); /* insert new jump in false list */
+ luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */
e->t = NO_JUMP;
}
+/*
+** Emit code to go through if 'e' is false, jump otherwise.
+*/
void luaK_goiffalse (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
+ int pc; /* pc of new jump */
luaK_dischargevars(fs, e);
switch (e->k) {
case VJMP: {
- pc = e->u.info;
+ pc = e->u.info; /* already jump if true */
break;
}
case VNIL: case VFALSE: {
@@ -689,29 +894,32 @@ void luaK_goiffalse (FuncState *fs, expdesc *e) {
break;
}
default: {
- pc = jumponcond(fs, e, 1);
+ pc = jumponcond(fs, e, 1); /* jump if true */
break;
}
}
- luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */
- luaK_patchtohere(fs, e->f);
+ luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */
+ luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */
e->f = NO_JUMP;
}
+/*
+** Code 'not e', doing constant folding.
+*/
static void codenot (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: case VFALSE: {
- e->k = VTRUE;
+ e->k = VTRUE; /* true == not nil == not false */
break;
}
case VK: case VKFLT: case VKINT: case VTRUE: {
- e->k = VFALSE;
+ e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */
break;
}
case VJMP: {
- invertjump(fs, e);
+ negatecondition(fs, e);
break;
}
case VRELOCABLE:
@@ -722,30 +930,32 @@ static void codenot (FuncState *fs, expdesc *e) {
e->k = VRELOCABLE;
break;
}
- default: {
- lua_assert(0); /* cannot happen */
- break;
- }
+ default: lua_assert(0); /* cannot happen */
}
/* interchange true and false lists */
{ int temp = e->f; e->f = e->t; e->t = temp; }
- removevalues(fs, e->f);
+ removevalues(fs, e->f); /* values are useless when negated */
removevalues(fs, e->t);
}
+/*
+** Create expression 't[k]'. 't' must have its final result already in a
+** register or upvalue.
+*/
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
- lua_assert(!hasjumps(t));
- t->u.ind.t = t->u.info;
- t->u.ind.idx = luaK_exp2RK(fs, k);
- t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
- : check_exp(vkisinreg(t->k), VLOCAL);
+ lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
+ t->u.ind.t = t->u.info; /* register or upvalue index */
+ t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */
+ t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
t->k = VINDEXED;
}
/*
-** return false if folding can raise an error
+** Return false if folding can raise an error.
+** Bitwise operations need operands convertible to integers; division
+** operations cannot have 0 as divisor.
*/
static int validop (int op, TValue *v1, TValue *v2) {
switch (op) {
@@ -762,7 +972,8 @@ static int validop (int op, TValue *v1, TValue *v2) {
/*
-** Try to "constant-fold" an operation; return 1 iff successful
+** Try to "constant-fold" an operation; return 1 iff successful.
+** (In this case, 'e1' has the final result.)
*/
static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
TValue v1, v2, res;
@@ -773,7 +984,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
e1->k = VKINT;
e1->u.ival = ivalue(&res);
}
- else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */
+ else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
lua_Number n = fltvalue(&res);
if (luai_numisnan(n) || n == 0)
return 0;
@@ -785,81 +996,97 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
/*
-** Code for binary and unary expressions that "produce values"
-** (arithmetic operations, bitwise operations, concat, length). First
-** try to do constant folding (only for numeric [arithmetic and
-** bitwise] operations, which is what 'lua_arith' accepts).
+** Emit code for unary expressions that "produce values"
+** (everything but 'not').
+** Expression to produce final result will be encoded in 'e'.
+*/
+static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
+ int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */
+ freeexp(fs, e);
+ e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */
+ e->k = VRELOCABLE; /* all those operations are relocatable */
+ luaK_fixline(fs, line);
+}
+
+
+/*
+** Emit code for binary expressions that "produce values"
+** (everything but logical operators 'and'/'or' and comparison
+** operators).
** Expression to produce final result will be encoded in 'e1'.
*/
-static void codeexpval (FuncState *fs, OpCode op,
- expdesc *e1, expdesc *e2, int line) {
- lua_assert(op >= OP_ADD);
- if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
- return; /* result has been folded */
- else {
- int o1, o2;
- /* move operands to registers (if needed) */
- if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
- o2 = 0; /* no second expression */
- o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
- }
- else { /* regular case (binary operators) */
- o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
- o1 = luaK_exp2RK(fs, e1);
- }
- if (o1 > o2) { /* free registers in proper order */
- freeexp(fs, e1);
- freeexp(fs, e2);
- }
- else {
- freeexp(fs, e2);
- freeexp(fs, e1);
- }
- e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
- e1->k = VRELOCABLE; /* all those operations are relocatable */
- luaK_fixline(fs, line);
- }
+static void codebinexpval (FuncState *fs, OpCode op,
+ expdesc *e1, expdesc *e2, int line) {
+ int rk1 = luaK_exp2RK(fs, e1); /* both operands are "RK" */
+ int rk2 = luaK_exp2RK(fs, e2);
+ freeexps(fs, e1, e2);
+ e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */
+ e1->k = VRELOCABLE; /* all those operations are relocatable */
+ luaK_fixline(fs, line);
}
-static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
- expdesc *e2) {
- int o1 = luaK_exp2RK(fs, e1);
- int o2 = luaK_exp2RK(fs, e2);
- freeexp(fs, e2);
- freeexp(fs, e1);
- if (cond == 0 && op != OP_EQ) {
- int temp; /* exchange args to replace by '<' or '<=' */
- temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
- cond = 1;
+/*
+** Emit code for comparisons.
+** 'e1' was already put in R/K form by 'luaK_infix'.
+*/
+static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
+ int rk1 = (e1->k == VK) ? RKASK(e1->u.info)
+ : check_exp(e1->k == VNONRELOC, e1->u.info);
+ int rk2 = luaK_exp2RK(fs, e2);
+ freeexps(fs, e1, e2);
+ switch (opr) {
+ case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */
+ e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
+ break;
+ }
+ case OPR_GT: case OPR_GE: {
+ /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */
+ OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
+ e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */
+ break;
+ }
+ default: { /* '==', '<', '<=' use their own opcodes */
+ OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
+ e1->u.info = condjump(fs, op, 1, rk1, rk2);
+ break;
+ }
}
- e1->u.info = condjump(fs, op, cond, o1, o2);
e1->k = VJMP;
}
+/*
+** Aplly prefix operation 'op' to expression 'e'.
+*/
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
- expdesc e2;
- e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
+ static expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; /* fake 2nd operand */
switch (op) {
- case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
- codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
+ case OPR_MINUS: case OPR_BNOT:
+ if (constfolding(fs, op + LUA_OPUNM, e, &ef))
+ break;
+ /* FALLTHROUGH */
+ case OPR_LEN:
+ codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
break;
- }
case OPR_NOT: codenot(fs, e); break;
default: lua_assert(0);
}
}
+/*
+** Process 1st operand 'v' of binary operation 'op' before reading
+** 2nd operand.
+*/
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
switch (op) {
case OPR_AND: {
- luaK_goiftrue(fs, v);
+ luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */
break;
}
case OPR_OR: {
- luaK_goiffalse(fs, v);
+ luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */
break;
}
case OPR_CONCAT: {
@@ -871,7 +1098,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
case OPR_MOD: case OPR_POW:
case OPR_BAND: case OPR_BOR: case OPR_BXOR:
case OPR_SHL: case OPR_SHR: {
- if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
+ if (!tonumeral(v, NULL))
+ luaK_exp2RK(fs, v);
+ /* else keep numeral, which may be folded with 2nd operand */
break;
}
default: {
@@ -882,18 +1111,24 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
}
+/*
+** Finalize code for binary operation, after reading 2nd operand.
+** For '(a .. b .. c)' (which is '(a .. (b .. c))', because
+** concatenation is right associative), merge second CONCAT into first
+** one.
+*/
void luaK_posfix (FuncState *fs, BinOpr op,
expdesc *e1, expdesc *e2, int line) {
switch (op) {
case OPR_AND: {
- lua_assert(e1->t == NO_JUMP); /* list must be closed */
+ lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e2->f, e1->f);
*e1 = *e2;
break;
}
case OPR_OR: {
- lua_assert(e1->f == NO_JUMP); /* list must be closed */
+ lua_assert(e1->f == NO_JUMP); /* list closed by 'luK_infix' */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e2->t, e1->t);
*e1 = *e2;
@@ -901,15 +1136,16 @@ void luaK_posfix (FuncState *fs, BinOpr op,
}
case OPR_CONCAT: {
luaK_exp2val(fs, e2);
- if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
- lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
+ if (e2->k == VRELOCABLE &&
+ GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) {
+ lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1);
freeexp(fs, e1);
- SETARG_B(getcode(fs, e2), e1->u.info);
+ SETARG_B(getinstruction(fs, e2), e1->u.info);
e1->k = VRELOCABLE; e1->u.info = e2->u.info;
}
else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
- codeexpval(fs, OP_CONCAT, e1, e2, line);
+ codebinexpval(fs, OP_CONCAT, e1, e2, line);
}
break;
}
@@ -917,15 +1153,13 @@ void luaK_posfix (FuncState *fs, BinOpr op,
case OPR_IDIV: case OPR_MOD: case OPR_POW:
case OPR_BAND: case OPR_BOR: case OPR_BXOR:
case OPR_SHL: case OPR_SHR: {
- codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
- break;
- }
- case OPR_EQ: case OPR_LT: case OPR_LE: {
- codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
+ if (!constfolding(fs, op + LUA_OPADD, e1, e2))
+ codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
break;
}
+ case OPR_EQ: case OPR_LT: case OPR_LE:
case OPR_NE: case OPR_GT: case OPR_GE: {
- codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
+ codecomp(fs, op, e1, e2);
break;
}
default: lua_assert(0);
@@ -933,15 +1167,25 @@ void luaK_posfix (FuncState *fs, BinOpr op,
}
+/*
+** Change line information associated with current position.
+*/
void luaK_fixline (FuncState *fs, int line) {
fs->f->lineinfo[fs->pc - 1] = line;
}
+/*
+** Emit a SETLIST instruction.
+** 'base' is register that keeps table;
+** 'nelems' is #table plus those to be stored now;
+** 'tostore' is number of values (in registers 'base + 1',...) to add to
+** table (or LUA_MULTRET to add up to stack top).
+*/
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore;
- lua_assert(tostore != 0);
+ lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
if (c <= MAXARG_C)
luaK_codeABC(fs, OP_SETLIST, base, b, c);
else if (c <= MAXARG_Ax) {
diff --git a/libs/lua/lua-5.3.2/lcode.h b/libs/lua/lua-5.3.3/lcode.h
index 43ab86db77..cd306d573a 100644
--- a/libs/lua/lua-5.3.2/lcode.h
+++ b/libs/lua/lua-5.3.3/lcode.h
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
+** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -40,7 +40,8 @@ typedef enum BinOpr {
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
-#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
+/* get (pointer to) instruction of given 'expdesc' */
+#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
diff --git a/libs/lua/lua-5.3.2/lcorolib.c b/libs/lua/lua-5.3.3/lcorolib.c
index 0c0b7fa6b3..2303429e7b 100644
--- a/libs/lua/lua-5.3.2/lcorolib.c
+++ b/libs/lua/lua-5.3.3/lcorolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
+** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -75,7 +75,7 @@ static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
- if (lua_isstring(L, -1)) { /* error object is a string? */
+ if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
diff --git a/libs/lua/lua-5.3.2/lctype.c b/libs/lua/lua-5.3.3/lctype.c
index ae9367e691..ae9367e691 100644
--- a/libs/lua/lua-5.3.2/lctype.c
+++ b/libs/lua/lua-5.3.3/lctype.c
diff --git a/libs/lua/lua-5.3.2/lctype.h b/libs/lua/lua-5.3.3/lctype.h
index 99c7d12237..99c7d12237 100644
--- a/libs/lua/lua-5.3.2/lctype.h
+++ b/libs/lua/lua-5.3.3/lctype.h
diff --git a/libs/lua/lua-5.3.2/ldblib.c b/libs/lua/lua-5.3.3/ldblib.c
index 786f6cd95d..786f6cd95d 100644
--- a/libs/lua/lua-5.3.2/ldblib.c
+++ b/libs/lua/lua-5.3.3/ldblib.c
diff --git a/libs/lua/lua-5.3.2/ldebug.c b/libs/lua/lua-5.3.3/ldebug.c
index 9bd86d0294..e499ee362c 100644
--- a/libs/lua/lua-5.3.2/ldebug.c
+++ b/libs/lua/lua-5.3.3/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.117 2015/11/02 18:48:07 roberto Exp $
+** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -69,7 +69,13 @@ static void swapextra (lua_State *L) {
/*
-** this function can be called asynchronous (e.g. during a signal)
+** This function can be called asynchronously (e.g. during a signal).
+** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
+** 'resethookcount') are for debug only, and it is no problem if they
+** get arbitrary values (causes at most one wrong hook call). 'hookmask'
+** is an atomic value. We assume that pointers are atomic too (e.g., gcc
+** ensures that for all platforms where it runs). Moreover, 'hook' is
+** always checked before being called (see 'luaD_hook').
*/
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
@@ -558,7 +564,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
- const char *t = objtypename(o);
+ const char *t = luaT_objtypename(L, o);
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
}
@@ -590,9 +596,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
- const char *t1 = objtypename(p1);
- const char *t2 = objtypename(p2);
- if (t1 == t2)
+ const char *t1 = luaT_objtypename(L, p1);
+ const char *t2 = luaT_objtypename(L, p2);
+ if (strcmp(t1, t2) == 0)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
diff --git a/libs/lua/lua-5.3.2/ldebug.h b/libs/lua/lua-5.3.3/ldebug.h
index 0e31546b1b..0e31546b1b 100644
--- a/libs/lua/lua-5.3.2/ldebug.h
+++ b/libs/lua/lua-5.3.3/ldebug.h
diff --git a/libs/lua/lua-5.3.2/ldo.c b/libs/lua/lua-5.3.3/ldo.c
index 95efd56068..8804c99777 100644
--- a/libs/lua/lua-5.3.2/ldo.c
+++ b/libs/lua/lua-5.3.3/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.150 2015/11/19 19:16:22 roberto Exp $
+** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -242,9 +242,14 @@ void luaD_inctop (lua_State *L) {
/* }================================================================== */
+/*
+** Call a hook for the given event. Make sure there is a hook to be
+** called. (Both 'L->hook' and 'L->hookmask', which triggers this
+** function, can be changed asynchronously by signals.)
+*/
void luaD_hook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
- if (hook && L->allowhook) {
+ if (hook && L->allowhook) { /* make sure there is a hook */
CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, ci->top);
diff --git a/libs/lua/lua-5.3.2/ldo.h b/libs/lua/lua-5.3.3/ldo.h
index 80582dc2e3..4f5d51c3c7 100644
--- a/libs/lua/lua-5.3.2/ldo.h
+++ b/libs/lua/lua-5.3.3/ldo.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp $
+** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -25,7 +25,7 @@
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
/* In general, 'pre'/'pos' are empty (nothing to save) */
-#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,)
+#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
diff --git a/libs/lua/lua-5.3.2/ldump.c b/libs/lua/lua-5.3.3/ldump.c
index 016e300822..016e300822 100644
--- a/libs/lua/lua-5.3.2/ldump.c
+++ b/libs/lua/lua-5.3.3/ldump.c
diff --git a/libs/lua/lua-5.3.2/lfunc.c b/libs/lua/lua-5.3.3/lfunc.c
index 67967dab3f..67967dab3f 100644
--- a/libs/lua/lua-5.3.2/lfunc.c
+++ b/libs/lua/lua-5.3.3/lfunc.c
diff --git a/libs/lua/lua-5.3.2/lfunc.h b/libs/lua/lua-5.3.3/lfunc.h
index 2eeb0d5a48..2eeb0d5a48 100644
--- a/libs/lua/lua-5.3.2/lfunc.h
+++ b/libs/lua/lua-5.3.3/lfunc.h
diff --git a/libs/lua/lua-5.3.2/lgc.c b/libs/lua/lua-5.3.3/lgc.c
index 49d8ecb7c3..7c29fb030a 100644
--- a/libs/lua/lua-5.3.2/lgc.c
+++ b/libs/lua/lua-5.3.3/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.210 2015/11/03 18:10:44 roberto Exp $
+** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -754,14 +754,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
/*
** sweep a list until a live object (or end of list)
*/
-static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
+static GCObject **sweeptolive (lua_State *L, GCObject **p) {
GCObject **old = p;
- int i = 0;
do {
- i++;
p = sweeplist(L, p, 1);
} while (p == old);
- if (n) *n += i;
return p;
}
@@ -856,10 +853,10 @@ static int runafewfinalizers (lua_State *L) {
/*
** call all pending finalizers
*/
-static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
+static void callallpendingfinalizers (lua_State *L) {
global_State *g = G(L);
while (g->tobefnz)
- GCTM(L, propagateerrors);
+ GCTM(L, 0);
}
@@ -909,7 +906,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
- g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
+ g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
}
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
@@ -951,19 +948,16 @@ static void setpause (global_State *g) {
/*
** Enter first sweep phase.
-** The call to 'sweeptolive' makes pointer point to an object inside
-** the list (instead of to the header), so that the real sweep do not
-** need to skip objects created between "now" and the start of the real
-** sweep.
-** Returns how many objects it swept.
+** The call to 'sweeplist' tries to make pointer point to an object
+** inside the list (instead of to the header), so that the real sweep do
+** not need to skip objects created between "now" and the start of the
+** real sweep.
*/
-static int entersweep (lua_State *L) {
+static void entersweep (lua_State *L) {
global_State *g = G(L);
- int n = 0;
g->gcstate = GCSswpallgc;
lua_assert(g->sweepgc == NULL);
- g->sweepgc = sweeptolive(L, &g->allgc, &n);
- return n;
+ g->sweepgc = sweeplist(L, &g->allgc, 1);
}
@@ -971,7 +965,7 @@ void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
separatetobefnz(g, 1); /* separate all objects with finalizers */
lua_assert(g->finobj == NULL);
- callallpendingfinalizers(L, 0);
+ callallpendingfinalizers(L);
lua_assert(g->tobefnz == NULL);
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
g->gckind = KGC_NORMAL;
@@ -1064,12 +1058,11 @@ static lu_mem singlestep (lua_State *L) {
}
case GCSatomic: {
lu_mem work;
- int sw;
propagateall(g); /* make sure gray list is empty */
work = atomic(L); /* work is what was traversed by 'atomic' */
- sw = entersweep(L);
+ entersweep(L);
g->GCestimate = gettotalbytes(g); /* first estimate */;
- return work + sw * GCSWEEPCOST;
+ return work;
}
case GCSswpallgc: { /* sweep "regular" objects */
return sweepstep(L, g, GCSswpfinobj, &g->finobj);
diff --git a/libs/lua/lua-5.3.2/lgc.h b/libs/lua/lua-5.3.3/lgc.h
index 1775ca4595..aed3e18a5f 100644
--- a/libs/lua/lua-5.3.2/lgc.h
+++ b/libs/lua/lua-5.3.3/lgc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.h,v 2.90 2015/10/21 18:15:15 roberto Exp $
+** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -112,7 +112,7 @@
condchangemem(L,pre,pos); }
/* more often than not, 'pre'/'pos' are empty */
-#define luaC_checkGC(L) luaC_condGC(L,,)
+#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
#define luaC_barrier(L,p,v) ( \
diff --git a/libs/lua/lua-5.3.2/linit.c b/libs/lua/lua-5.3.3/linit.c
index 8ce94ccb35..8ce94ccb35 100644
--- a/libs/lua/lua-5.3.2/linit.c
+++ b/libs/lua/lua-5.3.3/linit.c
diff --git a/libs/lua/lua-5.3.2/liolib.c b/libs/lua/lua-5.3.3/liolib.c
index a91ba39181..aa78e593fa 100644
--- a/libs/lua/lua-5.3.2/liolib.c
+++ b/libs/lua/lua-5.3.3/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.148 2015/11/23 11:36:11 roberto Exp $
+** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -375,14 +375,17 @@ static int io_lines (lua_State *L) {
/* maximum length of a numeral */
-#define MAXRN 200
+#if !defined (L_MAXLENNUM)
+#define L_MAXLENNUM 200
+#endif
+
/* auxiliary structure used by 'read_number' */
typedef struct {
FILE *f; /* file being read */
int c; /* current character (look ahead) */
int n; /* number of elements in buffer 'buff' */
- char buff[MAXRN + 1]; /* +1 for ending '\0' */
+ char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
} RN;
@@ -390,7 +393,7 @@ typedef struct {
** Add current char to buffer (if not out of space) and read next one
*/
static int nextc (RN *rn) {
- if (rn->n >= MAXRN) { /* buffer overflow? */
+ if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
rn->buff[0] = '\0'; /* invalidate result */
return 0; /* fail */
}
@@ -403,10 +406,10 @@ static int nextc (RN *rn) {
/*
-** Accept current char if it is in 'set' (of size 1 or 2)
+** Accept current char if it is in 'set' (of size 2)
*/
static int test2 (RN *rn, const char *set) {
- if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
+ if (rn->c == set[0] || rn->c == set[1])
return nextc(rn);
else return 0;
}
@@ -435,11 +438,11 @@ static int read_number (lua_State *L, FILE *f) {
char decp[2];
rn.f = f; rn.n = 0;
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
- decp[1] = '\0';
+ decp[1] = '.'; /* always accept a dot */
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
- if (test2(&rn, "0")) {
+ if (test2(&rn, "00")) {
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
else count = 1; /* count initial '0' as a valid digit */
}
diff --git a/libs/lua/lua-5.3.2/llex.c b/libs/lua/lua-5.3.3/llex.c
index 16ea3ebebe..70328273f7 100644
--- a/libs/lua/lua-5.3.2/llex.c
+++ b/libs/lua/lua-5.3.3/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.95 2015/11/19 19:16:22 roberto Exp $
+** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -162,7 +162,6 @@ static void inclinenumber (LexState *ls) {
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
int firstchar) {
ls->t.token = 0;
- ls->decpoint = '.';
ls->L = L;
ls->current = firstchar;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
@@ -207,35 +206,6 @@ static int check_next2 (LexState *ls, const char *set) {
}
-/*
-** change all characters 'from' in buffer to 'to'
-*/
-static void buffreplace (LexState *ls, char from, char to) {
- if (from != to) {
- size_t n = luaZ_bufflen(ls->buff);
- char *p = luaZ_buffer(ls->buff);
- while (n--)
- if (p[n] == from) p[n] = to;
- }
-}
-
-
-/*
-** in case of format error, try to change decimal point separator to
-** the one defined in the current locale and check again
-*/
-static void trydecpoint (LexState *ls, TValue *o) {
- char old = ls->decpoint;
- ls->decpoint = lua_getlocaledecpoint();
- buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
- if (luaO_str2num(luaZ_buffer(ls->buff), o) == 0) {
- /* format error with correct decimal point: no more options */
- buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
- lexerror(ls, "malformed number", TK_FLT);
- }
-}
-
-
/* LUA_NUMBER */
/*
** this function is quite liberal in what it accepts, as 'luaO_str2num'
@@ -259,9 +229,8 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
else break;
}
save(ls, '\0');
- buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
- trydecpoint(ls, &obj); /* try to update decimal point separator */
+ lexerror(ls, "malformed number", TK_FLT);
if (ttisinteger(&obj)) {
seminfo->i = ivalue(&obj);
return TK_INT;
diff --git a/libs/lua/lua-5.3.2/llex.h b/libs/lua/lua-5.3.3/llex.h
index afb40b5622..2363d87e40 100644
--- a/libs/lua/lua-5.3.2/llex.h
+++ b/libs/lua/lua-5.3.3/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $
+** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -69,7 +69,6 @@ typedef struct LexState {
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
- char decpoint; /* locale decimal point */
} LexState;
diff --git a/libs/lua/lua-5.3.2/llimits.h b/libs/lua/lua-5.3.3/llimits.h
index f21377fef9..f21377fef9 100644
--- a/libs/lua/lua-5.3.2/llimits.h
+++ b/libs/lua/lua-5.3.3/llimits.h
diff --git a/libs/lua/lua-5.3.2/lmathlib.c b/libs/lua/lua-5.3.3/lmathlib.c
index 94815f129f..94815f129f 100644
--- a/libs/lua/lua-5.3.2/lmathlib.c
+++ b/libs/lua/lua-5.3.3/lmathlib.c
diff --git a/libs/lua/lua-5.3.2/lmem.c b/libs/lua/lua-5.3.3/lmem.c
index 0a0476cc77..0a0476cc77 100644
--- a/libs/lua/lua-5.3.2/lmem.c
+++ b/libs/lua/lua-5.3.3/lmem.c
diff --git a/libs/lua/lua-5.3.2/lmem.h b/libs/lua/lua-5.3.3/lmem.h
index 30f484895e..30f484895e 100644
--- a/libs/lua/lua-5.3.2/lmem.h
+++ b/libs/lua/lua-5.3.3/lmem.h
diff --git a/libs/lua/lua-5.3.2/loadlib.c b/libs/lua/lua-5.3.3/loadlib.c
index 79119287ae..79119287ae 100644
--- a/libs/lua/lua-5.3.2/loadlib.c
+++ b/libs/lua/lua-5.3.3/loadlib.c
diff --git a/libs/lua/lua-5.3.2/lobject.c b/libs/lua/lua-5.3.3/lobject.c
index e24723febe..9fe441f157 100644
--- a/libs/lua/lua-5.3.2/lobject.c
+++ b/libs/lua/lua-5.3.3/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp $
+** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -243,20 +243,59 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
/* }====================================================== */
-static const char *l_str2d (const char *s, lua_Number *result) {
+/* maximum length of a numeral */
+#if !defined (L_MAXLENNUM)
+#define L_MAXLENNUM 200
+#endif
+
+static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
char *endptr;
- if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
+ *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
+ : lua_str2number(s, &endptr);
+ if (endptr == s) return NULL; /* nothing recognized? */
+ while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
+ return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
+}
+
+
+/*
+** Convert string 's' to a Lua number (put in 'result'). Return NULL
+** on fail or the address of the ending '\0' on success.
+** 'pmode' points to (and 'mode' contains) special things in the string:
+** - 'x'/'X' means an hexadecimal numeral
+** - '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
+** 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.
+*/
+static const char *l_str2d (const char *s, lua_Number *result) {
+ const char *endptr;
+ const char *pmode = strpbrk(s, ".xXnN");
+ int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
+ if (mode == 'n') /* reject 'inf' and 'nan' */
return NULL;
- else if (strpbrk(s, "xX")) /* hex? */
- *result = lua_strx2number(s, &endptr);
- else
- *result = lua_str2number(s, &endptr);
- if (endptr == s) return NULL; /* nothing recognized */
- while (lisspace(cast_uchar(*endptr))) endptr++;
- return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
+ endptr = l_str2dloc(s, result, mode); /* try to convert */
+ if (endptr == NULL) { /* failed? may be a different locale */
+ char buff[L_MAXLENNUM + 1];
+ const char *pdot = strchr(s, '.');
+ if (strlen(s) > L_MAXLENNUM || pdot == NULL)
+ return NULL; /* string too long or no dot; fail */
+ strcpy(buff, s); /* copy string to buffer */
+ buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
+ endptr = l_str2dloc(buff, result, mode); /* try again */
+ if (endptr != NULL)
+ endptr = s + (endptr - buff); /* make relative to 's' */
+ }
+ return endptr;
}
+#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
+#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
+
static const char *l_str2int (const char *s, lua_Integer *result) {
lua_Unsigned a = 0;
int empty = 1;
@@ -273,7 +312,10 @@ static const char *l_str2int (const char *s, lua_Integer *result) {
}
else { /* decimal */
for (; lisdigit(cast_uchar(*s)); s++) {
- a = a * 10 + *s - '0';
+ int d = *s - '0';
+ if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
+ return NULL; /* do not accept it (as integer) */
+ a = a * 10 + d;
empty = 0;
}
}
@@ -351,8 +393,10 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
}
-/* this function handles only '%d', '%c', '%f', '%p', and '%s'
- conventional formats, plus Lua-specific '%I' and '%U' */
+/*
+** this function handles only '%d', '%c', '%f', '%p', and '%s'
+ conventional formats, plus Lua-specific '%I' and '%U'
+*/
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
@@ -360,13 +404,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
if (e == NULL) break;
pushstr(L, fmt, e - fmt);
switch (*(e+1)) {
- case 's': {
+ case 's': { /* zero-terminated string */
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s, strlen(s));
break;
}
- case 'c': {
+ case 'c': { /* an 'int' as a character */
char buff = cast(char, va_arg(argp, int));
if (lisprint(cast_uchar(buff)))
pushstr(L, &buff, 1);
@@ -374,28 +418,28 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
break;
}
- case 'd': {
+ case 'd': { /* an 'int' */
setivalue(L->top, va_arg(argp, int));
goto top2str;
}
- case 'I': {
+ case 'I': { /* a 'lua_Integer' */
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
goto top2str;
}
- case 'f': {
+ case 'f': { /* a 'lua_Number' */
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
- top2str:
+ top2str: /* convert the top element to a string */
luaD_inctop(L);
luaO_tostring(L, L->top - 1);
break;
}
- case 'p': {
+ case 'p': { /* a pointer */
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
pushstr(L, buff, l);
break;
}
- case 'U': {
+ case 'U': { /* an 'int' as a UTF-8 sequence */
char buff[UTF8BUFFSZ];
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);
diff --git a/libs/lua/lua-5.3.2/lobject.h b/libs/lua/lua-5.3.3/lobject.h
index 2d52b41592..2d52b41592 100644
--- a/libs/lua/lua-5.3.2/lobject.h
+++ b/libs/lua/lua-5.3.3/lobject.h
diff --git a/libs/lua/lua-5.3.2/lopcodes.c b/libs/lua/lua-5.3.3/lopcodes.c
index a1cbef8573..a1cbef8573 100644
--- a/libs/lua/lua-5.3.2/lopcodes.c
+++ b/libs/lua/lua-5.3.3/lopcodes.c
diff --git a/libs/lua/lua-5.3.2/lopcodes.h b/libs/lua/lua-5.3.3/lopcodes.h
index 864b8e4bb5..864b8e4bb5 100644
--- a/libs/lua/lua-5.3.2/lopcodes.h
+++ b/libs/lua/lua-5.3.3/lopcodes.h
diff --git a/libs/lua/lua-5.3.2/loslib.c b/libs/lua/lua-5.3.3/loslib.c
index 7dae533661..4810655504 100644
--- a/libs/lua/lua-5.3.2/loslib.c
+++ b/libs/lua/lua-5.3.3/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp $
+** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -24,18 +24,29 @@
/*
** {==================================================================
-** list of valid conversion specifiers for the 'strftime' function
+** List of valid conversion specifiers for the 'strftime' function;
+** options are grouped by length; group of length 2 start with '||'.
** ===================================================================
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
-#if defined(LUA_USE_C89)
-#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
+/* options for ANSI C 89 */
+#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
+
+/* options for ISO C 99 and POSIX */
+#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
+ "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"
+
+/* options for Windows */
+#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
+ "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"
+
+#if defined(LUA_USE_WINDOWS)
+#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
+#elif defined(LUA_USE_C89)
+#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
#else /* C99 specification */
-#define LUA_STRFTIMEOPTIONS \
- { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
- "E", "cCxXyY", \
- "O", "deHImMSuUVwWy" }
+#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
#endif
#endif /* } */
@@ -195,6 +206,23 @@ static void setboolfield (lua_State *L, const char *key, int value) {
lua_setfield(L, -2, key);
}
+
+/*
+** Set all fields from structure 'tm' in the table on top of the stack
+*/
+static void setallfields (lua_State *L, struct tm *stm) {
+ setfield(L, "sec", stm->tm_sec);
+ setfield(L, "min", stm->tm_min);
+ setfield(L, "hour", stm->tm_hour);
+ setfield(L, "day", stm->tm_mday);
+ setfield(L, "month", stm->tm_mon + 1);
+ setfield(L, "year", stm->tm_year + 1900);
+ setfield(L, "wday", stm->tm_wday + 1);
+ setfield(L, "yday", stm->tm_yday + 1);
+ setboolfield(L, "isdst", stm->tm_isdst);
+}
+
+
static int getboolfield (lua_State *L, const char *key) {
int res;
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
@@ -210,18 +238,18 @@ static int getboolfield (lua_State *L, const char *key) {
static int getfield (lua_State *L, const char *key, int d, int delta) {
int isnum;
- int t = lua_getfield(L, -1, key);
+ int t = lua_getfield(L, -1, key); /* get field and its type */
lua_Integer res = lua_tointegerx(L, -1, &isnum);
- if (!isnum) { /* field is not a number? */
+ if (!isnum) { /* field is not an integer? */
if (t != LUA_TNIL) /* some other value? */
- return luaL_error(L, "field '%s' not an integer", key);
+ return luaL_error(L, "field '%s' is not an integer", key);
else if (d < 0) /* absent field; no default? */
return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
else {
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
- return luaL_error(L, "field '%s' out-of-bounds", key);
+ return luaL_error(L, "field '%s' is out-of-bound", key);
res -= delta;
}
lua_pop(L, 1);
@@ -230,21 +258,15 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
- static const char *const options[] = LUA_STRFTIMEOPTIONS;
- unsigned int i;
- for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
- if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
- buff[1] = *conv;
- if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
- buff[2] = '\0'; /* end buffer */
- return conv + 1;
- }
- else if (*(conv + 1) != '\0' &&
- strchr(options[i + 1], *(conv + 1)) != NULL) {
- buff[2] = *(conv + 1); /* valid two-char conversion specifier */
- buff[3] = '\0'; /* end buffer */
- return conv + 2;
- }
+ const char *option;
+ int oplen = 1;
+ for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
+ if (*option == '|') /* next block? */
+ oplen++; /* next length */
+ else if (memcmp(conv, option, oplen) == 0) { /* match? */
+ memcpy(buff, conv, oplen); /* copy valid option to buffer */
+ buff[oplen] = '\0';
+ return conv + oplen; /* return next item */
}
}
luaL_argerror(L, 1,
@@ -271,18 +293,10 @@ static int os_date (lua_State *L) {
luaL_error(L, "time result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
- setfield(L, "sec", stm->tm_sec);
- setfield(L, "min", stm->tm_min);
- setfield(L, "hour", stm->tm_hour);
- setfield(L, "day", stm->tm_mday);
- setfield(L, "month", stm->tm_mon+1);
- setfield(L, "year", stm->tm_year+1900);
- setfield(L, "wday", stm->tm_wday+1);
- setfield(L, "yday", stm->tm_yday+1);
- setboolfield(L, "isdst", stm->tm_isdst);
+ setallfields(L, stm);
}
else {
- char cc[4];
+ char cc[4]; /* buffer for individual conversion specifiers */
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
@@ -292,7 +306,7 @@ static int os_date (lua_State *L) {
else {
size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
- s = checkoption(L, s + 1, cc);
+ s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}
@@ -319,6 +333,7 @@ static int os_time (lua_State *L) {
ts.tm_year = getfield(L, "year", -1, 1900);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
+ setallfields(L, &ts); /* update fields with normalized values */
}
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
luaL_error(L, "time result cannot be represented in this installation");
diff --git a/libs/lua/lua-5.3.2/lparser.c b/libs/lua/lua-5.3.3/lparser.c
index 282a6b121c..22530a57b2 100644
--- a/libs/lua/lua-5.3.2/lparser.c
+++ b/libs/lua/lua-5.3.3/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp $
+** $Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -164,7 +164,8 @@ static int registerlocalvar (LexState *ls, TString *varname) {
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
LocVar, SHRT_MAX, "local variables");
- while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
+ while (oldsize < f->sizelocvars)
+ f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname;
luaC_objbarrier(ls->L, f, varname);
return fs->nlocvars++;
@@ -230,7 +231,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
Upvaldesc, MAXUPVAL, "upvalues");
- while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
+ while (oldsize < f->sizeupvalues)
+ f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
@@ -255,7 +257,8 @@ static int searchvar (FuncState *fs, TString *n) {
*/
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
- while (bl->nactvar > level) bl = bl->previous;
+ while (bl->nactvar > level)
+ bl = bl->previous;
bl->upval = 1;
}
@@ -264,27 +267,26 @@ static void markupval (FuncState *fs, int level) {
Find variable with given name 'n'. If it is an upvalue, add this
upvalue into all intermediate functions.
*/
-static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
if (fs == NULL) /* no more levels? */
- return VVOID; /* default is global */
+ init_exp(var, VVOID, 0); /* default is global */
else {
int v = searchvar(fs, n); /* look up locals at current level */
if (v >= 0) { /* found? */
init_exp(var, VLOCAL, v); /* variable is local */
if (!base)
markupval(fs, v); /* local will be used as an upval */
- return VLOCAL;
}
else { /* not found as local at current level; try upvalues */
int idx = searchupvalue(fs, n); /* try existing upvalues */
if (idx < 0) { /* not found? */
- if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
- return VVOID; /* not found; is a global */
+ singlevaraux(fs->prev, n, var, 0); /* try upper levels */
+ if (var->k == VVOID) /* not found? */
+ return; /* it is a global */
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, var); /* will be a new upvalue */
}
- init_exp(var, VUPVAL, idx);
- return VUPVAL;
+ init_exp(var, VUPVAL, idx); /* new or old upvalue */
}
}
}
@@ -293,10 +295,11 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;
- if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
+ singlevaraux(fs, varname, var, 1);
+ if (var->k == VVOID) { /* global name? */
expdesc key;
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
- lua_assert(var->k == VLOCAL || var->k == VUPVAL);
+ lua_assert(var->k != VVOID); /* this one must exist */
codestring(ls, &key, varname); /* key is variable name */
luaK_indexed(fs, var, &key); /* env[varname] */
}
@@ -499,7 +502,8 @@ static Proto *addprototype (LexState *ls) {
if (fs->np >= f->sizep) {
int oldsize = f->sizep;
luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
- while (oldsize < f->sizep) f->p[oldsize++] = NULL;
+ while (oldsize < f->sizep)
+ f->p[oldsize++] = NULL;
}
f->p[fs->np++] = clp = luaF_newproto(L);
luaC_objbarrier(L, f, clp);
@@ -1226,7 +1230,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
checkrepeated(fs, ll, label); /* check for repeated labels */
checknext(ls, TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
- l = newlabelentry(ls, ll, label, line, fs->pc);
+ l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
skipnoopstat(ls); /* skip other no-op statements */
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */
@@ -1494,7 +1498,7 @@ static void exprstat (LexState *ls) {
}
else { /* stat -> func */
check_condition(ls, v.v.k == VCALL, "syntax error");
- SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
+ SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */
}
}
@@ -1511,8 +1515,8 @@ static void retstat (LexState *ls) {
if (hasmultret(e.k)) {
luaK_setmultret(fs, &e);
if (e.k == VCALL && nret == 1) { /* tail call? */
- SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
- lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
+ SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
+ lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
}
first = fs->nactvar;
nret = LUA_MULTRET; /* return all values */
diff --git a/libs/lua/lua-5.3.2/lparser.h b/libs/lua/lua-5.3.3/lparser.h
index 62c50cac7c..02e9b03aeb 100644
--- a/libs/lua/lua-5.3.2/lparser.h
+++ b/libs/lua/lua-5.3.3/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $
+** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -13,25 +13,38 @@
/*
-** Expression descriptor
+** Expression and variable descriptor.
+** Code generation for variables and expressions can be delayed to allow
+** optimizations; An 'expdesc' structure describes a potentially-delayed
+** variable/expression. It has a description of its "main" value plus a
+** list of conditional jumps that can also produce its value (generated
+** by short-circuit operators 'and'/'or').
*/
+/* kinds of variables/expressions */
typedef enum {
- VVOID, /* no value */
- VNIL,
- VTRUE,
- VFALSE,
- VK, /* info = index of constant in 'k' */
- VKFLT, /* nval = numerical float value */
- VKINT, /* nval = numerical integer value */
- VNONRELOC, /* info = result register */
- VLOCAL, /* info = local register */
- VUPVAL, /* info = index of upvalue in 'upvalues' */
- VINDEXED, /* t = table register/upvalue; idx = index R/K */
- VJMP, /* info = instruction pc */
- VRELOCABLE, /* info = instruction pc */
- VCALL, /* info = instruction pc */
- VVARARG /* info = instruction pc */
+ VVOID, /* when 'expdesc' describes the last expression a list,
+ this kind means an empty list (so, no expression) */
+ VNIL, /* constant nil */
+ VTRUE, /* constant true */
+ VFALSE, /* constant false */
+ VK, /* constant in 'k'; info = index of constant in 'k' */
+ VKFLT, /* floating constant; nval = numerical float value */
+ VKINT, /* integer constant; nval = numerical integer value */
+ VNONRELOC, /* expression has its value in a fixed register;
+ info = result register */
+ VLOCAL, /* local variable; info = local register */
+ VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
+ VINDEXED, /* indexed variable;
+ ind.vt = whether 't' is register or upvalue;
+ ind.t = table register or upvalue;
+ ind.idx = key's R/K index */
+ VJMP, /* expression is a test/comparison;
+ info = pc of corresponding jump instruction */
+ VRELOCABLE, /* expression can put result in any register;
+ info = instruction pc */
+ VCALL, /* expression is a function call; info = instruction pc */
+ VVARARG /* vararg expression; info = instruction pc */
} expkind;
@@ -41,14 +54,14 @@ typedef enum {
typedef struct expdesc {
expkind k;
union {
+ lua_Integer ival; /* for VKINT */
+ lua_Number nval; /* for VKFLT */
+ int info; /* for generic use */
struct { /* for indexed variables (VINDEXED) */
short idx; /* index (R/K) */
lu_byte t; /* table (register or upvalue) */
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
} ind;
- int info; /* for generic use */
- lua_Number nval; /* for VKFLT */
- lua_Integer ival; /* for VKINT */
} u;
int t; /* patch list of 'exit when true' */
int f; /* patch list of 'exit when false' */
diff --git a/libs/lua/lua-5.3.2/lprefix.h b/libs/lua/lua-5.3.3/lprefix.h
index 02daa837f5..02daa837f5 100644
--- a/libs/lua/lua-5.3.2/lprefix.h
+++ b/libs/lua/lua-5.3.3/lprefix.h
diff --git a/libs/lua/lua-5.3.2/lstate.c b/libs/lua/lua-5.3.3/lstate.c
index 9194ac3419..9194ac3419 100644
--- a/libs/lua/lua-5.3.2/lstate.c
+++ b/libs/lua/lua-5.3.3/lstate.c
diff --git a/libs/lua/lua-5.3.2/lstate.h b/libs/lua/lua-5.3.3/lstate.h
index 65c914d274..b3033bee55 100644
--- a/libs/lua/lua-5.3.2/lstate.h
+++ b/libs/lua/lua-5.3.3/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.128 2015/11/13 12:16:51 roberto Exp $
+** $Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -33,6 +33,15 @@
struct lua_longjmp; /* defined in ldo.c */
+/*
+** Atomic type (relative to signals) to better ensure that 'lua_sethook'
+** is thread safe
+*/
+#if !defined(l_signalT)
+#include <signal.h>
+#define l_signalT sig_atomic_t
+#endif
+
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
@@ -162,14 +171,14 @@ struct lua_State {
struct lua_State *twups; /* list of threads with open upvalues */
struct lua_longjmp *errorJmp; /* current error recover point */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
- lua_Hook hook;
+ volatile lua_Hook hook;
ptrdiff_t errfunc; /* current error handling function (stack index) */
int stacksize;
int basehookcount;
int hookcount;
unsigned short nny; /* number of non-yieldable calls in stack */
unsigned short nCcalls; /* number of nested C calls */
- lu_byte hookmask;
+ l_signalT hookmask;
lu_byte allowhook;
};
diff --git a/libs/lua/lua-5.3.2/lstring.c b/libs/lua/lua-5.3.3/lstring.c
index 9351766fd6..9351766fd6 100644
--- a/libs/lua/lua-5.3.2/lstring.c
+++ b/libs/lua/lua-5.3.3/lstring.c
diff --git a/libs/lua/lua-5.3.2/lstring.h b/libs/lua/lua-5.3.3/lstring.h
index 27efd20772..27efd20772 100644
--- a/libs/lua/lua-5.3.2/lstring.h
+++ b/libs/lua/lua-5.3.3/lstring.h
diff --git a/libs/lua/lua-5.3.2/lstrlib.c b/libs/lua/lua-5.3.3/lstrlib.c
index fe30e34b95..cd1ced5046 100644
--- a/libs/lua/lua-5.3.2/lstrlib.c
+++ b/libs/lua/lua-5.3.3/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp $
+** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -13,6 +13,7 @@
#include <ctype.h>
#include <float.h>
#include <limits.h>
+#include <locale.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -26,7 +27,8 @@
/*
** maximum number of captures that a pattern can do during
-** pattern-matching. This limit is arbitrary.
+** pattern-matching. This limit is arbitrary, but must fit in
+** an unsigned char.
*/
#if !defined(LUA_MAXCAPTURES)
#define LUA_MAXCAPTURES 32
@@ -214,9 +216,8 @@ typedef struct MatchState {
const char *src_end; /* end ('\0') of source string */
const char *p_end; /* end ('\0') of pattern */
lua_State *L;
- size_t nrep; /* limit to avoid non-linear complexity */
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
- int level; /* total number of captures (finished or unfinished) */
+ unsigned char level; /* total number of captures (finished or unfinished) */
struct {
const char *init;
ptrdiff_t len;
@@ -234,17 +235,6 @@ static const char *match (MatchState *ms, const char *s, const char *p);
#endif
-/*
-** parameters to control the maximum number of operators handled in
-** a match (to avoid non-linear complexity). The maximum will be:
-** (subject length) * A_REPS + B_REPS
-*/
-#if !defined(A_REPS)
-#define A_REPS 4
-#define B_REPS 100000
-#endif
-
-
#define L_ESC '%'
#define SPECIALS "^$*+?.([%-"
@@ -502,8 +492,6 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
s = NULL; /* fail */
}
else { /* matched once */
- if (ms->nrep-- == 0)
- luaL_error(ms->L, "pattern too complex");
switch (*ep) { /* handle optional suffix */
case '?': { /* optional */
const char *res;
@@ -607,10 +595,6 @@ static void prepstate (MatchState *ms, lua_State *L,
ms->src_init = s;
ms->src_end = s + ls;
ms->p_end = p + lp;
- if (ls < (MAX_SIZET - B_REPS) / A_REPS)
- ms->nrep = A_REPS * ls + B_REPS;
- else /* overflow (very long subject) */
- ms->nrep = MAX_SIZET; /* no limit */
}
@@ -681,6 +665,7 @@ static int str_match (lua_State *L) {
typedef struct GMatchState {
const char *src; /* current position */
const char *p; /* pattern */
+ const char *lastmatch; /* end of last match */
MatchState ms; /* match state */
} GMatchState;
@@ -688,14 +673,12 @@ typedef struct GMatchState {
static int gmatch_aux (lua_State *L) {
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
const char *src;
+ gm->ms.L = L;
for (src = gm->src; src <= gm->ms.src_end; src++) {
const char *e;
reprepstate(&gm->ms);
- if ((e = match(&gm->ms, src, gm->p)) != NULL) {
- if (e == src) /* empty match? */
- gm->src =src + 1; /* go at least one position */
- else
- gm->src = e;
+ if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
+ gm->src = gm->lastmatch = e;
return push_captures(&gm->ms, src, e);
}
}
@@ -711,7 +694,7 @@ static int gmatch (lua_State *L) {
lua_settop(L, 2); /* keep them on closure to avoid being collected */
gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
prepstate(&gm->ms, L, s, ls, p, lp);
- gm->src = s; gm->p = p;
+ gm->src = s; gm->p = p; gm->lastmatch = NULL;
lua_pushcclosure(L, gmatch_aux, 3);
return 1;
}
@@ -778,12 +761,13 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
static int str_gsub (lua_State *L) {
size_t srcl, lp;
- const char *src = luaL_checklstring(L, 1, &srcl);
- const char *p = luaL_checklstring(L, 2, &lp);
- int tr = lua_type(L, 3);
- lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
+ const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
+ const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
+ const char *lastmatch = NULL; /* end of last match */
+ int tr = lua_type(L, 3); /* replacement type */
+ lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
int anchor = (*p == '^');
- lua_Integer n = 0;
+ lua_Integer n = 0; /* replacement count */
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
@@ -796,16 +780,15 @@ static int str_gsub (lua_State *L) {
prepstate(&ms, L, src, srcl, p, lp);
while (n < max_s) {
const char *e;
- reprepstate(&ms);
- if ((e = match(&ms, src, p)) != NULL) {
+ reprepstate(&ms); /* (re)prepare state for new match */
+ if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
n++;
- add_value(&ms, &b, src, e, tr);
+ add_value(&ms, &b, src, e, tr); /* add replacement to buffer */
+ src = lastmatch = e;
}
- if (e && e>src) /* non empty match? */
- src = e; /* skip it */
- else if (src < ms.src_end)
+ else if (src < ms.src_end) /* otherwise, skip one character */
luaL_addchar(&b, *src++);
- else break;
+ else break; /* end of subject */
if (anchor) break;
}
luaL_addlstring(&b, src, ms.src_end-src);
@@ -830,7 +813,6 @@ static int str_gsub (lua_State *L) {
** Hexadecimal floating-point formatter
*/
-#include <locale.h>
#include <math.h>
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
@@ -922,16 +904,14 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
#define MAX_FORMAT 32
-static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
+static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
luaL_addchar(b, '"');
- while (l--) {
+ while (len--) {
if (*s == '"' || *s == '\\' || *s == '\n') {
luaL_addchar(b, '\\');
luaL_addchar(b, *s);
}
- else if (*s == '\0' || iscntrl(uchar(*s))) {
+ else if (iscntrl(uchar(*s))) {
char buff[10];
if (!isdigit(uchar(*(s+1))))
l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
@@ -946,6 +926,57 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
luaL_addchar(b, '"');
}
+
+/*
+** Ensures the 'buff' string uses a dot as the radix character.
+*/
+static void checkdp (char *buff, int nb) {
+ if (memchr(buff, '.', nb) == NULL) { /* no dot? */
+ char point = lua_getlocaledecpoint(); /* try locale point */
+ char *ppoint = (char*) memchr(buff, point, nb);
+ if (ppoint) *ppoint = '.'; /* change it to a dot */
+ }
+}
+
+
+static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
+ switch (lua_type(L, arg)) {
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(L, arg, &len);
+ addquoted(b, s, len);
+ break;
+ }
+ case LUA_TNUMBER: {
+ char *buff = luaL_prepbuffsize(b, MAX_ITEM);
+ int nb;
+ if (!lua_isinteger(L, arg)) { /* float? */
+ lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */
+ nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n);
+ checkdp(buff, nb); /* ensure it uses a dot */
+ }
+ else { /* integers */
+ lua_Integer n = lua_tointeger(L, arg);
+ const char *format = (n == LUA_MININTEGER) /* corner case? */
+ ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */
+ : LUA_INTEGER_FMT; /* else use default format */
+ nb = l_sprintf(buff, MAX_ITEM, format, n);
+ }
+ luaL_addsize(b, nb);
+ break;
+ }
+ case LUA_TNIL: case LUA_TBOOLEAN: {
+ luaL_tolstring(L, arg, NULL);
+ luaL_addvalue(b);
+ break;
+ }
+ default: {
+ luaL_argerror(L, arg, "value has no literal form");
+ }
+ }
+}
+
+
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
const char *p = strfrmt;
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
@@ -1025,7 +1056,7 @@ static int str_format (lua_State *L) {
break;
}
case 'q': {
- addquoted(L, &b, arg);
+ addliteral(L, &b, arg);
break;
}
case 's': {
@@ -1070,8 +1101,8 @@ static int str_format (lua_State *L) {
/* value used for padding */
-#if !defined(LUA_PACKPADBYTE)
-#define LUA_PACKPADBYTE 0x00
+#if !defined(LUAL_PACKPADBYTE)
+#define LUAL_PACKPADBYTE 0x00
#endif
/* maximum size for the binary representation of an integer */
@@ -1308,7 +1339,7 @@ static int str_pack (lua_State *L) {
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
totalsize += ntoalign + size;
while (ntoalign-- > 0)
- luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */
+ luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
arg++;
switch (opt) {
case Kint: { /* signed integers */
@@ -1343,13 +1374,11 @@ static int str_pack (lua_State *L) {
case Kchar: { /* fixed-size string */
size_t len;
const char *s = luaL_checklstring(L, arg, &len);
- if ((size_t)size <= len) /* string larger than (or equal to) needed? */
- luaL_addlstring(&b, s, size); /* truncate string to asked size */
- else { /* string smaller than needed */
- luaL_addlstring(&b, s, len); /* add it all */
- while (len++ < (size_t)size) /* pad extra space */
- luaL_addchar(&b, LUA_PACKPADBYTE);
- }
+ luaL_argcheck(L, len <= (size_t)size, arg,
+ "string longer than given size");
+ luaL_addlstring(&b, s, len); /* add string */
+ while (len++ < (size_t)size) /* pad extra space */
+ luaL_addchar(&b, LUAL_PACKPADBYTE);
break;
}
case Kstring: { /* strings with length count */
@@ -1372,7 +1401,7 @@ static int str_pack (lua_State *L) {
totalsize += len + 1;
break;
}
- case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
+ case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
case Kpaddalign: case Knop:
arg--; /* undo increment */
break;
diff --git a/libs/lua/lua-5.3.2/ltable.c b/libs/lua/lua-5.3.3/ltable.c
index 7e15b71bad..7e15b71bad 100644
--- a/libs/lua/lua-5.3.2/ltable.c
+++ b/libs/lua/lua-5.3.3/ltable.c
diff --git a/libs/lua/lua-5.3.2/ltable.h b/libs/lua/lua-5.3.3/ltable.h
index 213cc13987..213cc13987 100644
--- a/libs/lua/lua-5.3.2/ltable.h
+++ b/libs/lua/lua-5.3.3/ltable.h
diff --git a/libs/lua/lua-5.3.2/ltablib.c b/libs/lua/lua-5.3.3/ltablib.c
index b3c9a7c528..98b2f87137 100644
--- a/libs/lua/lua-5.3.2/ltablib.c
+++ b/libs/lua/lua-5.3.3/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.90 2015/11/25 12:48:57 roberto Exp $
+** $Id: ltablib.c,v 1.93 2016/02/25 19:41:54 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -53,7 +53,7 @@ static void checktab (lua_State *L, int arg, int what) {
lua_pop(L, n); /* pop metatable and tested metamethods */
}
else
- luaL_argerror(L, arg, "table expected"); /* force an error */
+ luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
}
}
@@ -139,7 +139,7 @@ static int tmove (lua_State *L) {
n = e - f + 1; /* number of elements to move */
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
"destination wrap around");
- if (t > e || t <= f || tt != 1) {
+ if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
for (i = 0; i < n; i++) {
lua_geti(L, 1, f + i);
lua_seti(L, tt, t + i);
@@ -152,7 +152,7 @@ static int tmove (lua_State *L) {
}
}
}
- lua_pushvalue(L, tt); /* return "to table" */
+ lua_pushvalue(L, tt); /* return destination table */
return 1;
}
@@ -172,7 +172,7 @@ static int tconcat (lua_State *L) {
size_t lsep;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
lua_Integer i = luaL_optinteger(L, 3, 1);
- last = luaL_opt(L, luaL_checkinteger, 4, last);
+ last = luaL_optinteger(L, 4, last);
luaL_buffinit(L, &b);
for (; i < last; i++) {
addfield(L, &b, i);
@@ -232,6 +232,10 @@ static int unpack (lua_State *L) {
*/
+/* type for array indices */
+typedef unsigned int IdxT;
+
+
/*
** Produce a "random" 'unsigned int' to randomize pivot choice. This
** macro is used only when 'sort' detects a big imbalance in the result
@@ -270,7 +274,7 @@ static unsigned int l_randomizePivot (void) {
#define RANLIMIT 100u
-static void set2 (lua_State *L, unsigned int i, unsigned int j) {
+static void set2 (lua_State *L, IdxT i, IdxT j) {
lua_seti(L, 1, i);
lua_seti(L, 1, j);
}
@@ -303,10 +307,9 @@ static int sort_comp (lua_State *L, int a, int b) {
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
** returns 'i'.
*/
-static unsigned int partition (lua_State *L, unsigned int lo,
- unsigned int up) {
- unsigned int i = lo; /* will be incremented before first use */
- unsigned int j = up - 1; /* will be decremented before first use */
+static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
+ IdxT i = lo; /* will be incremented before first use */
+ IdxT j = up - 1; /* will be decremented before first use */
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
for (;;) {
/* next loop: repeat ++i while a[i] < P */
@@ -340,10 +343,9 @@ static unsigned int partition (lua_State *L, unsigned int lo,
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
** "randomized" by 'rnd'
*/
-static unsigned int choosePivot (unsigned int lo, unsigned int up,
- unsigned int rnd) {
- unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */
- unsigned int p = rnd % (r4 * 2) + (lo + r4);
+static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
+ IdxT r4 = (up - lo) / 4; /* range/4 */
+ IdxT p = rnd % (r4 * 2) + (lo + r4);
lua_assert(lo + r4 <= p && p <= up - r4);
return p;
}
@@ -352,11 +354,11 @@ static unsigned int choosePivot (unsigned int lo, unsigned int up,
/*
** QuickSort algorithm (recursive function)
*/
-static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
+static void auxsort (lua_State *L, IdxT lo, IdxT up,
unsigned int rnd) {
while (lo < up) { /* loop for tail recursion */
- unsigned int p; /* Pivot index */
- unsigned int n; /* to be used later */
+ IdxT p; /* Pivot index */
+ IdxT n; /* to be used later */
/* sort elements 'lo', 'p', and 'up' */
lua_geti(L, 1, lo);
lua_geti(L, 1, up);
@@ -400,7 +402,7 @@ static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
n = up - p; /* size of smaller interval */
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
}
- if ((up - lo) / 128u > n) /* partition too imbalanced? */
+ if ((up - lo) / 128 > n) /* partition too imbalanced? */
rnd = l_randomizePivot(); /* try a new randomization */
} /* tail call auxsort(L, lo, up, rnd) */
}
@@ -410,11 +412,10 @@ static int sort (lua_State *L) {
lua_Integer n = aux_getn(L, 1, TAB_RW);
if (n > 1) { /* non-trivial interval? */
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
- luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
lua_settop(L, 2); /* make sure there are two arguments */
- auxsort(L, 1, (unsigned int)n, 0u);
+ auxsort(L, 1, (IdxT)n, 0);
}
return 0;
}
diff --git a/libs/lua/lua-5.3.2/ltm.c b/libs/lua/lua-5.3.3/ltm.c
index 22b4df39df..4650cc2931 100644
--- a/libs/lua/lua-5.3.2/ltm.c
+++ b/libs/lua/lua-5.3.3/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp $
+** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -83,6 +83,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
}
+/*
+** Return the name of the type of an object. For tables and userdata
+** with metatable, use their '__name' metafield, if present.
+*/
+const char *luaT_objtypename (lua_State *L, const TValue *o) {
+ Table *mt;
+ if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
+ (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
+ const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
+ if (ttisstring(name)) /* is '__name' a string? */
+ return getstr(tsvalue(name)); /* use it as type name */
+ }
+ return ttypename(ttnov(o)); /* else use standard type name */
+}
+
+
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, TValue *p3, int hasres) {
ptrdiff_t result = savestack(L, p3);
diff --git a/libs/lua/lua-5.3.2/ltm.h b/libs/lua/lua-5.3.3/ltm.h
index 180179ce03..63db7269bb 100644
--- a/libs/lua/lua-5.3.2/ltm.h
+++ b/libs/lua/lua-5.3.3/ltm.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
+** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -51,11 +51,12 @@ typedef enum {
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
-#define objtypename(x) ttypename(ttnov(x))
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
+LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
+
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);
diff --git a/libs/lua/lua-5.3.2/lua.c b/libs/lua/lua-5.3.3/lua.c
index 545d23d49b..545d23d49b 100644
--- a/libs/lua/lua-5.3.2/lua.c
+++ b/libs/lua/lua-5.3.3/lua.c
diff --git a/libs/lua/lua-5.3.2/lua.h b/libs/lua/lua-5.3.3/lua.h
index 06381d7159..f78899fc55 100644
--- a/libs/lua/lua-5.3.2/lua.h
+++ b/libs/lua/lua-5.3.3/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.329 2015/11/13 17:18:42 roberto Exp $
+** $Id: lua.h,v 1.331 2016/05/30 15:53:28 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 +19,11 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
-#define LUA_VERSION_RELEASE "2"
+#define LUA_VERSION_RELEASE "3"
#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-2015 Lua.org, PUC-Rio"
+#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
@@ -361,7 +361,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushglobaltable(L) \
- lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
+ ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
@@ -460,7 +460,7 @@ struct lua_Debug {
/******************************************************************************
-* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
+* Copyright (C) 1994-2016 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/libs/lua/lua-5.3.2/lua.hpp b/libs/lua/lua-5.3.3/lua.hpp
index ec417f5946..ec417f5946 100644
--- a/libs/lua/lua-5.3.2/lua.hpp
+++ b/libs/lua/lua-5.3.3/lua.hpp
diff --git a/libs/lua/lua-5.3.2/luac.c b/libs/lua/lua-5.3.3/luac.c
index c0c91d017a..c0c91d017a 100644
--- a/libs/lua/lua-5.3.2/luac.c
+++ b/libs/lua/lua-5.3.3/luac.c
diff --git a/libs/lua/lua-5.3.2/luaconf.h b/libs/lua/lua-5.3.3/luaconf.h
index b4ed500118..fd447ccb93 100644
--- a/libs/lua/lua-5.3.2/luaconf.h
+++ b/libs/lua/lua-5.3.3/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.254 2015/10/21 18:17:40 roberto Exp $
+** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -612,7 +612,7 @@
** provide its own implementation.
*/
#if !defined(LUA_USE_C89)
-#define lua_number2strx(L,b,sz,f,n) l_sprintf(b,sz,f,n)
+#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n))
#endif
diff --git a/libs/lua/lua-5.3.2/lualib.h b/libs/lua/lua-5.3.3/lualib.h
index 5165c0fb3f..5165c0fb3f 100644
--- a/libs/lua/lua-5.3.2/lualib.h
+++ b/libs/lua/lua-5.3.3/lualib.h
diff --git a/libs/lua/lua-5.3.2/lundump.c b/libs/lua/lua-5.3.3/lundump.c
index 4080af9c0d..4080af9c0d 100644
--- a/libs/lua/lua-5.3.2/lundump.c
+++ b/libs/lua/lua-5.3.3/lundump.c
diff --git a/libs/lua/lua-5.3.2/lundump.h b/libs/lua/lua-5.3.3/lundump.h
index aa5cc82f1b..aa5cc82f1b 100644
--- a/libs/lua/lua-5.3.2/lundump.h
+++ b/libs/lua/lua-5.3.3/lundump.h
diff --git a/libs/lua/lua-5.3.2/lutf8lib.c b/libs/lua/lua-5.3.3/lutf8lib.c
index 9042582d1e..9042582d1e 100644
--- a/libs/lua/lua-5.3.2/lutf8lib.c
+++ b/libs/lua/lua-5.3.3/lutf8lib.c
diff --git a/libs/lua/lua-5.3.2/lvm.c b/libs/lua/lua-5.3.3/lvm.c
index aba7ace817..84ade6b2fa 100644
--- a/libs/lua/lua-5.3.2/lvm.c
+++ b/libs/lua/lua-5.3.3/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.265 2015/11/23 11:30:45 roberto Exp $
+** $Id: lvm.c,v 2.268 2016/02/05 19:59:14 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -153,55 +153,69 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
/*
-** Complete a table access: if 't' is a table, 'tm' has its metamethod;
-** otherwise, 'tm' is NULL.
+** Finish the table access 'val = t[key]'.
+** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
+** t[k] entry (which must be nil).
*/
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
- const TValue *tm) {
+ const TValue *slot) {
int loop; /* counter to avoid infinite loops */
- lua_assert(tm != NULL || !ttistable(t));
+ const TValue *tm; /* metamethod */
for (loop = 0; loop < MAXTAGLOOP; loop++) {
- if (tm == NULL) { /* no metamethod (from a table)? */
- if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
+ if (slot == NULL) { /* 't' is not a table? */
+ lua_assert(!ttistable(t));
+ tm = luaT_gettmbyobj(L, t, TM_INDEX);
+ if (ttisnil(tm))
luaG_typeerror(L, t, "index"); /* no metamethod */
+ /* else will try the metamethod */
}
- if (ttisfunction(tm)) { /* metamethod is a function */
+ else { /* 't' is a table */
+ lua_assert(ttisnil(slot));
+ tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
+ if (tm == NULL) { /* no metamethod? */
+ setnilvalue(val); /* result is nil */
+ return;
+ }
+ /* else will try the metamethod */
+ }
+ if (ttisfunction(tm)) { /* is metamethod a function? */
luaT_callTM(L, tm, t, key, val, 1); /* call it */
return;
}
- t = tm; /* else repeat access over 'tm' */
- if (luaV_fastget(L,t,key,tm,luaH_get)) { /* try fast track */
- setobj2s(L, val, tm); /* done */
+ t = tm; /* else try to access 'tm[key]' */
+ if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
+ setobj2s(L, val, slot); /* done */
return;
}
- /* else repeat */
+ /* else repeat (tail call 'luaV_finishget') */
}
- luaG_runerror(L, "gettable chain too long; possible loop");
+ luaG_runerror(L, "'__index' chain too long; possible loop");
}
/*
-** Main function for table assignment (invoking metamethods if needed).
-** Compute 't[key] = val'
+** Finish a table assignment 't[key] = val'.
+** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
+** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
+** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
+** would have done the job.)
*/
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
- StkId val, const TValue *oldval) {
+ StkId val, const TValue *slot) {
int loop; /* counter to avoid infinite loops */
for (loop = 0; loop < MAXTAGLOOP; loop++) {
- const TValue *tm;
- if (oldval != NULL) {
- lua_assert(ttistable(t) && ttisnil(oldval));
- /* must check the metamethod */
- if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL &&
- /* no metamethod; is there a previous entry in the table? */
- (oldval != luaO_nilobject ||
- /* no previous entry; must create one. (The next test is
- always true; we only need the assignment.) */
- (oldval = luaH_newkey(L, hvalue(t), key), 1))) {
+ const TValue *tm; /* '__newindex' metamethod */
+ if (slot != NULL) { /* is 't' a table? */
+ Table *h = hvalue(t); /* save 't' table */
+ lua_assert(ttisnil(slot)); /* old value must be nil */
+ tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
+ if (tm == NULL) { /* no metamethod? */
+ if (slot == luaO_nilobject) /* no previous entry? */
+ slot = luaH_newkey(L, h, key); /* create one */
/* no metamethod and (now) there is an entry with given key */
- setobj2t(L, cast(TValue *, oldval), val);
- invalidateTMcache(hvalue(t));
- luaC_barrierback(L, hvalue(t), val);
+ setobj2t(L, cast(TValue *, slot), val); /* set its new value */
+ invalidateTMcache(h);
+ luaC_barrierback(L, h, val);
return;
}
/* else will try the metamethod */
@@ -216,11 +230,11 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
return;
}
t = tm; /* else repeat assignment over 'tm' */
- if (luaV_fastset(L, t, key, oldval, luaH_get, val))
+ if (luaV_fastset(L, t, key, slot, luaH_get, val))
return; /* done */
/* else loop */
}
- luaG_runerror(L, "settable chain too long; possible loop");
+ luaG_runerror(L, "'__newindex' chain too long; possible loop");
}
@@ -738,18 +752,28 @@ void luaV_finishOp (lua_State *L) {
luai_threadyield(L); }
+/* fetch an instruction and prepare its execution */
+#define vmfetch() { \
+ i = *(ci->u.l.savedpc++); \
+ if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
+ Protect(luaG_traceexec(L)); \
+ ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
+ lua_assert(base == ci->u.l.base); \
+ lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
+}
+
#define vmdispatch(o) switch(o)
#define vmcase(l) case l:
#define vmbreak break
/*
-** copy of 'luaV_gettable', but protecting call to potential metamethod
-** (which can reallocate the stack)
+** copy of 'luaV_gettable', but protecting the call to potential
+** metamethod (which can reallocate the stack)
*/
-#define gettableProtected(L,t,k,v) { const TValue *aux; \
- if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
- else Protect(luaV_finishget(L,t,k,v,aux)); }
+#define gettableProtected(L,t,k,v) { const TValue *slot; \
+ if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
+ else Protect(luaV_finishget(L,t,k,v,slot)); }
/* same for 'luaV_settable' */
@@ -772,14 +796,9 @@ void luaV_execute (lua_State *L) {
base = ci->u.l.base; /* local copy of function's base */
/* main loop of interpreter */
for (;;) {
- Instruction i = *(ci->u.l.savedpc++);
+ Instruction i;
StkId ra;
- if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT))
- Protect(luaG_traceexec(L));
- /* WARNING: several calls may realloc the stack and invalidate 'ra' */
- ra = RA(i);
- lua_assert(base == ci->u.l.base);
- lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
+ vmfetch();
vmdispatch (GET_OPCODE(i)) {
vmcase(OP_MOVE) {
setobjs2s(L, ra, RB(i));
diff --git a/libs/lua/lua-5.3.2/lvm.h b/libs/lua/lua-5.3.3/lvm.h
index fd0e748d4e..bcf52d20a1 100644
--- a/libs/lua/lua-5.3.2/lvm.h
+++ b/libs/lua/lua-5.3.3/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.39 2015/09/09 13:44:07 roberto Exp $
+** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -49,25 +49,24 @@
/*
-** fast track for 'gettable': 1 means 'aux' points to resulted value;
-** 0 means 'aux' is metamethod (if 't' is a table) or NULL. 'f' is
-** the raw get function to use.
+** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
+** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
+** return 0 (meaning it will have to check metamethod) with 'slot'
+** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
+** 'f' is the raw get function to use.
*/
-#define luaV_fastget(L,t,k,aux,f) \
+#define luaV_fastget(L,t,k,slot,f) \
(!ttistable(t) \
- ? (aux = NULL, 0) /* not a table; 'aux' is NULL and result is 0 */ \
- : (aux = f(hvalue(t), k), /* else, do raw access */ \
- !ttisnil(aux) ? 1 /* result not nil? 'aux' has it */ \
- : (aux = fasttm(L, hvalue(t)->metatable, TM_INDEX), /* get metamethod */\
- aux != NULL ? 0 /* has metamethod? must call it */ \
- : (aux = luaO_nilobject, 1)))) /* else, final result is nil */
+ ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
+ : (slot = f(hvalue(t), k), /* else, do raw access */ \
+ !ttisnil(slot))) /* result not nil? */
/*
** standard implementation for 'gettable'
*/
-#define luaV_gettable(L,t,k,v) { const TValue *aux; \
- if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
- else luaV_finishget(L,t,k,v,aux); }
+#define luaV_gettable(L,t,k,v) { const TValue *slot; \
+ if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
+ else luaV_finishget(L,t,k,v,slot); }
/*
@@ -100,9 +99,9 @@ LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
- StkId val, const TValue *tm);
+ StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
- StkId val, const TValue *oldval);
+ StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);
diff --git a/libs/lua/lua-5.3.2/lzio.c b/libs/lua/lua-5.3.3/lzio.c
index c9e1f491f3..c9e1f491f3 100644
--- a/libs/lua/lua-5.3.2/lzio.c
+++ b/libs/lua/lua-5.3.3/lzio.c
diff --git a/libs/lua/lua-5.3.2/lzio.h b/libs/lua/lua-5.3.3/lzio.h
index e7b6f34b1e..e7b6f34b1e 100644
--- a/libs/lua/lua-5.3.2/lzio.h
+++ b/libs/lua/lua-5.3.3/lzio.h
diff --git a/libs/lua/lua.cc b/libs/lua/lua.cc
index c86938f126..7eed622f9b 100644
--- a/libs/lua/lua.cc
+++ b/libs/lua/lua.cc
@@ -39,7 +39,7 @@ extern "C"
#define lvm_c
#define LUA_CORE
#define LUA_LIB
-#include "lua-5.3.2/luaconf.h"
+#include "lua-5.3.3/luaconf.h"
#undef lobject_c
#undef lvm_c
#undef LUA_CORE
@@ -68,43 +68,43 @@ extern "C"
#pragma warning (disable: 4702) /* Unreachable code */
#endif
-#include "lua-5.3.2/ltable.c"
-
-#include "lua-5.3.2/lauxlib.c"
-#include "lua-5.3.2/lbaselib.c"
-
-#include "lua-5.3.2/lbitlib.c"
-#include "lua-5.3.2/lcorolib.c"
-#include "lua-5.3.2/ldblib.c"
-#include "lua-5.3.2/linit.c"
-#include "lua-5.3.2/liolib.c"
-#include "lua-5.3.2/lmathlib.c"
-#include "lua-5.3.2/loslib.c"
-#include "lua-5.3.2/lstrlib.c"
-#include "lua-5.3.2/ltablib.c"
-
-#include "lua-5.3.2/lapi.c"
-#include "lua-5.3.2/lcode.c"
-#include "lua-5.3.2/lctype.c"
-#include "lua-5.3.2/ldebug.c"
-#include "lua-5.3.2/ldo.c"
-#include "lua-5.3.2/ldump.c"
-#include "lua-5.3.2/lfunc.c"
-#include "lua-5.3.2/lgc.c"
-#include "lua-5.3.2/llex.c"
-#include "lua-5.3.2/lmem.c"
-#include "lua-5.3.2/lobject.c"
-#include "lua-5.3.2/lopcodes.c"
-#include "lua-5.3.2/lparser.c"
-#include "lua-5.3.2/lstate.c"
-#include "lua-5.3.2/lstring.c"
-#include "lua-5.3.2/ltm.c"
-#include "lua-5.3.2/lundump.c"
-#include "lua-5.3.2/lutf8lib.c"
-#include "lua-5.3.2/lvm.c"
-#include "lua-5.3.2/lzio.c"
-
-#include "lua-5.3.2/loadlib.c"
+#include "lua-5.3.3/ltable.c"
+
+#include "lua-5.3.3/lauxlib.c"
+#include "lua-5.3.3/lbaselib.c"
+
+#include "lua-5.3.3/lbitlib.c"
+#include "lua-5.3.3/lcorolib.c"
+#include "lua-5.3.3/ldblib.c"
+#include "lua-5.3.3/linit.c"
+#include "lua-5.3.3/liolib.c"
+#include "lua-5.3.3/lmathlib.c"
+#include "lua-5.3.3/loslib.c"
+#include "lua-5.3.3/lstrlib.c"
+#include "lua-5.3.3/ltablib.c"
+
+#include "lua-5.3.3/lapi.c"
+#include "lua-5.3.3/lcode.c"
+#include "lua-5.3.3/lctype.c"
+#include "lua-5.3.3/ldebug.c"
+#include "lua-5.3.3/ldo.c"
+#include "lua-5.3.3/ldump.c"
+#include "lua-5.3.3/lfunc.c"
+#include "lua-5.3.3/lgc.c"
+#include "lua-5.3.3/llex.c"
+#include "lua-5.3.3/lmem.c"
+#include "lua-5.3.3/lobject.c"
+#include "lua-5.3.3/lopcodes.c"
+#include "lua-5.3.3/lparser.c"
+#include "lua-5.3.3/lstate.c"
+#include "lua-5.3.3/lstring.c"
+#include "lua-5.3.3/ltm.c"
+#include "lua-5.3.3/lundump.c"
+#include "lua-5.3.3/lutf8lib.c"
+#include "lua-5.3.3/lvm.c"
+#include "lua-5.3.3/lzio.c"
+
+#include "lua-5.3.3/loadlib.c"
#if _MSC_VER
#pragma warning (pop)