diff options
Diffstat (limited to 'plugins/MirLua/src')
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,  | 
