summaryrefslogtreecommitdiff
path: root/plugins/MirLua/src
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-06-21 19:42:06 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-06-21 19:42:06 +0000
commite79638b70be57501bb9995b24665a109188922fc (patch)
tree9482f9a9fcd5a461a6b9cf1b9742b3bc0df505bb /plugins/MirLua/src
parent8ba0d63234b84060efe27542bf317cb9cf50b3af (diff)
MirLua: lua updated to 5.3.1
git-svn-id: http://svn.miranda-ng.org/main/trunk@14308 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirLua/src')
-rw-r--r--plugins/MirLua/src/lua/lapi.c123
-rw-r--r--plugins/MirLua/src/lua/lapi.h6
-rw-r--r--plugins/MirLua/src/lua/lauxlib.c4
-rw-r--r--plugins/MirLua/src/lua/lbaselib.c4
-rw-r--r--plugins/MirLua/src/lua/lcode.c17
-rw-r--r--plugins/MirLua/src/lua/ldblib.c21
-rw-r--r--plugins/MirLua/src/lua/ldebug.c66
-rw-r--r--plugins/MirLua/src/lua/ldebug.h7
-rw-r--r--plugins/MirLua/src/lua/ldo.c26
-rw-r--r--plugins/MirLua/src/lua/ldo.h4
-rw-r--r--plugins/MirLua/src/lua/ldump.c7
-rw-r--r--plugins/MirLua/src/lua/lfunc.h9
-rw-r--r--plugins/MirLua/src/lua/lgc.c46
-rw-r--r--plugins/MirLua/src/lua/liolib.c15
-rw-r--r--plugins/MirLua/src/lua/llex.c28
-rw-r--r--plugins/MirLua/src/lua/llimits.h107
-rw-r--r--plugins/MirLua/src/lua/lmathlib.c5
-rw-r--r--plugins/MirLua/src/lua/lmem.c11
-rw-r--r--plugins/MirLua/src/lua/loadlib.c7
-rw-r--r--plugins/MirLua/src/lua/lobject.c41
-rw-r--r--plugins/MirLua/src/lua/lobject.h35
-rw-r--r--plugins/MirLua/src/lua/loslib.c74
-rw-r--r--plugins/MirLua/src/lua/lstate.c10
-rw-r--r--plugins/MirLua/src/lua/lstate.h4
-rw-r--r--plugins/MirLua/src/lua/lstring.c72
-rw-r--r--plugins/MirLua/src/lua/lstring.h5
-rw-r--r--plugins/MirLua/src/lua/lstrlib.c124
-rw-r--r--plugins/MirLua/src/lua/ltable.c123
-rw-r--r--plugins/MirLua/src/lua/ltablib.c8
-rw-r--r--plugins/MirLua/src/lua/ltm.c5
-rw-r--r--plugins/MirLua/src/lua/lua.h13
-rw-r--r--plugins/MirLua/src/lua/luaconf.h211
-rw-r--r--plugins/MirLua/src/lua/lutf8lib.c13
-rw-r--r--plugins/MirLua/src/lua/lvm.c256
-rw-r--r--plugins/MirLua/src/lua/lvm.h16
35 files changed, 977 insertions, 546 deletions
diff --git a/plugins/MirLua/src/lua/lapi.c b/plugins/MirLua/src/lua/lapi.c
index fbfafa304f..fea9eb2765 100644
--- a/plugins/MirLua/src/lua/lapi.c
+++ b/plugins/MirLua/src/lua/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp $
+** $Id: lapi.c,v 2.249 2015/04/06 12:23:48 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -51,29 +51,29 @@ const char lua_ident[] =
/* test for valid but not pseudo index */
#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
-#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
+#define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index")
-#define api_checkstackindex(i, o) \
- api_check(isstackindex(i, o), "index not in the stack")
+#define api_checkstackindex(l, i, o) \
+ api_check(l, isstackindex(i, o), "index not in the stack")
static TValue *index2addr (lua_State *L, int idx) {
CallInfo *ci = L->ci;
if (idx > 0) {
TValue *o = ci->func + idx;
- api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
+ api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (!ispseudo(idx)) { /* negative index */
- api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+ api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry;
else { /* upvalues */
idx = LUA_REGISTRYINDEX - idx;
- api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
+ api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
return NONVALIDVALUE; /* it has no upvalues */
else {
@@ -98,7 +98,7 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
int res;
CallInfo *ci = L->ci;
lua_lock(L);
- api_check(n >= 0, "negative 'n'");
+ api_check(L, n >= 0, "negative 'n'");
if (L->stack_last - L->top > n) /* stack large enough? */
res = 1; /* yes; check is OK */
else { /* no; need to grow stack */
@@ -120,11 +120,12 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
- api_check(G(from) == G(to), "moving among independent states");
- api_check(to->ci->top - to->top >= n, "not enough elements to move");
+ api_check(from, G(from) == G(to), "moving among independent states");
+ api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
from->top -= n;
for (i = 0; i < n; i++) {
- setobj2s(to, to->top++, from->top + i);
+ setobj2s(to, to->top, from->top + i);
+ api_incr_top(to);
}
lua_unlock(to);
}
@@ -159,7 +160,7 @@ LUA_API const lua_Number *lua_version (lua_State *L) {
LUA_API int lua_absindex (lua_State *L, int idx) {
return (idx > 0 || ispseudo(idx))
? idx
- : cast_int(L->top - L->ci->func + idx);
+ : cast_int(L->top - L->ci->func) + idx;
}
@@ -172,13 +173,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
StkId func = L->ci->func;
lua_lock(L);
if (idx >= 0) {
- api_check(idx <= L->stack_last - (func + 1), "new top too large");
+ api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
while (L->top < (func + 1) + idx)
setnilvalue(L->top++);
L->top = (func + 1) + idx;
}
else {
- api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
+ api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
L->top += idx+1; /* 'subtract' index (index is negative) */
}
lua_unlock(L);
@@ -208,8 +209,8 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
lua_lock(L);
t = L->top - 1; /* end of stack segment being rotated */
p = index2addr(L, idx); /* start of segment */
- api_checkstackindex(idx, p);
- api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
+ api_checkstackindex(L, idx, p);
+ api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
reverse(L, p, m); /* reverse the prefix with length 'n' */
reverse(L, m + 1, t); /* reverse the suffix */
@@ -223,7 +224,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
lua_lock(L);
fr = index2addr(L, fromidx);
to = index2addr(L, toidx);
- api_checkvalidindex(to);
+ api_checkvalidindex(L, to);
setobj(L, to, fr);
if (isupvalue(toidx)) /* function upvalue? */
luaC_barrier(L, clCvalue(L->ci->func), fr);
@@ -255,7 +256,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
- api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
+ api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
return ttypename(t);
}
@@ -305,7 +306,7 @@ LUA_API void lua_arith (lua_State *L, int op) {
else { /* for unary operations, add fake 2nd operand */
api_checknelems(L, 1);
setobjs2s(L, L->top, L->top - 1);
- L->top++;
+ api_incr_top(L);
}
/* first operand at top - 2, second at top - 1; result go to top - 2 */
luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
@@ -325,7 +326,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
- default: api_check(0, "invalid option");
+ default: api_check(L, 0, "invalid option");
}
}
lua_unlock(L);
@@ -382,15 +383,17 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
luaO_tostring(L, o);
lua_unlock(L);
}
- if (len != NULL) *len = tsvalue(o)->len;
+ if (len != NULL)
+ *len = vslen(o);
return svalue(o);
}
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- switch (ttnov(o)) {
- case LUA_TSTRING: return tsvalue(o)->len;
+ switch (ttype(o)) {
+ case LUA_TSHRSTR: return tsvalue(o)->shrlen;
+ case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
default: return 0;
@@ -431,9 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TCCL: return clCvalue(o);
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
case LUA_TTHREAD: return thvalue(o);
- case LUA_TUSERDATA:
- case LUA_TLIGHTUSERDATA:
- return lua_touserdata(L, idx);
+ case LUA_TUSERDATA: return getudatamem(uvalue(o));
+ case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
}
}
@@ -482,20 +484,19 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
- if (s == NULL) {
- lua_pushnil(L);
- return NULL;
- }
+ lua_lock(L);
+ if (s == NULL)
+ setnilvalue(L->top);
else {
TString *ts;
- lua_lock(L);
luaC_checkGC(L);
ts = luaS_new(L, s);
setsvalue2s(L, L->top, ts);
- api_incr_top(L);
- lua_unlock(L);
- return getstr(ts);
+ s = getstr(ts); /* internal copy's address */
}
+ api_incr_top(L);
+ lua_unlock(L);
+ return s;
}
@@ -531,7 +532,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
else {
CClosure *cl;
api_checknelems(L, n);
- api_check(n <= MAXUPVAL, "upvalue index too large");
+ api_check(L, n <= MAXUPVAL, "upvalue index too large");
luaC_checkGC(L);
cl = luaF_newCclosure(L, n);
cl->f = fn;
@@ -583,7 +584,8 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
const TValue *gt; /* global table */
lua_lock(L);
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- setsvalue2s(L, L->top++, luaS_new(L, name));
+ setsvalue2s(L, L->top, luaS_new(L, name));
+ api_incr_top(L);
luaV_gettable(L, gt, L->top - 1, L->top - 1);
lua_unlock(L);
return ttnov(L->top - 1);
@@ -628,7 +630,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
+ api_check(L, ttistable(t), "table expected");
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
return ttnov(L->top - 1);
@@ -639,7 +641,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
+ api_check(L, ttistable(t), "table expected");
setobj2s(L, L->top, luaH_getint(hvalue(t), n));
api_incr_top(L);
lua_unlock(L);
@@ -652,7 +654,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
TValue k;
lua_lock(L);
t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
+ api_check(L, ttistable(t), "table expected");
setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
@@ -705,7 +707,7 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = index2addr(L, idx);
- api_check(ttisfulluserdata(o), "full userdata expected");
+ api_check(L, ttisfulluserdata(o), "full userdata expected");
getuservalue(L, uvalue(o), L->top);
api_incr_top(L);
lua_unlock(L);
@@ -724,7 +726,8 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
lua_lock(L);
api_checknelems(L, 1);
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- setsvalue2s(L, L->top++, luaS_new(L, name));
+ setsvalue2s(L, L->top, luaS_new(L, name));
+ api_incr_top(L);
luaV_settable(L, gt, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -747,7 +750,8 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
- setsvalue2s(L, L->top++, luaS_new(L, k));
+ setsvalue2s(L, L->top, luaS_new(L, k));
+ api_incr_top(L);
luaV_settable(L, t, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -759,7 +763,8 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
- setivalue(L->top++, n);
+ setivalue(L->top, n);
+ api_incr_top(L);
luaV_settable(L, t, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -772,7 +777,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 2);
o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
+ api_check(L, ttistable(o), "table expected");
t = hvalue(o);
setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
invalidateTMcache(t);
@@ -788,7 +793,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
+ api_check(L, ttistable(o), "table expected");
t = hvalue(o);
luaH_setint(L, t, n, L->top - 1);
luaC_barrierback(L, t, L->top-1);
@@ -804,7 +809,7 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
+ api_check(L, ttistable(o), "table expected");
t = hvalue(o);
setpvalue(&k, cast(void *, p));
setobj2t(L, luaH_set(L, t, &k), L->top - 1);
@@ -823,7 +828,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
if (ttisnil(L->top - 1))
mt = NULL;
else {
- api_check(ttistable(L->top - 1), "table expected");
+ api_check(L, ttistable(L->top - 1), "table expected");
mt = hvalue(L->top - 1);
}
switch (ttnov(obj)) {
@@ -859,7 +864,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
- api_check(ttisfulluserdata(o), "full userdata expected");
+ api_check(L, ttisfulluserdata(o), "full userdata expected");
setuservalue(L, uvalue(o), L->top - 1);
luaC_barrier(L, gcvalue(o), L->top - 1);
L->top--;
@@ -873,7 +878,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
- api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
+ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
"results from function overflow current stack size")
@@ -881,10 +886,10 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
lua_KContext ctx, lua_KFunction k) {
StkId func;
lua_lock(L);
- api_check(k == NULL || !isLua(L->ci),
+ api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
- api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
+ api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
@@ -922,16 +927,16 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
int status;
ptrdiff_t func;
lua_lock(L);
- api_check(k == NULL || !isLua(L->ci),
+ api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
- api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
+ api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2addr(L, errfunc);
- api_checkstackindex(errfunc, o);
+ api_checkstackindex(L, errfunc, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
@@ -1096,7 +1101,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
+ api_check(L, ttistable(t), "table expected");
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
@@ -1228,9 +1233,9 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
LClosure *f;
StkId fi = index2addr(L, fidx);
- api_check(ttisLclosure(fi), "Lua function expected");
+ api_check(L, ttisLclosure(fi), "Lua function expected");
f = clLvalue(fi);
- api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
+ api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
if (pf) *pf = f;
return &f->upvals[n - 1]; /* get its upvalue pointer */
}
@@ -1244,11 +1249,11 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
}
case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi);
- api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
+ api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
return &f->upvalue[n - 1];
}
default: {
- api_check(0, "closure expected");
+ api_check(L, 0, "closure expected");
return NULL;
}
}
diff --git a/plugins/MirLua/src/lua/lapi.h b/plugins/MirLua/src/lua/lapi.h
index 092f5e974c..6d36dee3fb 100644
--- a/plugins/MirLua/src/lua/lapi.h
+++ b/plugins/MirLua/src/lua/lapi.h
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
+** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -11,13 +11,13 @@
#include "llimits.h"
#include "lstate.h"
-#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
+#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
-#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
+#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")
diff --git a/plugins/MirLua/src/lua/lauxlib.c b/plugins/MirLua/src/lua/lauxlib.c
index 1c41d6a8ea..b8bace7f96 100644
--- a/plugins/MirLua/src/lua/lauxlib.c
+++ b/plugins/MirLua/src/lua/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp $
+** $Id: lauxlib.c,v 1.280 2015/02/03 17:38:24 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -286,7 +286,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
*/
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- if (luaL_getmetatable(L, tname)) /* name already in use? */
+ if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
diff --git a/plugins/MirLua/src/lua/lbaselib.c b/plugins/MirLua/src/lua/lbaselib.c
index a2403952f0..9a15124502 100644
--- a/plugins/MirLua/src/lua/lbaselib.c
+++ b/plugins/MirLua/src/lua/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp $
+** $Id: lbaselib.c,v 1.310 2015/03/28 19:14:47 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -55,7 +55,7 @@ static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
return NULL;
do {
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
- : toupper((unsigned char)*s) - 'A' + 10;
+ : (toupper((unsigned char)*s) - 'A') + 10;
if (digit >= base) return NULL; /* invalid numeral */
n = n * base + digit;
s++;
diff --git a/plugins/MirLua/src/lua/lcode.c b/plugins/MirLua/src/lua/lcode.c
index 5e34624bf4..d6f0fcd847 100644
--- a/plugins/MirLua/src/lua/lcode.c
+++ b/plugins/MirLua/src/lua/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.99 2014/12/29 16:49:25 roberto Exp $
+** $Id: lcode.c,v 2.101 2015/04/29 18:24:11 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -29,8 +29,8 @@
#include "lvm.h"
-/* Maximum number of registers in a Lua function */
-#define MAXREGS 250
+/* Maximum number of registers in a Lua function (must fit in 8 bits) */
+#define MAXREGS 255
#define hasjumps(e) ((e)->t != (e)->f)
@@ -279,7 +279,8 @@ void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
if (newstack >= MAXREGS)
- luaX_syntaxerror(fs->ls, "function or expression too complex");
+ luaX_syntaxerror(fs->ls,
+ "function or expression needs too many registers");
fs->f->maxstacksize = cast_byte(newstack);
}
}
@@ -573,8 +574,8 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
case VKFLT: {
e->u.info = luaK_numberK(fs, e->u.nval);
e->k = VK;
- /* go through */
}
+ /* FALLTHROUGH */
case VK: {
vk:
if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
@@ -793,7 +794,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
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))
+ if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
return; /* result has been folded */
else {
int o1, o2;
@@ -920,11 +921,11 @@ void luaK_posfix (FuncState *fs, BinOpr op,
break;
}
case OPR_EQ: case OPR_LT: case OPR_LE: {
- codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
+ codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
break;
}
case OPR_NE: case OPR_GT: case OPR_GE: {
- codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
+ codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
break;
}
default: lua_assert(0);
diff --git a/plugins/MirLua/src/lua/ldblib.c b/plugins/MirLua/src/lua/ldblib.c
index 24a11b53ee..915145845e 100644
--- a/plugins/MirLua/src/lua/ldblib.c
+++ b/plugins/MirLua/src/lua/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp $
+** $Id: ldblib.c,v 1.149 2015/02/19 17:06:21 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -27,6 +27,17 @@
static const int HOOKKEY = 0;
+/*
+** If L1 != L, L1 can be in any state, and therefore there is no
+** garanties about its stack space; any push in L1 must be
+** checked.
+*/
+static void checkstack (lua_State *L, lua_State *L1, int n) {
+ if (L != L1 && !lua_checkstack(L1, n))
+ luaL_error(L, "stack overflow");
+}
+
+
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
@@ -127,12 +138,16 @@ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
/*
** Calls 'lua_getinfo' and collects all results in a new table.
+** L1 needs stack space for an optional input (function) plus
+** two optional outputs (function and line table) from function
+** 'lua_getinfo'.
*/
static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnStu");
+ checkstack(L, L1, 3);
if (lua_isfunction(L, arg + 1)) { /* info about a function? */
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
@@ -190,6 +205,7 @@ static int db_getlocal (lua_State *L) {
int level = (int)luaL_checkinteger(L, arg + 1);
if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
+ checkstack(L, L1, 1);
name = lua_getlocal(L1, &ar, nvar);
if (name) {
lua_xmove(L1, L, 1); /* move local value */
@@ -216,6 +232,7 @@ static int db_setlocal (lua_State *L) {
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
+ checkstack(L, L1, 1);
lua_xmove(L, L1, 1);
name = lua_setlocal(L1, &ar, nvar);
if (name == NULL)
@@ -350,6 +367,7 @@ static int db_sethook (lua_State *L) {
lua_pushvalue(L, -1);
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
}
+ checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
lua_pushvalue(L, arg + 1); /* value (hook function) */
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
@@ -370,6 +388,7 @@ static int db_gethook (lua_State *L) {
lua_pushliteral(L, "external hook");
else { /* hook table must exist */
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
+ checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1);
lua_rawget(L, -2); /* 1st result = hooktable[L1] */
lua_remove(L, -2); /* remove hook table */
diff --git a/plugins/MirLua/src/lua/ldebug.c b/plugins/MirLua/src/lua/ldebug.c
index 6986bf0f60..f76582c5b5 100644
--- a/plugins/MirLua/src/lua/ldebug.c
+++ b/plugins/MirLua/src/lua/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp $
+** $Id: ldebug.c,v 2.115 2015/05/22 17:45:56 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -34,6 +34,10 @@
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
+/* Active Lua function (given call info) */
+#define ci_func(ci) (clLvalue((ci)->func))
+
+
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
@@ -49,6 +53,22 @@ static int currentline (CallInfo *ci) {
/*
+** If function yielded, its 'func' can be in the 'extra' field. The
+** next function restores 'func' to its correct value for debugging
+** purposes. (It exchanges 'func' and 'extra'; so, when called again,
+** after debugging, it also "re-restores" ** 'func' to its altered value.
+*/
+static void swapextra (lua_State *L) {
+ if (L->status == LUA_YIELD) {
+ CallInfo *ci = L->ci; /* get function that yielded */
+ StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
+ ci->func = restorestack(L, ci->extra);
+ ci->extra = savestack(L, temp);
+ }
+}
+
+
+/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
@@ -106,7 +126,7 @@ static const char *upvalname (Proto *p, int uv) {
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
- if (n >= ci->u.l.base - ci->func - nparams)
+ if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
return NULL; /* no such vararg */
else {
*pos = ci->func + nparams + n;
@@ -144,6 +164,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
lua_lock(L);
+ swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
@@ -151,26 +172,30 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
}
else { /* active function; get information through 'ar' */
- StkId pos = 0; /* to avoid warnings */
+ StkId pos = NULL; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
}
}
+ swapextra(L);
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
- StkId pos = 0; /* to avoid warnings */
- const char *name = findlocal(L, ar->i_ci, n, &pos);
+ StkId pos = NULL; /* to avoid warnings */
+ const char *name;
lua_lock(L);
+ swapextra(L);
+ name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
}
+ swapextra(L);
lua_unlock(L);
return name;
}
@@ -270,10 +295,11 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
CallInfo *ci;
StkId func;
lua_lock(L);
+ swapextra(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
- api_check(ttisfunction(func), "function expected");
+ api_check(L, ttisfunction(func), "function expected");
what++; /* skip the '>' */
L->top--; /* pop function */
}
@@ -288,6 +314,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
setobjs2s(L, L->top, func);
api_incr_top(L);
}
+ swapextra(L); /* correct before option 'L', which can raise a mem. error */
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
@@ -572,19 +599,16 @@ l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
}
-static void addinfo (lua_State *L, const char *msg) {
- CallInfo *ci = L->ci;
- if (isLua(ci)) { /* is Lua code? */
- char buff[LUA_IDSIZE]; /* add file:line information */
- int line = currentline(ci);
- TString *src = ci_func(ci)->p->source;
- if (src)
- luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
- else { /* no source available; use "?" instead */
- buff[0] = '?'; buff[1] = '\0';
- }
- luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+/* add src:line information to 'msg' */
+const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
+ int line) {
+ char buff[LUA_IDSIZE];
+ if (src)
+ luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
+ else { /* no source available; use "?" instead */
+ buff[0] = '?'; buff[1] = '\0';
}
+ return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
@@ -601,10 +625,14 @@ l_noret luaG_errormsg (lua_State *L) {
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
+ CallInfo *ci = L->ci;
+ const char *msg;
va_list argp;
va_start(argp, fmt);
- addinfo(L, luaO_pushvfstring(L, fmt, argp));
+ msg = luaO_pushvfstring(L, fmt, argp); /* format message */
va_end(argp);
+ if (isLua(ci)) /* if Lua function, add source:line information */
+ luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
luaG_errormsg(L);
}
diff --git a/plugins/MirLua/src/lua/ldebug.h b/plugins/MirLua/src/lua/ldebug.h
index 0d8966ca9a..0e31546b1b 100644
--- a/plugins/MirLua/src/lua/ldebug.h
+++ b/plugins/MirLua/src/lua/ldebug.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.h,v 2.12 2014/11/10 14:46:05 roberto Exp $
+** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -17,9 +17,6 @@
#define resethookcount(L) (L->hookcount = L->basehookcount)
-/* Active Lua function (given call info) */
-#define ci_func(ci) (clLvalue((ci)->func))
-
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
@@ -33,6 +30,8 @@ LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
+ TString *src, int line);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
LUAI_FUNC void luaG_traceexec (lua_State *L);
diff --git a/plugins/MirLua/src/lua/ldo.c b/plugins/MirLua/src/lua/ldo.c
index 6159e51da2..5c93a259fe 100644
--- a/plugins/MirLua/src/lua/ldo.c
+++ b/plugins/MirLua/src/lua/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.135 2014/11/11 17:13:39 roberto Exp $
+** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -323,6 +323,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
case LUA_TCCL: { /* C closure */
f = clCvalue(func)->f;
Cfunc:
+ luaC_checkGC(L); /* stack grow uses memory */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
@@ -330,20 +331,20 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
- luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
- luaD_poscall(L, L->top - n);
+ luaD_poscall(L, L->top - n, n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
n = cast_int(L->top - func) - 1; /* number of real arguments */
+ luaC_checkGC(L); /* stack grow uses memory */
luaD_checkstack(L, p->maxstacksize);
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
@@ -364,7 +365,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
L->top = ci->top;
- luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
@@ -379,7 +379,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
}
-int luaD_poscall (lua_State *L, StkId firstResult) {
+int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
StkId res;
int wanted, i;
CallInfo *ci = L->ci;
@@ -393,9 +393,9 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
}
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
- L->ci = ci = ci->previous; /* back to caller */
+ L->ci = ci->previous; /* back to caller */
/* move results to correct place */
- for (i = wanted; i != 0 && firstResult < L->top; i--)
+ for (i = wanted; i != 0 && nres-- > 0; i--)
setobjs2s(L, res++, firstResult++);
while (i-- > 0)
setnilvalue(res++);
@@ -449,7 +449,7 @@ static void finishCcall (lua_State *L, int status) {
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
- luaD_poscall(L, L->top - n);
+ luaD_poscall(L, L->top - n, n);
}
@@ -533,7 +533,8 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
*/
static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
- StkId firstArg = cast(StkId, ud);
+ int n = *(cast(int*, ud)); /* number of arguments */
+ StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
@@ -553,14 +554,13 @@ static void resume (lua_State *L, void *ud) {
luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
- int n;
lua_unlock(L);
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
lua_lock(L);
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
- luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
+ luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */
}
unroll(L, NULL); /* run continuation */
}
@@ -576,7 +576,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
- status = luaD_rawrunprotected(L, resume, L->top - nargs);
+ status = luaD_rawrunprotected(L, resume, &nargs);
if (status == -1) /* error calling 'lua_resume'? */
status = LUA_ERRRUN;
else { /* continue running after recoverable errors */
@@ -619,7 +619,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
L->status = LUA_YIELD;
ci->extra = savestack(L, ci->func); /* save current 'func' */
if (isLua(ci)) { /* inside a hook? */
- api_check(k == NULL, "hooks cannot continue after yielding");
+ api_check(L, k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
diff --git a/plugins/MirLua/src/lua/ldo.h b/plugins/MirLua/src/lua/ldo.h
index 05745c8ad8..edade657c7 100644
--- a/plugins/MirLua/src/lua/ldo.h
+++ b/plugins/MirLua/src/lua/ldo.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
+** $Id: ldo.h,v 2.22 2015/05/22 17:48:19 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -34,7 +34,7 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
int allowyield);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
diff --git a/plugins/MirLua/src/lua/ldump.c b/plugins/MirLua/src/lua/ldump.c
index b6c7114f5d..4c04812a78 100644
--- a/plugins/MirLua/src/lua/ldump.c
+++ b/plugins/MirLua/src/lua/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp $
+** $Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -74,14 +74,15 @@ static void DumpString (const TString *s, DumpState *D) {
if (s == NULL)
DumpByte(0, D);
else {
- size_t size = s->len + 1; /* include trailing '\0' */
+ size_t size = tsslen(s) + 1; /* include trailing '\0' */
+ const char *str = getstr(s);
if (size < 0xFF)
DumpByte(cast_int(size), D);
else {
DumpByte(0xFF, D);
DumpVar(size, D);
}
- DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */
+ DumpVector(str, size - 1, D); /* no need to save '\0' */
}
}
diff --git a/plugins/MirLua/src/lua/lfunc.h b/plugins/MirLua/src/lua/lfunc.h
index 256d3cf90b..2eeb0d5a48 100644
--- a/plugins/MirLua/src/lua/lfunc.h
+++ b/plugins/MirLua/src/lua/lfunc.h
@@ -1,5 +1,5 @@
/*
-** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp $
+** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -23,6 +23,13 @@
/*
+** maximum number of upvalues in a closure (both C and Lua). (Value
+** must fit in a VM register.)
+*/
+#define MAXUPVAL 255
+
+
+/*
** Upvalues for Lua closures
*/
struct UpVal {
diff --git a/plugins/MirLua/src/lua/lgc.c b/plugins/MirLua/src/lua/lgc.c
index 8b95fb67da..973c269f73 100644
--- a/plugins/MirLua/src/lua/lgc.c
+++ b/plugins/MirLua/src/lua/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp $
+** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -83,8 +83,13 @@
#define markvalue(g,o) { checkconsistency(o); \
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
-#define markobject(g,t) \
- { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
+#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
+
+/*
+** mark an object that can be NULL (either because it is really optional,
+** or it was stripped as debug info, or inside an uncompleted structure)
+*/
+#define markobjectN(g,t) { if (t) markobject(g,t); }
static void reallymarkobject (global_State *g, GCObject *o);
@@ -226,15 +231,19 @@ static void reallymarkobject (global_State *g, GCObject *o) {
reentry:
white2gray(o);
switch (o->tt) {
- case LUA_TSHRSTR:
+ case LUA_TSHRSTR: {
+ gray2black(o);
+ g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
+ break;
+ }
case LUA_TLNGSTR: {
gray2black(o);
- g->GCmemtrav += sizestring(gco2ts(o));
+ g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
break;
}
case LUA_TUSERDATA: {
TValue uvalue;
- markobject(g, gco2u(o)->metatable); /* mark its metatable */
+ markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
gray2black(o);
g->GCmemtrav += sizeudata(gco2u(o));
getuservalue(g->mainthread, gco2u(o), &uvalue);
@@ -275,7 +284,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
static void markmt (global_State *g) {
int i;
for (i=0; i < LUA_NUMTAGS; i++)
- markobject(g, g->mt[i]);
+ markobjectN(g, g->mt[i]);
}
@@ -437,7 +446,7 @@ static void traversestrongtable (global_State *g, Table *h) {
static lu_mem traversetable (global_State *g, Table *h) {
const char *weakkey, *weakvalue;
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
- markobject(g, h->metatable);
+ markobjectN(g, h->metatable);
if (mode && ttisstring(mode) && /* is there a weak mode? */
((weakkey = strchr(svalue(mode), 'k')),
(weakvalue = strchr(svalue(mode), 'v')),
@@ -457,19 +466,24 @@ static lu_mem traversetable (global_State *g, Table *h) {
}
+/*
+** Traverse a prototype. (While a prototype is being build, its
+** arrays can be larger than needed; the extra slots are filled with
+** NULL, so the use of 'markobjectN')
+*/
static int traverseproto (global_State *g, Proto *f) {
int i;
if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */
- markobject(g, f->source);
+ markobjectN(g, f->source);
for (i = 0; i < f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]);
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
- markobject(g, f->upvalues[i].name);
+ markobjectN(g, f->upvalues[i].name);
for (i = 0; i < f->sizep; i++) /* mark nested protos */
- markobject(g, f->p[i]);
+ markobjectN(g, f->p[i]);
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
- markobject(g, f->locvars[i].varname);
+ markobjectN(g, f->locvars[i].varname);
return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
sizeof(Proto *) * f->sizep +
sizeof(TValue) * f->sizek +
@@ -494,7 +508,7 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
*/
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
int i;
- markobject(g, cl->p); /* mark its prototype */
+ markobjectN(g, cl->p); /* mark its prototype */
for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
UpVal *uv = cl->upvals[i];
if (uv != NULL) {
@@ -689,9 +703,10 @@ static void freeobj (lua_State *L, GCObject *o) {
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
case LUA_TSHRSTR:
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
- /* go through */
+ luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
+ break;
case LUA_TLNGSTR: {
- luaM_freemem(L, o, sizestring(gco2ts(o)));
+ luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
break;
}
default: lua_assert(0);
@@ -1002,6 +1017,7 @@ static l_mem atomic (lua_State *L) {
/* clear values from resurrected weak tables */
clearvalues(g, g->weak, origweak);
clearvalues(g, g->allweak, origall);
+ luaS_clearcache(g);
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
work += g->GCmemtrav; /* complete counting */
return work; /* estimate of memory marked by 'atomic' */
diff --git a/plugins/MirLua/src/lua/liolib.c b/plugins/MirLua/src/lua/liolib.c
index 4dea39684a..193cac6777 100644
--- a/plugins/MirLua/src/lua/liolib.c
+++ b/plugins/MirLua/src/lua/liolib.c
@@ -1,5 +1,5 @@
/*
-** $Id: liolib.c,v 2.142 2015/01/02 12:50:28 roberto Exp $
+** $Id: liolib.c,v 2.144 2015/04/03 18:41:57 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -410,12 +410,6 @@ static int readdigits (RN *rn, int hex) {
}
-/* access to locale "radix character" (decimal point) */
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
-#endif
-
-
/*
** Read a number: first reads a valid prefix of a numeral into a buffer.
** Then it calls 'lua_stringtonumber' to check whether the format is
@@ -425,9 +419,10 @@ static int read_number (lua_State *L, FILE *f) {
RN rn;
int count = 0;
int hex = 0;
- char decp[2] = ".";
+ char decp[2];
rn.f = f; rn.n = 0;
- decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
+ decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
+ decp[1] = '\0';
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
@@ -457,7 +452,7 @@ static int read_number (lua_State *L, FILE *f) {
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f); /* no-op when c == EOF */
- lua_pushlstring(L, NULL, 0);
+ lua_pushliteral(L, "");
return (c != EOF);
}
diff --git a/plugins/MirLua/src/lua/llex.c b/plugins/MirLua/src/lua/llex.c
index 6e4a457ad6..c35bd55fa7 100644
--- a/plugins/MirLua/src/lua/llex.c
+++ b/plugins/MirLua/src/lua/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.89 2014/11/14 16:06:09 roberto Exp $
+** $Id: llex.c,v 2.93 2015/05/22 17:45:56 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -16,6 +16,7 @@
#include "lua.h"
#include "lctype.h"
+#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
@@ -68,7 +69,7 @@ static void save (LexState *ls, int c) {
void luaX_init (lua_State *L) {
int i;
- TString *e = luaS_new(L, LUA_ENV); /* create env name */
+ TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
luaC_fix(L, obj2gco(e)); /* never collect this name */
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
@@ -106,9 +107,7 @@ static const char *txtToken (LexState *ls, int token) {
static l_noret lexerror (LexState *ls, const char *msg, int token) {
- char buff[LUA_IDSIZE];
- luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
- msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
+ msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
if (token)
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
@@ -172,7 +171,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
- ls->envn = luaS_new(L, LUA_ENV); /* get env name */
+ ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
}
@@ -221,11 +220,6 @@ static void buffreplace (LexState *ls, char from, char to) {
}
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
-#endif
-
-
#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0)
/*
@@ -234,7 +228,7 @@ static void buffreplace (LexState *ls, char from, char to) {
*/
static void trydecpoint (LexState *ls, TValue *o) {
char old = ls->decpoint;
- ls->decpoint = l_getlocaledecpoint();
+ ls->decpoint = lua_getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!buff2num(ls->buff, o)) {
/* format error with correct decimal point: no more options */
@@ -283,8 +277,9 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
/*
-** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
-** -1 if sequence is malformed
+** skip a sequence '[=*[' or ']=*]'; if sequence is wellformed, return
+** its number of '='s; otherwise, return a negative number (-1 iff there
+** are no '='s after initial bracket)
*/
static int skip_sep (LexState *ls) {
int count = 0;
@@ -501,8 +496,9 @@ static int llex (LexState *ls, SemInfo *seminfo) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
- else if (sep == -1) return '[';
- else lexerror(ls, "invalid long string delimiter", TK_STRING);
+ else if (sep != -1) /* '[=...' missing second bracket */
+ lexerror(ls, "invalid long string delimiter", TK_STRING);
+ return '[';
}
case '=': {
next(ls);
diff --git a/plugins/MirLua/src/lua/llimits.h b/plugins/MirLua/src/lua/llimits.h
index 8f71a6ffb9..277c724d90 100644
--- a/plugins/MirLua/src/lua/llimits.h
+++ b/plugins/MirLua/src/lua/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $
+** $Id: llimits.h,v 1.135 2015/06/09 14:21:00 roberto Exp $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -52,11 +52,11 @@ typedef unsigned char lu_byte;
/*
-** conversion of pointer to integer:
+** conversion of pointer to unsigned integer:
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
-#define point2int(p) ((unsigned int)((size_t)(p) & UINT_MAX))
+#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
@@ -88,22 +88,20 @@ typedef LUAI_UACINT l_uacInt;
/*
** assertion for checking API calls
*/
-#if defined(LUA_USE_APICHECK)
-#include <assert.h>
-#define luai_apicheck(e) assert(e)
-#else
-#define luai_apicheck(e) lua_assert(e)
+#if !defined(luai_apicheck)
+#define luai_apicheck(l,e) lua_assert(e)
#endif
-
-#define api_check(e,msg) luai_apicheck((e) && msg)
+#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
+/* macro to avoid warnings about unused variables */
#if !defined(UNUSED)
-#define UNUSED(x) ((void)(x)) /* to avoid warnings */
+#define UNUSED(x) ((void)(x))
#endif
+/* type casts (a macro highlights casts in the code) */
#define cast(t, exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
@@ -149,11 +147,6 @@ typedef LUAI_UACINT l_uacInt;
#define LUAI_MAXCCALLS 200
#endif
-/*
-** maximum number of upvalues in a closure (both C and Lua). (Value
-** must fit in an unsigned char.)
-*/
-#define MAXUPVAL UCHAR_MAX
/*
@@ -168,10 +161,33 @@ typedef unsigned long Instruction;
+/*
+** Maximum length for short strings, that is, strings that are
+** internalized. (Cannot be smaller than reserved words or tags for
+** metamethods, as these strings must be internalized;
+** #("function") = 8, #("__newindex") = 10.)
+*/
+#if !defined(LUAI_MAXSHORTLEN)
+#define LUAI_MAXSHORTLEN 40
+#endif
+
-/* minimum size for the string table (must be power of 2) */
+/*
+** Initial size for the string table (must be power of 2).
+** The Lua core alone registers ~50 strings (reserved words +
+** metaevent keys + a few others). Libraries would typically add
+** a few dozens more.
+*/
#if !defined(MINSTRTABSIZE)
-#define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */
+#define MINSTRTABSIZE 128
+#endif
+
+
+/*
+** Size of cache for strings in the API (better be a prime)
+*/
+#if !defined(STRCACHE_SIZE)
+#define STRCACHE_SIZE 127
#endif
@@ -181,11 +197,19 @@ typedef unsigned long Instruction;
#endif
+/*
+** macros that are executed whenether program enters the Lua core
+** ('lua_lock') and leaves the core ('lua_unlock')
+*/
#if !defined(lua_lock)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
+/*
+** macro executed during Lua functions at points where the
+** function can yield.
+*/
#if !defined(luai_threadyield)
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
@@ -223,6 +247,53 @@ typedef unsigned long Instruction;
/*
+** The luai_num* macros define the primitive operations over numbers.
+*/
+
+/* floor division (defined as 'floor(a/b)') */
+#if !defined(luai_numidiv)
+#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b)))
+#endif
+
+/* float division */
+#if !defined(luai_numdiv)
+#define luai_numdiv(L,a,b) ((a)/(b))
+#endif
+
+/*
+** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
+** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
+** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
+** ~= floor(a/b)'. That happens when the division has a non-integer
+** negative result, which is equivalent to the test below.
+*/
+#if !defined(luai_nummod)
+#define luai_nummod(L,a,b,m) \
+ { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
+#endif
+
+/* exponentiation */
+#if !defined(luai_numpow)
+#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
+#endif
+
+/* the others are quite standard operations */
+#if !defined(luai_numadd)
+#define luai_numadd(L,a,b) ((a)+(b))
+#define luai_numsub(L,a,b) ((a)-(b))
+#define luai_nummul(L,a,b) ((a)*(b))
+#define luai_numunm(L,a) (-(a))
+#define luai_numeq(a,b) ((a)==(b))
+#define luai_numlt(a,b) ((a)<(b))
+#define luai_numle(a,b) ((a)<=(b))
+#define luai_numisnan(a) (!luai_numeq((a), (a)))
+#endif
+
+
+
+
+
+/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#if !defined(HARDSTACKTESTS)
diff --git a/plugins/MirLua/src/lua/lmathlib.c b/plugins/MirLua/src/lua/lmathlib.c
index 002c508bc4..4f2ec60aa2 100644
--- a/plugins/MirLua/src/lua/lmathlib.c
+++ b/plugins/MirLua/src/lua/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.114 2014/12/27 20:32:26 roberto Exp $
+** $Id: lmathlib.c,v 1.115 2015/03/12 14:04:04 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -183,6 +183,9 @@ static int math_log (lua_State *L) {
res = l_mathop(log)(x);
else {
lua_Number base = luaL_checknumber(L, 2);
+#if !defined(LUA_USE_C89)
+ if (base == 2.0) res = l_mathop(log2)(x); else
+#endif
if (base == 10.0) res = l_mathop(log10)(x);
else res = l_mathop(log)(x)/l_mathop(log)(base);
}
diff --git a/plugins/MirLua/src/lua/lmem.c b/plugins/MirLua/src/lua/lmem.c
index 4feaf036c7..0a0476cc77 100644
--- a/plugins/MirLua/src/lua/lmem.c
+++ b/plugins/MirLua/src/lua/lmem.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmem.c,v 1.89 2014/11/02 19:33:33 roberto Exp $
+** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -85,10 +85,11 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
- api_check( nsize > realosize,
- "realloc cannot fail when shrinking a block");
- luaC_fullgc(L, 1); /* try to free some memory... */
- newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
+ lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
+ if (g->version) { /* is state fully built? */
+ luaC_fullgc(L, 1); /* try to free some memory... */
+ newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
+ }
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}
diff --git a/plugins/MirLua/src/lua/loadlib.c b/plugins/MirLua/src/lua/loadlib.c
index 7f8d990298..bbf8f67afb 100644
--- a/plugins/MirLua/src/lua/loadlib.c
+++ b/plugins/MirLua/src/lua/loadlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.124 2015/01/05 13:51:39 roberto Exp $
+** $Id: loadlib.c,v 1.126 2015/02/16 13:14:33 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -14,6 +14,7 @@
#include "lprefix.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -136,8 +137,8 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
#include <dlfcn.h>
/*
-** Macro to covert pointer to void* to pointer to function. This cast
-** is undefined according to ISO C, but POSIX assumes that it must work.
+** Macro to convert pointer-to-void* to pointer-to-function. This cast
+** is undefined according to ISO C, but POSIX assumes that it works.
** (The '__extension__' in gnu compilers is only to avoid warnings.)
*/
#if defined(__GNUC__)
diff --git a/plugins/MirLua/src/lua/lobject.c b/plugins/MirLua/src/lua/lobject.c
index 6a24aff95d..6c53b981df 100644
--- a/plugins/MirLua/src/lua/lobject.c
+++ b/plugins/MirLua/src/lua/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.101 2014/12/26 14:43:45 roberto Exp $
+** $Id: lobject.c,v 2.104 2015/04/11 18:30:08 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -10,6 +10,8 @@
#include "lprefix.h"
+#include <locale.h>
+#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,8 +41,12 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
int luaO_int2fb (unsigned int x) {
int e = 0; /* exponent */
if (x < 8) return x;
- while (x >= 0x10) {
- x = (x+1) >> 1;
+ while (x >= (8 << 4)) { /* coarse steps */
+ x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
+ e += 4;
+ }
+ while (x >= (8 << 1)) { /* fine steps */
+ x = (x + 1) >> 1; /* x = ceil(x / 2) */
e++;
}
return ((e+1) << 3) | (cast_int(x) - 8);
@@ -55,8 +61,11 @@ int luaO_fb2int (int x) {
}
+/*
+** Computes ceil(log2(x))
+*/
int luaO_ceillog2 (unsigned int x) {
- static const lu_byte log_2[256] = {
+ static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
@@ -149,13 +158,13 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
}
/* could not perform raw operation; try metamethod */
lua_assert(L != NULL); /* should not fail when folding (compile time) */
- luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
+ luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
}
int luaO_hexavalue (int c) {
if (lisdigit(c)) return c - '0';
- else return ltolower(c) - 'a' + 10;
+ else return (ltolower(c) - 'a') + 10;
}
@@ -172,9 +181,8 @@ static int isneg (const char **s) {
** Lua's implementation for 'lua_strx2number'
** ===================================================================
*/
-#if !defined(lua_strx2number)
-#include <math.h>
+#if !defined(lua_strx2number)
/* maximum number of significant digits to read (to avoid overflows
even with single floats) */
@@ -185,21 +193,22 @@ static int isneg (const char **s) {
** C99 specification for 'strtod'
*/
static lua_Number lua_strx2number (const char *s, char **endptr) {
+ int dot = lua_getlocaledecpoint();
lua_Number r = 0.0; /* result (accumulator) */
int sigdig = 0; /* number of significant digits */
int nosigdig = 0; /* number of non-significant digits */
int e = 0; /* exponent correction */
int neg; /* 1 if number is negative */
- int dot = 0; /* true after seen a dot */
+ int hasdot = 0; /* true after seen a dot */
*endptr = cast(char *, s); /* nothing is valid yet */
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
neg = isneg(&s); /* check signal */
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
for (s += 2; ; s++) { /* skip '0x' and read numeral */
- if (*s == '.') {
- if (dot) break; /* second dot? stop loop */
- else dot = 1;
+ if (*s == dot) {
+ if (hasdot) break; /* second dot? stop loop */
+ else hasdot = 1;
}
else if (lisxdigit(cast_uchar(*s))) {
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
@@ -207,7 +216,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
else e++; /* too many digits; ignore, but still count for exponent */
- if (dot) e--; /* decimal digit? correct exponent */
+ if (hasdot) e--; /* decimal digit? correct exponent */
}
else break; /* neither a dot nor a digit */
}
@@ -244,7 +253,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* nothing recognized */
+ if (endptr == s) return NULL; /* nothing recognized */
while (lisspace(cast_uchar(*endptr))) endptr++;
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
}
@@ -290,7 +299,7 @@ size_t luaO_str2num (const char *s, TValue *o) {
}
else
return 0; /* conversion failed */
- return (e - s + 1); /* success; return string size */
+ return (e - s) + 1; /* success; return string size */
}
@@ -329,7 +338,7 @@ void luaO_tostring (lua_State *L, StkId obj) {
len = lua_number2str(buff, fltvalue(obj));
#if !defined(LUA_COMPAT_FLOATSTRING)
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
- buff[len++] = '.';
+ buff[len++] = lua_getlocaledecpoint();
buff[len++] = '0'; /* adds '.0' to result */
}
#endif
diff --git a/plugins/MirLua/src/lua/lobject.h b/plugins/MirLua/src/lua/lobject.h
index d7d0ebf31b..9230b7a9f8 100644
--- a/plugins/MirLua/src/lua/lobject.h
+++ b/plugins/MirLua/src/lua/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp $
+** $Id: lobject.h,v 2.111 2015/06/09 14:21:42 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -35,8 +35,6 @@
** bit 6: whether value is collectable
*/
-#define VARBITS (3 << 4)
-
/*
** LUA_TFUNCTION variants:
@@ -190,9 +188,15 @@ typedef struct lua_TValue TValue;
#define setfltvalue(obj,x) \
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
+#define chgfltvalue(obj,x) \
+ { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
+
#define setivalue(obj,x) \
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
+#define chgivalue(obj,x) \
+ { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
+
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define setfvalue(obj,x) \
@@ -303,9 +307,12 @@ typedef TValue *StkId; /* index to stack elements */
typedef struct TString {
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
+ lu_byte shrlen; /* length for short strings */
unsigned int hash;
- size_t len; /* number of characters in string */
- struct TString *hnext; /* linked list for hash table */
+ union {
+ size_t lnglen; /* length for long strings */
+ struct TString *hnext; /* linked list for hash table */
+ } u;
} TString;
@@ -329,6 +336,12 @@ typedef union UTString {
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
+/* get string length from 'TString *s' */
+#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
+
+/* get string length from 'TValue *o' */
+#define vslen(o) tsslen(tsvalue(o))
+
/*
** Header for userdata; memory area follows the end of this structure
@@ -361,13 +374,13 @@ typedef union UUdata {
#define setuservalue(L,u,o) \
{ const TValue *io=(o); Udata *iu = (u); \
- iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
+ iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
checkliveness(G(L),io); }
#define getuservalue(L,u,o) \
{ TValue *io=(o); const Udata *iu = (u); \
- io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
+ io->value_ = iu->user_; settt_(io, iu->ttuv_); \
checkliveness(G(L),io); }
@@ -376,7 +389,7 @@ typedef union UUdata {
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
- lu_byte instack; /* whether it is in stack */
+ lu_byte instack; /* whether it is in stack (register) */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
@@ -399,7 +412,7 @@ typedef struct Proto {
CommonHeader;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
- lu_byte maxstacksize; /* maximum stack used by this function */
+ lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */
int sizecode;
@@ -409,12 +422,12 @@ typedef struct Proto {
int linedefined;
int lastlinedefined;
TValue *k; /* constants used by the function */
- Instruction *code;
+ Instruction *code; /* opcodes */
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines (debug information) */
LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
- struct LClosure *cache; /* last created closure with this prototype */
+ struct LClosure *cache; /* last-created closure with this prototype */
TString *source; /* used for debug information */
GCObject *gclist;
} Proto;
diff --git a/plugins/MirLua/src/lua/loslib.c b/plugins/MirLua/src/lua/loslib.c
index 20359b2474..cb8a3c3314 100644
--- a/plugins/MirLua/src/lua/loslib.c
+++ b/plugins/MirLua/src/lua/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.54 2014/12/26 14:46:07 roberto Exp $
+** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -22,10 +22,12 @@
#include "lualib.h"
-#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/*
+** {==================================================================
** list of valid conversion specifiers for the 'strftime' function
+** ===================================================================
*/
+#if !defined(LUA_STRFTIMEOPTIONS) /* { */
#if defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
@@ -37,8 +39,14 @@
#endif
#endif /* } */
+/* }================================================================== */
+/*
+** {==================================================================
+** Configuration for time-related stuff
+** ===================================================================
+*/
#if !defined(l_time_t) /* { */
/*
@@ -51,12 +59,38 @@
#endif /* } */
+#if !defined(l_gmtime) /* { */
+/*
+** By default, Lua uses gmtime/localtime, except when POSIX is available,
+** where it uses gmtime_r/localtime_r
+*/
+
+#if defined(LUA_USE_POSIX) /* { */
+
+#define l_gmtime(t,r) gmtime_r(t,r)
+#define l_localtime(t,r) localtime_r(t,r)
+
+#else /* }{ */
+
+/* ISO C definitions */
+#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
+#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
+
+#endif /* } */
+
+#endif /* } */
+
+/* }================================================================== */
+
-#if !defined(lua_tmpnam) /* { */
/*
-** By default, Lua uses tmpnam except when POSIX is available, where it
-** uses mkstemp.
+** {==================================================================
+** Configuration for 'tmpnam':
+** By default, Lua uses tmpnam except when POSIX is available, where
+** it uses mkstemp.
+** ===================================================================
*/
+#if !defined(lua_tmpnam) /* { */
#if defined(LUA_USE_POSIX) /* { */
@@ -83,31 +117,10 @@
#endif /* } */
#endif /* } */
+/* }================================================================== */
-#if !defined(l_gmtime) /* { */
-/*
-** By default, Lua uses gmtime/localtime, except when POSIX is available,
-** where it uses gmtime_r/localtime_r
-*/
-
-#if defined(LUA_USE_POSIX) /* { */
-
-#define l_gmtime(t,r) gmtime_r(t,r)
-#define l_localtime(t,r) localtime_r(t,r)
-
-#else /* }{ */
-
-/* ISO C definitions */
-#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
-#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
-
-#endif /* } */
-
-#endif /* } */
-
-
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
@@ -287,7 +300,7 @@ static int os_time (lua_State *L) {
t = mktime(&ts);
}
if (t != (time_t)(l_timet)t)
- luaL_error(L, "time result cannot be represented in this Lua instalation");
+ luaL_error(L, "time result cannot be represented in this Lua installation");
else if (t == (time_t)(-1))
lua_pushnil(L);
else
@@ -297,8 +310,9 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
- double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
- lua_pushnumber(L, (lua_Number)res);
+ time_t t1 = l_checktime(L, 1);
+ time_t t2 = l_checktime(L, 2);
+ lua_pushnumber(L, (lua_Number)difftime(t1, t2));
return 1;
}
diff --git a/plugins/MirLua/src/lua/lstate.c b/plugins/MirLua/src/lua/lstate.c
index ff6b02d36a..12e51d242f 100644
--- a/plugins/MirLua/src/lua/lstate.c
+++ b/plugins/MirLua/src/lua/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp $
+** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -37,9 +37,6 @@
#endif
-#define MEMERRMSG "not enough memory"
-
-
/*
** a macro to help the creation of a unique random seed when a state is
** created; the seed is used to randomize hashes.
@@ -200,12 +197,9 @@ static void f_luaopen (lua_State *L, void *ud) {
UNUSED(ud);
stack_init(L, L); /* init stack */
init_registry(L, g);
- luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
+ luaS_init(L);
luaT_init(L);
luaX_init(L);
- /* pre-create memory-error message */
- g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
- luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
g->gcrunning = 1; /* allow gc */
g->version = lua_version(NULL);
luai_userstateopen(L);
diff --git a/plugins/MirLua/src/lua/lstate.h b/plugins/MirLua/src/lua/lstate.h
index 81e12c40db..eefc217d26 100644
--- a/plugins/MirLua/src/lua/lstate.h
+++ b/plugins/MirLua/src/lua/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.119 2014/10/30 18:53:28 roberto Exp $
+** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,7 @@ typedef struct CallInfo {
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
+#define CIST_LEQ (1<<7) /* using __lt for __le */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
@@ -140,6 +141,7 @@ typedef struct global_State {
TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
+ TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */
} global_State;
diff --git a/plugins/MirLua/src/lua/lstring.c b/plugins/MirLua/src/lua/lstring.c
index 2947113c3c..5e0e3c40be 100644
--- a/plugins/MirLua/src/lua/lstring.c
+++ b/plugins/MirLua/src/lua/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp $
+** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,8 @@
#include "lstring.h"
+#define MEMERRMSG "not enough memory"
+
/*
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
@@ -36,10 +38,10 @@
** equality for long strings
*/
int luaS_eqlngstr (TString *a, TString *b) {
- size_t len = a->len;
+ size_t len = a->u.lnglen;
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
return (a == b) || /* same instance or... */
- ((len == b->len) && /* equal length and ... */
+ ((len == b->u.lnglen) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
}
@@ -69,9 +71,9 @@ void luaS_resize (lua_State *L, int newsize) {
TString *p = tb->hash[i];
tb->hash[i] = NULL;
while (p) { /* for each node in the list */
- TString *hnext = p->hnext; /* save next */
+ TString *hnext = p->u.hnext; /* save next */
unsigned int h = lmod(p->hash, newsize); /* new position */
- p->hnext = tb->hash[h]; /* chain it */
+ p->u.hnext = tb->hash[h]; /* chain it */
tb->hash[h] = p;
p = hnext;
}
@@ -85,6 +87,34 @@ void luaS_resize (lua_State *L, int newsize) {
}
+/*
+** Clear API string cache. (Entries cannot be empty, so fill them with
+** a non-collectable string.)
+*/
+void luaS_clearcache (global_State *g) {
+ int i;
+ for (i = 0; i < STRCACHE_SIZE; i++) {
+ if (iswhite(g->strcache[i][0])) /* will entry be collected? */
+ g->strcache[i][0] = g->memerrmsg; /* replace it with something fixed */
+ }
+}
+
+
+/*
+** Initialize the string table and the string cache
+*/
+void luaS_init (lua_State *L) {
+ global_State *g = G(L);
+ int i;
+ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
+ /* pre-create memory-error message */
+ g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
+ luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
+ for (i = 0; i < STRCACHE_SIZE; i++) /* fill cache with valid strings */
+ g->strcache[i][0] = g->memerrmsg;
+}
+
+
/*
** creates a new string object
@@ -97,7 +127,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
totalsize = sizelstring(l);
o = luaC_newobj(L, tag, totalsize);
ts = gco2ts(o);
- ts->len = l;
ts->hash = h;
ts->extra = 0;
memcpy(getaddrstr(ts), str, l * sizeof(char));
@@ -110,8 +139,8 @@ void luaS_remove (lua_State *L, TString *ts) {
stringtable *tb = &G(L)->strt;
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
while (*p != ts) /* find previous element */
- p = &(*p)->hnext;
- *p = (*p)->hnext; /* remove element from its list */
+ p = &(*p)->u.hnext;
+ *p = (*p)->u.hnext; /* remove element from its list */
tb->nuse--;
}
@@ -124,8 +153,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
global_State *g = G(L);
unsigned int h = luaS_hash(str, l, g->seed);
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
- for (ts = *list; ts != NULL; ts = ts->hnext) {
- if (l == ts->len &&
+ for (ts = *list; ts != NULL; ts = ts->u.hnext) {
+ if (l == ts->shrlen &&
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
/* found! */
if (isdead(g, ts)) /* dead (but not collected yet)? */
@@ -138,7 +167,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
}
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
- ts->hnext = *list;
+ ts->shrlen = cast_byte(l);
+ ts->u.hnext = *list;
*list = ts;
g->strt.nuse++;
return ts;
@@ -152,18 +182,32 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
if (l <= LUAI_MAXSHORTLEN) /* short string? */
return internshrstr(L, str, l);
else {
+ TString *ts;
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
luaM_toobig(L);
- return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
+ ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
+ ts->u.lnglen = l;
+ return ts;
}
}
/*
-** new zero-terminated string
+** Create or reuse a zero-terminated string, first checking in the
+** cache (using the string address as a key). The cache can contain
+** only zero-terminated strings, so it is safe to use 'strcmp' to
+** check hits.
*/
TString *luaS_new (lua_State *L, const char *str) {
- return luaS_newlstr(L, str, strlen(str));
+ unsigned int i = point2uint(str) % STRCACHE_SIZE; /* hash */
+ TString **p = G(L)->strcache[i];
+ if (strcmp(str, getstr(p[0])) == 0) /* hit? */
+ return p[0]; /* that it is */
+ else { /* normal route */
+ TString *s = luaS_newlstr(L, str, strlen(str));
+ p[0] = s;
+ return s;
+ }
}
diff --git a/plugins/MirLua/src/lua/lstring.h b/plugins/MirLua/src/lua/lstring.h
index d3f04caf72..e746f5fc8b 100644
--- a/plugins/MirLua/src/lua/lstring.h
+++ b/plugins/MirLua/src/lua/lstring.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp $
+** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -13,7 +13,6 @@
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
-#define sizestring(s) sizelstring((s)->len)
#define sizeludata(l) (sizeof(union UUdata) + (l))
#define sizeudata(u) sizeludata((u)->len)
@@ -37,6 +36,8 @@
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+LUAI_FUNC void luaS_clearcache (global_State *g);
+LUAI_FUNC void luaS_init (lua_State *L);
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
diff --git a/plugins/MirLua/src/lua/lstrlib.c b/plugins/MirLua/src/lua/lstrlib.c
index a650b768d5..19c350de15 100644
--- a/plugins/MirLua/src/lua/lstrlib.c
+++ b/plugins/MirLua/src/lua/lstrlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstrlib.c,v 1.221 2014/12/11 14:03:07 roberto Exp $
+** $Id: lstrlib.c,v 1.229 2015/05/20 17:39:23 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,7 @@
#include <ctype.h>
+#include <float.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
@@ -70,7 +71,7 @@ static int str_sub (lua_State *L) {
if (start < 1) start = 1;
if (end > (lua_Integer)l) end = l;
if (start <= end)
- lua_pushlstring(L, s + start - 1, (size_t)(end - start + 1));
+ lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
else lua_pushliteral(L, "");
return 1;
}
@@ -149,9 +150,9 @@ static int str_byte (lua_State *L) {
if (posi < 1) posi = 1;
if (pose > (lua_Integer)l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
- n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* arithmetic overflow? */
+ if (pose - posi >= INT_MAX) /* arithmetic overflow? */
return luaL_error(L, "string slice too long");
+ n = (int)(pose - posi) + 1;
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
lua_pushinteger(L, uchar(s[posi+i-1]));
@@ -499,7 +500,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
}
case '+': /* 1 or more repetitions */
s++; /* 1 match already done */
- /* go through */
+ /* FALLTHROUGH */
case '*': /* 0 or more repetitions */
s = max_expand(ms, s, p, ep);
break;
@@ -554,7 +555,7 @@ static void push_onecapture (MatchState *ms, int i, const char *s,
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
if (l == CAP_POSITION)
- lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
+ lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
else
lua_pushlstring(ms->L, ms->capture[i].init, l);
}
@@ -598,8 +599,8 @@ static int str_find_aux (lua_State *L, int find) {
/* do a plain search */
const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
if (s2) {
- lua_pushinteger(L, s2 - s + 1);
- lua_pushinteger(L, s2 - s + lp);
+ lua_pushinteger(L, (s2 - s) + 1);
+ lua_pushinteger(L, (s2 - s) + lp);
return 2;
}
}
@@ -621,7 +622,7 @@ static int str_find_aux (lua_State *L, int find) {
lua_assert(ms.matchdepth == MAXCCALLS);
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
- lua_pushinteger(L, s1 - s + 1); /* start */
+ lua_pushinteger(L, (s1 - s) + 1); /* start */
lua_pushinteger(L, res - s); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
@@ -797,17 +798,100 @@ static int str_gsub (lua_State *L) {
** =======================================================
*/
-/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM 512
+#if !defined(lua_number2strx) /* { */
+
+/*
+** Hexadecimal floating-point formatter
+*/
+
+#include <locale.h>
+#include <math.h>
+
+#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
+
+
+/*
+** Number of bits that goes into the first digit. It can be any value
+** between 1 and 4; the following definition tries to align the number
+** to nibble boundaries by making what is left after that first digit a
+** multiple of 4.
+*/
+#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1)
+
+
+/*
+** Add integer part of 'x' to buffer and return new 'x'
+*/
+static lua_Number adddigit (char *buff, int n, lua_Number x) {
+ lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
+ int d = (int)dd;
+ buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
+ return x - dd; /* return what is left */
+}
+
+
+static int num2straux (char *buff, lua_Number x) {
+ if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
+ return sprintf(buff, LUA_NUMBER_FMT, x); /* equal to '%g' */
+ else if (x == 0) { /* can be -0... */
+ sprintf(buff, LUA_NUMBER_FMT, x);
+ strcat(buff, "x0p+0"); /* reuses '0/-0' from 'sprintf'... */
+ return strlen(buff);
+ }
+ else {
+ int e;
+ lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
+ int n = 0; /* character count */
+ if (m < 0) { /* is number negative? */
+ buff[n++] = '-'; /* add signal */
+ m = -m; /* make it positive */
+ }
+ buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
+ m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
+ e -= L_NBFD; /* this digit goes before the radix point */
+ if (m > 0) { /* more digits? */
+ buff[n++] = lua_getlocaledecpoint(); /* add radix point */
+ do { /* add as many digits as needed */
+ m = adddigit(buff, n++, m * 16);
+ } while (m > 0);
+ }
+ n += sprintf(buff + n, "p%+d", e); /* add exponent */
+ return n;
+ }
+}
+
+
+static int lua_number2strx (lua_State *L, char *buff, const char *fmt,
+ lua_Number x) {
+ int n = num2straux(buff, x);
+ if (fmt[SIZELENMOD] == 'A') {
+ int i;
+ for (i = 0; i < n; i++)
+ buff[i] = toupper(uchar(buff[i]));
+ }
+ else if (fmt[SIZELENMOD] != 'a')
+ luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
+ return n;
+}
+
+#endif /* } */
+
+
+/*
+** Maximum size of each formatted item. This maximum size is produced
+** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
+** number of decimal digits to represent minfloat.
+*/
+#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP))
+
/* valid flags in a format specification */
#define FLAGS "-+ #0"
/*
** maximum size of each format specification (such as "%-099.99d")
-** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error)
*/
-#define MAX_FORMAT (sizeof(FLAGS) + 2 + 10)
+#define MAX_FORMAT 32
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
@@ -849,8 +933,8 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
if (isdigit(uchar(*p)))
luaL_error(L, "invalid format (width or precision too long)");
*(form++) = '%';
- memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
- form += p - strfrmt + 1;
+ memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
+ form += (p - strfrmt) + 1;
*form = '\0';
return p;
}
@@ -901,9 +985,10 @@ static int str_format (lua_State *L) {
nb = sprintf(buff, form, n);
break;
}
-#if defined(LUA_USE_AFORMAT)
case 'a': case 'A':
-#endif
+ addlenmod(form, LUA_NUMBER_FRMLEN);
+ nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg));
+ break;
case 'e': case 'E': case 'f':
case 'g': case 'G': {
addlenmod(form, LUA_NUMBER_FRMLEN);
@@ -921,13 +1006,12 @@ static int str_format (lua_State *L) {
/* no precision and string is too long to be formatted;
keep original string */
luaL_addvalue(&b);
- break;
}
else {
nb = sprintf(buff, form, s);
lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
- break;
}
+ break;
}
default: { /* also treat cases 'pnLlh' */
return luaL_error(L, "invalid option '%%%c' to 'format'",
@@ -1249,7 +1333,7 @@ static int str_pack (lua_State *L) {
totalsize += len + 1;
break;
}
- case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* go through */
+ case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
case Kpaddalign: case Knop:
arg--; /* undo increment */
break;
diff --git a/plugins/MirLua/src/lua/ltable.c b/plugins/MirLua/src/lua/ltable.c
index 38be00513d..04f2a34735 100644
--- a/plugins/MirLua/src/lua/ltable.c
+++ b/plugins/MirLua/src/lua/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.100 2015/01/05 13:52:37 roberto Exp $
+** $Id: ltable.c,v 2.111 2015/06/09 14:21:13 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -14,8 +14,8 @@
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
-** part. The actual size of the array is the largest 'n' such that at
-** least half the slots between 0 and n are in use.
+** part. The actual size of the array is the largest 'n' such that
+** more than half the slots between 1 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the 'original' position that its hash gives
@@ -23,9 +23,7 @@
** Hence even when the load factor reaches 100%, performance remains good.
*/
-#include <float.h>
#include <math.h>
-#include <string.h>
#include <limits.h>
#include "lua.h"
@@ -71,7 +69,7 @@
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
-#define hashpointer(t,p) hashmod(t, point2int(p))
+#define hashpointer(t,p) hashmod(t, point2uint(p))
#define dummynode (&dummynode_)
@@ -85,31 +83,33 @@ static const Node dummynode_ = {
/*
-** Checks whether a float has a value representable as a lua_Integer
-** (and does the conversion if so)
+** Hash for floating-point numbers.
+** The main computation should be just
+** n = frepx(n, &i); return (n * INT_MAX) + i
+** but there are some numerical subtleties.
+** In a two-complement representation, INT_MAX does not has an exact
+** representation as a float, but INT_MIN does; because the absolute
+** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
+** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
+** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
+** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
+** INT_MIN.
*/
-static int numisinteger (lua_Number x, lua_Integer *p) {
- if ((x) == l_floor(x)) /* integral value? */
- return lua_numbertointeger(x, p); /* try as an integer */
- else return 0;
-}
-
-
-/*
-** hash for floating-point numbers
-*/
-static Node *hashfloat (const Table *t, lua_Number n) {
+#if !defined(l_hashfloat)
+static int l_hashfloat (lua_Number n) {
int i;
- n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP);
- i += cast_int(n);
- if (i < 0) {
- if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
- i = 0; /* handle INT_MIN */
- i = -i; /* must be a positive value */
+ lua_Integer ni;
+ n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
+ if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */
+ lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == HUGE_VAL);
+ return 0;
+ }
+ else { /* normal case */
+ unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
+ return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
}
- return hashmod(t, i);
}
-
+#endif
/*
@@ -121,13 +121,13 @@ static Node *mainposition (const Table *t, const TValue *key) {
case LUA_TNUMINT:
return hashint(t, ivalue(key));
case LUA_TNUMFLT:
- return hashfloat(t, fltvalue(key));
+ return hashmod(t, l_hashfloat(fltvalue(key)));
case LUA_TSHRSTR:
return hashstr(t, tsvalue(key));
case LUA_TLNGSTR: {
TString *s = tsvalue(key);
if (s->extra == 0) { /* no hash? */
- s->hash = luaS_hash(getstr(s), s->len, s->hash);
+ s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
s->extra = 1; /* now it has its hash */
}
return hashstr(t, tsvalue(key));
@@ -219,28 +219,29 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
/*
** Compute the optimal size for the array part of table 't'. 'nums' is a
** "count array" where 'nums[i]' is the number of integers in the table
-** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and
-** return the number of elements that will go to that part.
+** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
+** integer keys in the table and leaves with the number of keys that
+** will go to the array part; return the optimal size.
*/
-static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
+static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
int i;
- unsigned int twotoi; /* 2^i */
+ unsigned int twotoi; /* 2^i (candidate for optimal size) */
unsigned int a = 0; /* number of elements smaller than 2^i */
unsigned int na = 0; /* number of elements to go to array part */
- unsigned int n = 0; /* optimal size for array part */
- for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
+ unsigned int optimal = 0; /* optimal size for array part */
+ /* loop while keys can fill more than half of total size */
+ for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
- n = twotoi; /* optimal size (till now) */
- na = a; /* all elements up to 'n' will go to array part */
+ optimal = twotoi; /* optimal size (till now) */
+ na = a; /* all elements up to 'optimal' will go to array part */
}
}
- if (a == *narray) break; /* all elements already counted */
}
- *narray = n;
- lua_assert(*narray/2 <= na && na <= *narray);
- return na;
+ lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
+ *pna = na;
+ return optimal;
}
@@ -255,6 +256,11 @@ static int countint (const TValue *key, unsigned int *nums) {
}
+/*
+** Count keys in array part of table 't': Fill 'nums[i]' with
+** number of keys that will go into corresponding slice and return
+** total number of non-nil keys.
+*/
static unsigned int numusearray (const Table *t, unsigned int *nums) {
int lg;
unsigned int ttlg; /* 2^lg */
@@ -281,8 +287,7 @@ static unsigned int numusearray (const Table *t, unsigned int *nums) {
}
-static int numusehash (const Table *t, unsigned int *nums,
- unsigned int *pnasize) {
+static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
int totaluse = 0; /* total number of elements */
int ause = 0; /* elements added to 'nums' (can go to array part) */
int i = sizenode(t);
@@ -293,7 +298,7 @@ static int numusehash (const Table *t, unsigned int *nums,
totaluse++;
}
}
- *pnasize += ause;
+ *pna += ause;
return totaluse;
}
@@ -363,7 +368,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
}
}
if (!isdummy(nold))
- luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
+ luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
}
@@ -376,21 +381,22 @@ void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
*/
static void rehash (lua_State *L, Table *t, const TValue *ek) {
- unsigned int nasize, na;
+ unsigned int asize; /* optimal size for array part */
+ unsigned int na; /* number of keys in the array part */
unsigned int nums[MAXABITS + 1];
int i;
int totaluse;
for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
- nasize = numusearray(t, nums); /* count keys in array part */
- totaluse = nasize; /* all those keys are integer keys */
- totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
+ na = numusearray(t, nums); /* count keys in array part */
+ totaluse = na; /* all those keys are integer keys */
+ totaluse += numusehash(t, nums, &na); /* count keys in hash part */
/* count extra key */
- nasize += countint(ek, nums);
+ na += countint(ek, nums);
totaluse++;
/* compute new size for array part */
- na = computesizes(nums, &nasize);
+ asize = computesizes(nums, &na);
/* resize the table to new computed sizes */
- luaH_resize(L, t, nasize, totaluse - na);
+ luaH_resize(L, t, asize, totaluse - na);
}
@@ -443,14 +449,13 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
TValue aux;
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisfloat(key)) {
- lua_Number n = fltvalue(key);
lua_Integer k;
- if (luai_numisnan(n))
- luaG_runerror(L, "table index is NaN");
- if (numisinteger(n, &k)) { /* index is int? */
+ if (luaV_tointeger(key, &k, 0)) { /* index is int? */
setivalue(&aux, k);
key = &aux; /* insert it as an integer */
}
+ else if (luai_numisnan(fltvalue(key)))
+ luaG_runerror(L, "table index is NaN");
}
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
@@ -544,10 +549,10 @@ const TValue *luaH_get (Table *t, const TValue *key) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMFLT: {
lua_Integer k;
- if (numisinteger(fltvalue(key), &k)) /* index is int? */
+ if (luaV_tointeger(key, &k, 0)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
- /* else go through */
- }
+ /* else... */
+ } /* FALLTHROUGH */
default: {
Node *n = mainposition(t, key);
for (;;) { /* check whether 'key' is somewhere in the chain */
diff --git a/plugins/MirLua/src/lua/ltablib.c b/plugins/MirLua/src/lua/ltablib.c
index 8f78afb7f2..a05c885c03 100644
--- a/plugins/MirLua/src/lua/ltablib.c
+++ b/plugins/MirLua/src/lua/ltablib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltablib.c,v 1.79 2014/11/02 19:19:04 roberto Exp $
+** $Id: ltablib.c,v 1.80 2015/01/13 16:27:29 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -124,8 +124,6 @@ static int tmove (lua_State *L) {
lua_Integer e = luaL_checkinteger(L, 3);
lua_Integer t = luaL_checkinteger(L, 4);
int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
- /* the following restriction avoids several problems with overflows */
- luaL_argcheck(L, f > 0, 2, "initial position must be positive");
if (e >= f) { /* otherwise, nothing to move */
lua_Integer n, i;
ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
@@ -134,7 +132,11 @@ static int tmove (lua_State *L) {
ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
: lua_seti;
+ luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
+ "too many elements to move");
n = e - f + 1; /* number of elements to move */
+ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
+ "destination wrap around");
if (t > f) {
for (i = n - 1; i >= 0; i--) {
(*ta.geti)(L, 1, f + i);
diff --git a/plugins/MirLua/src/lua/ltm.c b/plugins/MirLua/src/lua/ltm.c
index 25b46b17f9..c38e5c34b5 100644
--- a/plugins/MirLua/src/lua/ltm.c
+++ b/plugins/MirLua/src/lua/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 2.33 2014/11/21 12:15:57 roberto Exp $
+** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -117,6 +117,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
switch (event) {
case TM_CONCAT:
luaG_concaterror(L, p1, p2);
+ /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
case TM_BAND: case TM_BOR: case TM_BXOR:
case TM_SHL: case TM_SHR: case TM_BNOT: {
lua_Number dummy;
@@ -124,8 +125,8 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
luaG_tointerror(L, p1, p2);
else
luaG_opinterror(L, p1, p2, "perform bitwise operation on");
- /* else go through */
}
+ /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
default:
luaG_opinterror(L, p1, p2, "perform arithmetic on");
}
diff --git a/plugins/MirLua/src/lua/lua.h b/plugins/MirLua/src/lua/lua.h
index 09a4ccaf89..1c2b95ac4b 100644
--- a/plugins/MirLua/src/lua/lua.h
+++ b/plugins/MirLua/src/lua/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.325 2014/12/26 17:24:27 roberto Exp $
+** $Id: lua.h,v 1.328 2015/06/03 13:03:38 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,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
-#define LUA_VERSION_RELEASE "0"
+#define LUA_VERSION_RELEASE "1"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -35,9 +35,11 @@
/*
-** pseudo-indices
+** Pseudo-indices
+** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+** space after that to help overflow detection)
*/
-#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
+#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
@@ -356,8 +358,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
-#define lua_pushliteral(L, s) \
- lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushglobaltable(L) \
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
diff --git a/plugins/MirLua/src/lua/luaconf.h b/plugins/MirLua/src/lua/luaconf.h
index fd28d21aec..7cfa4faf77 100644
--- a/plugins/MirLua/src/lua/luaconf.h
+++ b/plugins/MirLua/src/lua/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.238 2014/12/29 13:27:55 roberto Exp $
+** $Id: luaconf.h,v 1.251 2015/05/20 17:39:23 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -96,10 +96,8 @@
/*
-@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines the type for
-** Lua integers.
-@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
-** the type for Lua floats.
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
** Lua should work fine with any mix of these options (if supported
** by your C compiler). The usual configurations are 64-bit integers
** and 'double' (the default), 32-bit integers and 'float' (for
@@ -107,31 +105,46 @@
** compliant with C99, which may not have support for 'long long').
*/
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT 1
+#define LUA_INT_LONG 2
+#define LUA_INT_LONGLONG 3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT 1
+#define LUA_FLOAT_DOUBLE 2
+#define LUA_FLOAT_LONGDOUBLE 3
+
#if defined(LUA_32BITS) /* { */
/*
** 32-bit integers and 'float'
*/
#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
-#define LUA_INT_INT
+#define LUA_INT_TYPE LUA_INT_INT
#else /* otherwise use 'long' */
-#define LUA_INT_LONG
+#define LUA_INT_TYPE LUA_INT_LONG
#endif
-#define LUA_REAL_FLOAT
+#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
#elif defined(LUA_C89_NUMBERS) /* }{ */
/*
** largest types available for C89 ('long' and 'double')
*/
-#define LUA_INT_LONG
-#define LUA_REAL_DOUBLE
+#define LUA_INT_TYPE LUA_INT_LONG
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+
+#endif /* } */
+
-#else /* }{ */
/*
** default configuration for 64-bit Lua ('long long' and 'double')
*/
-#define LUA_INT_LONGLONG
-#define LUA_REAL_DOUBLE
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE LUA_INT_LONGLONG
+#endif
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
#endif /* } */
/* }================================================================== */
@@ -155,7 +168,7 @@
** non-conventional directories.
*/
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
-#if defined(_WIN32) /* { */
+#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
@@ -300,20 +313,15 @@
*/
#define LUA_COMPAT_APIINTCASTS
-
-/*
-@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
-@@ a float mark ('.0').
-** This macro is not on by default even in compatibility mode,
-** because this is not really an incompatibility.
-*/
-/* #define LUA_COMPAT_FLOATSTRING */
-
#endif /* } */
#if defined(LUA_COMPAT_5_1) /* { */
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
/*
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
** You can replace it with 'table.unpack'.
@@ -373,6 +381,15 @@
#endif /* } */
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
/* }================================================================== */
@@ -380,30 +397,30 @@
/*
** {==================================================================
** Configuration for Numbers.
-** Change these definitions if no predefined LUA_REAL_* / LUA_INT_*
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
** satisfy your needs.
** ===================================================================
*/
/*
@@ LUA_NUMBER is the floating-point type used by Lua.
-**
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@@ over a floating number.
-**
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
-**
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
-**
@@ lua_str2number converts a decimal numeric string to a number.
*/
-#if defined(LUA_REAL_FLOAT) /* { single float */
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
#define LUA_NUMBER float
+#define l_mathlim(n) (FLT_##n)
+
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
@@ -414,10 +431,12 @@
#define lua_str2number(s,p) strtof((s), (p))
-#elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
#define LUA_NUMBER long double
+#define l_mathlim(n) (LDBL_##n)
+
#define LUAI_UACNUMBER long double
#define LUA_NUMBER_FRMLEN "L"
@@ -427,10 +446,12 @@
#define lua_str2number(s,p) strtold((s), (p))
-#elif defined(LUA_REAL_DOUBLE) /* }{ double */
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
#define LUA_NUMBER double
+#define l_mathlim(n) (DBL_##n)
+
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
@@ -440,9 +461,9 @@
#define lua_str2number(s,p) strtod((s), (p))
-#else /* }{ */
+#else /* }{ */
-#error "numeric real type not defined"
+#error "numeric float type not defined"
#endif /* } */
@@ -466,46 +487,6 @@
(*(p) = (LUA_INTEGER)(n), 1))
-/*
-@@ The luai_num* macros define the primitive operations over numbers.
-** They should work for any size of floating numbers.
-*/
-
-/* the following operations need the math library */
-#if defined(lobject_c) || defined(lvm_c)
-#include <math.h>
-
-/* floor division (defined as 'floor(a/b)') */
-#define luai_numidiv(L,a,b) ((void)L, l_mathop(floor)(luai_numdiv(L,a,b)))
-
-/*
-** module: defined as 'a - floor(a/b)*b'; the previous definition gives
-** NaN when 'b' is huge, but the result should be 'a'. 'fmod' gives the
-** result of 'a - trunc(a/b)*b', and therefore must be corrected when
-** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a
-** non-integer negative result, which is equivalent to the test below
-*/
-#define luai_nummod(L,a,b,m) \
- { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
-
-/* exponentiation */
-#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
-
-#endif
-
-/* these are quite standard operations */
-#if defined(LUA_CORE)
-#define luai_numadd(L,a,b) ((a)+(b))
-#define luai_numsub(L,a,b) ((a)-(b))
-#define luai_nummul(L,a,b) ((a)*(b))
-#define luai_numdiv(L,a,b) ((a)/(b))
-#define luai_numunm(L,a) (-(a))
-#define luai_numeq(a,b) ((a)==(b))
-#define luai_numlt(a,b) ((a)<(b))
-#define luai_numle(a,b) ((a)<=(b))
-#define luai_numisnan(a) (!luai_numeq((a), (a)))
-#endif
-
/*
@@ LUA_INTEGER is the integer type used by Lua.
@@ -538,7 +519,7 @@
/* now the variable definitions */
-#if defined(LUA_INT_INT) /* { int */
+#if LUA_INT_TYPE == LUA_INT_INT /* { int */
#define LUA_INTEGER int
#define LUA_INTEGER_FRMLEN ""
@@ -546,7 +527,7 @@
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
-#elif defined(LUA_INT_LONG) /* }{ long */
+#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#define LUA_INTEGER long
#define LUA_INTEGER_FRMLEN "l"
@@ -554,7 +535,7 @@
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
-#elif defined(LUA_INT_LONGLONG) /* }{ long long */
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
#if defined(LLONG_MAX) /* { */
/* use ISO C99 stuff */
@@ -592,13 +573,13 @@
/*
** {==================================================================
-** Dependencies with C99
+** Dependencies with C99 and other C details
** ===================================================================
*/
/*
@@ lua_strx2number converts an hexadecimal numeric string to a number.
-** In C99, 'strtod' does both conversions. Otherwise, you can
+** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
*/
@@ -608,12 +589,13 @@
/*
-@@ LUA_USE_AFORMAT allows '%a'/'%A' specifiers in 'string.format'
-** Enable it if the C function 'printf' supports these specifiers.
-** (C99 demands it and Windows also supports it.)
+@@ lua_number2strx converts a float to an hexadecimal numeric string.
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
*/
-#if !defined(LUA_USE_C89) || defined(LUA_USE_WINDOWS)
-#define LUA_USE_AFORMAT
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,f,n) sprintf(b,f,n)
#endif
@@ -642,12 +624,50 @@
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 199901L
#include <stdint.h>
-#if defined (INTPTR_MAX) /* even in C99 this type is optional */
+#if defined(INTPTR_MAX) /* even in C99 this type is optional */
#undef LUA_KCONTEXT
#define LUA_KCONTEXT intptr_t
#endif
#endif
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e) assert(e)
+#endif
+
/* }================================================================== */
@@ -671,9 +691,6 @@
#define LUAI_MAXSTACK 15000
#endif
-/* reserve some space for error handling */
-#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
-
/*
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
@@ -692,19 +709,17 @@
/*
-@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
-** strings that are internalized. (Cannot be smaller than reserved words
-** or tags for metamethods, as these strings must be internalized;
-** #("function") = 8, #("__newindex") = 10.)
-*/
-#define LUAI_MAXSHORTLEN 40
-
-
-/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
-** CHANGE it if it uses too much C-stack space.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
*/
-#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#if defined(LUA_FLOAT_LONGDOUBLE)
+#define LUAL_BUFFERSIZE 8192
+#else
+#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
/* }================================================================== */
diff --git a/plugins/MirLua/src/lua/lutf8lib.c b/plugins/MirLua/src/lua/lutf8lib.c
index be4f087f76..9042582d1e 100644
--- a/plugins/MirLua/src/lua/lutf8lib.c
+++ b/plugins/MirLua/src/lua/lutf8lib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lutf8lib.c,v 1.13 2014/11/02 19:19:04 roberto Exp $
+** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,7 @@
#include <assert.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -37,7 +38,7 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
*/
static const char *utf8_decode (const char *o, int *val) {
- static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
+ static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
const unsigned char *s = (const unsigned char *)o;
unsigned int c = s[0];
unsigned int res = 0; /* final result */
@@ -106,9 +107,9 @@ static int codepoint (lua_State *L) {
luaL_argcheck(L, posi >= 1, 2, "out of range");
luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
if (posi > pose) return 0; /* empty interval; return no values */
- n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* (lua_Integer -> int) overflow? */
+ if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */
return luaL_error(L, "string slice too long");
+ n = (int)(pose - posi) + 1;
luaL_checkstack(L, n, "string slice too long");
n = 0;
se = s + pose;
@@ -234,7 +235,7 @@ static int iter_codes (lua_State *L) {
#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
-static struct luaL_Reg funcs[] = {
+static const luaL_Reg funcs[] = {
{"offset", byteoffset},
{"codepoint", codepoint},
{"char", utfchar},
@@ -248,7 +249,7 @@ static struct luaL_Reg funcs[] = {
LUAMOD_API int luaopen_utf8 (lua_State *L) {
luaL_newlib(L, funcs);
- lua_pushliteral(L, UTF8PATT);
+ lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
lua_setfield(L, -2, "charpattern");
return 1;
}
diff --git a/plugins/MirLua/src/lua/lvm.c b/plugins/MirLua/src/lua/lvm.c
index 2ac1b02df4..a8cefc52b1 100644
--- a/plugins/MirLua/src/lua/lvm.c
+++ b/plugins/MirLua/src/lua/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.232 2014/12/27 20:30:38 roberto Exp $
+** $Id: lvm.c,v 2.245 2015/06/09 15:53:35 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -9,8 +9,9 @@
#include "lprefix.h"
-
+#include <float.h>
#include <limits.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,36 +31,38 @@
#include "lvm.h"
-/*
-** You can define LUA_FLOORN2I if you want to convert floats to integers
-** by flooring them (instead of raising an error if they are not
-** integral values)
-*/
-#if !defined(LUA_FLOORN2I)
-#define LUA_FLOORN2I 0
-#endif
-
-
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 2000
+
/*
-** Similar to 'tonumber', but does not attempt to convert strings and
-** ensure correct precision (no extra bits). Used in comparisons.
+** 'l_intfitsf' checks whether a given integer can be converted to a
+** float without rounding. Used in comparisons. Left undefined if
+** all integers fit in a float precisely.
*/
-static int tofloat (const TValue *obj, lua_Number *n) {
- if (ttisfloat(obj)) *n = fltvalue(obj);
- else if (ttisinteger(obj)) {
- volatile lua_Number x = cast_num(ivalue(obj)); /* avoid extra precision */
- *n = x;
- }
- else {
- *n = 0; /* to avoid warnings */
- return 0;
- }
- return 1;
-}
+#if !defined(l_intfitsf)
+
+/* number of bits in the mantissa of a float */
+#define NBM (l_mathlim(MANT_DIG))
+
+/*
+** Check whether some integers may not fit in a float, that is, whether
+** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
+** (The shifts are done in parts to avoid shifting by more than the size
+** of an integer. In a worst case, NBM == 113 for long double and
+** sizeof(integer) == 32.)
+*/
+#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
+ >> (NBM - (3 * (NBM / 4)))) > 0
+
+#define l_intfitsf(i) \
+ (-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
+
+#endif
+
+#endif
+
/*
@@ -73,7 +76,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
return 1;
}
else if (cvt2num(obj) && /* string convertible to number? */
- luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
+ luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
return 1;
}
@@ -88,7 +91,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
** mode == 1: takes the floor of the number
** mode == 2: takes the ceil of the number
*/
-static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
+int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
TValue v;
again:
if (ttisfloat(obj)) {
@@ -106,7 +109,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
return 1;
}
else if (cvt2num(obj) &&
- luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
+ luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
obj = &v;
goto again; /* convert result from 'luaO_str2num' to an integer */
}
@@ -115,14 +118,6 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
/*
-** try to convert a value to an integer
-*/
-int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
- return tointeger_aux(obj, p, LUA_FLOORN2I);
-}
-
-
-/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
** (The following explanation assumes a non-negative step; it is valid
@@ -140,11 +135,11 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
int *stopnow) {
*stopnow = 0; /* usually, let loops run */
- if (!tointeger_aux(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
+ if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
lua_Number n; /* try to convert to float */
if (!tonumber(obj, &n)) /* cannot convert to float? */
return 0; /* not a number */
- if (n > 0) { /* if true, float is larger than max integer */
+ if (luai_numlt(0, n)) { /* if true, float is larger than max integer */
*p = LUA_MAXINTEGER;
if (step < 0) *stopnow = 1;
}
@@ -239,9 +234,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
*/
static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
- size_t ll = ls->len;
+ size_t ll = tsslen(ls);
const char *r = getstr(rs);
- size_t lr = rs->len;
+ size_t lr = tsslen(rs);
for (;;) { /* for each segment */
int temp = strcoll(l, r);
if (temp != 0) /* not equal? */
@@ -261,15 +256,102 @@ static int l_strcmp (const TString *ls, const TString *rs) {
/*
+** Check whether integer 'i' is less than float 'f'. If 'i' has an
+** exact representation as a float ('l_intfitsf'), compare numbers as
+** floats. Otherwise, if 'f' is outside the range for integers, result
+** is trivial. Otherwise, compare them as integers. (When 'i' has no
+** float representation, either 'f' is "far away" from 'i' or 'f' has
+** no precision left for a fractional part; either way, how 'f' is
+** truncated is irrelevant.) When 'f' is NaN, comparisons must result
+** in false.
+*/
+static int LTintfloat (lua_Integer i, lua_Number f) {
+#if defined(l_intfitsf)
+ if (!l_intfitsf(i)) {
+ if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
+ return 1; /* f >= maxint + 1 > i */
+ else if (f > cast_num(LUA_MININTEGER)) /* minint < f <= maxint ? */
+ return (i < cast(lua_Integer, f)); /* compare them as integers */
+ else /* f <= minint <= i (or 'f' is NaN) --> not(i < f) */
+ return 0;
+ }
+#endif
+ return luai_numlt(cast_num(i), f); /* compare them as floats */
+}
+
+
+/*
+** Check whether integer 'i' is less than or equal to float 'f'.
+** See comments on previous function.
+*/
+static int LEintfloat (lua_Integer i, lua_Number f) {
+#if defined(l_intfitsf)
+ if (!l_intfitsf(i)) {
+ if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
+ return 1; /* f >= maxint + 1 > i */
+ else if (f >= cast_num(LUA_MININTEGER)) /* minint <= f <= maxint ? */
+ return (i <= cast(lua_Integer, f)); /* compare them as integers */
+ else /* f < minint <= i (or 'f' is NaN) --> not(i <= f) */
+ return 0;
+ }
+#endif
+ return luai_numle(cast_num(i), f); /* compare them as floats */
+}
+
+
+/*
+** Return 'l < r', for numbers.
+*/
+static int LTnum (const TValue *l, const TValue *r) {
+ if (ttisinteger(l)) {
+ lua_Integer li = ivalue(l);
+ if (ttisinteger(r))
+ return li < ivalue(r); /* both are integers */
+ else /* 'l' is int and 'r' is float */
+ return LTintfloat(li, fltvalue(r)); /* l < r ? */
+ }
+ else {
+ lua_Number lf = fltvalue(l); /* 'l' must be float */
+ if (ttisfloat(r))
+ return luai_numlt(lf, fltvalue(r)); /* both are float */
+ else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
+ return 0; /* NaN < i is always false */
+ else /* without NaN, (l < r) <--> not(r <= l) */
+ return !LEintfloat(ivalue(r), lf); /* not (r <= l) ? */
+ }
+}
+
+
+/*
+** Return 'l <= r', for numbers.
+*/
+static int LEnum (const TValue *l, const TValue *r) {
+ if (ttisinteger(l)) {
+ lua_Integer li = ivalue(l);
+ if (ttisinteger(r))
+ return li <= ivalue(r); /* both are integers */
+ else /* 'l' is int and 'r' is float */
+ return LEintfloat(li, fltvalue(r)); /* l <= r ? */
+ }
+ else {
+ lua_Number lf = fltvalue(l); /* 'l' must be float */
+ if (ttisfloat(r))
+ return luai_numle(lf, fltvalue(r)); /* both are float */
+ else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
+ return 0; /* NaN <= i is always false */
+ else /* without NaN, (l <= r) <--> not(r < l) */
+ return !LTintfloat(ivalue(r), lf); /* not (r < l) ? */
+ }
+}
+
+
+/*
** Main operation less than; return 'l < r'.
*/
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
- lua_Number nl, nr;
- if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
- return (ivalue(l) < ivalue(r));
- else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
- return luai_numlt(nl, nr);
+ if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
+ return LTnum(l, r);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
@@ -279,27 +361,34 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
/*
-** Main operation less than or equal to; return 'l <= r'.
+** Main operation less than or equal to; return 'l <= r'. If it needs
+** a metamethod and there is no '__le', try '__lt', based on
+** l <= r iff !(r < l) (assuming a total order). If the metamethod
+** yields during this substitution, the continuation has to know
+** about it (to negate the result of r<l); bit CIST_LEQ in the call
+** status keeps that information.
*/
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
- lua_Number nl, nr;
- if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
- return (ivalue(l) <= ivalue(r));
- else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
- return luai_numle(nl, nr);
+ if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
+ return LEnum(l, r);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
- else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
+ else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */
return res;
- else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
- luaG_ordererror(L, l, r);
- return !res;
+ else { /* try 'lt': */
+ L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
+ res = luaT_callorderTM(L, r, l, TM_LT);
+ L->ci->callstatus ^= CIST_LEQ; /* clear mark */
+ if (res < 0)
+ luaG_ordererror(L, l, r);
+ return !res; /* result is negated */
+ }
}
/*
-** Main operation for equality of Lua values; return 't1 == t2'.
+** Main operation for equality of Lua values; return 't1 == t2'.
** L == NULL means raw equality (no metamethods)
*/
int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
@@ -308,10 +397,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
return 0; /* only numbers can be equal with different variants */
else { /* two numbers with different variants */
- lua_Number n1, n2; /* compare them as floats */
- lua_assert(ttisnumber(t1) && ttisnumber(t2));
- cast_void(tofloat(t1, &n1)); cast_void(tofloat(t2, &n2));
- return luai_numeq(n1, n2);
+ lua_Integer i1, i2; /* compare them as integers */
+ return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
}
}
/* values have same type and same variant */
@@ -354,6 +441,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
#define tostring(L,o) \
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
+#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
+
/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
@@ -365,19 +454,19 @@ void luaV_concat (lua_State *L, int total) {
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
- else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
+ else if (isemptystr(top - 1)) /* second operand is empty? */
cast_void(tostring(L, top - 2)); /* result is first operand */
- else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
+ else if (isemptystr(top - 2)) { /* first operand is an empty string? */
setobjs2s(L, top - 2, top - 1); /* result is second op. */
}
else {
/* at least two non-empty string values; get as many as possible */
- size_t tl = tsvalue(top-1)->len;
+ size_t tl = vslen(top - 1);
char *buffer;
int i;
/* collect total length */
for (i = 1; i < total && tostring(L, top-i-1); i++) {
- size_t l = tsvalue(top-i-1)->len;
+ size_t l = vslen(top - i - 1);
if (l >= (MAX_SIZE/sizeof(char)) - tl)
luaG_runerror(L, "string length overflow");
tl += l;
@@ -386,7 +475,7 @@ void luaV_concat (lua_State *L, int total) {
tl = 0;
n = i;
do { /* copy all strings to buffer */
- size_t l = tsvalue(top-i)->len;
+ size_t l = vslen(top - i);
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
tl += l;
} while (--i > 0);
@@ -403,7 +492,7 @@ void luaV_concat (lua_State *L, int total) {
*/
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
const TValue *tm;
- switch (ttnov(rb)) {
+ switch (ttype(rb)) {
case LUA_TTABLE: {
Table *h = hvalue(rb);
tm = fasttm(L, h->metatable, TM_LEN);
@@ -411,8 +500,12 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
setivalue(ra, luaH_getn(h)); /* else primitive len */
return;
}
- case LUA_TSTRING: {
- setivalue(ra, tsvalue(rb)->len);
+ case LUA_TSHRSTR: {
+ setivalue(ra, tsvalue(rb)->shrlen);
+ return;
+ }
+ case LUA_TLNGSTR: {
+ setivalue(ra, tsvalue(rb)->u.lnglen);
return;
}
default: { /* try metamethod */
@@ -448,7 +541,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) {
/*
-** Integer modulus; return 'm % n'. (Assume that C '%' with
+** Integer modulus; return 'm % n'. (Assume that C '%' with
** negative operands follows C99 behavior. See previous comment
** about luaV_div.)
*/
@@ -553,11 +646,11 @@ void luaV_finishOp (lua_State *L) {
case OP_LE: case OP_LT: case OP_EQ: {
int res = !l_isfalse(L->top - 1);
L->top--;
- /* metamethod should not be called when operand is K */
- lua_assert(!ISK(GETARG_B(inst)));
- if (op == OP_LE && /* "<=" using "<" instead? */
- ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
- res = !res; /* invert result */
+ if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
+ lua_assert(op == OP_LE);
+ ci->callstatus ^= CIST_LEQ; /* clear mark */
+ res = !res; /* negate result */
+ }
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
if (res != GETARG_A(inst)) /* condition failed? */
ci->u.l.savedpc++; /* skip jump instruction */
@@ -607,7 +700,7 @@ void luaV_finishOp (lua_State *L) {
** some macros for common tasks in 'luaV_execute'
*/
-#if !defined luai_runtimecheck
+#if !defined(luai_runtimecheck)
#define luai_runtimecheck(L, c) /* void */
#endif
@@ -743,7 +836,7 @@ void luaV_execute (lua_State *L) {
Protect(luaV_gettable(L, rb, RKC(i), ra));
vmbreak;
}
- vmcase(OP_ADD) {
+ vmcase(OP_ADD) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Number nb; lua_Number nc;
@@ -928,7 +1021,7 @@ void luaV_execute (lua_State *L) {
L->top = base + c + 1; /* mark the end of concat operands */
Protect(luaV_concat(L, c - b + 1));
ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
- rb = b + base;
+ rb = base + b;
setobjs2s(L, ra, rb);
checkGC(L, (ra >= rb ? ra + 1 : rb));
L->top = ci->top; /* restore top */
@@ -1031,9 +1124,8 @@ void luaV_execute (lua_State *L) {
}
vmcase(OP_RETURN) {
int b = GETARG_B(i);
- if (b != 0) L->top = ra+b-1;
if (cl->p->sizep > 0) luaF_close(L, base);
- b = luaD_poscall(L, ra);
+ b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
return; /* external invocation: return */
else { /* invocation via reentry: continue execution */
@@ -1051,7 +1143,7 @@ void luaV_execute (lua_State *L) {
lua_Integer limit = ivalue(ra + 1);
if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
- setivalue(ra, idx); /* update internal index... */
+ chgivalue(ra, idx); /* update internal index... */
setivalue(ra + 3, idx); /* ...and external index */
}
}
@@ -1062,7 +1154,7 @@ void luaV_execute (lua_State *L) {
if (luai_numlt(0, step) ? luai_numle(idx, limit)
: luai_numle(limit, idx)) {
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
- setfltvalue(ra, idx); /* update internal index... */
+ chgfltvalue(ra, idx); /* update internal index... */
setfltvalue(ra + 3, idx); /* ...and external index */
}
}
diff --git a/plugins/MirLua/src/lua/lvm.h b/plugins/MirLua/src/lua/lvm.h
index 5c5e18c3ac..0613826a62 100644
--- a/plugins/MirLua/src/lua/lvm.h
+++ b/plugins/MirLua/src/lua/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $
+** $Id: lvm.h,v 2.35 2015/02/20 14:27:53 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -27,11 +27,21 @@
#endif
+/*
+** You can define LUA_FLOORN2I if you want to convert floats to integers
+** by flooring them (instead of raising an error if they are not
+** integral values)
+*/
+#if !defined(LUA_FLOORN2I)
+#define LUA_FLOORN2I 0
+#endif
+
+
#define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
#define tointeger(o,i) \
- (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i))
+ (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
@@ -42,7 +52,7 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
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);
+LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,