From f36b1731553afa033ee6d287bd195bd1209d11dc Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 17 Jun 2015 22:06:11 +0800 Subject: [PATCH] update to lua 5.3.1 --- 3rd/lua/Makefile | 62 +++++------ 3rd/lua/README | 2 +- 3rd/lua/lapi.c | 179 +++++++++++------------------- 3rd/lua/lapi.h | 6 +- 3rd/lua/lauxlib.c | 126 +-------------------- 3rd/lua/lbaselib.c | 4 +- 3rd/lua/lcode.c | 53 ++++----- 3rd/lua/lcode.h | 2 +- 3rd/lua/ldblib.c | 21 +++- 3rd/lua/ldebug.c | 63 ++++++----- 3rd/lua/ldebug.h | 11 +- 3rd/lua/ldo.c | 30 ++--- 3rd/lua/ldo.h | 4 +- 3rd/lua/ldump.c | 28 ++--- 3rd/lua/lfunc.c | 62 ++++------- 3rd/lua/lfunc.h | 11 +- 3rd/lua/lgc.c | 72 ++++++------ 3rd/lua/liolib.c | 15 +-- 3rd/lua/llex.c | 28 ++--- 3rd/lua/llimits.h | 107 +++++++++++++++--- 3rd/lua/lmathlib.c | 5 +- 3rd/lua/lmem.c | 11 +- 3rd/lua/loadlib.c | 7 +- 3rd/lua/lobject.c | 41 ++++--- 3rd/lua/lobject.h | 54 +++++---- 3rd/lua/loslib.c | 76 +++++++------ 3rd/lua/lparser.c | 75 ++++++------- 3rd/lua/lstate.c | 10 +- 3rd/lua/lstate.h | 3 +- 3rd/lua/lstring.c | 72 +++++++++--- 3rd/lua/lstring.h | 5 +- 3rd/lua/lstrlib.c | 125 +++++++++++++++++---- 3rd/lua/ltable.c | 123 +++++++++++---------- 3rd/lua/ltablib.c | 8 +- 3rd/lua/ltm.c | 5 +- 3rd/lua/lua.c | 36 +++--- 3rd/lua/lua.h | 19 ++-- 3rd/lua/luac.c | 34 +++--- 3rd/lua/luaconf.h | 211 +++++++++++++++++++----------------- 3rd/lua/lualib.h | 2 - 3rd/lua/lundump.c | 23 ++-- 3rd/lua/lutf8lib.c | 13 ++- 3rd/lua/lvm.c | 265 ++++++++++++++++++++++++++++----------------- 3rd/lua/lvm.h | 16 ++- 44 files changed, 1149 insertions(+), 976 deletions(-) diff --git a/3rd/lua/Makefile b/3rd/lua/Makefile index 7430722c..d71c75c8 100644 --- a/3rd/lua/Makefile +++ b/3rd/lua/Makefile @@ -7,7 +7,7 @@ PLAT= none CC= gcc -std=gnu99 -CFLAGS= -O2 -Wall -Wextra $(SYSCFLAGS) $(MYCFLAGS) +CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) @@ -130,68 +130,68 @@ solaris: # DO NOT DELETE lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ - ltable.h lundump.h lvm.h + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ + ltable.h lundump.h lvm.h lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ - llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ - ldo.h lgc.h lstring.h ltable.h lvm.h + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lgc.h lstring.h ltable.h lvm.h lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ - ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h + lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ + ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ - lparser.h lstring.h ltable.h lundump.h lvm.h + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ + lparser.h lstring.h ltable.h lundump.h lvm.h ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ - ltm.h lzio.h lmem.h lundump.h + ltm.h lzio.h lmem.h lundump.h lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ - lgc.h lstate.h ltm.h lzio.h lmem.h + lgc.h lstate.h ltm.h lzio.h lmem.h lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h -llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \ - lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \ - ltable.h +llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \ + lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \ + lstring.h ltable.h lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ - ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ - lvm.h + ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ + lvm.h lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ - llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ - ldo.h lfunc.h lstring.h lgc.h ltable.h + llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ + ldo.h lfunc.h lstring.h lgc.h ltable.h lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ - lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ - lstring.h ltable.h + lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ + lstring.h ltable.h lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ - lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h + llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h + llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \ - lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h + lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ - lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ - lundump.h + lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ + lundump.h lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ - ltable.h lvm.h + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ + ltable.h lvm.h lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ - lobject.h ltm.h lzio.h + lobject.h ltm.h lzio.h # (end of Makefile) diff --git a/3rd/lua/README b/3rd/lua/README index d658c4fd..a77dc6bf 100644 --- a/3rd/lua/README +++ b/3rd/lua/README @@ -1,4 +1,4 @@ -This is a modify version of lua 5.3.0 (http://www.lua.org/ftp/lua-5.3.0.tar.gz) . +This is a modify version of lua 5.3.1 (http://www.lua.org/ftp/lua-5.3.1.tar.gz) . For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html diff --git a/3rd/lua/lapi.c b/3rd/lua/lapi.c index 8d9c3765..fea9eb27 100644 --- a/3rd/lua/lapi.c +++ b/3rd/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 */ @@ -28,7 +28,6 @@ #include "ltm.h" #include "lundump.h" #include "lvm.h" -#include "lfunc.h" @@ -52,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 { @@ -99,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 */ @@ -121,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); } @@ -160,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; } @@ -173,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); @@ -209,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 */ @@ -224,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); @@ -256,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); } @@ -306,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); @@ -326,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); @@ -383,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; @@ -432,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; } } @@ -483,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; } @@ -532,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; @@ -584,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); @@ -629,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); @@ -640,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); @@ -653,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); @@ -706,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); @@ -725,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); @@ -748,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); @@ -760,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); @@ -773,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); @@ -789,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); @@ -805,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); @@ -824,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)) { @@ -860,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--; @@ -874,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") @@ -882,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? */ @@ -923,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 */ @@ -985,59 +989,6 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, } -static Proto * cloneproto (lua_State *L, const Proto *src) { - /* copy constants and nested proto */ - int i,n; - Proto *f = luaF_newproto(L, src->sp); - n = src->sp->sizek; - f->k=luaM_newvector(L,n,TValue); - for (i=0; ik[i]); - for (i=0; ik[i]; - TValue *o=&f->k[i]; - if (ttisstring(s)) { - TString * str = luaS_newlstr(L,svalue(s),tsvalue(s)->len); - setsvalue2n(L,o,str); - } else { - setobj(L,o,s); - } - } - n = src->sp->sizep; - f->p=luaM_newvector(L,n,struct Proto *); - for (i=0; ip[i]=NULL; - for (i=0; ip[i]=cloneproto(L, src->p[i]); - } - return f; -} - -LUA_API void lua_clonefunction (lua_State *L, const void * fp) { - LClosure *cl; - LClosure *f = cast(LClosure *, fp); - lua_lock(L); - if (f->p->sp->l_G == G(L)) { - setclLvalue(L,L->top,f); - api_incr_top(L); - lua_unlock(L); - return; - } - cl = luaF_newLclosure(L,f->nupvalues); - cl->p = cloneproto(L, f->p); - setclLvalue(L,L->top,cl); - api_incr_top(L); - luaF_initupvals(L, cl); - - if (cl->nupvalues >= 1) { /* does it have an upvalue? */ - /* get global table from registry */ - Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ - setobj(L, cl->upvals[0]->v, gt); - luaC_upvalbarrier(L, cl->upvals[0]); - } - lua_unlock(L); -} - LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { int status; TValue *o; @@ -1150,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); @@ -1232,7 +1183,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, case LUA_TLCL: { /* Lua closure */ LClosure *f = clLvalue(fi); TString *name; - SharedProto *p = f->p->sp; + Proto *p = f->p; if (!(1 <= n && n <= p->sizeupvalues)) return NULL; *val = f->upvals[n-1]->v; if (uv) *uv = f->upvals[n - 1]; @@ -1282,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 */ } @@ -1298,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/3rd/lua/lapi.h b/3rd/lua/lapi.h index 092f5e97..6d36dee3 100644 --- a/3rd/lua/lapi.h +++ b/3rd/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/3rd/lua/lauxlib.c b/3rd/lua/lauxlib.c index 72ef5d95..b8bace7f 100644 --- a/3rd/lua/lauxlib.c +++ b/3rd/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 */ @@ -638,7 +638,7 @@ static int skipcomment (LoadF *lf, int *cp) { } -static int luaL_loadfilex_ (lua_State *L, const char *filename, +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) { LoadF lf; int status, readstatus; @@ -970,123 +970,3 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { ver, *v); } -// use clonefunction - -#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {} -#define UNLOCK(q) __sync_lock_release(&(q)->lock); - -struct codecache { - int lock; - lua_State *L; -}; - -static struct codecache CC = { 0 , NULL }; - -static void -clearcache() { - if (CC.L == NULL) - return; - LOCK(&CC) - lua_close(CC.L); - CC.L = luaL_newstate(); - UNLOCK(&CC) -} - -static void -init() { - CC.lock = 0; - CC.L = luaL_newstate(); -} - -static const void * -load(const char *key) { - if (CC.L == NULL) - return NULL; - LOCK(&CC) - lua_State *L = CC.L; - lua_pushstring(L, key); - lua_rawget(L, LUA_REGISTRYINDEX); - const void * result = lua_touserdata(L, -1); - lua_pop(L, 1); - UNLOCK(&CC) - - return result; -} - -static const void * -save(const char *key, const void * proto) { - lua_State *L; - const void * result = NULL; - - LOCK(&CC) - if (CC.L == NULL) { - init(); - L = CC.L; - } else { - L = CC.L; - lua_pushstring(L, key); - lua_pushvalue(L, -1); - lua_rawget(L, LUA_REGISTRYINDEX); - result = lua_touserdata(L, -1); /* stack: key oldvalue */ - if (result == NULL) { - lua_pop(L,1); - lua_pushlightuserdata(L, (void *)proto); - lua_rawset(L, LUA_REGISTRYINDEX); - } else { - lua_pop(L,2); - } - } - UNLOCK(&CC) - return result; -} - -LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, - const char *mode) { - const void * proto = load(filename); - if (proto) { - lua_clonefunction(L, proto); - return LUA_OK; - } - lua_State * eL = luaL_newstate(); - if (eL == NULL) { - lua_pushliteral(L, "New state failed"); - return LUA_ERRMEM; - } - int err = luaL_loadfilex_(eL, filename, mode); - if (err != LUA_OK) { - size_t sz = 0; - const char * msg = lua_tolstring(eL, -1, &sz); - lua_pushlstring(L, msg, sz); - lua_close(eL); - return err; - } - proto = lua_topointer(eL, -1); - const void * oldv = save(filename, proto); - if (oldv) { - lua_close(eL); - lua_clonefunction(L, oldv); - } else { - lua_clonefunction(L, proto); - /* Never close it. notice: memory leak */ - } - - return LUA_OK; -} - -static int -cache_clear(lua_State *L) { - (void)(L); - clearcache(); - return 0; -} - -LUAMOD_API int luaopen_cache(lua_State *L) { - luaL_Reg l[] = { - { "clear", cache_clear }, - { NULL, NULL }, - }; - luaL_newlib(L,l); - lua_getglobal(L, "loadfile"); - lua_setfield(L, -2, "loadfile"); - return 1; -} diff --git a/3rd/lua/lbaselib.c b/3rd/lua/lbaselib.c index a2403952..9a151245 100644 --- a/3rd/lua/lbaselib.c +++ b/3rd/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/3rd/lua/lcode.c b/3rd/lua/lcode.c index 0f0a6752..d6f0fcd8 100644 --- a/3rd/lua/lcode.c +++ b/3rd/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) @@ -55,7 +55,7 @@ void luaK_nil (FuncState *fs, int from, int n) { Instruction *previous; int l = from + n - 1; /* last register to set nil */ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ - previous = &fs->f->sp->code[fs->pc-1]; + previous = &fs->f->code[fs->pc-1]; if (GET_OPCODE(*previous) == OP_LOADNIL) { int pfrom = GETARG_A(*previous); int pl = pfrom + GETARG_B(*previous); @@ -95,7 +95,7 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { static void fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->sp->code[pc]; + Instruction *jmp = &fs->f->code[pc]; int offset = dest-(pc+1); lua_assert(dest != NO_JUMP); if (abs(offset) > MAXARG_sBx) @@ -115,7 +115,7 @@ int luaK_getlabel (FuncState *fs) { static int getjump (FuncState *fs, int pc) { - int offset = GETARG_sBx(fs->f->sp->code[pc]); + int offset = GETARG_sBx(fs->f->code[pc]); if (offset == NO_JUMP) /* point to itself represents end of list */ return NO_JUMP; /* end of list */ else @@ -124,7 +124,7 @@ static int getjump (FuncState *fs, int pc) { static Instruction *getjumpcontrol (FuncState *fs, int pc) { - Instruction *pi = &fs->f->sp->code[pc]; + Instruction *pi = &fs->f->code[pc]; if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) return pi-1; else @@ -197,10 +197,10 @@ void luaK_patchclose (FuncState *fs, int list, int level) { level++; /* argument is +1 to reserve 0 as non-op */ while (list != NO_JUMP) { int next = getjump(fs, list); - lua_assert(GET_OPCODE(fs->f->sp->code[list]) == OP_JMP && - (GETARG_A(fs->f->sp->code[list]) == 0 || - GETARG_A(fs->f->sp->code[list]) >= level)); - SETARG_A(fs->f->sp->code[list], level); + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); list = next; } } @@ -230,13 +230,13 @@ static int luaK_code (FuncState *fs, Instruction i) { Proto *f = fs->f; dischargejpc(fs); /* 'pc' will change */ /* put new instruction in code array */ - luaM_growvector(fs->ls->L, f->sp->code, fs->pc, f->sp->sizecode, Instruction, + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "opcodes"); - f->sp->code[fs->pc] = i; + f->code[fs->pc] = i; /* save corresponding line information */ - luaM_growvector(fs->ls->L, f->sp->lineinfo, fs->pc, f->sp->sizelineinfo, int, + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "opcodes"); - f->sp->lineinfo[fs->pc] = fs->ls->lastline; + f->lineinfo[fs->pc] = fs->ls->lastline; return fs->pc++; } @@ -277,10 +277,11 @@ int luaK_codek (FuncState *fs, int reg, int k) { void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; - if (newstack > fs->f->sp->maxstacksize) { + if (newstack > fs->f->maxstacksize) { if (newstack >= MAXREGS) - luaX_syntaxerror(fs->ls, "function or expression too complex"); - fs->f->sp->maxstacksize = cast_byte(newstack); + luaX_syntaxerror(fs->ls, + "function or expression needs too many registers"); + fs->f->maxstacksize = cast_byte(newstack); } } @@ -322,13 +323,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { return k; /* reuse index */ } /* constant not found; create a new entry */ - oldsize = f->sp->sizek; + oldsize = f->sizek; k = fs->nk; /* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ setivalue(idx, k); - luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants"); - while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); setobj(L, &f->k[k], v); fs->nk++; luaC_barrier(L, f, v); @@ -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); @@ -933,7 +934,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, void luaK_fixline (FuncState *fs, int line) { - fs->f->sp->lineinfo[fs->pc - 1] = line; + fs->f->lineinfo[fs->pc - 1] = line; } diff --git a/3rd/lua/lcode.h b/3rd/lua/lcode.h index b4c865f9..43ab86db 100644 --- a/3rd/lua/lcode.h +++ b/3rd/lua/lcode.h @@ -40,7 +40,7 @@ typedef enum BinOpr { typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; -#define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info]) +#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) diff --git a/3rd/lua/ldblib.c b/3rd/lua/ldblib.c index 24a11b53..91514584 100644 --- a/3rd/lua/ldblib.c +++ b/3rd/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/3rd/lua/ldebug.c b/3rd/lua/ldebug.c index a8cb5606..f76582c5 100644 --- a/3rd/lua/ldebug.c +++ b/3rd/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); @@ -114,15 +118,15 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { static const char *upvalname (Proto *p, int uv) { - TString *s = check_exp(uv < p->sizeupvalues, p->sp->upvalues[uv].name); + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); if (s == NULL) return "?"; else return getstr(s); } static const char *findvararg (CallInfo *ci, int n, StkId *pos) { - int nparams = clLvalue(ci->func)->p->sp->numparams; - if (n >= ci->u.l.base - ci->func - nparams) + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= cast_int(ci->u.l.base - ci->func) - nparams) return NULL; /* no such vararg */ else { *pos = ci->func + nparams + n; @@ -168,7 +172,7 @@ 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); @@ -182,7 +186,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - StkId pos = 0; /* to avoid warnings */ + StkId pos = NULL; /* to avoid warnings */ const char *name; lua_lock(L); swapextra(L); @@ -205,7 +209,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) { ar->what = "C"; } else { - SharedProto *p = cl->l.p->sp; + Proto *p = cl->l.p; ar->source = p->source ? getstr(p->source) : "=?"; ar->linedefined = p->linedefined; ar->lastlinedefined = p->lastlinedefined; @@ -223,12 +227,12 @@ static void collectvalidlines (lua_State *L, Closure *f) { else { int i; TValue v; - int *lineinfo = f->l.p->sp->lineinfo; + int *lineinfo = f->l.p->lineinfo; Table *t = luaH_new(L); /* new table to store active lines */ sethvalue(L, L->top, t); /* push it on stack */ api_incr_top(L); setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ - for (i = 0; i < f->l.p->sp->sizelineinfo; i++) /* for all lines with code */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ } } @@ -254,8 +258,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, ar->nparams = 0; } else { - ar->isvararg = f->l.p->sp->is_vararg; - ar->nparams = f->l.p->sp->numparams; + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; } break; } @@ -295,7 +299,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 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 */ } @@ -366,7 +370,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) { int setreg = -1; /* keep last instruction that changed 'reg' */ int jmptarget = 0; /* any code before this address is conditional */ for (pc = 0; pc < lastpc; pc++) { - Instruction i = p->sp->code[pc]; + Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); int a = GETARG_A(i); switch (op) { @@ -416,7 +420,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, /* else try symbolic execution */ pc = findsetreg(p, lastpc, reg); if (pc != -1) { /* could find instruction? */ - Instruction i = p->sp->code[pc]; + Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); switch (op) { case OP_MOVE: { @@ -442,7 +446,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, case OP_LOADK: case OP_LOADKX: { int b = (op == OP_LOADK) ? GETARG_Bx(i) - : GETARG_Ax(p->sp->code[pc + 1]); + : GETARG_Ax(p->code[pc + 1]); if (ttisstring(&p->k[b])) { *name = svalue(&p->k[b]); return "constant"; @@ -465,7 +469,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { TMS tm = (TMS)0; /* to avoid warnings */ Proto *p = ci_func(ci)->p; /* calling function */ int pc = currentpc(ci); /* calling instruction index */ - Instruction i = p->sp->code[pc]; /* calling instruction */ + Instruction i = p->code[pc]; /* calling instruction */ if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ *name = "?"; return "hook"; @@ -595,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->sp->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); } @@ -624,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/3rd/lua/ldebug.h b/3rd/lua/ldebug.h index 916ce308..0e31546b 100644 --- a/3rd/lua/ldebug.h +++ b/3rd/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 */ @@ -11,15 +11,12 @@ #include "lstate.h" -#define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1) +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) -#define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1) +#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) #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/3rd/lua/ldo.c b/3rd/lua/ldo.c index 227a8b82..5c93a259 100644 --- a/3rd/lua/ldo.c +++ b/3rd/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 */ @@ -269,7 +269,7 @@ static void callhook (lua_State *L, CallInfo *ci) { } -static StkId adjust_varargs (lua_State *L, SharedProto *p, int actual) { +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { int i; int nfixargs = p->numparams; StkId base, fixed; @@ -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; - SharedProto *p = clLvalue(func)->p->sp; + 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/3rd/lua/ldo.h b/3rd/lua/ldo.h index 05745c8a..edade657 100644 --- a/3rd/lua/ldo.h +++ b/3rd/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/3rd/lua/ldump.c b/3rd/lua/ldump.c index c4efac16..4c04812a 100644 --- a/3rd/lua/ldump.c +++ b/3rd/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,19 +74,20 @@ 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' */ } } -static void DumpCode (const SharedProto *f, DumpState *D) { +static void DumpCode (const Proto *f, DumpState *D) { DumpInt(f->sizecode, D); DumpVector(f->code, f->sizecode, D); } @@ -96,7 +97,7 @@ static void DumpFunction(const Proto *f, TString *psource, DumpState *D); static void DumpConstants (const Proto *f, DumpState *D) { int i; - int n = f->sp->sizek; + int n = f->sizek; DumpInt(n, D); for (i = 0; i < n; i++) { const TValue *o = &f->k[i]; @@ -126,14 +127,14 @@ static void DumpConstants (const Proto *f, DumpState *D) { static void DumpProtos (const Proto *f, DumpState *D) { int i; - int n = f->sp->sizep; + int n = f->sizep; DumpInt(n, D); for (i = 0; i < n; i++) - DumpFunction(f->p[i], f->sp->source, D); + DumpFunction(f->p[i], f->source, D); } -static void DumpUpvalues (const SharedProto *f, DumpState *D) { +static void DumpUpvalues (const Proto *f, DumpState *D) { int i, n = f->sizeupvalues; DumpInt(n, D); for (i = 0; i < n; i++) { @@ -143,7 +144,7 @@ static void DumpUpvalues (const SharedProto *f, DumpState *D) { } -static void DumpDebug (const SharedProto *f, DumpState *D) { +static void DumpDebug (const Proto *f, DumpState *D) { int i, n; n = (D->strip) ? 0 : f->sizelineinfo; DumpInt(n, D); @@ -162,8 +163,7 @@ static void DumpDebug (const SharedProto *f, DumpState *D) { } -static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) { - const SharedProto *f = fp->sp; +static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { if (D->strip || f->source == psource) DumpString(NULL, D); /* no debug info or same source as its parent */ else @@ -174,9 +174,9 @@ static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) { DumpByte(f->is_vararg, D); DumpByte(f->maxstacksize, D); DumpCode(f, D); - DumpConstants(fp, D); + DumpConstants(f, D); DumpUpvalues(f, D); - DumpProtos(fp, D); + DumpProtos(f, D); DumpDebug(f, D); } @@ -208,7 +208,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, D.strip = strip; D.status = 0; DumpHeader(&D); - DumpByte(f->sp->sizeupvalues, &D); + DumpByte(f->sizeupvalues, &D); DumpFunction(f, NULL, &D); return D.status; } diff --git a/3rd/lua/lfunc.c b/3rd/lua/lfunc.c index c1f2daf7..67967dab 100644 --- a/3rd/lua/lfunc.c +++ b/3rd/lua/lfunc.c @@ -96,52 +96,39 @@ void luaF_close (lua_State *L, StkId level) { } -Proto *luaF_newproto (lua_State *L, SharedProto *sp) { +Proto *luaF_newproto (lua_State *L) { GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); Proto *f = gco2p(o); - f->sp = NULL; f->k = NULL; + f->sizek = 0; f->p = NULL; + f->sizep = 0; + f->code = NULL; f->cache = NULL; - if (sp == NULL) { - sp = luaM_new(L, SharedProto); - sp->l_G = G(L); - sp->sizek = 0; - sp->sizep = 0; - sp->code = NULL; - sp->sizecode = 0; - sp->lineinfo = NULL; - sp->sizelineinfo = 0; - sp->upvalues = NULL; - sp->sizeupvalues = 0; - sp->numparams = 0; - sp->is_vararg = 0; - sp->maxstacksize = 0; - sp->locvars = NULL; - sp->sizelocvars = 0; - sp->linedefined = 0; - sp->lastlinedefined = 0; - sp->source = NULL; - } - f->sp = sp; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; return f; } -static void freesharedproto (lua_State *L, SharedProto *f) { - if (f == NULL || G(L) != f->l_G) - return; - luaM_freearray(L, f->code, f->sizecode); - luaM_freearray(L, f->lineinfo, f->sizelineinfo); - luaM_freearray(L, f->locvars, f->sizelocvars); - luaM_freearray(L, f->upvalues, f->sizeupvalues); - luaM_free(L, f); -} - void luaF_freeproto (lua_State *L, Proto *f) { - luaM_freearray(L, f->p, f->sp->sizep); - luaM_freearray(L, f->k, f->sp->sizek); - freesharedproto(L, f->sp); + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); luaM_free(L, f); } @@ -150,9 +137,8 @@ void luaF_freeproto (lua_State *L, Proto *f) { ** Look for n-th local variable at line 'line' in function 'func'. ** Returns NULL if not found. */ -const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) { +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { int i; - const SharedProto *f = fp->sp; for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ local_number--; diff --git a/3rd/lua/lfunc.h b/3rd/lua/lfunc.h index 9d02a4b3..2eeb0d5a 100644 --- a/3rd/lua/lfunc.h +++ b/3rd/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 */ @@ -22,6 +22,13 @@ #define isintwups(L) (L->twups != L) +/* +** 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 */ @@ -40,7 +47,7 @@ struct UpVal { #define upisopen(up) ((up)->v != &(up)->u.value) -LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp); +LUAI_FUNC Proto *luaF_newproto (lua_State *L); LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); diff --git a/3rd/lua/lgc.c b/3rd/lua/lgc.c index 0be4866a..973c269f 100644 --- a/3rd/lua/lgc.c +++ b/3rd/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')), @@ -456,32 +465,31 @@ static lu_mem traversetable (global_State *g, Table *h) { sizeof(Node) * cast(size_t, sizenode(h)); } -static int marksharedproto (global_State *g, SharedProto *f) { - int i; - if (g != f->l_G) - return 0; - markobject(g, f->source); - for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ - markobject(g, f->upvalues[i].name); - for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ - markobject(g, f->locvars[i].varname); - return sizeof(Instruction) * f->sizecode + - sizeof(int) * f->sizelineinfo + - sizeof(LocVar) * f->sizelocvars + - sizeof(Upvaldesc) * f->sizeupvalues; -} +/* +** 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 */ - for (i = 0; i < f->sp->sizek; i++) /* mark literals */ + markobjectN(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ markvalue(g, &f->k[i]); - for (i = 0; i < f->sp->sizep; i++) /* mark nested protos */ - markobject(g, f->p[i]); - return sizeof(Proto) + sizeof(Proto *) * f->sp->sizep + - sizeof(TValue) * f->sp->sizek + - marksharedproto(g, f->sp); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobjectN(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobjectN(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobjectN(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; } @@ -500,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) { @@ -695,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); @@ -1008,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/3rd/lua/liolib.c b/3rd/lua/liolib.c index 4dea3968..193cac67 100644 --- a/3rd/lua/liolib.c +++ b/3rd/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/3rd/lua/llex.c b/3rd/lua/llex.c index 6e4a457a..c35bd55f 100644 --- a/3rd/lua/llex.c +++ b/3rd/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; isource), 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/3rd/lua/llimits.h b/3rd/lua/llimits.h index 8f71a6ff..277c724d 100644 --- a/3rd/lua/llimits.h +++ b/3rd/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 -#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 @@ -222,6 +246,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 */ diff --git a/3rd/lua/lmathlib.c b/3rd/lua/lmathlib.c index 002c508b..4f2ec60a 100644 --- a/3rd/lua/lmathlib.c +++ b/3rd/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/3rd/lua/lmem.c b/3rd/lua/lmem.c index 4feaf036..0a0476cc 100644 --- a/3rd/lua/lmem.c +++ b/3rd/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/3rd/lua/loadlib.c b/3rd/lua/loadlib.c index 7f8d9902..bbf8f67a 100644 --- a/3rd/lua/loadlib.c +++ b/3rd/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 #include #include @@ -136,8 +137,8 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); #include /* -** 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/3rd/lua/lobject.c b/3rd/lua/lobject.c index 6a24aff9..6c53b981 100644 --- a/3rd/lua/lobject.c +++ b/3rd/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 +#include #include #include #include @@ -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 +#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/3rd/lua/lobject.h b/3rd/lua/lobject.h index 01f29139..9230b7a9 100644 --- a/3rd/lua/lobject.h +++ b/3rd/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; @@ -392,10 +405,14 @@ typedef struct LocVar { } LocVar; -typedef struct SharedProto { +/* +** Function Prototypes +*/ +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; @@ -404,23 +421,14 @@ typedef struct SharedProto { int sizelocvars; int linedefined; int lastlinedefined; - void *l_G; /* global state belongs to */ - Instruction *code; + TValue *k; /* constants used by the function */ + 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 */ TString *source; /* used for debug information */ -} SharedProto; - -/* -** Function Prototypes -*/ -typedef struct Proto { - CommonHeader; - struct SharedProto *sp; - TValue *k; /* constants used by the function */ - struct Proto **p; /* functions defined inside the function */ - struct LClosure *cache; /* last created closure with this prototype */ GCObject *gclist; } Proto; diff --git a/3rd/lua/loslib.c b/3rd/lua/loslib.c index 20359b24..cb8a3c33 100644 --- a/3rd/lua/loslib.c +++ b/3rd/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,15 +59,41 @@ #endif /* } */ - -#if !defined(lua_tmpnam) /* { */ +#if !defined(l_gmtime) /* { */ /* -** By default, Lua uses tmpnam except when POSIX is available, where it -** uses mkstemp. +** 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 /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** 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) /* { */ + #include #define LUA_TMPNAMBUFSIZE 32 @@ -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/3rd/lua/lparser.c b/3rd/lua/lparser.c index 0bed0dd3..9a54dfc9 100644 --- a/3rd/lua/lparser.c +++ b/3rd/lua/lparser.c @@ -79,7 +79,7 @@ static l_noret error_expected (LexState *ls, int token) { static l_noret errorlimit (FuncState *fs, int limit, const char *what) { lua_State *L = fs->ls->L; const char *msg; - int line = fs->f->sp->linedefined; + int line = fs->f->linedefined; const char *where = (line == 0) ? "main function" : luaO_pushfstring(L, "function at line %d", line); @@ -160,14 +160,13 @@ static void checkname (LexState *ls, expdesc *e) { static int registerlocalvar (LexState *ls, TString *varname) { FuncState *fs = ls->fs; - Proto *fp = fs->f; - SharedProto *f = fp->sp; + Proto *f = fs->f; int oldsize = f->sizelocvars; luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, SHRT_MAX, "local variables"); while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; f->locvars[fs->nlocvars].varname = varname; - luaC_objbarrier(ls->L, fp, varname); + luaC_objbarrier(ls->L, f, varname); return fs->nlocvars++; } @@ -195,7 +194,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { static LocVar *getlocvar (FuncState *fs, int i) { int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; lua_assert(idx < fs->nlocvars); - return &fs->f->sp->locvars[idx]; + return &fs->f->locvars[idx]; } @@ -217,7 +216,7 @@ static void removevars (FuncState *fs, int tolevel) { static int searchupvalue (FuncState *fs, TString *name) { int i; - Upvaldesc *up = fs->f->sp->upvalues; + Upvaldesc *up = fs->f->upvalues; for (i = 0; i < fs->nups; i++) { if (eqstr(up[i].name, name)) return i; } @@ -226,8 +225,7 @@ static int searchupvalue (FuncState *fs, TString *name) { static int newupvalue (FuncState *fs, TString *name, expdesc *v) { - Proto *fp = fs->f; - SharedProto *f = fp->sp; + Proto *f = fs->f; int oldsize = f->sizeupvalues; checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, @@ -236,7 +234,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { f->upvalues[fs->nups].instack = (v->k == VLOCAL); f->upvalues[fs->nups].idx = cast_byte(v->u.info); f->upvalues[fs->nups].name = name; - luaC_objbarrier(fs->ls->L, fp, name); + luaC_objbarrier(fs->ls->L, f, name); return fs->nups++; } @@ -498,12 +496,12 @@ static Proto *addprototype (LexState *ls) { lua_State *L = ls->L; FuncState *fs = ls->fs; Proto *f = fs->f; /* prototype of current function */ - if (fs->np >= f->sp->sizep) { - int oldsize = f->sp->sizep; - luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions"); - while (oldsize < f->sp->sizep) f->p[oldsize++] = NULL; + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; } - f->p[fs->np++] = clp = luaF_newproto(L, NULL); + f->p[fs->np++] = clp = luaF_newproto(L); luaC_objbarrier(L, f, clp); return clp; } @@ -523,7 +521,7 @@ static void codeclosure (LexState *ls, expdesc *v) { static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { - SharedProto *f; + Proto *f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; ls->fs = fs; @@ -538,7 +536,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->nactvar = 0; fs->firstlocal = ls->dyd->actvar.n; fs->bl = NULL; - f = fs->f->sp; + f = fs->f; f->source = ls->source; f->maxstacksize = 2; /* registers 0/1 are always valid */ enterblock(fs, bl, 0); @@ -549,21 +547,20 @@ static void close_func (LexState *ls) { lua_State *L = ls->L; FuncState *fs = ls->fs; Proto *f = fs->f; - SharedProto *sp = f->sp; luaK_ret(fs, 0, 0); /* final return */ leaveblock(fs); - luaM_reallocvector(L, sp->code, sp->sizecode, fs->pc, Instruction); - sp->sizecode = fs->pc; - luaM_reallocvector(L, sp->lineinfo, sp->sizelineinfo, fs->pc, int); - sp->sizelineinfo = fs->pc; - luaM_reallocvector(L, f->k, sp->sizek, fs->nk, TValue); - sp->sizek = fs->nk; - luaM_reallocvector(L, f->p, sp->sizep, fs->np, Proto *); - sp->sizep = fs->np; - luaM_reallocvector(L, sp->locvars, sp->sizelocvars, fs->nlocvars, LocVar); - sp->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, sp->upvalues, sp->sizeupvalues, fs->nups, Upvaldesc); - sp->sizeupvalues = fs->nups; + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; lua_assert(fs->bl == NULL); ls->fs = fs->prev; luaC_checkGC(L); @@ -739,8 +736,8 @@ static void constructor (LexState *ls, expdesc *t) { } while (testnext(ls, ',') || testnext(ls, ';')); check_match(ls, '}', '{', line); lastlistfield(fs, &cc); - SETARG_B(fs->f->sp->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ - SETARG_C(fs->f->sp->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ } /* }====================================================================== */ @@ -750,7 +747,7 @@ static void constructor (LexState *ls, expdesc *t) { static void parlist (LexState *ls) { /* parlist -> [ param { ',' param } ] */ FuncState *fs = ls->fs; - SharedProto *f = fs->f->sp; + Proto *f = fs->f; int nparams = 0; f->is_vararg = 0; if (ls->t.token != ')') { /* is 'parlist' not empty? */ @@ -781,7 +778,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) { FuncState new_fs; BlockCnt bl; new_fs.f = addprototype(ls); - new_fs.f->sp->linedefined = line; + new_fs.f->linedefined = line; open_func(ls, &new_fs, &bl); checknext(ls, '('); if (ismethod) { @@ -791,7 +788,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) { parlist(ls); checknext(ls, ')'); statlist(ls); - new_fs.f->sp->lastlinedefined = ls->linenumber; + new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); codeclosure(ls, e); close_func(ls); @@ -957,7 +954,7 @@ static void simpleexp (LexState *ls, expdesc *v) { } case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; - check_condition(ls, fs->f->sp->is_vararg, + check_condition(ls, fs->f->is_vararg, "cannot use '...' outside a vararg function"); init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; @@ -1613,7 +1610,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { BlockCnt bl; expdesc v; open_func(ls, fs, &bl); - fs->f->sp->is_vararg = 1; /* main function is always vararg */ + fs->f->is_vararg = 1; /* main function is always vararg */ init_exp(&v, VLOCAL, 0); /* create and... */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ luaX_next(ls); /* read first token */ @@ -1633,13 +1630,13 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, lexstate.h = luaH_new(L); /* create table for scanner */ sethvalue(L, L->top, lexstate.h); /* anchor it */ incr_top(L); - funcstate.f = cl->p = luaF_newproto(L, NULL); - funcstate.f->sp->source = luaS_new(L, name); /* create and anchor TString */ + funcstate.f = cl->p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lexstate.buff = buff; lexstate.dyd = dyd; dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; - luaX_setinput(L, &lexstate, z, funcstate.f->sp->source, firstchar); + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); mainfunc(&lexstate, &funcstate); lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); /* all scopes should be correctly finished */ diff --git a/3rd/lua/lstate.c b/3rd/lua/lstate.c index ff6b02d3..12e51d24 100644 --- a/3rd/lua/lstate.c +++ b/3rd/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/3rd/lua/lstate.h b/3rd/lua/lstate.h index cdcdd5a4..eefc217d 100644 --- a/3rd/lua/lstate.h +++ b/3rd/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 */ @@ -141,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/3rd/lua/lstring.c b/3rd/lua/lstring.c index 2947113c..5e0e3c40 100644 --- a/3rd/lua/lstring.c +++ b/3rd/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/3rd/lua/lstring.h b/3rd/lua/lstring.h index d3f04caf..e746f5fc 100644 --- a/3rd/lua/lstring.h +++ b/3rd/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/3rd/lua/lstrlib.c b/3rd/lua/lstrlib.c index 43be88ec..19c350de 100644 --- a/3rd/lua/lstrlib.c +++ b/3rd/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 +#include #include #include #include @@ -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; icapture[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,18 +798,100 @@ static int str_gsub (lua_State *L) { ** ======================================================= */ -/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ -#define MAX_ITEM \ - (sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050) +#if !defined(lua_number2strx) /* { */ + +/* +** Hexadecimal floating-point formatter +*/ + +#include +#include + +#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) { @@ -850,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; } @@ -902,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); @@ -922,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'", @@ -1250,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/3rd/lua/ltable.c b/3rd/lua/ltable.c index 38be0051..04f2a347 100644 --- a/3rd/lua/ltable.c +++ b/3rd/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 #include -#include #include #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/3rd/lua/ltablib.c b/3rd/lua/ltablib.c index 8f78afb7..a05c885c 100644 --- a/3rd/lua/ltablib.c +++ b/3rd/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/3rd/lua/ltm.c b/3rd/lua/ltm.c index 25b46b17..c38e5c34 100644 --- a/3rd/lua/ltm.c +++ b/3rd/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/3rd/lua/lua.c b/3rd/lua/lua.c index 34a3900a..7a47582c 100644 --- a/3rd/lua/lua.c +++ b/3rd/lua/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.222 2014/11/11 19:41:27 roberto Exp $ +** $Id: lua.c,v 1.225 2015/03/30 15:42:59 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -80,9 +80,7 @@ #include #include #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) -#define lua_saveline(L,idx) \ - if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \ - add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_saveline(L,line) ((void)L, add_history(line)) #define lua_freeline(L,b) ((void)L, free(b)) #else /* }{ */ @@ -90,7 +88,7 @@ #define lua_readline(L,b,p) \ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ -#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_saveline(L,line) { (void)L; (void)line; } #define lua_freeline(L,b) { (void)L; (void)b; } #endif /* } */ @@ -315,11 +313,11 @@ static int pushline (lua_State *L, int firstline) { lua_pop(L, 1); /* remove prompt */ l = strlen(b); if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ - b[l-1] = '\0'; /* remove it */ + b[--l] = '\0'; /* remove it */ if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */ lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */ else - lua_pushstring(L, b); + lua_pushlstring(L, b, l); lua_freeline(L, b); return 1; } @@ -336,8 +334,12 @@ static int addreturn (lua_State *L) { lua_pushvalue(L, -2); /* duplicate line */ lua_concat(L, 2); /* new line is "return ..." */ line = lua_tolstring(L, -1, &len); - if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) + if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) { lua_remove(L, -3); /* remove original line */ + line += sizeof("return")/sizeof(char); /* remove 'return' for history */ + if (line[0] != '\0') /* non empty? */ + lua_saveline(L, line); /* keep history */ + } else lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */ return status; @@ -352,8 +354,10 @@ static int multiline (lua_State *L) { size_t len; const char *line = lua_tolstring(L, 1, &len); /* get what it has */ int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ - if (!incomplete(L, status) || !pushline(L, 0)) + if (!incomplete(L, status) || !pushline(L, 0)) { + lua_saveline(L, line); /* keep history */ return status; /* cannot or should not try to add continuation line */ + } lua_pushliteral(L, "\n"); /* add newline... */ lua_insert(L, -2); /* ...between the two lines */ lua_concat(L, 3); /* join them */ @@ -374,7 +378,6 @@ static int loadline (lua_State *L) { return -1; /* no input */ if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ status = multiline(L); /* try as command, maybe with continuation lines */ - lua_saveline(L, 1); /* keep history */ lua_remove(L, 1); /* remove line from the stack */ lua_assert(lua_gettop(L) == 1); return status; @@ -482,14 +485,14 @@ static int collectargs (char **argv, int *first) { args |= has_E; break; case 'i': - args |= has_i; /* goes through (-i implies -v) */ + args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */ case 'v': if (argv[i][2] != '\0') /* extra characters after 1st? */ return has_error; /* invalid option */ args |= has_v; break; case 'e': - args |= has_e; /* go through */ + args |= has_e; /* FALLTHROUGH */ case 'l': /* both options need an argument */ if (argv[i][2] == '\0') { /* no concatenated argument? */ i++; /* try next 'argv' */ @@ -513,17 +516,16 @@ static int collectargs (char **argv, int *first) { static int runargs (lua_State *L, char **argv, int n) { int i; for (i = 1; i < n; i++) { - int status; int option = argv[i][1]; lua_assert(argv[i][0] == '-'); /* already checked */ if (option == 'e' || option == 'l') { + int status; const char *extra = argv[i] + 2; /* both options need an argument */ if (*extra == '\0') extra = argv[++i]; lua_assert(extra != NULL); - if (option == 'e') - status = dostring(L, extra, "=(command line)"); - else - status = dolibrary(L, extra); + status = (option == 'e') + ? dostring(L, extra, "=(command line)") + : dolibrary(L, extra); if (status != LUA_OK) return 0; } } diff --git a/3rd/lua/lua.h b/3rd/lua/lua.h index 313e4cd0..1c2b95ac 100644 --- a/3rd/lua/lua.h +++ b/3rd/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)) @@ -280,7 +282,6 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); -LUA_API void (lua_clonefunction) (lua_State *L, const void *eL); /* ** coroutine functions @@ -357,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) @@ -458,11 +458,6 @@ struct lua_Debug { /* }====================================================================== */ -/* Add by skynet */ - -LUA_API lua_State * skynet_sig_L; -LUA_API void (lua_checksig_)(lua_State *L); -#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); } /****************************************************************************** * Copyright (C) 1994-2015 Lua.org, PUC-Rio. diff --git a/3rd/lua/luac.c b/3rd/lua/luac.c index ea2f1c8f..c0c91d01 100644 --- a/3rd/lua/luac.c +++ b/3rd/lua/luac.c @@ -1,5 +1,5 @@ /* -** $Id: luac.c,v 1.72 2015/01/06 03:09:13 lhf Exp $ +** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $ ** Lua compiler (saves bytecodes to files; also lists bytecodes) ** See Copyright Notice in lua.h */ @@ -149,9 +149,9 @@ static const Proto* combine(lua_State* L, int n) for (i=0; ip[i]=toproto(L,i-n-1); - if (f->p[i]->sp->sizeupvalues>0) f->p[i]->sp->upvalues[0].instack=0; + if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; } - f->sp->sizelineinfo=0; + f->sizelineinfo=0; return f; } } @@ -206,7 +206,7 @@ int main(int argc, char* argv[]) } /* -** $Id: print.c,v 1.76 2015/01/05 16:12:50 lhf Exp $ +** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $ ** print bytecodes ** See Copyright Notice in lua.h */ @@ -226,7 +226,7 @@ int main(int argc, char* argv[]) static void PrintString(const TString* ts) { const char* s=getstr(ts); - size_t i,n=ts->len; + size_t i,n=tsslen(ts); printf("%c",'"'); for (i=0; isp->upvalues[x].name) ? getstr(f->sp->upvalues[x].name) : "-") +#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") #define MYK(x) (-1-(x)) static void PrintCode(const Proto* f) { - const SharedProto *sp = f->sp; - const Instruction* code=sp->code; - int pc,n=sp->sizecode; + const Instruction* code=f->code; + int pc,n=f->sizecode; for (pc=0; pcsource ? getstr(f->source) : "=?"; if (*s=='@' || *s=='=') @@ -415,9 +414,8 @@ static void PrintHeader(const SharedProto* f) static void PrintDebug(const Proto* f) { - const SharedProto *sp = f->sp; int i,n; - n=sp->sizek; + n=f->sizek; printf("constants (%d) for %p:\n",n,VOID(f)); for (i=0; isizelocvars; + n=f->sizelocvars; printf("locals (%d) for %p:\n",n,VOID(f)); for (i=0; ilocvars[i].varname),sp->locvars[i].startpc+1,sp->locvars[i].endpc+1); + i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); } - n=f->sp->sizeupvalues; + n=f->sizeupvalues; printf("upvalues (%d) for %p:\n",n,VOID(f)); for (i=0; iupvalues[i].instack,sp->upvalues[i].idx); + i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx); } } static void PrintFunction(const Proto* f, int full) { - int i,n=f->sp->sizep; - PrintHeader(f->sp); + int i,n=f->sizep; + PrintHeader(f); PrintCode(f); if (full) PrintDebug(f); for (i=0; ip[i],full); diff --git a/3rd/lua/luaconf.h b/3rd/lua/luaconf.h index fd28d21a..7cfa4faf 100644 --- a/3rd/lua/luaconf.h +++ b/3rd/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 - -/* 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 -#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 +#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 @@ -691,20 +708,18 @@ #define LUA_IDSIZE 60 -/* -@@ 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/3rd/lua/lualib.h b/3rd/lua/lualib.h index c43f8a2d..5165c0fb 100644 --- a/3rd/lua/lualib.h +++ b/3rd/lua/lualib.h @@ -44,8 +44,6 @@ LUAMOD_API int (luaopen_debug) (lua_State *L); #define LUA_LOADLIBNAME "package" LUAMOD_API int (luaopen_package) (lua_State *L); -#define LUA_CACHELIB -LUAMOD_API int (luaopen_cache) (lua_State *L); /* open all previous libraries */ LUALIB_API void (luaL_openlibs) (lua_State *L); diff --git a/3rd/lua/lundump.c b/3rd/lua/lundump.c index 451c9097..510f3258 100644 --- a/3rd/lua/lundump.c +++ b/3rd/lua/lundump.c @@ -100,7 +100,7 @@ static TString *LoadString (LoadState *S) { } -static void LoadCode (LoadState *S, SharedProto *f) { +static void LoadCode (LoadState *S, Proto *f) { int n = LoadInt(S); f->code = luaM_newvector(S->L, n, Instruction); f->sizecode = n; @@ -115,7 +115,7 @@ static void LoadConstants (LoadState *S, Proto *f) { int i; int n = LoadInt(S); f->k = luaM_newvector(S->L, n, TValue); - f->sp->sizek = n; + f->sizek = n; for (i = 0; i < n; i++) setnilvalue(&f->k[i]); for (i = 0; i < n; i++) { @@ -149,17 +149,17 @@ static void LoadProtos (LoadState *S, Proto *f) { int i; int n = LoadInt(S); f->p = luaM_newvector(S->L, n, Proto *); - f->sp->sizep = n; + f->sizep = n; for (i = 0; i < n; i++) f->p[i] = NULL; for (i = 0; i < n; i++) { - f->p[i] = luaF_newproto(S->L, NULL); - LoadFunction(S, f->p[i], f->sp->source); + f->p[i] = luaF_newproto(S->L); + LoadFunction(S, f->p[i], f->source); } } -static void LoadUpvalues (LoadState *S, SharedProto *f) { +static void LoadUpvalues (LoadState *S, Proto *f) { int i, n; n = LoadInt(S); f->upvalues = luaM_newvector(S->L, n, Upvaldesc); @@ -173,7 +173,7 @@ static void LoadUpvalues (LoadState *S, SharedProto *f) { } -static void LoadDebug (LoadState *S, SharedProto *f) { +static void LoadDebug (LoadState *S, Proto *f) { int i, n; n = LoadInt(S); f->lineinfo = luaM_newvector(S->L, n, int); @@ -195,8 +195,7 @@ static void LoadDebug (LoadState *S, SharedProto *f) { } -static void LoadFunction (LoadState *S, Proto *fp, TString *psource) { - SharedProto *f = fp->sp; +static void LoadFunction (LoadState *S, Proto *f, TString *psource) { f->source = LoadString(S); if (f->source == NULL) /* no source in dump? */ f->source = psource; /* reuse parent's source */ @@ -206,9 +205,9 @@ static void LoadFunction (LoadState *S, Proto *fp, TString *psource) { f->is_vararg = LoadByte(S); f->maxstacksize = LoadByte(S); LoadCode(S, f); - LoadConstants(S, fp); + LoadConstants(S, f); LoadUpvalues(S, f); - LoadProtos(S, fp); + LoadProtos(S, f); LoadDebug(S, f); } @@ -269,7 +268,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, cl = luaF_newLclosure(L, LoadByte(&S)); setclLvalue(L, L->top, cl); incr_top(L); - cl->p = luaF_newproto(L, NULL); + cl->p = luaF_newproto(L); LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p); diff --git a/3rd/lua/lutf8lib.c b/3rd/lua/lutf8lib.c index be4f087f..9042582d 100644 --- a/3rd/lua/lutf8lib.c +++ b/3rd/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 +#include #include #include @@ -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/3rd/lua/lvm.c b/3rd/lua/lvm.c index cb2e2809..a8cefc52 100644 --- a/3rd/lua/lvm.c +++ b/3rd/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 #include +#include #include #include #include @@ -30,47 +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 -/* Add by skynet */ -lua_State * skynet_sig_L = NULL; -LUA_API void -lua_checksig_(lua_State *L) { - if (skynet_sig_L == G(L)->mainthread) { - skynet_sig_L = NULL; - lua_pushnil(L); - lua_error(L); - } -} /* -** 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 + /* @@ -84,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; } @@ -99,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)) { @@ -117,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 */ } @@ -125,14 +117,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. @@ -151,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; } @@ -250,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? */ @@ -271,16 +255,103 @@ 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? */ @@ -290,18 +361,20 @@ 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= 0) /* first try 'le' */ + else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ return res; else { /* try 'lt': */ L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ @@ -314,9 +387,8 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { } - /* -** 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) { @@ -325,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 */ @@ -371,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'. @@ -382,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; @@ -403,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); @@ -420,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); @@ -428,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 */ @@ -465,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.) */ @@ -510,8 +586,8 @@ lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { LClosure *c = p->cache; if (c != NULL) { /* is there a cached closure? */ - int nup = p->sp->sizeupvalues; - Upvaldesc *uv = p->sp->upvalues; + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; int i; for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; @@ -531,8 +607,8 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { */ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, StkId ra) { - int nup = p->sp->sizeupvalues; - Upvaldesc *uv = p->sp->upvalues; + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; int i; LClosure *ncl = luaF_newLclosure(L, nup); ncl->p = p; @@ -624,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 @@ -760,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; @@ -945,14 +1021,13 @@ 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 */ vmbreak; } vmcase(OP_JMP) { - lua_checksig(L); dojump(ci, i, 0); vmbreak; } @@ -1005,7 +1080,6 @@ void luaV_execute (lua_State *L) { vmcase(OP_CALL) { int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; - lua_checksig(L); if (b != 0) L->top = ra+b; /* else previous instruction set top */ if (luaD_precall(L, ra, nresults)) { /* C function? */ if (nresults >= 0) L->top = ci->top; /* adjust results */ @@ -1020,7 +1094,6 @@ void luaV_execute (lua_State *L) { } vmcase(OP_TAILCALL) { int b = GETARG_B(i); - lua_checksig(L); if (b != 0) L->top = ra+b; /* else previous instruction set top */ lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ @@ -1032,10 +1105,10 @@ void luaV_execute (lua_State *L) { StkId nfunc = nci->func; /* called function */ StkId ofunc = oci->func; /* caller function */ /* last stack slot filled by 'precall' */ - StkId lim = nci->u.l.base + getproto(nfunc)->sp->numparams; + StkId lim = nci->u.l.base + getproto(nfunc)->numparams; int aux; /* close all upvalues from previous call */ - if (cl->p->sp->sizep > 0) luaF_close(L, oci->u.l.base); + if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); /* move new frame into old one */ for (aux = 0; nfunc + aux < lim; aux++) setobjs2s(L, ofunc + aux, nfunc + aux); @@ -1051,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->sp->sizep > 0) luaF_close(L, base); - b = luaD_poscall(L, ra); + if (cl->p->sizep > 0) luaF_close(L, base); + 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 */ @@ -1071,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 */ } } @@ -1082,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 */ } } @@ -1131,7 +1203,6 @@ void luaV_execute (lua_State *L) { } vmcase(OP_TFORLOOP) { l_tforloop: - lua_checksig(L); if (!ttisnil(ra + 1)) { /* continue loop? */ setobjs2s(L, ra, ra + 1); /* save control variable */ ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ @@ -1174,7 +1245,7 @@ void luaV_execute (lua_State *L) { vmcase(OP_VARARG) { int b = GETARG_B(i) - 1; int j; - int n = cast_int(base - ci->func) - cl->p->sp->numparams - 1; + int n = cast_int(base - ci->func) - cl->p->numparams - 1; if (b < 0) { /* B == 0? */ b = n; /* get all var. arguments */ Protect(luaD_checkstack(L, n)); diff --git a/3rd/lua/lvm.h b/3rd/lua/lvm.h index 5c5e18c3..0613826a 100644 --- a/3rd/lua/lvm.h +++ b/3rd/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,